diff --git a/ProgettoRestylingWall/Wall/BatchProcess.lua b/ProgettoRestylingWall/Wall/BatchProcess.lua new file mode 100644 index 0000000..616cd84 --- /dev/null +++ b/ProgettoRestylingWall/Wall/BatchProcess.lua @@ -0,0 +1,657 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2022/02/24 +-- Gestione calcolo batch disposizione e lavorazioni per Pareti +-- 2020/07/24 Nuvola di punti riferita allo Zero Tavola. +-- 2020/10/28 Corretto spostamento pezzi per rotazioni (0 o 180) e inversioni( 0, 90, 180, o 270). +-- 2020/12/03 Ora riconosciute rotazioni di inversione con angoli negativi. +-- 2021/03/05 Aggiunta gestione altri angoli di inversione e rotazione combinati. +-- 2021/03/06 La creazione del file ori si fa solo alla fine se non ci sono stati errori o se edit. +-- 2021/03/08 Aggiunta gestione lavorazione su macchine per travi. +-- 2021/04/09 Corretto spostamento pezzi per rotazioni e inversioni. +-- 2021/07/28 Aggiunta scelta direzione di vista per modifica e simulazione. +-- 2021/10/27 Nel controllo spessore si deve considerare anche PosY. +-- 2022/02/24 Se ricalcolo si aggiorna il setup. In ogni caso si verifica prima di simulazione. + + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--WALL = {} +--WALL.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl' +--WALL.MACHINE = '90480019_MW' +--WALL.FLAG = 5 + +-- 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 == 5 then + sFlag = 'CLOUD' +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 or WALL.FLAG == 5) 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 or WALL.FLAG == 5) 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' +local sPntFile = sDir..sTitle..'.pnt' + +-- 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 .. '\\Wall\\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 + -- 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 + end + + -- Aggiorno eventuali dati ausiliari + UpdateAuxData( sBtmFile) + + -- Recupero informazione se progetto o produzione + local bProj = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PROJECT', 'i') == 1) + + -- Dimensioni del pannello + local dRawL = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PANELLEN', 'd') or 100) + local dRawW = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PANELWIDTH', 'd') or 50) + local dExtraL = 0 + local dExtraW = 0 + if bProj then + if WD.BEAM_MACHINE then + if dRawL < WD.MIN_LENGTH then + dExtraL = WD.MIN_LENGTH - dRawL + dRawL = WD.MIN_LENGTH + elseif dRawL < WD.MAX_LENGTH then + dExtraL = min( WD.MAX_LENGTH - dRawL, 3000) + dRawL = dRawL + dExtraL + end + if dRawW + 10 < WD.MIN_WIDTH then + dExtraW = WD.MIN_WIDTH - dRawW + dRawW = WD.MIN_WIDTH + elseif dRawW < WD.MAX_WIDTH then + dExtraW = min( WD.MAX_WIDTH - dRawW, 10) + dRawW = dRawW + dExtraW + end + else + dExtraW = 10 + dRawW = dRawW + dExtraW + end + end + + -- 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 + min( dExtraL, 1200) + if WD.USE_POSY then + local PosY = EgtGetInfo( vWall[i].Id, 'POSY', 'd') + vWall[i].PosY = max( PosY, 0) + else + vWall[i].PosY = 0 + end + local PosZ = EgtGetInfo( vWall[i].Id, 'POSZ', 'd') + vWall[i].PosZ = PosZ + dExtraW / 2 + 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 then + if 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 + EgtSetInfo( vWall[i].Id, 'ROTATED_DONE', dRotAng) + end + -- inversione + local dInvAng = EgtGetInfo( vWall[i].Id, 'INVERTED', 'd') + if dInvAng then + if abs( dInvAng - 180) > GEO.EPS_ANG_SMALL and abs( dInvAng + 180) > GEO.EPS_ANG_SMALL then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vWall[i].Id, ptInvCen, Z_AX(), dInvAng - 180, GDB_RT.GLOB) + b3Solid:rotate( ptInvCen, Z_AX(), dInvAng - 180) + end + EgtSetInfo( vWall[i].Id, 'INVERTED_DONE', dInvAng) + end + -- correzioni per rotazioni non centrate di produzioni TS3 (quasi sempre multipli di 90 deg) + local sType = EgtGetInfo( vWall[i].Id, 'TYPE', 's') + if not bProj and dRotAng and dInvAng and sType ~= 'LAYER' then + if abs( dInvAng - 0) < GEO.EPS_ANG_SMALL then + if abs( dRotAng - 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + end + elseif abs( dInvAng - 90) < GEO.EPS_ANG_SMALL or abs( dInvAng + 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + if abs( dRotAng - 180) < GEO.EPS_ANG_SMALL or abs( dRotAng + 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL or abs( dRotAng + 90) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + end + elseif abs( dInvAng - 180) < GEO.EPS_ANG_SMALL or abs( dInvAng + 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + if abs( dRotAng - 0) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL or abs( dRotAng + 90) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 90) < GEO.EPS_ANG_SMALL or abs( dRotAng + 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + end + elseif abs( dInvAng - 270) < GEO.EPS_ANG_SMALL or abs( dInvAng + 90) < GEO.EPS_ANG_SMALL then + if abs( dRotAng - 0) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + end + end + end + end + + -- Ne verifico le dimensioni + local dRawH = vWall[1].Box:getDimZ() + vWall[1].PosY + local vWallErr = {} + for i = 2, #vWall do + local dDimH = vWall[i].Box:getDimZ() + vWall[i].PosY + 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 or '', '\n', ' ', 10) + sMsg = string.gsub( sMsg or '', '\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) + + -- Se non ci sono errori o modalità modifica, salvo il file originale + if nErrCnt == 0 or WALL.FLAG == 1 then + EgtCopyFile( WALL.FILE, sDir..sTitle..'.ori'..sExt) + end + + -- 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 LayerId = {} + LayerId[1] = EgtGetFirstNameInGroup( nPartId, 'Outline') + LayerId[2] = EgtGetFirstNameInGroup( nPartId, 'Processings') + for nInd = 1, #LayerId do + local nProcId = EgtGetFirstInGroup( LayerId[nInd] 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 + 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 >>>') + EgtImportSetup() + 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 >>>') + -- verifico setup + local bSetUpOk, SetUpErrors = EgtVerifyCurrSetup() + if not bSetUpOk then + local sToolsList = "" + for ToolIndex = 1, #SetUpErrors do + sToolsList = sToolsList .. SetUpErrors[ToolIndex] + if ToolIndex ~= #SetUpErrors then + sToolsList = sToolsList .. ", " + end + end + WriteErrToLogFile( 19, 'Error in setup: tool/s ' .. sToolsList .. ' not found', 0, 0, 0) + return + end + -- lancio simulazione + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.INIT then + WALL.ERR = 19 + WALL.MSG = 'Error starting simulation' + 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 = 'Special 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 >>>') + local sInfo = 'EgtCAM5 - ' + if EgtGetExeVersion then + sInfo = 'EgtCAM5 ver.' .. EgtGetExeVersion() .. ' - ' + end + if not EgtGenerate( '', sInfo .. 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) + +-- Se modalità Cloud, importo la nuvola di punti +if WALL.FLAG == 5 then + EgtOutLog( ' +++ Importing Point Cloud >>>') + -- Creo gruppo Cloud nel gruppo di lavorazione + local nMGrpId = EgtGetCurrMachGroup() + local nCloudId = EgtGetFirstNameInGroup( nMGrpId or GDB_ID.NULL, 'Cloud') + if nCloudId then + EgtEmptyGroup( nCloudId) + else + nCloudId = EgtGroup( nMGrpId) + EgtSetName( nCloudId, 'Cloud') + end + -- Recupero BBox della tavola + local b3Tab = EgtGetTableArea() + if not b3Tab or b3Tab:isEmpty() then + WALL.ERR = 22 + WALL.MSG = 'Machine table not found' + return + end + -- Recupero i punti della nuvola + local hFile = io.open( sPntFile, 'r') + if not hFile then + WALL.ERR = 23 + WALL.MSG = 'Missing point cloud file' + return + end + local vPoints = {} + local sLine = hFile:read( '*l') + while sLine do + local vCoord = EgtSplitString( sLine, ' ') + if vCoord and #vCoord >= 2 then + local dX = tonumber( vCoord[1]) + b3Tab:getMax():getX() + local dY = tonumber( vCoord[2]) + b3Tab:getMin():getY() + local dZ = b3Tab:getMax():getZ() + EgtOutLog( ' X='..EgtNumToString( dX, 3)..' Y='..EgtNumToString( dY, 3), 3) + table.insert( vPoints, { dX, dY, dZ}) + end + sLine = hFile:read( '*l') + end + hFile:close() + -- Inserisco la curva di contorno della nuvola + local nClCrvId = EgtCurveCompoFromPoints( nCloudId, vPoints, GDB_RT.GLOB) + if not nClCrvId then + WALL.ERR = 24 + WALL.MSG = 'Failed to create Point cloud Contour' + return + end + EgtCloseCurveCompo( nClCrvId) + EgtApproxCurve( nClCrvId, GDB_CA.LINES, 1.0) + EgtSetColor( nClCrvId, 'RED') +end + +-- Se modifica o simula, imposto la vista ISO 3d opportuna +if WALL.FLAG == 1 or WALL.FLAG == 2 then + local vView = { SCE_VD.ISO_NW, SCE_VD.ISO_SW, SCE_VD.ISO_NE, SCE_VD.ISO_SE} + local nV = min( max( WD.SIMUL_VIEW_DIR or 2, 1), 4) + EgtSetView( vView[nV], false) +-- se cloud, imposto la vista TOP +elseif WALL.FLAG == 5 then + EgtSetView( SCE_VD.TOP, 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/ProgettoRestylingWall/Wall/BatchProcessNew.lua b/ProgettoRestylingWall/Wall/BatchProcessNew.lua new file mode 100644 index 0000000..ca59a6a --- /dev/null +++ b/ProgettoRestylingWall/Wall/BatchProcessNew.lua @@ -0,0 +1,713 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2022/01/20 +-- Gestione calcolo batch disposizione e lavorazioni per Pareti +-- 2021/01/15 Per nuova interfaccia Egt. +-- 2021/11/10 Aggiunta modifica per gestione modifiche manuali come in Beam. +-- 2022/01/06 Per CUTID/TASKID senza ToProcess si verificano anche eventuali Duplo. +-- 2022/01/17 Eliminata assegnazione Feature ok se non calcolata. +-- 2022/01/20 Si aggiorna il setup anche quando si creano le lavorazioni (MachGroup vecchio...). + + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( true) + +-- Per test --**CB: inizializzazione** +--WALL = {} +--WALL.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl' +--WALL.MACHINE = 'Essetre-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 == 5 then + sFlag = 'CLOUD' +elseif WALL.FLAG == 6 then + sFlag = 'CREATE_PANEL' +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 BWMessageId( nMsgId, sMsg, params) + if WALL.BW and nMsgId and nMsgId > 0 then + local sFinalMsg = '$$' .. nMsgId + for Index = 1, #params do + sFinalMsg = sFinalMsg .. ',' .. params[Index] + end + return sFinalMsg + else + return string.format( sMsg, table.unpack( params)) + end +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 or WALL.FLAG == 5) 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 or WALL.FLAG == 5) 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 + +-- Funzione di reset gruppo di lavoro in caso di impossibilità di inserire i pezzi +local function ResetMachGroup( vWall) + for i = 1, #vWall do + EgtErase( vWall[i].Id) + end + EgtRemoveMachGroup( EgtGetCurrMachGroup() or GDB_ID.NULL) +end + +-- **CB: INIZIO PROGRAMMA** + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Se necessario, impostazione della macchina corrente +local sMachine = WALL.MACHINE +if WALL.FLAG ~= 6 then + EgtResetCurrMachGroup() + 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 +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti +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') + +-- Carico le librerie +_G.package.loaded.WallExec = nil +local WE = require( 'WallExec') +local WL = require( 'WallLib') + +-- Carico i dati globali +local WD = require( 'WallData') + +-- Dati del file +local sDir, sTitle, sExt = EgtSplitPath( WALL.FILE) +local sOriFile = sDir..sTitle..'.ori.bwe' +local sNgeFile = sDir..sTitle..'.bwe' +local sBtmFile = sDir..sTitle..'.btm' +local sPntFile = sDir..sTitle..'.pnt' + +-- In generale va completamente riprocessato +local bToProcess = true +local bToRecalc = false +-- se BTL, barra ed esiste già il corrispondente progetto Nge +if EgtExistsFile( sOriFile) then + bToProcess = false + EgtCopyFile( sOriFile, sNgeFile) + -- se cambiata configurazione macchina da ultima elaborazione, devo aggiornare + if EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\Wall\\TS3Data.lua') == -1 or + EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\Tools\\Tools.data') == -1 or + EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\' .. sMachine ..'.mlde') == -1 then + bToRecalc = true + end +end + +-- Inizializzo contatori errori e avvisi +local nErrCnt = 0 +local nWarnCnt = 0 + +-- Se da elaborare +if bToProcess then + EgtOutLog( ' +++ Processing Parts >>>') + + -- Flag di pannello da creare + local bCreatePanel + -- Dimensioni del pannello ed elenco pareti + local dPanelLen + local dPanelWidth + local vWall = {} + -- flag per Nesting da Btl + local bNestingFromBtl = false + local nRawOutlineId = GDB_ID.NULL + + -- Se necessario, apro il file Bwe **cb: se ~= 'create panel "** + if WALL.FLAG ~= 6 then + if not EgtOpenFile( WALL.FILE) then + WALL.ERR = 13 + WALL.MSG = 'Error opening BWE file : ' .. WALL.FILE + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end + -- faccio copia del file originale + EgtCopyFile( WALL.FILE, sOriFile) + + -- Aggiorno eventuali dati ausiliari + --UpdateAuxData( sBtmFile) + + -- Se già presente un gruppo di lavoro + if EgtGetFirstMachGroup() then + -- Barra già presente + bCreatePanel = false + -- Rendo corrente il gruppo di lavoro + EgtSetCurrMachGroup() + -- 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) + + -- altrimenti devo recuperare i pezzi per creare il pannello + else + -- Pannello da creare + bCreatePanel = true + -- Recupero l'elenco ordinato delle pareti + 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( 'Pareti trovate : ' .. sOut, 1) + end + -- variabile che indica se ci sono fori orizzontali lunghi + local bUseMinRawYForLongDrill = false + -- recupero libreria fori + _G.package.loaded.WProcessDrill = nil + local Drill = require( 'WProcessDrill') + -- 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 wall ' .. vWall[i].Name + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + else + vWall[i].Box = b3Solid + end + -- recupero lista feature e ciclo + local vPartProc = WE.CollectFeatures( vWall[i].Id) + for nInd = 1, #vPartProc do + if Drill.Identify( vPartProc[nInd]) and Drill.UseMinYForLongDrill(vPartProc[nInd]) then + bUseMinRawYForLongDrill = true + end + end + end + -- se parete con fori lunghi orizzontali + local dMinY = 0 + if bUseMinRawYForLongDrill then + -- considero minima larghezza per permettere di farli + dMinY = ( WD.MINRAWY_HOR_DRILL or 2800) + end + -- Assegno dimensioni del pannello + dPanelLen = vWall[1].Box:getDimX() + 20 + dPanelWidth = math.max( vWall[1].Box:getDimY() + 20, dMinY) + -- Assegno posizione prima ed unica parete + vWall[1].PosX = 10 + vWall[1].PosZ = 10 + vWall[1].Rot = 0 + vWall[1].Flip = 0 + end + + -- Altrimenti, opero sul progetto corrente + else + -- Recupero l'identificativo del gruppo di lavoro corrente + local nMGrpId = EgtGetCurrMachGroup() + -- Pannello da creare + bCreatePanel = true + -- leggo se grezzo da nesting btl + bNestingFromBtl = EgtGetInfo( nMGrpId, 'BTLNESTING', 'b') or false + if bNestingFromBtl then + -- recupero superficie + nRawOutlineId = EgtGetInfo( nMGrpId, 'RAWOUTLINEID') or GDB_ID.NULL + if nRawOutlineId ~= GDB_ID.NULL then + local nRawPartId = EgtGetParent( EgtGetParent( nRawOutlineId)) + EgtSetStatus( nRawPartId, GDB_ST.ON) + local b3RawSurf = EgtGetBBoxGlob( nRawPartId, GDB_BB.STANDARD) + EgtSetStatus( nRawPartId, GDB_ST.OFF) + --EgtSurfTmBBox( nRawOutlineId, b3RawSurf, false, GDB_RT.GLOB) + if b3RawSurf then + -- Lunghezza e larghezza del pannello + dPanelLen = b3RawSurf:getDimX() + dPanelWidth = b3RawSurf:getDimY() + end + end + else + -- Lunghezza e larghezza del pannello + dPanelLen = EgtGetInfo( nMGrpId, 'PANELLEN', 'd') + dPanelWidth = EgtGetInfo( nMGrpId, 'PANELWIDTH', 'd') + end + -- Recupero l'elenco ordinato delle pareti da inserire nel pannello + for i = 1, 100 do + local sKey = 'PART'..tostring( i) + local sVal = EgtGetInfo( nMGrpId, sKey) + local vVal = EgtSplitString( sVal or '') + if not vVal or #vVal < 5 then break end + local nPartId = tonumber( vVal[1]) + local dPosX = tonumber( vVal[2]) + local dPosY = tonumber( vVal[3]) + local dRot = tonumber( vVal[4]) + local dFlip = tonumber( vVal[5]) + table.insert( vWall, { Id = nPartId, PosX = dPosX, PosZ = dPosY, Rot = dRot, Flip = dFlip, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + if #vWall == 0 then + WALL.ERR = 14 + WALL.MSG = 'Error : no walls in the project' + WriteErrToLogFile( 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( 'Pareti 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) + return + else + vWall[i].Box = b3Solid + end + end + end + + -- Se devo creare il pannello + if bCreatePanel then + -- 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 + ResetMachGroup( vWall) + WALL.ERR = 16 + WALL.MSG = sOut + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end + + local dRawL = dPanelLen + local dRawW = dPanelWidth + + -- 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 + ResetMachGroup( vWall) + local sOut = BWMessageId( 1, 'Grezzo (%s x %s x %s) oltre il limite della macchina (%s x %s x %s)', + {EgtNumToString( dRawL, 2), EgtNumToString( dRawW, 2), EgtNumToString( dRawH, 2), + EgtNumToString( WD.MAX_LENGTH, 2), EgtNumToString( WD.MAX_WIDTH, 2), 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 + ResetMachGroup( vWall) + 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, WALL.FLAG == 6, true, nRawOutlineId) + if not bPbOk then + WALL.ERR = 18 + WALL.MSG = sPbErr + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + else + -- Scrivo altezza grezzo nel gruppo di lavoro corrente + local nMGrpId = EgtGetCurrMachGroup() + EgtSetInfo( nMGrpId, 'PANELHEIGHT', dRawH) + end + -- altrimenti sistemo + else + -- recupero il grezzo + local nRawId = EgtGetFirstRawPart() + -- ciclo sui pezzi + local nPartId = EgtGetFirstPartInRawPart( nRawId) + while nPartId do + WL.CreateOrEmptyAddGroup( nPartId) + nPartId = EgtGetNextPartInRawPart( nPartId) + end + end + + -- Se richiesta solo pannello, esco + if WALL.FLAG == 6 then + -- Completamento senza errori e avvisi + if nWarnCnt == 0 then + WALL.ERR = 0 + WALL.MSG = '---' + WriteErrToLogFile( WALL.ERR, WALL.MSG) + end + EgtOutLog( ' +++ BatchProcess completed') + return + end + + -- Imposto Nome file CN + local _, sName, _ = EgtSplitPath( WALL.FILE) + EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + + -- Abilito Vmill + EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + + -- Aggiorno Setup utensili + EgtImportSetup() + + -- Lavoro le features + local bPfOk, Stats = WE.ProcessFeatures() + local sOutput = '' + for i = 1, #Stats do + local sMsg = Stats[i].Msg + sMsg = string.gsub( sMsg or '', '\n', ' ', 10) + sMsg = string.gsub( sMsg or '', '\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) + -- copio come originale (per dichiarare progetto ricalcolato) + EgtCopyFile( sNgeFile, sOriFile) + + -- 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 vDup = EgtDuploList( nPartId) + -- if not vDup or #vDup == 0 then + -- vDup = { nPartId} + -- end + -- for i = 1, #vDup do + -- local nCutId = EgtGetInfo( vDup[i], 'CUTID', 'i') + -- if nCutId then + -- local LayerId = {} + -- LayerId[1] = EgtGetFirstNameInGroup( vDup[i], 'Outline') + -- LayerId[2] = EgtGetFirstNameInGroup( vDup[i], 'Processings') + -- for nInd = 1, #LayerId do + -- local nProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL) + -- while nProcId do + -- local bIsFea = EgtExistsInfo( nProcId, 'GRP') and EgtExistsInfo( nProcId, 'PRC') + -- local nTaskId = EgtGetInfo( nProcId, 'TASKID', 'i') + -- 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 + -- end + -- end + -- nPartId = EgtGetNextPart( nPartId) + --end + -- Aggiorno eventuali dati ausiliari + --UpdateAuxData( sBtmFile) + -- Passo in modalità lavora + EgtSetCurrMachGroup( EgtGetLastMachGroup()) + -- Se necessario eseguo aggiornamento con setup corrente e ricalcolo delle lavorazioni + if bToRecalc then + EgtOutLog( ' +++ Recalculating all dispositions and machinings >>>') + EgtImportSetup() + EgtApplyAllMachinings() + -- Salvo il progetto + EgtSaveFile( sNgeFile) + -- copio come originale (per dichiarare progetto ricalcolato) + EgtCopyFile( sNgeFile, sOriFile) + end +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 >>>') + -- verifico setup + local bSetUpOk, SetUpErrors = EgtVerifyCurrSetup() + if not bSetUpOk then + local sToolsList = "" + for ToolIndex = 1, #SetUpErrors do + sToolsList = sToolsList .. SetUpErrors[ToolIndex] + if ToolIndex ~= #SetUpErrors then + sToolsList = sToolsList .. ", " + end + end + WriteErrToLogFile( 19, 'Error in setup: tool/s ' .. sToolsList .. ' not found', 0, 0, 0) + return + end + -- lancio simulazione + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.INIT then + WALL.ERR = 19 + WALL.MSG = 'Error starting simulation' + 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 = 'Special 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 >>>') + local sInfo = 'EgtCAM5 - ' + if EgtGetExeVersion then + sInfo = 'EgtCAM5 ver.' .. EgtGetExeVersion() .. ' - ' + end + if not EgtGenerate( '', sInfo .. 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', 'd') +local sTime = 'Total Time = ' .. EgtNumToString( Ttot, 1) +EgtOutLog( sTime) + +-- Se modalità Cloud, importo la nuvola di punti +if WALL.FLAG == 5 then + EgtOutLog( ' +++ Importing Point Cloud >>>') + -- Creo gruppo Cloud nel gruppo di lavorazione + local nMGrpId = EgtGetCurrMachGroup() + local nCloudId = EgtGetFirstNameInGroup( nMGrpId or GDB_ID.NULL, 'Cloud') + if nCloudId then + EgtEmptyGroup( nCloudId) + else + nCloudId = EgtGroup( nMGrpId) + EgtSetName( nCloudId, 'Cloud') + end + -- Recupero BBox della tavola + local b3Tab = EgtGetTableArea() + if not b3Tab or b3Tab:isEmpty() then + WALL.ERR = 22 + WALL.MSG = 'Machine table not found' + return + end + -- Recupero i punti della nuvola + local hFile = io.open( sPntFile, 'r') + if not hFile then + WALL.ERR = 23 + WALL.MSG = 'Missing point cloud file' + return + end + local vPoints = {} + local sLine = hFile:read( '*l') + while sLine do + local vCoord = EgtSplitString( sLine, ' ') + if vCoord and #vCoord >= 2 then + local dX = tonumber( vCoord[1]) + b3Tab:getMax():getX() + local dY = tonumber( vCoord[2]) + b3Tab:getMin():getY() + local dZ = b3Tab:getMax():getZ() + EgtOutLog( ' X='..EgtNumToString( dX, 3)..' Y='..EgtNumToString( dY, 3), 3) + table.insert( vPoints, { dX, dY, dZ}) + end + sLine = hFile:read( '*l') + end + hFile:close() + -- Inserisco la curva di contorno della nuvola + local nClCrvId = EgtCurveCompoFromPoints( nCloudId, vPoints, GDB_RT.GLOB) + if not nClCrvId then + WALL.ERR = 24 + WALL.MSG = 'Failed to create Point cloud Contour' + return + end + EgtCloseCurveCompo( nClCrvId) + EgtApproxCurve( nClCrvId, GDB_CA.LINES, 1.0) + EgtSetColor( nClCrvId, 'RED') +end + +-- Se modifica o simula, imposto la vista ISO 3d opportuna +if WALL.FLAG == 1 or WALL.FLAG == 2 then + local vView = { SCE_VD.ISO_NW, SCE_VD.ISO_SW, SCE_VD.ISO_NE, SCE_VD.ISO_SE} + local nV = min( max( WD.SIMUL_VIEW_DIR or 2, 1), 4) + EgtSetView( vView[nV], false) +-- se cloud, imposto la vista TOP +elseif WALL.FLAG == 5 then + EgtSetView( SCE_VD.TOP, 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/ProgettoRestylingWall/Wall/GetWallData.lua b/ProgettoRestylingWall/Wall/GetWallData.lua new file mode 100644 index 0000000..6c62842 --- /dev/null +++ b/ProgettoRestylingWall/Wall/GetWallData.lua @@ -0,0 +1,48 @@ +-- GetWallData.lua by Egaltech s.r.l. 2021/11/22 +-- Recupero dati da file WallData.lua di macchina + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--GWD = {} +--GWD.MACHINE = 'Essetre-90480019_MW' + +local sLog = 'GetWallData : ' .. GWD.MACHINE +EgtOutLog( sLog) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Wall\\WallData.lua') then + GWD.ERR = 12 + GWD.MSG = 'Error not configured for walls machine : ' .. GWD.MACHINE + WriteErrToLogFile( GWD.ERR, GWD.MSG) + PostErrView( GWD.ERR, GWD.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua') + +-- Carico i dati globali +local WD = require( 'WallData') + +-- Assegno valori di interesse +GWD.SIMUL_VIEW_DIR = WD.SIMUL_VIEW_DIR +GWD.ORIG_CORNER = WD.ORIG_CORNER +GWD.NESTING_CORNER = WD.NESTING_CORNER +GWD.HOR_DRILL_DIAM = WD.HOR_DRILL_DIAM +GWD.MIN_HEIGHT = WD.MIN_HEIGHT +GWD.MAX_HEIGHT = WD.MAX_HEIGHT + +-- Tutto ok +GWD.ERR = 0 + +EgtOutLog( ' +++ GetWallData completed') diff --git a/ProgettoRestylingWall/Wall/Images/Overturn.png b/ProgettoRestylingWall/Wall/Images/Overturn.png new file mode 100644 index 0000000..9854743 Binary files /dev/null and b/ProgettoRestylingWall/Wall/Images/Overturn.png differ diff --git a/ProgettoRestylingWall/Wall/Images/Process.png b/ProgettoRestylingWall/Wall/Images/Process.png new file mode 100644 index 0000000..e51b0b9 Binary files /dev/null and b/ProgettoRestylingWall/Wall/Images/Process.png differ diff --git a/ProgettoRestylingWall/Wall/Images/Rotate.png b/ProgettoRestylingWall/Wall/Images/Rotate.png new file mode 100644 index 0000000..fc5b749 Binary files /dev/null and b/ProgettoRestylingWall/Wall/Images/Rotate.png differ diff --git a/ProgettoRestylingWall/Wall/Images/WallMachinings.png b/ProgettoRestylingWall/Wall/Images/WallMachinings.png new file mode 100644 index 0000000..e88dd70 Binary files /dev/null and b/ProgettoRestylingWall/Wall/Images/WallMachinings.png differ diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WMachiningLib.lua b/ProgettoRestylingWall/Wall/LuaLibs/WMachiningLib.lua new file mode 100644 index 0000000..efc4d5c --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WMachiningLib.lua @@ -0,0 +1,181 @@ +-- MachiningLib.lua by Egaltech s.r.l. 2022/01/12 +-- Libreria ricerca lavorazioni per Pareti + +-- Tabella per definizione modulo +local WMachiningLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' WMachiningLib 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 Surfacings +if EgtExistsFile( EgtGetCurrMachineDir() .. '\\Wall\\SurfacingData.lua') then + Surfacings = require( 'SurfacingData') +end + +--------------------------------------------------------------------- +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 WMachiningLib.FindCutting( sType, dDepth, nTool_ID) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.On and Cutting.Type == sType and SetCurrMachiningAndTool( Cutting.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or 0 + local dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or 0 + local dSawMaxDepth = EgtTdbGetCurrToolMaxDepth() or 0 + local nMyTool_ID = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'Tool_ID', 'i') + if nMchType == MCH_MY.SAWING and + ( not dDepth or dSawMaxDepth > dDepth - 10 * GEO.EPS_SMALL) and + ( not nTool_ID or nTool_ID == 0 or nTool_ID == nMyTool_ID) then + return Cutting.Name, dSawDiam, dSawThick, dSawMaxDepth + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindMilling( sType, dDepth, sTuuid, nTool_ID, dMaxDiam, dMaxMat, bTipFeed, dMinSideElev) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.On and Milling.Type == sType and SetCurrMachiningAndTool( Milling.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local sMyTuuid = EgtGetMachiningParam( MCH_MP.TUUID) + local dTMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + local dTMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, dTMaxMat, EgtTdbGetCurrToolMaxDepth()) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTDiamTh = EgtTdbGetCurrToolThDiam() or 0 + local dTTipFeed = EgtTdbGetCurrToolParam( MCH_TP.TIPFEED) + local dTMaxDepthOnSide = min( EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or 0, 0.5 * ( dTDiam - dTDiamTh)) + local nMyTool_ID = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'Tool_ID', 'i') + if nMchType == MCH_MY.MILLING and + ( not sTuuid or sTuuid == sMyTuuid) and + ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and + ( not dMaxDiam or dTDiam < dMaxDiam + GEO.EPS_SMALL) and + ( not dMaxMat or dTMaxMat < dMaxMat + GEO.EPS_SMALL) and + ( not bTipFeed or dTTipFeed > 1) and + ( not dMinSideElev or dTMaxDepthOnSide > dMinSideElev - GEO.EPS_SMALL) and + ( not nTool_ID or nTool_ID == 0 or nTool_ID == nMyTool_ID) then + return Milling.Name, dTMaxDepth, dTMaxMat, dTDiam + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindNailing( nType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.On and Milling.Type == 'Nailing' and SetCurrMachiningAndTool( Milling.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local sTName = EgtTdbGetCurrToolParam( MCH_TP.NAME) + if nMchType == MCH_MY.MILLING and + sTName == tostring( nType) then + return Milling.Name + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindPocketing( sType, dMaxDiam, dDepth, nTool_ID) + for i = 1, #Pocketings do + local Pocketing = Pocketings[i] + if Pocketing.On and Pocketing.Type == sType and SetCurrMachiningAndTool( Pocketing.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) + local nMyTool_ID = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'Tool_ID', 'i') + if nMchType == MCH_MY.POCKETING and + ( not dMaxDiam or dTDiam < dMaxDiam + GEO.EPS_SMALL) and + ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and + ( not nTool_ID or nTool_ID == 0 or nTool_ID == nMyTool_ID) then + return Pocketing.Name, dTDiam, dTMaxDepth + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindSawing( sType) + for i = 1, #Sawings do + local Sawing = Sawings[i] + if Sawing.On and Sawing.Type == sType and SetCurrMachiningAndTool( Sawing.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + if nMchType == MCH_MY.MORTISING then + return Sawing.Name + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindDrilling( dDiam, dDepth, sHead, bOnlyPockets) + if bOnlyPockets == nil or not bOnlyPockets then + -- 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 nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + local sMyHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if nMchType == MCH_MY.DRILLING and + dTDiam < dDiam + 10 * GEO.EPS_SMALL and dTDiam > dDiam - WD.DRILL_TOL - 10 * GEO.EPS_SMALL and + ( not dDepth or dTMaxMat > dDepth - GEO.EPS_SMALL) and + (( not sHead and sMyHead ~= 'H5' and sMyHead ~= 'H6') or sHead == sMyHead) then + return Drilling.Name, Drilling.Type, dTMaxMat + end + 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 nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) + local sMyHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if nMchType == MCH_MY.POCKETING and + dTDiam < dDiam - 10 * GEO.EPS_SMALL and + ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and + ( ( not sHead and sMyHead ~= 'H5' and sMyHead ~= 'H6') or sHead == sMyHead) then + return Drilling.Name, Drilling.Type, dTMaxDepth + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindSurfacing( sType) + if not Surfacings then return end + for i = 1, #Surfacings do + local Surfacing = Surfacings[i] + if Surfacing.On and Surfacing.Type == sType and SetCurrMachiningAndTool( Surfacing.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + if nMchType == MCH_MY.SURFFINISHING then + return Surfacing.Name + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +return WMachiningLib diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessCut.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessCut.lua new file mode 100644 index 0000000..3523ea7 --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessCut.lua @@ -0,0 +1,74 @@ +-- WProcessCut.lua by Egaltech s.r.l. 2020/11/13 +-- Gestione calcolo taglio di testa o longitudinale per Pareti + +-- Tabella per definizione modulo +local WPC = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') +local FreeContour = require( 'WProcessFreeContour') + +EgtOutLog( ' WProcessCut started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPC.Identify( Proc) + return ( (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) or + (( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 10)) +end + + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPC.Classify( Proc, b3Raw) + -- verifico abbia una sola faccia + if Proc.Fct ~= 1 then return false end + -- controllo la normale + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 then return false end + return true +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPC.FlipClassify( Proc) + -- verifico abbia una sola faccia + if Proc.Fct ~= 1 then return 0, 0 end + -- controllo la normale + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local vtNZ = vtN:getZ() + if vtNZ > - GEO.EPS_SMALL then + nFlip0 = 100 + elseif vtNZ < -0.5 then + nFlip0 = 0 + else + nFlip0 = 50 + end + + if - vtNZ > - GEO.EPS_SMALL then + nFlip1 = 100 + elseif - vtNZ < -0.5 then + nFlip1 = 0 + else + nFlip1 = 50 + end + + --nFlip0 = EgtIf( vtN:getZ() < -0.5, 0, 100) + --nFlip1 = EgtIf( - vtN:getZ() < -0.5, 0, 100) + return nFlip0, nFlip1 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPC.Make( Proc, nRawId, b3Raw) + return FreeContour.Make( Proc, nRawId, b3Raw) +end + +--------------------------------------------------------------------- +return WPC diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessDoubleCut.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessDoubleCut.lua new file mode 100644 index 0000000..74a0bc4 --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessDoubleCut.lua @@ -0,0 +1,65 @@ +-- WProcessDoubleCut.lua by Egaltech s.r.l. 2021/04/28 +-- Gestione calcolo doppi tagli di lama per Pareti + +-- Tabella per definizione modulo +local WPDC = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') +local Cut = require( 'WProcessCut') +local LapJoint = require( 'WProcessLapJoint') + +EgtOutLog( ' WProcessDoubleCut started', 1) + +-- Dati +local WD = require( 'WallData') +local ML = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPDC.Identify( Proc) + return ( (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 11) or + ( Proc.Grp == 0 and Proc.Prc == 12)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPDC.Classify( Proc, b3Raw) + -- se una faccia, uso la classificazione dei tagli singoli + if Proc.Fct == 1 then return Cut.Classify( Proc, b3Raw) end + -- se più di due facce non si fa + if Proc.Fct > 2 then return false end + -- dati delle facce + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile da sopra o di fianco + return ( vtN[1]:getZ() >= - 0.01 or vtN[2]:getZ() >= - 0.01) +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPDC.FlipClassify( Proc) + + -- se una faccia, uso la classificazione dei tagli singoli + if Proc.Fct == 1 then return Cut.FlipClassify( Proc) end + -- se due facce, uso la classificazione del lap joint a due facce + if Proc.Fct == 2 then return LapJoint.FlipClassify( Proc) end + -- se più di due facce non si fa + if Proc.Fct > 2 then return 0, 0 end + +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPDC.Make( Proc, nRawId, b3Raw) + -- se singola faccia, passo a quella lavorazione + if Proc.Fct == 1 then return Cut.Make( Proc, nRawId, b3Raw) end + -- altrimenti due facce e passo alla LapJoint + return LapJoint.Make( Proc, nRawId, b3Raw) +end + +--------------------------------------------------------------------- +return WPDC diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessDrill.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessDrill.lua new file mode 100644 index 0000000..79e2295 --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessDrill.lua @@ -0,0 +1,544 @@ +-- WProcessDrill.lua by Egaltech s.r.l. 2022/03/08 +-- Gestione calcolo forature per Pareti +-- 2021/08/29 DS Se foratura di fianco setto flag per farla dopo i tagli. +-- 2021/12/04 DS Modifiche per forature speciali lungo Y. +-- 2022/01/12 DS Se con fresatura richiedo che l'utensile possa lavorare di testa. +-- 2022/01/19 DS Forature orizzontali lunghe con nome LhDrill_. +-- 2022/01/20 DS Aggiunta gestione Q01 (flag forzatura solo contornatura). +-- 2022/01/29 DS Corretta gestione ingombro portautensili per fori inclinati da sopra. +-- 2022/02/22 ES Aggiunta gestione prefori. +-- 2022/03/08 DS Vanno accettati fori orizzontali sul bordo anche senza foratori orizzontali speciali. + +-- Tabella per definizione modulo +local WPD = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') + +EgtOutLog( ' WProcessDrill started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +-- Parametri Q +local sContourOnly = 'Q01' -- 0=no, 1=si + + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPD.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 40) +end + +--------------------------------------------------------------------- +-- Recupero dati foro e adattamento se speciale +function WPD.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 WPD.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) + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- se inizia o finisce sulla faccia sopra + if ptCen:getZ() > b3Raw:getMax():getZ() - dDiam / 2 or ( bOpen and ptCen:getZ() - vtExtr:getZ() * dLen > b3Raw:getMax():getZ() - dDiam / 2) then + -- è lavorabile se non troppo inclinato + return ( abs( vtExtr:getZ()) >= WD.DRILL_VZ_MIN) + end + -- se con direzione asse Y e macchina con foratore orizzontale del giusto diametro + if WD.HOR_DRILL_DIAM and abs( dDiam - WD.HOR_DRILL_DIAM) < WD.DRILL_TOL and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then + return true + end + -- se foro orizzontale, verifico sia sul bordo del grezzo + local b3RedRaw = BBox3d( b3Raw) + b3RedRaw:expand( -20) + if ( WD.HOR_DRILL_5AX or WD.HOR_DRILL_5AX == nil) and vtExtr:getZ() > -0.05 and not EnclosesPointXY( b3RedRaw, ptCen) then + return true + end + -- altrimenti non lavorabile + return false +end + +--------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPD.FlipClassify( Proc, b3Part) + -- 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) + -- se foro cieco + if Proc.Fcs == 0 or Proc.Fce == 0 then + -- se normale positiva + local dVtExtrZ = vtExtr:getZ() + -- verifico se è lavorabile da sopra + local nFlip0 = EgtIf( dVtExtrZ >= WD.DRILL_VZ_MIN, 100, 0) + -- verifico se e' lavorabile da flipped: cambio segno al versore + local nFlip1 = EgtIf( -dVtExtrZ >= WD.DRILL_VZ_MIN, 100, 0) + return nFlip0, nFlip1 + end + -- altrimenti + return 0, 0 +end + +--------------------------------------------------------------------- +-- Classificazione della rotazione della feature per nesting +-- return nRot0, nRot90, nRot180, nRot270 +function WPD.RotateClassify( Proc) + + local nRot0 = -1 + local nRot90 = -1 + local nRot180 = -1 + local nRot270 = -1 + -- 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) + -- se foro orizzontale con punta lunga + if dDiam <= WD.HOR_DRILL_DIAM + WD.DRILL_TOL and dDiam >= WD.HOR_DRILL_DIAM - WD.DRILL_TOL and vtExtr:getZ() > -0.1 and vtExtr:getZ() < 0.1 then + -- se orientato perpendicolare ad X + if AreSameOrOppositeVectorApprox( vtExtr, X_AX()) then + nRot0 = 0 + nRot90 = 100 + nRot180 = 0 + nRot270 = 100 + return nRot0, nRot90, nRot180, nRot270 + elseif AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then + nRot0 = 100 + nRot90 = 0 + nRot180 = 100 + nRot270 = 0 + return nRot0, nRot90, nRot180, nRot270 + end + end +end + +--------------------------------------------------------------------- +local function IsHorizLongDrill( Proc) + -- 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 vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + return dDiam <= WD.HOR_DRILL_DIAM + WD.DRILL_TOL and dDiam >= WD.HOR_DRILL_DIAM - WD.DRILL_TOL and vtExtr:getZ() > -0.1 and vtExtr:getZ() < 0.1 +end + +--------------------------------------------------------------------- +function WPD.UseMinYForLongDrill( Proc) + if IsHorizLongDrill( Proc) then + -- 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) + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- se foro lungo orizzontale e piu' lungo della punta o orientato in Y- + if dDiam <= WD.HOR_DRILL_DIAM + WD.DRILL_TOL and dDiam >= WD.HOR_DRILL_DIAM - WD.DRILL_TOL and vtExtr:getZ() > -0.1 and vtExtr:getZ() < 0.1 and + ( (bOpen and dLen > WD.HOR_DRILL_LEN) or ( not bOpen and vtExtr:getY() < 0)) then + return true + end + end + return false +end + +--------------------------------------------------------------------- +-- Verifica se da lavorare in due metà +function WPD.Split( 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 bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- verifico se foro orizzontale in Y da lavorare in due metà + if WD.HOR_DRILL_Y_SPLIT and bOpen and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) and + Proc.Box:getMin():getY() < WD.HOR_DRILL_Y_SPLIT - 10 and Proc.Box:getMax():getY() > WD.HOR_DRILL_Y_SPLIT + 10 then + return true + else + return false + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPD.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 : 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 ptCen = EgtCP( 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.1) + if bToInvert and ( not bOpen or Proc.Flg ~= 1) then + local sErr = 'Error : drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- se foro da fare dall'altra parte forzo inversione + if Proc.Flg == -2 then bToInvert = true end + -- se foro chiuso sulla partenza forzo inversione + if Proc.Fcs == 0 then bToInvert = true end + -- se richiesta inversione, inverto versore di riferimento + if bToInvert then vtExtr = - vtExtr end + -- recupero la lavorazione (foratura/svuotatura) + local sHead + if WD.HOR_DRILL_Y_SPLIT and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then + local dExtrY = vtExtr:getY() + if not bOpen or abs( Proc.Flg) == 2 then + sHead = EgtIf( dExtrY > 0, 'H5', 'H6') + else + if Proc.Box:getMax():getY() > WD.HOR_DRILL_Y_SPLIT + 10 then + sHead = 'H5' + if vtExtr:getY() < 0 then bToInvert = true end + else + sHead = 'H6' + if vtExtr:getY() > 0 then bToInvert = true end + end + end + end + local sDrilling, nType = WM.FindDrilling( dDiam, dLen, sHead) + if not sDrilling then + sDrilling, nType = WM.FindDrilling( dDiam, nil, sHead) + end + if sHead and not sDrilling then + sDrilling, nType = WM.FindDrilling( dDiam, dLen) + if not sDrilling then + sDrilling, nType = WM.FindDrilling( dDiam) + end + if sDrilling then sHead = '' end + end + local bAngledContourDrill = false + local nAngledContourDrillId = GDB_ID.NULL + local dReduceDepth = 0 + -- se trovata svuotatura, verifico se richiesta invece contornatura + if nType == 'Pocket' then + -- recupero eventuale flag per fare sola contornatura + local nContourOnly = ( EgtGetInfo( Proc.Id, sContourOnly, 'i') or 0) + if nContourOnly == 1 then + -- imposto riduzione profondita' per evitare distacco pezzo interno + dReduceDepth = 5 + -- se inclinato e passante + if abs( vtExtr:getZ()) >= WD.DRILL_VZ_MIN and abs( vtExtr:getZ()) < 0.999 and Proc.Fcs > 0 and Proc.Fce > 0 then + -- gruppo ausiliario per preforo + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + -- ricavo contorno inferiore della superficie + local nAngledCircleId, nAngledCircleCnt = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId) + local dMinZ = 10000 + local nMinCircleId = GDB_ID.NULL + for Circleindex = 1, nAngledCircleCnt do + local b3Circle = EgtGetBBoxGlob( nAngledCircleId + Circleindex -1, GDB_BB.EXACT) + if b3Circle:getMin():getZ() < dMinZ then + nMinCircleId = nAngledCircleId + Circleindex -1 + end + end + -- estrudo + EgtModifyCurveExtrusion( nMinCircleId, vtExtr, GDB_RT.GLOB) + EgtModifyCurveThickness( nMinCircleId, dLen) + bAngledContourDrill = true + nAngledContourDrillId = nMinCircleId + end + sDrilling = WM.FindMilling( 'FreeContour', dLen, nil, nil, nil, nil, true) + if sDrilling then + nType = 'Mill' + sHead = '' + end + end + end + if not sDrilling then + local sErr = 'Error : drilling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- controllo posizione Y inizio foro con testa H6 + if WD.HOR_DRILL_YNEG_MAXMIN and sHead == 'H6' then + if b3Raw:getMin():getY() > WD.HOR_DRILL_YNEG_MAXMIN then + local sErr = 'Error : horizontal hole with Drilling2 starting too far' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dMaxDepth = 20 + local dFreeLen = 20 + local dDiamTh = 35 + local dDiamT = 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 + dFreeLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) - EgtTdbGetCurrToolThLength() - EgtMdbGetGeneralParam( MCH_GP.MAXDEPTHSAFE) + dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth + else + dFreeLen = EgtTdbGetCurrToolMaxDepth() or dFreeLen + dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth, dFreeLen) + end + dDiamTh = EgtTdbGetCurrToolThDiam() + dDiamT = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dDiamT + end + end + -- calcolo riduzione lunghezza aggiuntiva per inclinazione utensile + if bAngledContourDrill then + local dToolAngleReduce = ( dDiamT / 2) * sqrt( 1 - vtExtr:getZ() * vtExtr:getZ()) / vtExtr:getZ() + dReduceDepth = ( dToolAngleReduce) + ( 5 / vtExtr:getZ()) + end + -- aggiusto massimo affondamento per fori lungo Y con teste speciali + if sHead == 'H5' then + local dMaxY = WD.HOR_DRILL_Y_SPLIT + WD.HOR_DRILL_Y_TABLE / 2 + local dDeltaY = dMaxY - Proc.Box:getMax():getY() + if dDeltaY > 0 then + dMaxDepth = dMaxDepth - dDeltaY + end + elseif sHead == 'H6' then + local dMinY = WD.HOR_DRILL_Y_SPLIT - WD.HOR_DRILL_Y_TABLE / 2 + local dDeltaY = Proc.Box:getMin():getY() - dMinY + if dDeltaY > 0 then + dMaxDepth = dMaxDepth - dDeltaY + end + end + -- se foro faccia sopra, limito il massimo affondamento secondo inclinazione + if ptCen:getZ() > b3Raw:getMax():getZ() - dDiam / 2 then + local SinA = abs( vtExtr:getZ()) + if SinA >= WD.DRILL_VZ_MIN then + local CosA = sqrt( 1 - SinA * SinA) + local dSlantFreeLen = dFreeLen - ( dDiamTh / 2 * CosA / SinA) + dMaxDepth = min( dMaxDepth, dSlantFreeLen) + else + dMaxDepth = 0 + end + end + -- inserisco la lavorazione + local sName = EgtIf( sHead == 'H5' or sHead == 'H6', 'LhDrill_', '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 + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- se foratura di fianco setto la nota per spostarla dopo i tagli di lama + if vtExtr:getZ() < WD.NZ_MINA and not sHead then + EgtSetInfo( nMchId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + if bAngledContourDrill then + EgtSetMachiningGeometry( nAngledContourDrillId) + else + EgtSetMachiningGeometry( {{ AuxId, -1}}) + end + -- eventuale inversione + if nType == 'Drill' then + EgtSetMachiningParam( MCH_MP.INVERT, bToInvert) + else + EgtSetMachiningParam( MCH_MP.TOOLINVERT, bToInvert) + end + -- se fresatura gestisco il lato di lavoro + if bAngledContourDrill then + local nWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nWorkSide == MCH_MILL_WS.CENTER then + nWorkSide = MCH_MILL_WS.RIGHT + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, nWorkSide == MCH_MILL_WS.LEFT) + elseif nType == 'Mill' then + local frRef = EgtGetGlobFrame( AuxId) + local vtNa, _, dArea = EgtCurveArea( AuxId) + vtNa:toGlob( frRef) + if vtNa:getZ() * dArea > 0 then + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + -- per fori lungo Y con teste speciali aggiusto eventuale parte prima del foro ma nel grezzo + if sHead == 'H5' then + local dSafeStart = b3Raw:getMax():getY() - Proc.Box:getMax():getY() + 10 + if dSafeStart > 20 then + EgtSetMachiningParam( MCH_MP.STARTPOS, dSafeStart) + end + elseif sHead == 'H6' then + local dSafeStart = Proc.Box:getMin():getY() - b3Raw:getMin():getY() + 10 + if dSafeStart > 20 then + EgtSetMachiningParam( MCH_MP.STARTPOS, dSafeStart) + end + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- aggiusto l'affondamento + local sMyWarn + local dDepth = dLen - dReduceDepth + if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth + if abs( Proc.Flg) ~= 2 then + sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dLen, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + EgtOutLog( sMyWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- Note utente + local sUserNotes = '' + -- se foratura o svuotatura, dichiarazione nessuna generazione sfridi per Vmill + if nType == 'Drill' or nType == 'Pocket' then + sUserNotes = 'VMRS=0;' + end + -- 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 + sMyWarn = (sMyWarn or sWarn) + end + end + -- se preforo inclinato impostato, inclinazione oltre limite impostato e foro non orizzontale + if WD.PREDRILL_DIAM and WD.PREDRILL_DIAM > 0 and vtExtr:getZ() < ( WD.PREDRILL_MINANGLE or 0.707) and vtExtr:getZ() > 0.1 then + -- gruppo ausiliario per preforo + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + -- calcolo profondita' foro + local dLen = ( WD.PREDRILL_DIAM / 2) * sqrt( 1 - vtExtr:getZ() * vtExtr:getZ()) / vtExtr:getZ() + -- copio foro originale + local nPreHoleId = EgtCopyGlob( AuxId, nAddGrpId) + EgtModifyArcRadius( nPreHoleId, WD.PREDRILL_DIAM / 2) + EgtModifyCurveThickness( nPreHoleId, -dLen) --dLen = 10 + + -- se da invertire + if bToInvert then + -- lo sposto della lunghezza d'estrusione e ne inverto il versore + local dThickness = EgtCurveThickness( AuxId) + EgtMove( nPreHoleId, abs( dThickness) * vtExtr, GDB_RT.GLOB) + EgtModifyCurveExtrusion( nPreHoleId, vtExtr, GDB_RT.GLOB) + end + -- recupero lavorazione di pocket + local sDrilling = WM.FindDrilling( WD.PREDRILL_DIAM, dLen, nil, true) --dLen = 10 + + if not sDrilling then + local sErr = 'Error : prehole pocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + + -- inserisco la lavorazione + local sName = 'PreDrill_' .. ( 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 + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- setto la nota per spostarla prima della foratura + EgtSetInfo( nMchId, 'MOVE_BEFORE', 1) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nPreHoleId, -1}}) + + -- note utente, dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + 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 + sMyWarn = (sMyWarn or sWarn) + end + end + end + + return true, sMyWarn + +end + +--------------------------------------------------------------------- +return WPD diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessDtMortise.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessDtMortise.lua new file mode 100644 index 0000000..811e74a --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessDtMortise.lua @@ -0,0 +1,220 @@ +-- WProcessDtMortise.lua by Egaltech s.r.l. 2021/04/20 +-- Gestione calcolo mortase a coda di rondine per Pareti + +-- Tabella per definizione modulo +local WPDM= {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') + +EgtOutLog( ' WProcessDtMortise started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +-- settaggi interni ( poi andrà utilizzato parametro ACTIVE_AS proveniente da parametri utente di TechnoEssetre) +local bMakeAntiSplitPath = true +local bMakeAsByArc = true + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPDM.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 55)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPDM.Classify( Proc, b3Raw) + -- recupero i dati della curva di contorno della faccia di fondo + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se la mortasa è lavorabile + return ( vtExtr:getZ() > WD.NZ_MINA) +end + + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPDM.FlipClassify( Proc) + -- recupero i dati della curva di contorno della faccia di fondo + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se la mortasa è lavorabile + nFlip0 = EgtIf( vtExtr:getZ() > WD.NZ_MINA, 100, 0) + nFlip1 = EgtIf( - vtExtr:getZ() > WD.NZ_MINA, 100, 0) + + return nFlip0, nFlip1 + +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPDM.Make( Proc, nRawId, b3Raw) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Missing profile geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + -- verifico che la mortasa non sia orientata verso il basso (-5 deg) o che ci sia una testa da sotto + local bFaceDown = ( vtExtr:getZ() < - 0.1) + if bFaceDown then + local sErr = 'Machining from bottom impossible : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- determino l'altezza della mortasa (0=faccia di fondo) + local rfDtMrt = Frame3d( ptBC, vtExtr) + local b3DtMrt = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfDtMrt) + local dAltMort = b3DtMrt:getDimZ() + -- verifico se di tipo pocket + local bPocket = ( EgtGetInfo( Proc.Id, 'P05', 'i') == 1) + if bPocket then bMakeAntiSplitPath = false end + -- recupero il raggio minimo della mortasa + local dMinRad = 1000 + local nSt, nEnd = EgtCurveDomain( AuxId) + for i = nSt, nEnd - 1 do + local dRad = EgtCurveCompoRadius( AuxId, i) + if dRad > 0 and dRad < dMinRad then + dMinRad = dRad + end + end + -- recupero la lavorazione + local sMillType = 'DtMortise' + -- recupero la lavorazione : prima ricerca per sola tipologia + local sMilling = WM.FindMilling( sMillType) + if not sMilling then + local sErr = 'Milling not found in library : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione : seconda ricerca con tipologia e diametro massimo + sMilling = WM.FindMilling( sMillType, nil, nil, nil, 2 * dMinRad) + if not sMilling then + local sErr = 'Radius too small : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile e l'angolo di spoglia + local dToolDiam = 100 + local dMaxMat = 30 + local dSideAng = 0 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolDiam = max( dToolDiam, 10) + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- verifico che la profondità non superi il massimo materiale dell'utensile + if dAltMort > dMaxMat + 10 * GEO.EPS_SMALL then + local sErr = 'Error : DtMortise Depth bigger than Tool Cutting edge' + EgtOutLog( sErr) + return false, sErr + end + -- se con tasca, la lavoro + if bPocket then + -- recupero il contorno della tasca (seconda curva ausiliaria) + local sVal = EgtGetInfo( Proc.Id, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local Aux2Id + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if Aux2Id then Aux2Id = Aux2Id + Proc.Id end + if not Aux2Id or ( EgtGetType( Aux2Id) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Missing pocket geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sPocketing + if Proc.Prc ~= 53 then + sPocketing = WM.FindPocketing( 'Mortise', dToolDiam) + end + if not sPocketing then + sPocketing = WM.FindPocketing( 'Pocket', dToolDiam) + end + if not sPocketing then + local sErr = 'Error : Mortise or Pocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di svuotatura + local sName = 'DtMtPck_' .. ( 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( {{ Aux2Id, -1}}) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- verifico se necessarie più passate (distanza all'imbocco ortogonale all'asse) + local vtDiff = EgtEP( AuxId, GDB_RT.GLOB) - EgtSP( AuxId, GDB_RT.GLOB) + local vtAx = EgtEV( AuxId, GDB_RT.GLOB) - EgtSV( AuxId, GDB_RT.GLOB) + vtAx:normalize() + local vtOrtDiff = vtDiff - vtDiff * vtAx * vtAx + local dDist = vtOrtDiff:len() + -- calcolo le passate + local nPass = ceil( dDist / ( 1.9 * dToolDiam)) + local dStep = ( dDist - 0.95 * dToolDiam) / ( 2 * nPass) + for i = nPass, 1, -1 do + -- inserisco la lavorazione di contornatura + local sNameF = 'DtMt_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nPass) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto offset + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, false, true)) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return WPDM diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessFreeContour.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessFreeContour.lua new file mode 100644 index 0000000..dd671b8 --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessFreeContour.lua @@ -0,0 +1,2432 @@ +-- ProcessFreeContour.lua by Egaltech s.r.l. 2022/03/16 +-- Gestione calcolo profilo libero per Pareti +-- 2021/11/15 Penna e chiodature sono sempre riportate sulla faccia sopra anche se nel progetto sono sotto. +-- 2021/12/10 In taglio con lama aggiunta gestione SCC per testa Gearbox. +-- 2022/01/13 Aggiunta gestione massimo affondamento in Z anche per pulizia spigoli con fresa 60deg (WD.MAX_CLEAN_CRN60). +-- 2022/02/03 Corretto controllo massimo affondamento nella tavola. +-- 2022/02/21 Corretti allungamenti/accorciamenti tagli inclinati con fresa. Migliorata gestione tagli trasversali per macchine travi. +-- 2022/03/14 Corretto riconoscimento lato esterno per percorsi aperti. +-- 2022/03/16 Ulteriore modifica per riconoscimento lato esterno (aggiunto uso vExtr a GetFacesExternalSide). + +-- Tabella per definizione modulo +local WPF = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') + +EgtOutLog( ' WProcessFreeContour started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') +if WD.CHECK_MIN_Z_SAW == nil then WD.CHECK_MIN_Z_SAW = true end +if not WD.MIN_Z_SAW then WD.MIN_Z_SAW = 0 end +if not WD.MAX_CLEAN_CRN60 then WD.MAX_CLEAN_CRN60 = 150 end +local WHISK_OFFS = 0.1 +local WHISK_SAFE = 5 +local MIN_LEN_CUT = 250 + +-- variabili assegnazione parametri Q +local sTypeCornerCut = 'Q05' -- i +-- variabile settaggio doppia lavorazione su angoo > 90 +local bMakeTwinCut = true +-- variabile per valore sfondamento spigolo +local dExtraCorner = 1 +-- angolo sottosquadra ammesso per fresa cono 30° +local dAngleSmall = 70 + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPF.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 WPF.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) + -- recupero il tipo di lavorazione + local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0 + -- se tasca + if bPocket then + local bDown = ( vtN:getZ() < - 0.5) + return not bDown + -- se altrimenti profilo orizzontale + elseif abs( vtN:getZ()) < 0.5 then + return false + -- se penna o chiodatura va sempre bene (vengono sempre riportati sopra) + elseif nCntType == 10 or nCntType == 20 then + return true + -- 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 + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPF.FlipClassify( Proc, b3Raw) + local nFlip0 = 0 + local nFlip1 = 0 + + -- verifico se di tipo pocket + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- recupero la curva associata se esiste + 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) + local dVtNZ = vtN:getZ() + -- se tasca + if bPocket then + -- verifico se è lavorabile da sopra + nFlip0 = EgtIf( dVtNZ < -0.5, 0, 100) + -- verifico se e' lavorabile da fliped: cambio segno al versore + nFlip1 = EgtIf( -dVtNZ < -0.5, 0, 100) + + -- se altrimenti profilo orizzontale + elseif abs( dVtNZ) < WD.NZ_MINA then + return 0, 0 + -- se altrimenti profilo verticale che non interessa tutta la sezione + elseif Proc.Box:getMax():getZ() < b3Raw:getMax():getZ() - 2 then + return 0 , 0 + -- altrimenti è profilo verticale che interessa tutta la sezione + else + local dVtNZMedia = 0 + for i = 1, Proc.Fct do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT) + dVtNZMedia = dVtNZMedia + vtN:getZ() + end + dVtNZMedia = dVtNZMedia / Proc.Fct + if abs( dVtNZMedia) <= GEO.EPS_SMALL then + nFlip0 = 100 + nFlip1 = 100 + elseif dVtNZMedia >= 0 + GEO.EPS_SMALL then + nFlip0 = 75 + nFlip1 = 50 + else + nFlip0 = 50 + nFlip1 = 75 + end + end + return nFlip0, nFlip1 +end + +--------------------------------------------------------------------- +local function TestElleShape3( nIdGeom, nNumFacet) + -- valida solo nel caso di tre facce + if nNumFacet ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +local function TestElleShape4( nIdGeom, nNumFacet) + -- valida solo nel caso di quattro facce + if nNumFacet ~= 4 then return false end + -- determino se L con due facce terminali o O + local nFac3Adj = 0 + local dMinArea3 = GEO.INFINITO * GEO.INFINITO + local dMaxArea2 = 0 + for i = 1, 4 do + local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( nIdGeom, i - 1, GDB_ID.ROOT) + local dArea = dH * dV + if nCount == 2 then + dMaxArea2 = max( dMaxArea2, dArea) + elseif nCount == 3 then + dMinArea3 = min( dMinArea3, dArea) + nFac3Adj = nFac3Adj + 1 + end + end + if nFac3Adj ~= 2 then return false end + -- verifico se L profonda oppure lunga + if dMinArea3 < dMaxArea2 then + return 1 + else + return 2 + end +end + +--------------------------------------------------------------------- +local function VerifyCornerType( Proc) + -- Verifico il tipo di lavorazione su angolo : + -- 0 : niente + -- 1 : ripresa corner dopo pausa per rimozione sfridi (fresa 60deg) + -- 2 : ripresa corner senza pausa (fresa 30 deg) + -- 3 : scarico corner (tipo foro). + local nVal = EgtGetInfo( Proc.Id, sTypeCornerCut, 'i') + return ( nVal or 0) +end + +--------------------------------------------------------------------- +local function IsPointOnRawLongEdges( ptCen, b3Raw) + return ( abs( ptCen:getY() - b3Raw:getMin():getY()) < 0.1 or abs( ptCen:getY() - b3Raw:getMax():getY()) < 0.1) +end + +--------------------------------------------------------------------- +local function GetOtherRegions( nPartId) + local vOthers = {} + -- ciclo sui pezzi + local nOtherId = EgtGetFirstPartInRawPart( EgtGetFirstRawPart() or GDB_ID.NULL) + while nOtherId do + -- cerco le regioni marcate + local nCount = 0 + local nRegId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nOtherId, 'Outline') or GDB_ID.NULL) + while nRegId do + local vtN = EgtSurfFrNormVersor( nRegId, GDB_ID.ROOT) + if EgtExistsInfo( nRegId, 'REGION') and vtN and AreSameVectorApprox( vtN, Z_AX()) then + local b3Reg = EgtGetBBoxGlob( nRegId, GDB_BB.STANDARD) + if b3Reg then + nCount = nCount + 1 + table.insert( vOthers, { PartId = nOtherId, RegId = nRegId, Box = b3Reg}) + end + end + nRegId = EgtGetNext( nRegId) + end + -- se non trovate regioni marcate, cerco regioni con la normale corretta + if nCount == 0 then + local nRegId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nOtherId, 'Outline') or GDB_ID.NULL) + while nRegId do + local vtN = EgtSurfFrNormVersor( nRegId, GDB_ID.ROOT) + if EgtGetType( nRegId) == GDB_TY.SRF_FRGN and vtN and AreSameVectorApprox( vtN, Z_AX()) then + local b3Reg = EgtGetBBoxGlob( nRegId, GDB_BB.STANDARD) + if b3Reg then + table.insert( vOthers, { PartId = nOtherId, RegId = nRegId, Box = b3Reg}) + end + end + nRegId = EgtGetNext( nRegId) + end + end + -- passo al pezzo successivo + nOtherId = EgtGetNextPartInRawPart( nOtherId) + end + return vOthers +end + +--------------------------------------------------------------------- +local function ReorderFaces( nIdSurf, nNumFacet) + -- recupero le adiacenze di tutte le facce + local vAdj = {} + for i = 1, nNumFacet do + -- recupero le adiacenze della faccia + local vFacAdj = EgtSurfTmFacetAdjacencies( nIdSurf, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + vAdj[i] = nCount + end + -- sposto le facce isolate alla fine + for i = #vAdj, 1, -1 do + if vAdj[i] == 0 then + if vAdj[#vAdj] == 0 then + table.remove( vAdj, i) + end + EgtSurfTmSwapFacets( nIdSurf, i - 1, #vAdj) + end + end + -- se facce tutte isolate, esco + if #vAdj == 0 then return end + -- cerco la faccia non isolata con il minor numero di adiacenze + local nIdFace + local nAdjMin = 1000 + for i = 1, #vAdj do + if vAdj[i] < nAdjMin then + nAdjMin = vAdj[i] + nIdFace = i + end + end + -- se la faccia non isolata con minori adiacenze non è in prima posizione, eseguo scambio + if nIdFace and nIdFace ~= 1 and nAdjMin == 1 then + EgtSurfTmSwapFacets( nIdSurf, nIdFace-1, 0) + end + -- ordino le facce in modo da avere una sequenza di facce concatenate + for i = 1, #vAdj - 1 do + -- recupero l'angolo con la faccia precedente + local bAdj, _, _, _ = EgtSurfTmFacetsContact( nIdSurf, i-1, i, GDB_ID.ROOT) + -- se non ho adiacenza + if not bAdj then + for j = i+1, #vAdj do + bAdj, _, _, _ = EgtSurfTmFacetsContact( nIdSurf, i-1, j-1, GDB_ID.ROOT) + -- se ho adiacenza scambio le facce + if bAdj then + EgtSurfTmSwapFacets( nIdSurf, i, (j-1)) + break + end + end + end + end +end + +--------------------------------------------------------------------- +local function RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFaceToDel) + -- copio la superfice nel gruppo ausiliario + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + EgtSurfTmRemoveFacet( nNewProc, nFaceToDel) + local nNumFacet = EgtSurfTmFacetCount( nNewProc) + ReorderFaces( nNewProc, nNumFacet) + return nNewProc, nNumFacet +end + + +--------------------------------------------------------------------- +local function GetFacesExternalSide( Proc, vtExtr) + -- 3=sinistra, 4=destra + -- se meno di due facce considero esterno come dichiarato dal gruppo + local nNumFacet = EgtSurfTmFacetCount( Proc.Id) + if nNumFacet < 2 then return Proc.Grp end + -- se facce isolate, considero esterno come dichiarato dal gruppo + local bAdj, ptV1, ptV2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if not bAdj then return Proc.Grp end + -- calcolo dell'esterno rispetto all'avanzamento + local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local ptV = ( ptV1 + ptV2) / 2 + local vtDir1 = ptV - ptC1 + if ( vtN1 ^ vtDir1) * vtExtr > 0 then + return 4 + else + return 3 + end +end + +--------------------------------------------------------------------- +local function GetFacesData( Proc, bOpposite, bCalclForBlade, dToolDiam, dToolMaxDepth, dToolThick, nAddGrpId, b3Raw, nMasterNewProc) + --se richiesto, copio la superficie nel gruppo ausiliario + local nNewProc + if nMasterNewProc then + nNewProc = nMasterNewProc + else + nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + end + -- recupero i dati di tutte le facce + local vFace = {} + local nNumFacet = EgtSurfTmFacetCount( nNewProc) + for i = 1, nNumFacet do + -- indice faccia corrente e precedente + local nFac = EgtIf( bOpposite, nNumFacet - i, i - 1) + local nPrecFac + if bOpposite then + if nNumFacet > 2 then + nPrecFac = EgtIf( i == 1, 0, nFac + 1) + else + nPrecFac = EgtIf( i == 1, -1, nFac + 1) + end + else + if nNumFacet > 2 then + nPrecFac = EgtIf( i == 1, nNumFacet - 1, i - 2) + else + nPrecFac = EgtIf( i == 1, - 1, i - 2) + end + end + -- recupero centro e normale della faccia + local ptCen, vtN = EgtSurfTmFacetCenter( nNewProc, nFac, GDB_ID.ROOT) + -- recupero le dimensioni della faccia + local _, dLen, dWidth = WL.GetFaceHvRefDim( nNewProc, nFac) + -- recupero l'angolo con la faccia precedente + local bAdj, ptLocP1, ptLocP2, dAng = EgtSurfTmFacetsContact( nNewProc, nPrecFac, nFac, GDB_ID.ROOT) + local dPrevAng = EgtIf( bAdj, dAng, 0) + -- se angolo con faccia precedente negativo, calcolo anche angolo tra le facce nel piano + local dPlanePrevAng = 0 + if dPrevAng < 0 then + local vtPrevN = EgtSurfTmFacetNormVersor( nNewProc, nPrecFac, GDB_ID.ROOT) + local dCosA = ( Z_AX() ^ vtPrevN) * ( Z_AX() ^ vtN) + dPlanePrevAng = -acos( dCosA) + end + -- calcolo l'angolo di inclinazione (dalla verticale) + local dSideAng = asin( vtN:getZ()) + -- salvo i dati + vFace[i] = { Fac = nFac, Cen = ptCen, Norm = vtN, Len = dLen, Width = dWidth, PrevAng = dPrevAng, PlPrevAng = dPlanePrevAng, SideAng = dSideAng} + if bAdj then + if ptLocP1:getZ() < ptLocP2:getZ() then + vFace[i].PPrev = ptLocP1 + else + vFace[i].PPrev = ptLocP2 + end + end + end + -- analizzo le facce + local dMaxWidth = 0 + for i = 1, #vFace do + -- aggiorno la massima larghezza + if vFace[i].Width > dMaxWidth then + dMaxWidth = vFace[i].Width + end + -- verifico l'affondamento + local dDepth = WD.CUT_EXTRA + if vFace[i].Width + WD.CUT_EXTRA > dToolMaxDepth then + dDepth = dToolMaxDepth - vFace[i].Width + end + -- lunghezza baffo + local dElev = vFace[i].Width + dDepth + local dWhisk = EgtIf( bCalclForBlade, ( dElev * sqrt( dToolDiam / dElev - 1) + WHISK_SAFE) , (dToolDiam/2) + WHISK_SAFE) + -- determino la lunghezza del taglio passante e il tipo di attacco e uscita + local dLen = vFace[i].Len + local dLenY = dLen * abs( vFace[i].Norm:getX()) / sqrt( 1 - vFace[i].Norm:getZ() * vFace[i].Norm:getZ()) + local nType = 0 + if vFace[i].PrevAng < -0.1 or + ( WD.BEAM_MACHINE and not IsPointOnRawLongEdges( vFace[i].Cen, b3Raw) and ( dLen > 0.5 * WD.CUT_MAX_LENGTH or dLenY > 0.4 * b3Raw:getDimY())) then + dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0) + nType = nType + 1 + end + if vFace[EgtIf( i < nNumFacet, i + 1, 1)].PrevAng < -0.1 or + ( WD.BEAM_MACHINE and not IsPointOnRawLongEdges( vFace[i].Cen, b3Raw) and ( dLen > 0.5 * WD.CUT_MAX_LENGTH or dLenY > 0.4 * b3Raw:getDimY())) then + dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0) + nType = nType + 2 + end + -- se lunghezza non significativa, non va inserito il taglio + if dLen < MIN_LEN_CUT then + nType = 4 + end + -- numero dei lati + local nEdges = #(EgtSurfTmFacetAdjacencies( nNewProc, i - 1)[1]) + -- assegno i nuovi dati + vFace[i].Depth = dDepth + vFace[i].Whisk = dWhisk + vFace[i].Type = nType + vFace[i].Edges = nEdges + end + -- recupero le regioni degli altri pezzi + local vOthers = GetOtherRegions( Proc.PartId) + -- verifico i baffi sporgenti dei tagli rispetto alle altre regioni + for i = 1, #vFace do + -- verifico il baffo iniziale + if vFace[i].Type ~= 4 and ( vFace[i].Type & 1) == 0 then + -- creo il rettangolo del baffo + local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize() + local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), -90) + local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, -90) + local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt + local ptDir = ptIni + ( vFace[i].Whisk - WHISK_OFFS) * vtDir + local ptCross = ptDir + ( dToolThick - WHISK_OFFS) * vtOrt + local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB) + local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD) + -- verifico se interferisce con gli altri pezzi + for j = 1, #vOthers do + if OverlapsXY( b3Wh, vOthers[j].Box) then + local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0) + if nClass ~= GDB_RC.OUT then + local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 2) ~= 0, -vFace[i].Whisk, 0) + if dLen >= MIN_LEN_CUT then + vFace[i].Type = vFace[i].Type + 1 + else + vFace[i].Type = 4 + end + break + end + end + end + EgtErase( WhId) + end + -- verifico il baffo finale + if vFace[i].Type ~= 4 and ( vFace[i].Type & 2) == 0 then + -- creo il rettangolo del baffo + local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize() + local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), 90) + local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, 90) + local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt + local ptDir = ptIni + ( vFace[i].Whisk - WHISK_OFFS) * vtDir + local ptCross = ptDir + ( dToolThick - WHISK_OFFS) * vtOrt + local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB) + local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD) + -- verifico se interferisce con gli altri pezzi + for j = 1, #vOthers do + if OverlapsXY( b3Wh, vOthers[j].Box) then + local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0) + if nClass ~= GDB_RC.OUT then + local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 1) ~= 0, -vFace[i].Whisk, 0) + if dLen >= MIN_LEN_CUT then + vFace[i].Type = vFace[i].Type + 2 + else + vFace[i].Type = 4 + end + break + end + end + end + EgtErase( WhId) + end + end + -- se ciclo chiuso + if abs( vFace[1].PrevAng) > 0.1 then + -- verifico se c'è un solo tipo 3 e nessun tipo 0, 1 o 2 + local nInd3 + local nTot3 = 0 + local nTot012 = 0 + for i = 1, #vFace do + local Face = vFace[i] + if Face.Type == 0 or Face.Type == 1 or Face.Type == 2 then + nTot012 = nTot012 + 1 + elseif Face.Type == 3 then + nTot3 = nTot3 + 1 + nInd3 = i + end + end + -- se trovato il caso, trasformo il 3 in 4 (per evitare problemi con fresature con la stessa faccia a inizio e fine) + if nTot3 == 1 and nTot012 == 0 then + vFace[nInd3].Type = 4 + end + end + + -- eventuali stampe + for i = 1, #vFace do + local Face = vFace[i] + local sOut = 'Face '..tostring( Face.Fac)..' C'..tostring( Face.Cen)..' N'..tostring( Face.Norm).. + ' L='..EgtNumToString( Face.Len, 1)..' W='..EgtNumToString( Face.Width, 1)..' Ap='..EgtNumToString( Face.PrevAng, 1).. + ' App='..EgtNumToString( Face.PlPrevAng, 1)..' D='..EgtNumToString( Face.Depth, 1)..' B='..EgtNumToString( Face.Whisk, 1).. + ' As='..EgtNumToString( Face.SideAng, 1)..' T='..tostring( Face.Type)..' E='..tostring( Face.Edges) + EgtOutLog( sOut) + end + + return vFace, dMaxWidth, nNewProc +end + +--------------------------------------------------------------------- +local function GetTunnelDimension( nId, nPartId, nAddGrpId) + -- ottengo i versori delle 4 facce e ottengo l'orientamento del tunnel + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- variabili dimensioni fessura e id faccia lunga + local dDimMin + local dDimMax + local nLongIdFace = 0 + local bNegFace + local bOppoFace = false + -- ottengo il versore ortogonale + local ptN1, vtN1 = EgtSurfTmFacetCenter( nId, 0, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( nId, 1, GDB_ID.ROOT) + local vtOrtho = vtN1 ^ vtN2 + if vtOrtho:isSmall() then + _, vtN2 = EgtSurfTmFacetCenter( nId, 2, GDB_ID.ROOT) + vtOrtho = vtN1 ^ vtN2 + bOppoFace = true + end + vtOrtho:normalize() + if vtOrtho:getZ() < -0.5 then + vtOrtho = -vtOrtho + bNegFace = true + end + -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta la profondità della fessura + local frFc = Frame3d( ptN1, vtOrtho) ; + local bBoxLoc = EgtGetBBoxRef( nId, GDB_BB.STANDARD, frFc) + local dDepth = bBoxLoc:getDimZ() + -- mi assicuro che la Z del punto utilizzato per creare la superficie sia alla Z inferiore del bounding box locale + local ptN2 = Point3d(ptN1) + ptN2:toLoc(frFc) + ptN2 = Point3d( ptN2:getX(), ptN2:getY(), bBoxLoc:getMin():getZ() + 2*GEO.EPS_SMALL) + ptN2:toGlob(frFc) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN2, vtOrtho, b3Solid, GDB_ID.ROOT) + if not nSurfInt then return end + -- ritaglio la superficie con le facce della fessura + for i = 1, nFacCnt do + local ptN, vtN = EgtSurfTmFacetCenter( nId, i - 1, GDB_ID.ROOT) + EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) + end + -- sposto la geometria trovata sulla Z minima (era su di 2 * GEO.EPS_SMALL) + EgtMove( nSurfInt, Point3d(0,0,-2*GEO.EPS_SMALL) - ORIG(), GDB_RT.GLOB) + -- mi faccio dare il contorno della superfice e la ricreo in modo più corretto + local nIdCont, nIdNum = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) + if not nIdCont then return end + -- elimino le entità allineate dello stesso tipo + EgtMergeCurvesInCurveCompo( nIdCont, 2*GEO.EPS_SMALL) + EgtErase(nSurfInt) + nSurfInt = EgtSurfTmByFlatContour( nAddGrpId, nIdCont, 2*GEO.EPS_SMALL) + -- elimino il contorno + EgtErase(nIdCont) + -- se normale negativa inverto + _, vtN1 = EgtSurfTmFacetCenter( nSurfInt, 0, GDB_ID.ROOT) + if vtN1:getZ() < -0.5 then EgtInvertSurf( nSurfInt) end + local _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT) + dDimMin = min( DimH, DimV) + dDimMax = max( DimH, DimV) + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nId, nFacCnt-1, GDB_ID.ROOT) + -- se faccia pari alla larghezza fessura + if abs(DimH - dDimMax) < GEO.EPS_SMALL or abs(DimV - dDimMax) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + -- altrimenti verifico anche con la faccia precedente + else + local nFaceToCheck = EgtIf( bOppoFace, nFacCnt-3, nFacCnt-2) + -- prendo le dimensioni della faccia e poi confronto con il minimo + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nId, nFaceToCheck, GDB_ID.ROOT) + -- se trovato con il minimo, questa seconda faccia non è la più lunga + if abs(DimH - dDimMin) < GEO.EPS_SMALL or abs(DimV - dDimMin) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + else + nLongIdFace = nFaceToCheck + end + end + if not dDimMax then + return dDimMin, dDimMax, dDepth, nil, nil + end + return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt +end + +--------------------------------------------------------------------- +local function ReorderFacesFromTab( nIdSurf, vFace) + + local nFacCnt = EgtSurfTmFacetCount( nIdSurf) + for i = 1, #vFace do + for j = 1, nFacCnt do + -- ottengo punto iniziale e versore della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nIdSurf, (j-1), GDB_ID.ROOT) + -- se versore e posizione coincidono e non corrispondono al numero faccia, faccio lo swap + if AreSameVectorExact( vFace[i].Norm, vtN) and AreSamePointEpsilon( vFace[i].Cen, ptC, 50*GEO.EPS_SMALL) then + if (j-1) ~= vFace[i].Fac then + EgtSurfTmSwapFacets( nIdSurf, vFace[i].Fac, (j-1)) + end + break + end + end + end + return nIdSurf +end + +--------------------------------------------------------------------- +local function MakeCustomPath( vGeom, nConeCut, dMillDiam, nAddGrpId, dThick, bClosed) + + local nPath = {} + local nPathData = {} + + for i = 1, #vGeom do + local dAng + -- ottengo curva inferiore 1 + local ptP1, ptP2, ptP3, vtV1, vtV2, dDim1, dDim2 = EgtSurfTmFacetOppositeSide( vGeom[i][1], vGeom[i][2], Z_AX() , GDB_ID.ROOT) + if i < #vGeom then + -- ricavo i punti e l'angolo interno + _, _, _, dAng = EgtSurfTmFacetsContact( vGeom[i][1], vGeom[i][2], vGeom[i+1][2], GDB_ID.ROOT) + elseif i == #vGeom and nConeCut == 3 and bClosed then + -- ricavo i punti e l'angolo interno + _, _, _, dAng = EgtSurfTmFacetsContact( vGeom[i][1], vGeom[i][2], vGeom[1][2], GDB_ID.ROOT) + else + dAng = 0 + end + -- creo linea + local nId1 = EgtLine( nAddGrpId, ptP1, ptP3, GDB_RT.GLOB) + table.insert( nPath, nId1) + table.insert( nPathData, {nId1, dAng}) + end + + -- creo il percorso e poi lo offsetto del raggio utensile + local AuxId = EgtCurveCompo( nAddGrpId, nPath, true) + EgtOffsetCurve( AuxId, dMillDiam / 2, GDB_OT.EXTEND) + -- spezzo il percorso nelle entità componenti + local nId1st, nIdCount = EgtExplodeCurveCompo( AuxId) + -- se il numero entità è diverso da quelle iniziali esco con errore + if nIdCount ~= #vGeom then + local sErr = 'Error : cannot make offset path' + return 0, sErr + end + -- resetto la tabella + nPath = {} + AuxId = nil + -- in base al tipo di ripresa spigolo modifico il percorso + if nConeCut == 2 then + -- acquisisco la lunghezza utensile + sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner30') + if not sMilling then + local sErr = 'Error : CleanCorner 30 not found in library' + return 0, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMillLength = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMillLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dMillLength + end + end + -- calcolo la lunghezza della linea da inserire in base all'angolo e alla lunghezza utensile + local dLenAdd = abs(( dMillLength * sin(33)) - ( dMillDiam / 2)) + -- per ogni entità compongo la nuova lista per creare percorso + for i = 1, nIdCount do + -- aggiungo linea precedente + table.insert( nPath, ( nId1st + i - 1)) + -- se non è la linea finale e l'angolo tra le due facce è ammesso + if i < nIdCount and dThick <= ( WD.MAX_CLEAN_CRN30 + 20 * GEO.EPS_SMALL) and nPathData[i][2] < 0 and + nPathData[i][2] > -(180-dAngleSmall + 10 * GEO.EPS_SMALL) then + -- aggiungo una retta sulla bisettrice + local _, vtN2 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[i][2], GDB_ID.ROOT) + local _, vtN3 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[i+1][2], GDB_ID.ROOT) + local ptP1 = EgtEP( ( nId1st + i - 1), GDB_ID.ROOT) + -- sommo i tre versori per avere una direzione media + local vtExtrExit = vtN2 + vtN3 + vtExtrExit:normalize() + -- linea intermedia (componente lunghezza utensile in direzione bisettrice) + local pEnd = ptP1 + ( dLenAdd * vtExtrExit) + nAuxId = EgtLine( nAddGrpId, ptP1, pEnd, GDB_RT.GLOB) + table.insert( nPath, nAuxId) + -- linea di ritorno + nAuxId = EgtLine( nAddGrpId, pEnd, ptP1, GDB_RT.GLOB) + table.insert( nPath, nAuxId) + end + end + -- ricreo il percorso + AuxId = EgtCurveCompo( nAddGrpId, nPath, true) + -- altrimenti sfondo spigolo + elseif nConeCut == 3 then + -- per ogni entità compongo la nuova lista per creare percorso + for i = 1, nIdCount do + -- aggiungo linea precedente + table.insert( nPath, ( nId1st + i - 1)) + -- se non è la linea finale e l'angolo tra le due facce è ammesso + if ( i < nIdCount and nPathData[i][2] < 0) or ( i == nIdCount and bClosed and nPathData[i][2] < 0) then + -- aggiungo una retta sulla bisettrice + local _, vtN2 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[i][2], GDB_ID.ROOT) + local _, vtN3 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[ EgtIf( i == nIdCount and bClosed, 1, i+1)][2], GDB_ID.ROOT) + local ptP1 = EgtEP( ( nId1st + i - 1), GDB_ID.ROOT) + -- sommo i tre versori per avere una direzione media + local vtExtrExit = vtN2 + vtN3 + vtExtrExit:normalize() + vtExtrExit = -vtExtrExit + -- calcolo di quanto entrare + local dLenAdd = abs( (dMillDiam/2) / cos( nPathData[i][2]/2)) + dExtraCorner - (dMillDiam/2) + -- linea intermedia (componente lunghezza utensile in direzione bisettrice) + local pEnd = ptP1 + ( dLenAdd * vtExtrExit) + nAuxId = EgtLine( nAddGrpId, ptP1, pEnd, GDB_RT.GLOB) + table.insert( nPath, nAuxId) + -- linea di ritorno + nAuxId = EgtLine( nAddGrpId, pEnd, ptP1, GDB_RT.GLOB) + table.insert( nPath, nAuxId) + end + end + -- ricreo il percorso + AuxId = EgtCurveCompo( nAddGrpId, nPath, true) + end + if not AuxId then + local sErr = 'Error : Impossibe make custom machining path' + return 0, sErr + end + + return AuxId +end + +--------------------------------------------------------------------- +local function CalcInterference( nNewProc, vtExtr, ptCentr, dDiam1, dDiam2, + dTall1, dTall2, dDiam3, dTall3) + + local ptCentrGrid1 = ptCentr + ( vtExtr * 0.01) + local frOriTool = Frame3d( ptCentrGrid1, vtExtr) + local bColl1 = EgtCDeConeSolid( frOriTool, dDiam1/2, dDiam2/2, dTall1, nNewProc, 0, GDB_RT.GLOB) + if bColl1 then return true end + local ptCentrGrid2 = ptCentr + ( vtExtr * ( dTall1 + 0.01)) + frOriTool = Frame3d( ptCentrGrid2, vtExtr) + local bColl2 = EgtCDeCylSolid( frOriTool, dDiam2/2, (dTall2-dTall1), nNewProc, 0, GDB_RT.GLOB) + if bColl2 then return true end + local ptCentrGrid3 = ptCentr + ( vtExtr * ( dTall2 + 0.01)) + frOriTool = Frame3d( ptCentrGrid3, vtExtr) + local bColl3 = EgtCDeCylSolid( frOriTool, dDiam3/2, (dTall3-dTall2), nNewProc, 0, GDB_RT.GLOB) + if bColl3 then return true end + -- restituisco risultato controllo collisioni + return false +end + +--------------------------------------------------------------------- +local function MakeLocalSurf( ptP1, ptP2, ptP3, nAddGrpId) + + if not ptP1 or not ptP2 or not ptP3 then + return nil + end + + local pAuxId = {} + local nAuxId, AuxId + nAuxId = EgtLine( nAddGrpId, ptP1, ptP2, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + nAuxId = EgtLine( nAddGrpId, ptP2, ptP3, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + nAuxId = EgtLine( nAddGrpId, ptP3, ptP1, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- trasformo in percorso + if #pAuxId ~= 3 then + return nil + end + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + -- se non c'é il percorso esco + if not AuxId then + return nil + end + -- creo la superfice piana + local nidFace = EgtSurfTmByFlatContour( nAddGrpId, AuxId, 0.01) + if not nidFace then + EgtErase(AuxId) + return nil + end + -- se normale negativa inverto + local _, vtN1 = EgtSurfTmFacetCenter( nidFace, 0, GDB_ID.ROOT) + if vtN1:getZ() < -0.5 then EgtInvertSurf( nidFace) end + + EgtErase(AuxId) + return nidFace +end + +--------------------------------------------------------------------- +local function AddMillCornerMachining( nPartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, dOffsAng, dDepthMach, + bThruThick, dThSurf, dDiam1, dDiam2, dTall1, + dTall2, dDiam3, dTall3, bMakeLocSurf, vFace) + -- variabili costruzione geometria + local pAuxId = {} + local nAuxId + local ptApPoint + local AuxId + local nNewProcLoc + -- se devo creare superfice locale + if bMakeLocSurf then + -- creo superfice locale o esco + local nSurfToAdd = MakeLocalSurf( tFacAdj[1][7], tFacAdj[1][8], tFacAdj[1][9], nAddGrpId) + if nSurfToAdd then + local nFacCntPre = EgtSurfTmFacetCount( nNewProc) + -- creo copia del percorso principale e gli aggiungo la nuova faccia + nNewProcLoc = EgtCopyGlob( nNewProc, nAddGrpId) + nNewProcLoc = EgtSurfTmBySewing( nAddGrpId, {nNewProcLoc,nSurfToAdd} , true) + -- riordino le facce + ReorderFacesFromTab( nNewProcLoc, vFace) + -- acquisisco il numero della faccia + nFacCnt = EgtSurfTmFacetCount( nNewProcLoc) + nFacInd = nFacCnt - 1 + else + return true, '' + end + else + nNewProcLoc = nNewProc + end + -- prendo il primo versore + local _, vtN1 = EgtSurfTmFacetCenter( nNewProcLoc, nFacInd, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1][1], GDB_ID.ROOT) + local _, vtN3 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1][2], GDB_ID.ROOT) + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1][1], GDB_ID.ROOT) + local _, ptLocP3, ptLocP4, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1][2], GDB_ID.ROOT) + -- se ho creato faccia locale su copia superficie, cancella la copia + if bMakeLocSurf then + EgtErase( nNewProcLoc) + end + local nIdIniPoint + local nIdEndPoint + if ptLocP1 and ptLocP2 then + if ( dist( ptLocP1, tFacAdj[1][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[1][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptLocP1, tFacAdj[1][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[1][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- versore direzione + local vtExtr = tFacAdj[1][nIdIniPoint] - tFacAdj[1][nIdEndPoint] + vtExtr:normalize() + -- versore direzione di uscita + local vtExtrExit + -- inserisco le prime tre linee + if nIdIniPoint and nIdEndPoint then + -- se fresatura da sotto salto la lavorazione + if vtExtr:getZ() < WD.DRILL_VZ_MIN then + local sErr = 'Error : Impossible insert clean corner from bottom' + EgtOutLog( sErr) + return false, sErr + end + -- sommo i tre versori per avere una direzione media + vtExtrExit = vtN2 + vtN3 + vtExtrExit:normalize() + -- se tipo 1 calcolo angolo tilt di 45° + if nTypeConeCut == 1 then + vtExtr = vtExtrExit + Z_AX() + -- altrimenti tipo 2, calcolo angolo tilt di 33° (dalla verticale) + else + vtExtr = vtExtrExit + Vector3d(0,0,1.539865) + end + vtExtr:normalize() + local vtCheck = Vector3d(vtExtr) + -- se ho un offset angolare ruoto il percorso + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + vtCheck:rotate( Z_AX(), dOffsAng) + end + -- controllo se c'è collisione con le facce della superfice + if nTypeConeCut == 1 and CalcInterference( nNewProc, vtCheck, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), dDiam1, dDiam2, + dTall1, dTall2, dDiam3, dTall3) then + local sErr = 'Collision detect from clean corner tool and surface' + EgtOutLog( sErr) + return true, '' + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdIniPoint], tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- se uso utensile cono 60° + if nTypeConeCut == 1 then + -- se offset angolare valido e/o negativo creo il baffo precedente + if dOffsAng < ( 100 * GEO.EPS_SMALL) then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[1][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + local dLenTrimExt = dist( tFacAdj[1][nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + Point3d( 0, 0, dDepthMach) + else + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint + Point3d( 0, 0, -dDepthMach), tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + end + end + -- inserisco le ultime tre linee + -- trovo il secondo punto sulla superfice di riferimento + ptLocP1, ptLocP2 = ptLocP3, ptLocP4 + if ptLocP1 and ptLocP2 then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[1][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + -- se uso utensile cono 60° + if nTypeConeCut == 1 then + -- se offset angolare valido e/o negativo creo il baffo precedente + if dOffsAng > -( 100 * GEO.EPS_SMALL) then + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + local dLenTrimExt = dist( tFacAdj[1][nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + Point3d( 0, 0, dDepthMach) + else + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint + Point3d( 0, 0, -dDepthMach), tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- ultima linea di distacco (5mm in direzione utensile) + local pEnd = tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach) + ( 5 * vtExtr) + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + else + -- linea di distacco (2mm in direzione utensile) + local pEnd = tFacAdj[1][nIdEndPoint] + ( 2 * vtExtr) + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint], pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- ultima linea di risalita in Z + local pIni = pEnd + pEnd = pIni + ( dThick * Z_AX()) + nAuxId = EgtLine( nAddGrpId, pIni, pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + end + -- trasformo in percorso + if #pAuxId > 0 then + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + end + -- se non c'é il percorso do errore + if not AuxId then + local sErr = 'Error : impossible make clean corner path' + EgtOutLog( sErr) + return false, sErr + end + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- se ho un offset angolare ruoto il percorso + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( AuxId, tFacAdj[1][nIdEndPoint], Z_AX(), dOffsAng, GDB_RT.GLOB) + end + -- inserisco la lavorazione + local sName = 'Clean_' .. ( EgtGetName( nNewProc) or tostring( nNewProc)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', nPartId) + -- se flag lavorazione spessore passante setto la nota per spostarla dopo i tagli di lama + if bThruThick and nTypeConeCut == 1 then + EgtSetInfo( nMchId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- 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) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4) + -- allungo inizio e fine di 10mm + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- setto affondamento 0 + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione +-- sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( 0.0, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + 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 + end + end + + return true, '' +end + +--------------------------------------------------------------------- +local function AddMillCorner( nTypeConeCut, vFace, Proc, nRawId, b3Raw, + dToolDiam, nAddGrpId, dThick, nMasterNewProc, dDepthMach, + bThruThick) + + local sMilling, dMaxDepth + -- se ripresa angolo con fresa cono 60° con ripresa + if nTypeConeCut == 1 then + -- recupero la lavorazione di fresatura + sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner60') + if not sMilling then + local sErr = 'Error : CleanCorner 60 not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- se ripresa angolo con fresa cono piccola senza ripresa + else + sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner30') + if not sMilling then + local sErr = 'Error : CleanCorner 30 not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMillTotDiam = 20 + local dMillDiamTh = 20 + local dToolLength = 20 + local dThickTool = 20 + local dSideAng = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh + dMillTotDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) or dMillTotDiam + dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dThickTool = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThickTool + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth -- qui è la distanza dal portautensile + -- calcolo il secondo diametro del cono + dMillTotDiam = dMillDiam + ( abs(dThickTool) * tan(dSideAng)) * 2 + end + end + -- copio la feature nel layer di appoggio + local nNewProc + if nMasterNewProc then + nNewProc = nMasterNewProc + else + nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + end + local nFacCnt = EgtSurfTmFacetCount( nNewProc) + local nFacInd, dDimMin, dDimMax, dDepth, nSurfInt + local bMakeLocSurf + if nFacCnt <= 4 then + -- ottengo le dimensioni apertura, la normale e la faccia inferiore + dDimMin, dDimMax, dDepth, _, _, nSurfInt = GetTunnelDimension( nNewProc, Proc.PartId, nAddGrpId) + if nSurfInt then + -- uso la dimensione minima anche nel caso che la cava sborda perchè la lavorazione potrebbe collidere con un pezzo limitrofo + local dMinWidth = dDimMin + nNewProc = EgtSurfTmBySewing( nAddGrpId, {nNewProc,nSurfInt} , true) + -- riordino le facce + ReorderFacesFromTab( nNewProc, vFace) + -- acquisisco il numero della faccia + nFacCnt = EgtSurfTmFacetCount( nNewProc) + nFacInd = nFacCnt - 1 + else + return true + --local sErr = 'Error : cannot create base surface' + --EgtOutLog( sErr) + --return false, sErr + end + else + bMakeLocSurf = true + end + -- verifico se ciclo chiuso + local bClosed = ( abs( vFace[1].PrevAng) > 0.1) + -- ciclo di inserimento delle fresate sulle facce del contorno in esame + local i = 1 + -- se faccia finale con fine non lavorato, forzo partenza da prima faccia non tutta saltata (tipo 4) + if bClosed and ( vFace[#vFace].Type == 4 or ( vFace[#vFace].Type & 2) ~= 0) then + while i <= #vFace and vFace[i].Type == 4 do + i = i + 1 + end + end + -- se facce tutte da saltare, parto dall'inizio + local bAllType4 = ( i > #vFace) + if bAllType4 or bClosed then i = 1 end + while i <= #vFace do + -- se tutta la faccia o la sua fine senza taglio, inserisco una fresatura + if ( vFace[i].Type & 2) ~= 0 or vFace[i].Type == 4 then + -- variabili costruzione geometria + local tFacAdj = {} + local nFace1 = vFace[i].Fac + local nFace2 + -- ricavo i tre punti per eventuale superficie locale + local ptLoc1, ptLoc2, ptLoc3 + -- punto precedente (punto precedente della faccia [i]) + ptLoc3 = vFace[i].PPrev + -- aggiungo geometria + i = i + 1 + local j = EgtIf( i <= #vFace, i, EgtIf( bClosed, 1, nil)) + if not j then + return true + end + nFace2 = vFace[j].Fac + -- punto in comune tra le due facce (punto precedente della faccia [j]) + ptLoc1 = vFace[j].PPrev + -- punto successivo ( precedente della faccia successiva) + j = j + 1 + local k = EgtIf( j <= #vFace, j, EgtIf( bClosed, 1, nil)) + -- se è un percorso aperto prendo il punto medio della seconda faccia come punto locale 2 + if not k then + ptLoc2 = Point3d( vFace[j-1].Cen:getX(), vFace[j-1].Cen:getY(), ptLoc1:getZ()) + else + ptLoc2 = vFace[k].PPrev + end + -- ricavo i punti e l'angolo interno + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( nNewProc, nFace1, nFace2, GDB_ID.ROOT) + -- se punti validi e angolo è interno e non è quasi piatto e >= 90 creo istanza + if ptP1 and ptP2 and dAng < 0 and dAng < -6 and dAng > EgtIf( nTypeConeCut == 1, -(90 + 10 * GEO.EPS_SMALL), -(180-dAngleSmall + 10 * GEO.EPS_SMALL)) then + local dLen = dist( ptP1, ptP2) + table.insert( tFacAdj, { nFace1, nFace2, dLen, ptP1, ptP2, dAng, ptLoc1, ptLoc2, ptLoc3}) + end + -- se ho un elemento creo percorso o percorsi in base al tipo di cono e all'apertura dall'angolo rispetto ai 90° + -- con una tolleranza di 2 gradi + if #tFacAdj > 0 then + if nTypeConeCut == 1 and bMakeTwinCut and (dAng + 90) > 2 then + local dAngOffs = (dAng + 90) / 2 + -- primo taglio + local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, -dAngOffs, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + -- secondo taglio + bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, dAngOffs, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + -- altrimenti ho un solo percorso + else + local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, 0, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + end + end + else + i = i + 1 + end + end + -- cancello la copia della superfice + if nNewProc then + EgtErase( nNewProc) + end + return true +end + +--------------------------------------------------------------------- +local function GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen) + local CosA = abs( vtNz) + if CosA >= 0.05 then + local SinA = sqrt( 1 - CosA * CosA) + local dRad = dDiamTh / 2 + dMillDiam / 2 * EgtIf( vtNz > 0, -1, 1) + local dSlantFreeLen = dFreeLen - ( dRad * CosA / SinA) + return min( dMaxDepth, dSlantFreeLen) + else + return dMaxDepth + end +end + +--------------------------------------------------------------------- +local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAddGrpId) + -- flag per fresature non passanti + local bNotThrou + local dThick + local dOriDepth + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local dFreeLen = 0 + local dDiamTh = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dDiamTh = EgtTdbGetCurrToolThDiam() + dFreeLen = EgtTdbGetCurrToolMaxDepth() + dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), dFreeLen) or dMaxDepth + end + end + -- verifico se ciclo chiuso + local bClosed = ( abs( vFace[1].PrevAng) > 0.1) + -- ciclo di inserimento delle fresate sulle facce del contorno in esame + local i = 1 + -- se faccia finale con fine non lavorato, forzo partenza da prima faccia non tutta saltata (tipo 4) + if bClosed and ( ( vFace[#vFace].Type == 4 and vFace[#vFace].Edges > 3) or ( vFace[#vFace].Type & 2) ~= 0) then + while i <= #vFace and vFace[i].Type == 4 and vFace[i].Edges > 3 and abs( vFace[i].SideAng) < 0.1 do + i = i + 1 + end + end + -- se facce tutte da saltare, parto dall'inizio + local bAllType4 = ( i > #vFace) + if bAllType4 then i = 1 end + while i <= #vFace do + -- se inizio faccia senza taglio e non è successiva di senza taglio, inserisco una fresatura + local j = EgtIf( i > 1, i - 1, EgtIf( bClosed, #vFace, nil)) + if ( vFace[i].Type & 1) ~= 0 and ( not j or vFace[j].Type == 0 or vFace[j].Type == 1 or abs( vFace[i].SideAng) > 0.1 or abs( vFace[j].SideAng) > 0.1) then + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return 0, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- calcolo l'affondamento + local dDepth = vFace[i].Width + WD.CUT_EXTRA + dThick = vFace[i].Width + local vtNz = vFace[i].Norm:getZ() + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW) + else + dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz)) + end + end + local dCurrMaxDepth = GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen) + -- se affondamento superiore ai limiti della fresa + if dDepth > dCurrMaxDepth then + dOriDepth = dDepth + -- lo limito e tolgo eventuali Tabs + dDepth = dCurrMaxDepth + EgtSetMachiningParam( MCH_MP.LEAVETAB, false) + bNotThrou = true + end + -- tolgo i Tabs se devo rimuovere lo sfrido + if nConeCut == 1 then EgtSetMachiningParam( MCH_MP.LEAVETAB, false) end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}}) + local dSal = 0 + if #vFace == 1 then dSal = -dMillDiam / 2 end + -- se angolo interno prima + if vFace[i].PrevAng < -30 then + local dSinA = -sin( vFace[i].PlPrevAng + 90) + local dTanA = -tan( vFace[i].PlPrevAng + 90) + dSal = -dMillDiam / 2 * ( 1 + ( 1 + dSinA) * dTanA) + min( 0, vFace[i].Width * vFace[i].Norm:getZ() * dTanA) + -- se faccia precedente inclinata verso il basso + if j and vFace[j].Norm:getZ() < -0.017 then + dSal = dSal + vFace[j].Width * vFace[j].Norm:getZ() + end + -- se angolo esterno prima + elseif vFace[i].PrevAng > 30 then + -- se faccia precedente inclinata verso il basso + if j and vFace[j].Norm:getZ() < -0.017 then + dSal = dSal - vFace[j].Width * vFace[j].Norm:getZ() + end + end + local dEal = vFace[i].Whisk - vFace[i].Len + -- se angolo interno prima e faccia precedente inclinata verso l'alto oltre 16.1deg + if vFace[i].PrevAng < -30 and j and vFace[j].Norm:getZ() < 0.96078 and vFace[j].Norm:getZ() > 0 then + dEal = dEal + vFace[j].Width * vFace[j].Norm:getZ() + end + -- se angolo interno dopo e faccia successiva inclinata verso l'alto oltre 16.1deg + local k = EgtIf( i < #vFace, i + 1, EgtIf( bClosed, 1, nil)) + if k and vFace[k].PrevAng < -30 and vFace[k].Norm:getZ() < 0.96078 and vFace[k].Norm:getZ() > 0 then + dEal = dEal + vFace[k].Width * vFace[k].Norm:getZ() + -- se l'inclinazione è inferiore a 46.1deg + if vFace[k].Norm:getZ() > 0.72055 then + dEal = dEal - vFace[k].Width + end + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if abs( vFace[i].Norm:getZ()) < GEO.EPS_SMALL then + nSCC = EgtIf( abs( vFace[i].Norm:getX()) > abs( vFace[i].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return 0, sErr + end + end + -- se tutta la faccia o la sua fine senza taglio, inserisco una fresatura + if ( vFace[i].Type & 2) ~= 0 or ( vFace[i].Type == 4 and vFace[i].Edges > 3) then + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return 0, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- calcolo l'affondamento + local dDepth = vFace[i].Width + WD.CUT_EXTRA + dThick = vFace[i].Width + local vtNz = vFace[i].Norm:getZ() + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW) + else + dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz)) + end + end + local dCurrMaxDepth = GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen) + -- se affondamento superiore ai limiti della fresa + if dDepth > dCurrMaxDepth then + dOriDepth = dDepth + -- lo limito e tolgo eventuali Tabs + dDepth = dCurrMaxDepth + EgtSetMachiningParam( MCH_MP.LEAVETAB, false) + bNotThrou = true + end + -- tolgo i Tabs se devo rimuovere lo sfrido + if nConeCut == 1 then EgtSetMachiningParam( MCH_MP.LEAVETAB, false) end + -- aggiungo geometria + local vGeom = {{ Proc.Id, vFace[i].Fac}} + local dSal = EgtIf( ( vFace[i].Type & 2) ~= 0, vFace[i].Whisk - vFace[i].Len, 0) + local dEal = 0 + local OrigI = i + local OrigH = j + local LastJ + i = i + 1 + local j = EgtIf( i <= #vFace, i, EgtIf( bAllType4 or not bClosed, nil, 1)) + while j and ( ( vFace[j].Type & 1) ~= 0 or ( vFace[j].Type == 4 and vFace[j].Edges > 3)) and abs( vFace[j].SideAng) < 0.1 and abs( vFace[OrigI].SideAng) < 0.1 do + table.insert( vGeom, { Proc.Id, vFace[j].Fac}) + LastJ = j + dEal = EgtIf( ( vFace[j].Type & 1) ~= 0, vFace[j].Whisk - vFace[j].Len, 0) + if ( vFace[j].Type & 1) ~= 0 then + break + end + i = i + 1 + j = EgtIf( j + 1 <= #vFace, j + 1, EgtIf( bAllType4 or not bClosed, nil, 1)) + end + -- se faccia singola è da fare tutta senza oltrepassare estremi + if #vFace == 1 and vFace[OrigI].Type == 4 and vFace[OrigI].Edges > 3 then + dSal = -dMillDiam / 2 + dEal = -dMillDiam / 2 + -- altrimenti va verificato + else + -- se lavorazione completa su faccia iniziale + if vFace[OrigI].Type == 4 and vFace[OrigI].Edges > 3 then + -- se angolo interno prima + if vFace[OrigI].PrevAng < -30 then + local dSinA = -sin( vFace[OrigI].PlPrevAng + 90) + local dTanA = -tan( vFace[OrigI].PlPrevAng + 90) + dSal = -dMillDiam / 2 * ( 1 + ( 1 + dSinA) * dTanA) + min( 0, vFace[OrigI].Width * vFace[OrigI].Norm:getZ() * dTanA) + -- se faccia precedente inclinata verso il basso + if OrigH and vFace[OrigH].Norm:getZ() < -0.017 then + dSal = dSal + vFace[OrigH].Width * vFace[OrigH].Norm:getZ() + end + -- se angolo esterno prima + elseif vFace[OrigI].PrevAng > 30 then + -- se faccia precedente inclinata verso il basso + if OrigH and vFace[OrigH].Norm:getZ() < -0.017 then + dSal = dSal - vFace[OrigH].Width * vFace[OrigH].Norm:getZ() + end + end + end + -- se lavorazione completa o finale su faccia finale + local LastFace = ( LastJ or OrigI) + local OrigK = EgtIf( LastFace < #vFace, LastFace + 1, EgtIf( bClosed, 1, nil)) + if ( vFace[LastFace].Type == 4 and vFace[LastFace].Edges > 3) or ( LastFace == OrigI and ( vFace[LastFace].Type & 2) ~= 0) then + -- se angolo interno dopo + if OrigK and vFace[OrigK].PrevAng < -30 then + local dSinA = -sin( vFace[OrigK].PlPrevAng + 90) + local dTanA = -sin( vFace[OrigK].PlPrevAng + 90) + dEal = -dMillDiam / 2 * ( 1 + ( 1 + dSinA) * dTanA) + min( 0, vFace[OrigI].Width * vFace[OrigI].Norm:getZ() * dTanA) + -- se faccia successiva inclinata verso il basso + if vFace[OrigK].Norm:getZ() < -0.017 then + dEal = dEal + vFace[OrigK].Width * vFace[OrigK].Norm:getZ() + end + -- se angolo esterno dopo + elseif OrigK and vFace[OrigK].PrevAng > 30 then + -- se faccia successiva inclinata verso il basso + if vFace[OrigK].Norm:getZ() < -0.017 then + dEal = dEal - vFace[OrigK].Width * vFace[OrigK].Norm:getZ() + end + end + end + -- per sola lavorazione finale + if LastFace == OrigI and ( vFace[LastFace].Type & 2) ~= 0 then + -- se angolo interno dopo e faccia successiva inclinata verso l'alto oltre 16.1 deg + if OrigK and vFace[OrigK].PrevAng < -30 and vFace[OrigK].Norm:getZ() < 0.96078 and vFace[OrigK].Norm:getZ() > 0 then + dSal = dSal + vFace[OrigK].Width * vFace[OrigK].Norm:getZ() + end + -- se angolo interno prima e faccia precedente inclinata verso l'alto oltre 16.1 deg + if vFace[OrigI].PrevAng < -30 and OrigH and vFace[OrigH].Norm:getZ() < 0.96078 and vFace[OrigH].Norm:getZ() > 0 then + dSal = dSal + vFace[OrigH].Width * vFace[OrigH].Norm:getZ() + -- se l'inclinazione è inferiore a 46.1deg + if vFace[OrigH].Norm:getZ() > 0.72055 then + dSal = dSal - vFace[OrigH].Width + end + end + end + -- se percorso chiuso e completo con fresa + if bClosed and bAllType4 then + dSal = 0 + dEal = 0 + end + -- se faccia singola non oltrepasso l'estremo finale + if #vFace == 1 then + dEal = -dMillDiam / 2 + end + end + -- se non devo scaricare l'angolo o la faccia è inclinata + if nConeCut <= 1 or abs( vFace[OrigI].SideAng) > 0.1 then + EgtSetMachiningGeometry( vGeom) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- tolgo i Tabs se devo rimuovere lo sfrido + if nConeCut == 1 then EgtSetMachiningParam( MCH_MP.LEAVETAB, false) end + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + -- posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if abs( vFace[OrigI].Norm:getZ()) < GEO.EPS_SMALL then + nSCC = EgtIf( abs( vFace[OrigI].Norm:getX()) > abs( vFace[OrigI].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- altrimenti se devo fare rientranza per inserimento utensile cono 30° + elseif nConeCut == 2 then + -- eseguo la costruzione del percorso + local nPathId, sErr = MakeCustomPath( vGeom, nConeCut, dMillDiam, nAddGrpId, dThick) + if nPathId == 0 then return 0, sErr end + EgtSetMachiningGeometry({{ nPathId, -1}}) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- assegno affondamento +-- EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + if bNotThrou then + EgtSetMachiningParam( MCH_MP.DEPTH, ( dDepth - dOriDepth)) + else + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + end + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + -- altrimenti se devo scaricare l'angolo + elseif nConeCut == 3 then + -- eseguo la costruzione del percorso + local nPathId, sErr = MakeCustomPath( vGeom, nConeCut, dMillDiam, nAddGrpId, nil, bClosed and bAllType4) + if nPathId == 0 then return 0, sErr end + EgtSetMachiningGeometry({{ nPathId, -1}}) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno affondamento + if bNotThrou then + EgtSetMachiningParam( MCH_MP.DEPTH, ( dDepth - dOriDepth)) + else + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + end + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return 0, sErr + end + else + i = i + 1 + end + end + -- aggiungo eventuali fresature a metà faccia + for i =1, #vFace do + if vFace[i].Split then + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_M' + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return 0, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- calcolo l'affondamento + local dDepth = vFace[i].Width + WD.CUT_EXTRA + dThick = vFace[i].Width + local vtNz = vFace[i].Norm:getZ() + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW) + else + dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz)) + end + end + local dCurrMaxDepth = GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen) + -- se affondamento superiore ai limiti della fresa + if dDepth > dCurrMaxDepth then + dOriDepth = dDepth + -- lo limito e tolgo eventuali Tabs + dDepth = dCurrMaxDepth + EgtSetMachiningParam( MCH_MP.LEAVETAB, false) + bNotThrou = true + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}}) + local dSal = vFace[i].Whisk - vFace[i].Len / 2 + local dEal = vFace[i].Whisk - vFace[i].Len / 2 + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if abs( vFace[i].Norm:getZ()) < GEO.EPS_SMALL then + nSCC = EgtIf( abs( vFace[i].Norm:getX()) > abs( vFace[i].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return 0, sErr + end + end + end + -- se fresature non sono passanti + if bNotThrou then + return 2, dMillDiam, dThick + end + + return 1, dMillDiam, dThick +end + +--------------------------------------------------------------------- +local function AddSawings( sSawing, vFace, Proc, nRawId, b3Raw) + -- flag per tagli non passanti + local bNotThrou + local dThick + -- recupero i dati dell'utensile + local dSawDiam = 0 + local dMaxDepth = 0 + local dSawThick = 0 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- Calcolo angolo 3° asse rot (da direz. utensile) + local sRot3Ang = 'A1=180' + if WD.GetChainSawBlockedAxis then + sRot3Ang = WD.GetChainSawBlockedAxis( 1) + end + -- ciclo di inserimento dei tagli con sega a catena + for i = 1, #vFace do + -- se inizio faccia non tagliato completamente, inserisco un ripasso con sega a catena + if ( vFace[i].Type & 1) ~= 0 then + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) + local nMchId = EgtAddMachining( sName, sSawing) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return 0, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- calcolo l'affondamento + local dDepth = vFace[i].Width + min( WD.CUT_EXTRA, -WD.MIN_Z_SAW) + dThick = vFace[i].Width + -- se affondamento superiore ai limiti della sega a catena + if dDepth > dMaxDepth then + dDepth = dMaxDepth + bNotThrou = true + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}}) + local dSal = - dSawDiam / 2 + local dEal = vFace[i].Whisk - vFace[i].Len - dSawDiam / 2 + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, sRot3Ang) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- posizione braccio porta testa + if vFace[i].Norm:getX() < 0.018 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.OPPOSITE) + EgtSetMachiningParam( MCH_MP.OFFSR, dSawThick) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return 0, sErr + end + end + -- se fine faccia non tagliato completamente o faccia non tagliata completamente e abbastanza lunga, inserisco un ripasso con sega a catena + if ( vFace[i].Type & 2) ~= 0 or ( vFace[i].Type == 4 and vFace[i].Edges > 3 and vFace[i].Len > dSawDiam + 1) then + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) + local nMchId = EgtAddMachining( sName, sSawing) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return 0, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- calcolo l'affondamento + local dDepth = vFace[i].Width + min( WD.CUT_EXTRA, -WD.MIN_Z_SAW) + dThick = vFace[i].Width + -- se affondamento superiore ai limiti della sega a catena + if dDepth > dMaxDepth then + dDepth = dMaxDepth + bNotThrou = true + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}}) + local dSal = - dSawDiam / 2 + local dEal = - dSawDiam / 2 + if ( vFace[i].Type & 2) ~= 0 then + dSal = vFace[i].Whisk - vFace[i].Len - dSawDiam / 2 + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, sRot3Ang) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- posizione braccio porta testa + if vFace[i].Norm:getX() < 0.018 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.OPPOSITE) + EgtSetMachiningParam( MCH_MP.OFFSR, dSawThick) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return 0, sErr + end + end + end + -- se fresature non sono passanti + if bNotThrou then + return 2, dSawThick, dThick + end + return 1, dSawThick, dThick +end + +--------------------------------------------------------------------- +local function AddCuts( sCutting, vFace, Proc, nRawId, b3Raw, dSawThick) + -- ciclo di inserimento dei tagli sulle facce del contorno in esame + for i = 1, #vFace do + -- verifico se faccia da saltare, perchè macchina travi e faccia su bordo longitudinale esterno già finito + local bToSkip = ( WD.BEAM_MACHINE and IsPointOnRawLongEdges( vFace[i].Cen, b3Raw)) + -- se non è faccia da saltare, inserisco il taglio di lama + if not bToSkip and vFace[i].Type ~= 4 then + -- indice del successivo + local j = EgtIf( i < #vFace, i + 1, 1) + -- inserisco la lavorazione + local sName = 'Cut_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_' .. tostring( i) + local nMchId = EgtAddMachining( sName, sCutting) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + local dSpeed = EgtGetMachiningParam( MCH_MP.SPEED) + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local bGearbox = EgtGetInfo( EgtGetHeadId( sHead) or GDB_ID.NULL, 'Gearbox', 'b') + -- aggiungo geometria + EgtSetMachiningGeometry( { { Proc.Id, vFace[i].Fac}}) + -- calcolo l'affondamento + local dDepth = vFace[i].Depth + local vtNz = vFace[i].Norm:getZ() + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, -WD.MIN_Z_SAW) + else + dDepth = min( dDepth, -WD.MIN_Z_SAW + dSawThick * vtNz) + end + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- verifico se va invertita la direzione di lavorazione perchè faccia verso l'alto (angolo maggiore di 0.01 deg) + local bInvert = ( vFace[i].Norm:getZ() > 0.0001745) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, bInvert) + -- imposto lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bInvert, MCH_SAW_WS.LEFT, MCH_SAW_WS.RIGHT)) + -- lato mandrino ( standard a sinistra se rotazione CCW, altrimenti a destra, oppure da funzione di macchina) + local nHeadSide = EgtIf( dSpeed < 0, MCH_SAW_HS.LEFT, MCH_SAW_HS.RIGHT) + if WD.GetSawHeadSide then nHeadSide = WD.GetSawHeadSide( dSpeed, sHead) end + EgtSetMachiningParam( MCH_MP.HEADSIDE, nHeadSide) + -- assegno i dati di attacco (sicurezza solo se angolo interno) + local nLeadIn = MCH_SAW_LI.CENT + if ( not bInvert and ( vFace[i].Type & 1) ~= 0) or ( bInvert and ( vFace[i].Type & 2) ~= 0) then + nLeadIn = MCH_SAW_LI.STRICT + end + EgtSetMachiningParam( MCH_MP.LEADINTYPE, nLeadIn) + local dSal = 0 + if ( not bInvert and vFace[i].PrevAng < -0.1) or ( bInvert and vFace[j].PrevAng < -0.1) then + dSal = -WHISK_SAFE + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + -- assegno i dati di uscita (sicurezza solo se angolo interno) + local nLeadOut = MCH_SAW_LO.CENT + if ( not bInvert and ( vFace[i].Type & 2) ~= 0) or ( bInvert and ( vFace[i].Type & 1) ~= 0) then + nLeadOut = MCH_SAW_LO.STRICT + end + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nLeadOut) + local dEal = 0 + if ( not bInvert and vFace[j].PrevAng < -0.1) or ( bInvert and vFace[i].PrevAng < -0.1) then + dEal = -WHISK_SAFE + end + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- posizione braccio porta testa + if not bGearbox then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_NEAR) + end + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo a invertire direzione, lato di lavoro e attacco/uscita + EgtSetMachiningParam( MCH_MP.INVERT, not bInvert) + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( not bInvert, MCH_SAW_WS.LEFT, MCH_SAW_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, EgtIf( nLeadOut == MCH_SAW_LO.STRICT, MCH_SAW_LI.STRICT, MCH_SAW_LI.CENT)) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, EgtIf( nLeadIn == MCH_SAW_LI.STRICT, MCH_SAW_LO.STRICT, MCH_SAW_LO.CENT)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + -- ri-eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + -- se limite lunghezza di taglio e taglio lo supera + if WD.CUT_MAX_LENGTH and vFace[i].Len > WD.CUT_MAX_LENGTH then + -- sdoppio la lavorazione + local sSouName = EgtGetName( nMchId) + local nNewMchId = EgtCopyMachining( sSouName..'_B', sSouName) + --accorciamento iniziale della seconda + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, -vFace[i].Len/2) + --accorciamento finale della prima + EgtSetCurrMachining( nMchId) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, -vFace[i].Len/2) + -- segnalo spezzatura lavorazione faccia + vFace[i].Split = true + end + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByCut( Proc, nRawId, b3Raw) + local sWarn = '' + -- 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 : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la curva associata + local bOpposite = false + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then + AuxId = AuxId + Proc.Id + local vtExtr= EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if vtExtr then + bOpposite = ( Proc.Grp == 4 and vtExtr:getZ() < 0) or ( Proc.Grp == 3 and vtExtr:getZ() > 0) + if GetFacesExternalSide( Proc, vtExtr) ~= Proc.Grp then + bOpposite = not bOpposite + end + end + end + -- altezza massima delle facce + local dWidth = 0 + for i = 1, Proc.Fct do + local _, _, dFctW = WL.GetFaceHvRefDim( Proc.Id, i - 1) + dWidth = max( dWidth, dFctW) + end + -- lettura parametri (probabile/i parametro/i Q) + local nConeCut = VerifyCornerType( Proc) + -- recupero la lavorazione di taglio con lama e i suoi parametri (dapprima cerco quella che possa tagliare completamente) + local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') + local sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard', dWidth, nTool_ID) + if not sCutting then + sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard', nil, nTool_ID) + sWarn = 'Warning : elevation bigger than max sawcut depth' + end + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- gruppo ausiliario + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + -- recupero i dati di tutte le facce + local vFace, dMaxWidth, nNewProc = GetFacesData( Proc, bOpposite, true, dSawDiam, dSawMaxDepth, dSawThick, nAddGrpId, b3Raw, nil) + -- inserimento dei tagli di lama + local bCtOk, sCtErr = AddCuts( sCutting, vFace, Proc, nRawId, b3Raw, dSawThick) + if not bCtOk then return bCtOk, sCtErr end + -- se richiesta solo lama, esco + local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0 + if nCntType == 1 and nTool_ID ~= 0 then return true, sWarn end + -- se ci sono facce inclinate, escludo la sega a catena + local bSlanting = false + for i = 1, #vFace do + if abs( vFace[i].Norm:getZ()) > 0.01 then + bSlanting = true + break + end + end + -- recupero la lavorazione con sega a catena + local sSawing = WM.FindSawing( 'Sawing') + -- recupero la lavorazione di fresatura + local sMilling, dMillMaxDepth = WM.FindMilling( 'FreeContour', dMaxWidth + WD.CUT_EXTRA, nil, nil, nil, nil, true) + if not sMilling and ( not sSawing or bSlanting) then + sMilling = WM.FindMilling( 'FreeContour', nil, nil, nil, nil, nil, true) + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- se possibile, inserimento delle fresature + if sMilling then + local nMlOk, sMlErr, dThick = AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAddGrpId) + if nMlOk == 0 then return false, sMlErr end + -- se ci sono almeno due facce e lavorato almeno un angolo + if Proc.Fct >= 2 and dThick then + -- se abilitata la lavorazione corner con stop macchina e lavorazione precedente passante e spessore sotto il limite + -- o con fresa cono piccola e spessore sotto il limite + if ( nConeCut == 1 and nMlOk == 1 and dThick <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL)) or + ( nConeCut == 2 and dThick <= ( WD.MAX_CLEAN_CRN30 + 20 * GEO.EPS_SMALL)) then + local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw, + sMlErr, nAddGrpId, dThick, nNewProc, 0, + true) + if not bMcok then return bMcok, sMcErr end + else + -- messaggi nel log + if nConeCut == 1 then + if nMlOk ~= 1 then + local sErr = 'Clean corner 60° not applid because Milling not thru the thickness' + EgtOutLog( sErr) + else + local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) .. + ' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2) + EgtOutLog( sErr) + end + elseif nConeCut == 2 then + local sErr = 'Clean corner 30° not applid because thickness: ' .. EgtNumToString( dThick, 2) .. + ' is bigger than parameter MAX_CLEAN_CRN30: ' .. EgtNumToString( WD.MAX_CLEAN_CRN30 , 2) + EgtOutLog( sErr) + end + end + end + -- altrimenti provo con la sega a catena + else + local nCsOk, sCSErr, dThick = AddSawings( sSawing, vFace, Proc, nRawId, b3Raw) + if nCsOk == 0 then return false, sCsErr end + -- se ci sono almeno due facce e lavorato almeno un angolo + if Proc.Fct >= 2 and dThick then + -- se abilitata la lavorazione corner con stop macchina e lavorazione precedente passante e spessore sotto il limite + if nConeCut == 1 and nCsOk == 1 and dThick <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL) then + local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw, + sCSErr, nAddGrpId, nil, nNewProc, 0, + true) + if not bMcok then return bMcok, sMcErr end + else + if nConeCut == 1 then + if nCsOk ~= 1 then + local sErr = 'Clean corner 60° not applied because Chainsawing not thru the thickness' + EgtOutLog( sErr) + else + local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) .. + ' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2) + EgtOutLog( sErr) + end + elseif nConeCut == 2 then + local sErr = 'Not possible apply Clean corner 30° after use sawing' + EgtOutLog( sErr) + end + end + end + end + return true, sWarn +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 : 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 : 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) + local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') + -- recupero la lavorazione + local sMilling = WM.FindMilling( 'FreeContour', nil, nil, nTool_ID, nil, nil, true) + if not sMilling then + local sErr = 'Error : milling not found in library' + if nTool_ID then sErr = sErr .. ' (Tool_ID=' .. tostring( nTool_ID) .. ')' end + 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 = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth + end + end + -- eventuale spezzatura sul tratto più lungo se curva chiusa + --BL.PutStartOnLonger( AuxId) + -- verifiche per affondamento + if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then + dDepth = min( dDepth, b3Raw:getDimZ()) + WD.CUT_EXTRA + end + if dDepth > dMaxDepth then + -- lo limito e tolgo eventuali Tabs + dDepth = dMaxDepth + EgtSetMachiningParam( MCH_MP.LEAVETAB, false) + 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 + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- 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 + local nSCC = MCH_SCC.ADIR_ZP + if AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeByMark( 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 : 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 : 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) + local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') + -- recupero la lavorazione + local sMilling = WM.FindMilling( 'Text', nil, nil, nTool_ID) + if not sMilling then + local sErr = 'Error : milling not found in library' + if nTool_ID then sErr = sErr .. ' (Tool_ID=' .. tostring( nTool_ID) .. ')' end + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'FreeMark_' .. ( 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 + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se estrusione da sotto, inverto direzione fresa + if bToolInv then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeByNail( 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 : 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 : 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) + local nCntData = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') or 0 + if nCntData < 10 then + nCntData = nCntData + 10 + end + local dCntPar = EgtGetInfo( Proc.Id, 'CNT_PAR', 'd') or 100 + -- recupero la lavorazione + local sNailing = WM.FindNailing( nCntData) + if not sNailing then + local sErr = 'Error : nailing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Nail_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sNailing) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sNailing + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- 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, 10) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) + -- se in doppio lungo Y, devo dimezzare opportunamente la lavorazione + local dExtraDelta = 0 + if Proc.Double == 2 then + dExtraDelta = 0.45 * dCntPar + if Proc.Delta > 0 then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, -Proc.DblAcc - dExtraDelta) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, -Proc.DblAcc - dExtraDelta) + end + end + -- assegno parametri a note utente + local sUserNotes = 'Par=' .. EgtNumToString( dCntPar, 0) .. ';' + if Proc.Double and Proc.Double > 0 then + sUserNotes = sUserNotes .. 'Dbl=' .. EgtNumToString( Proc.Double, 0) .. ';' .. + 'Dlt=' .. EgtNumToString( abs( Proc.Delta) + dExtraDelta, 0) .. ';' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- 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 bOpposite = false + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + local vtExtr + if AuxId then + AuxId = AuxId + Proc.Id + vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if vtExtr then + bOpposite = ( Proc.Grp == 4 and vtExtr:getZ() < 0) or ( Proc.Grp == 3 and vtExtr:getZ() > 0) + if GetFacesExternalSide( Proc, vtExtr) ~= Proc.Grp then + bOpposite = not bOpposite + end + end + end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + local bPocketBotface = false + -- se la curva è aperta non la svuoto + if not EgtCurveIsClosed( AuxId) then + bPocketBotface = true + end + -- recupero i dati della curva e del profilo + local dDepth = EgtIf( bPocketBotface, 0, abs( EgtCurveThickness( AuxId))) + local dOriDepth = dDepth + -- cerco la faccia di fondo della superfice (deve avere direzione circa quella di estrusione della curva) + local nFacet + for i = 1, Proc.Fct do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + if abs( vtN * vtExtr) > 0.99 then + nFacet = i - 1 + break + end + end + if not nFacet then + return MakeByCut( Proc, nRawId, b3Raw) + end + -- dati della faccia di fondo + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local dDiam = min( dH, dV) + local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId) + -- gruppo ausiliario + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + local nNewProc, nNumFacet = RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFacet) + -- se ho forma a L + local bIsL = ( nNumFacet == 2 or TestElleShape3( nNewProc, nNumFacet) or TestElleShape4( nNewProc, nNumFacet) == 2) + -- verifico se U + local bIsU = ( nNumFacet == 3 and not TestElleShape3( nNewProc, nNumFacet)) + local dMiddleFacetLength = 0 + if bIsU then + local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( nNewProc, 1, GDB_ID.ROOT) + -- prendo la linea di base + if abs( dElev - dH2) < 1 and abs( dElev - dV2) > 1 then + dMiddleFacetLength = dV2 + elseif abs( dElev - dV2) < 1 and abs( dElev - dH2) > 1 then + dMiddleFacetLength = dH2 + end + end + if Proc.Fct < 5 and (( bIsL and not bIsU) or ( bIsU and dMiddleFacetLength > dDiam * 2)) then dDiam = dDiam * 2 end + local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') + -- recupero la lavorazione + local sPocketing = WM.FindPocketing( 'Pocket', dDiam, dDepth, nTool_ID) + if not sPocketing then + local sErr = 'Error : pocketing not found in library' + if nTool_ID then sErr = sErr .. ' (Tool_ID=' .. tostring( nTool_ID) .. ')' end + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local dThDiam = 100 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + 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 + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- aggiungo geometria + if bPocketBotface then + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + else + EgtSetMachiningGeometry( {{ AuxId, -1}}) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameVectorApprox( vtExtr, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + local sWarn = '' + if bPocketBotface then + local dThElev = dThDiam / 2 * sqrt( vtExtr:getX() * vtExtr:getX() + vtExtr:getY() * vtExtr:getY()) + if dElev + dThElev > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth - dElev - dThElev + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + else + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( EgtIf( bPocketBotface, min( dElev, dMaxDepth), dMaxDepth), 1) .. ';') + -- eseguo + local bAppOk = EgtApplyMachining( true, false) + if not bAppOk and not bPocketBotface then + bPocketBotface = true + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + dDepth = 0 + local dThElev = dThDiam / 2 * sqrt( vtExtr:getX() * vtExtr:getX() + vtExtr:getY() * vtExtr:getY()) + if dElev + dThElev > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth - dElev - dThElev + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + bAppOk = EgtApplyMachining( true, false) + end + if not bAppOk then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- lettura parametri (probabile/i parametro/i Q) + local nConeCut = VerifyCornerType( Proc) + -- recupero i dati di tutte le facce + local vFace, dMaxWidth + vFace, dMaxWidth, nNewProc = GetFacesData( Proc, bOpposite, false, dMillDiam, dMaxDepth, (dMillDiam/2), nAddGrpId, b3Raw, nNewProc) + -- se ci sono almeno due facce + if Proc.Fct >= 2 then + -- se abilitata la lavorazione corner con stop macchina e affondamento non superiore al limite + local dDepthMach = EgtIf( bPocketBotface, dDepth, ( dDepth - dOriDepth)) + if nConeCut == 1 and dDepthMach <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL) then + local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw, + dMillDiam, nAddGrpId, nil, nNewProc, dDepthMach) + if not bMcok then return bMcok, sMcErr end + else + EgtErase( nNewProc) + if nConeCut == 1 then + local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) .. + ' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2) + EgtOutLog( sErr) + elseif nConeCut == 2 then + local sErr = 'Clean corner 30° is not applied on pocketing' + EgtOutLog( sErr) + end + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPF.Make( Proc, nRawId, b3Raw) + -- recupero la tipologia (contorno o tasca) + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- se svuotatura + if bPocket then + return MakeByPocket( Proc, nRawId, b3Raw) + -- altrimenti contorno + else + -- riordino le facce + ReorderFaces( Proc.Id, EgtSurfTmFacetCount( Proc.Id)) + -- recupero il tipo di lavorazione + local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0 + -- se fresatura + if nCntType == 2 then + return MakeByMill( Proc, nRawId, b3Raw) + -- se marcatura + elseif nCntType == 10 then + return MakeByMark( Proc, nRawId, b3Raw) + -- se chiodatura + elseif nCntType == 20 then + return MakeByNail( Proc, nRawId, b3Raw) + -- altrimenti, taglio con lama e pulizia angoli con fresa + else + return MakeByCut( Proc, nRawId, b3Raw) + end + end +end + +--------------------------------------------------------------------- +return WPF diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessLapJoint.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessLapJoint.lua new file mode 100644 index 0000000..25b34b8 --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessLapJoint.lua @@ -0,0 +1,2579 @@ +-- WProcessLapJoint.lua by Egaltech s.r.l. 2022/02/04 +-- Gestione calcolo mezzo-legno per Pareti +-- 2021/08/27 DS Se tre o più facce con flag PCKT=1 forzo svuotatura con fresa (per Variant). +-- 2021/08/29 DS Se svuotatura di fianco setto flag per farla dopo i tagli. +-- 2021/09/03 DS Se due facce con sottosquadra ora si restituisce mesaaggio di errore. +-- 2021/10/05 FM Gestione lavorazioni SideMill con creazione gola passaggio gambo utensile +-- 2021/11/29 DS Correzione lav.ni SideMill quando più profonde che larghe. +-- 2022/01/04 DS Se U con fondo verso basso o alto non ci possono essere spigoli verticali da pulire. +-- 2022/01/17 ES Migliorata scelta fresa per lavorazione di fianco sotto. +-- 2022/02/03 DS Gorge larga come gambo più sicurezza. +-- 2022/02/04 DS In svuotatura aggiunta gestione WD.MAXDIAM_POCK_CORNER in presenza di almeno un angolo interno. + +-- Tabella per definizione modulo +local WPL = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') +local FreeContour = require( 'WProcessFreeContour') + +EgtOutLog( ' WProcessLapJoint started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') +local WHISK_OFFS = 0.1 +local WHISK_SAFE = 5 +local MIN_LEN_CUT = 30 + +-- variabili assegnazione parametri Q +local Q_FORCE_BLADE = '' -- i +local Q_SIDE_MILL = '' -- d +local Q_CORNER_CUT = '' -- i + +-- variabile settaggio doppia lavorazione su angoo > 90 +local bMakeTwinCut = true +-- angolo sottosquadra ammesso per fresa cono 30° +local dAngleSmall = 70 + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPL.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or + ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or + ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or + ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or + ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or + ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or + ( ( Proc.Grp == 4) and Proc.Prc == 39) +end + +--------------------------------------------------------------------- +local function AssignQIdent( Proc) + + -- reset assegnazione parametri Q + Q_FORCE_BLADE = '' + Q_SIDE_MILL = '' + Q_CORNER_CUT = '' + + if Proc.Grp == 0 and Proc.Prc == 12 then + Q_FORCE_BLADE = 'Q01' -- i + Q_SIDE_MILL = 'Q02' -- i + Q_CORNER_CUT = '' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then + Q_FORCE_BLADE = '' -- i + Q_SIDE_MILL = 'Q08' -- i + Q_CORNER_CUT = 'Q05' -- i + else + Q_FORCE_BLADE = 'Q01' -- i + Q_SIDE_MILL = 'Q03' -- i + Q_CORNER_CUT = 'Q05' -- i + end + -- le altre features gestite non hanno parametri Q +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc) + + local bForceUseBlade = false + if #Q_FORCE_BLADE == 0 or EgtGetInfo( Proc.Id, Q_FORCE_BLADE, 'i') == 1 then + bForceUseBlade = true + end + + -- Verifico se utilizzare la fresa di lato : + -- 0 : niente + -- 1 : utilizzo fresa di lato (alla faccia selezionata) + local nUseSideMillAsBlade = EgtGetInfo( Proc.Id, Q_SIDE_MILL, 'i') or 0 + + -- Verifico il tipo di lavorazione su angolo : + -- 0 : niente + -- 1 : ripresa corner dopo pausa per rimozione sfridi (fresa 60deg) + -- 2 : ripresa corner senza pausa (fresa 30 deg) + -- 3 : scarico corner (tipo foro). + local nTypeCornerCut = EgtGetInfo( Proc.Id, Q_CORNER_CUT, 'i') or 0 + + return nTypeCornerCut, nUseSideMillAsBlade, bForceUseBlade +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPL.Classify( Proc, b3Raw) + -- se 1 faccia + if Proc.Fct == 1 then + -- dati della faccia + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se è lavorabile da sopra + return vtN:getZ() >= WD.NZ_MINA + -- se 2 facce + elseif Proc.Fct == 2 then + -- dati delle facce + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile da sopra o di fianco + return ( vtN[1]:getZ() >= - 0.01 or vtN[2]:getZ() >= - 0.01) + -- se più di 2 facce + else + local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + -- se trovata faccia di fondo + if nFacInd >= 0 then + -- determino componente Z della normale più diretta verso il basso + local dMinNz = 1 + for i = 1, Proc.Fct do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT) + if vtN:getZ() < dMinNz then + dMinNz = vtN:getZ() + end + end + -- dati della faccia + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- per lavorare alcune superfici che sono di poco negative controllo che la minima Z sia al di sopra del punto minimo calcolato per + -- una lama da 500 + local bAllowNegativeFace + if vtN:getZ() < - 0.01 then + if vtN:getZ() > - 0.088 and Proc.Box:getMin():getZ() - b3Raw:getMin():getZ() - (500 * abs(vtN:getZ())) >= 0 then + bAllowNegativeFace = true + end + end + -- verifico se la faccia è lavorabile da sopra o di fianco + if ( vtN:getZ() >= WD.NZ_MINA or ( dMinNz < -0.866 and Proc.Fct >= 3 and ( vtN:getZ() > - 0.01 or bAllowNegativeFace))) then + Proc.Stype = 1 + return true + -- altrimenti verifico la eventuale seconda faccia + elseif nFacInd2 then + -- dati della faccia + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd2, GDB_ID.ROOT) + local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd2, GDB_ID.ROOT) + -- restituisco se faccia lavorabile + Proc.Stype = 2 + return ( vtN2:getZ() >= WD.NZ_MINA or ( dMinNz < -0.866 and Proc.Fct >= 3 and vtN2:getZ() > - 0.01)) + -- se tre facce + elseif Proc.Fct == 3 then + -- verifico se U da sopra + -- dati della faccia + local nFac2 = EgtIf( nFacInd == 0, 1, 0) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFac2, GDB_ID.ROOT) + Proc.Stype = 3 + return ( abs( ( vtN ^ vtN2) * Z_AX()) >= WD.NZ_MINA) + -- altrimenti non lavorabile + else + return false + end + -- se altrimenti tunnel + elseif nFacInd == -1 then + -- dati delle prime tre facce + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + vtN[3] = EgtSurfTmFacetNormVersor( Proc.Id, 2, GDB_ID.ROOT) + -- verifico se è lavorabile da sopra + local vtAxN = vtN[1] ^ vtN[2] + if vtAxN:isSmall() then vtAxN = vtN[1] ^ vtN[3] end + Proc.Stype = 4 + return ( abs( vtAxN:getZ()) >= WD.NZ_MINA) + -- altrimenti non lavorabile + else + return false + end + end +end + +-- funzione che verifica se faccia lavorabile da sopra +local function VerifyVtN( ProcId, nFct) + local nFlip0 = 0 + local nFlip1 = 0 + -- dati della faccia + local vtN = EgtSurfTmFacetNormVersor( ProcId, nFct, GDB_ID.ROOT) + local dVtNZ = vtN:getZ() + -- verifico se è lavorabile da sopra + nFlip0 = EgtIf( dVtNZ >= WD.NZ_MINA, 100, 0) + -- verifico se e' lavorabile da fliped: cambio segno al versore + nFlip1 = EgtIf( -dVtNZ >= WD.NZ_MINA, 100, 0) + return nFlip0, nFlip1 +end + +-- funzione che fa la media dei versori per assegnare punteggi flip +local function VerifyVtNMedia(ProcId, nFct1, nFct2) + local nFlip0 = 0 + local nFlip1 = 0 + -- dati delle facce + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( ProcId, nFct1, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( ProcId, nFct2, GDB_ID.ROOT) + local dVtN1Z = vtN[1]:getZ() + local dVtN2Z = vtN[2]:getZ() + -- se entrambi i versori positivi + if (dVtN1Z >= - 0.01 and dVtN2Z >= - 0.01) then + -- posso lavorarlo da sopra + nFlip0 = 100 + -- se almeno un versore positivo + elseif (dVtN1Z >= - 0.01 or dVtN2Z >= - 0.01) then + -- calcolo media dei versori: se positiva tende verso alto + local dVtNMedia = ( dVtN1Z + dVtN2Z) / 2 + if dVtNMedia >= 0 - GEO.EPS_SMALL and dVtNMedia <= 0 + GEO.EPS_SMALL then + nFlip0 = 100 + elseif dVtNMedia >= 0 + GEO.EPS_SMALL then + nFlip0 = 75 + else + nFlip0 = 25 + end + -- se entrambi i versori negativi, impossibile da fare + else + nFlip0 = 0 + end + -- verifico se e' lavorabile da fliped: cambio segno ai versori + dVtN1Z = -dVtN1Z + dVtN2Z = -dVtN2Z + -- se entrambi i versori positivi + if (dVtN1Z >= - 0.01 and dVtN2Z >= - 0.01) then + -- posso lavorarlo da sopra + nFlip1 = 100 + -- se almeno un versore positivo + elseif (dVtN1Z >= - 0.01 or dVtN2Z >= - 0.01) then + -- calcolo media dei versori: se positiva tende verso alto + local dVtNMedia = ( dVtN1Z + dVtN2Z) / 2 + if dVtNMedia >= 0 - GEO.EPS_SMALL and dVtNMedia <= 0 + GEO.EPS_SMALL then + nFlip1 = 100 + elseif dVtNMedia >= 0 + GEO.EPS_SMALL then + nFlip1 = 75 + else + nFlip1 = 25 + end + -- se entrambi i versori negativi, impossibile da fare + else + nFlip0 = 0 + end + return nFlip0, nFlip1 +end + +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPL.FlipClassify( Proc) + local nFlip0 = -1 + local nFlip1 = -1 + -- se 1 faccia + if Proc.Fct == 1 then + -- verifico che la normale permetta la lavorazione da sopra ed assegno punteggio di conseguenza + nFlip0, nFlip1 = VerifyVtN( Proc.Id, 0) + -- se 2 facce + elseif Proc.Fct == 2 then + -- calcolo la media delle normali delle facce ed assegno punteggio maggiore se positiva + nFlip0, nFlip1 = VerifyVtNMedia(Proc.Id, 0, 1) + -- se più di 2 facce + else + local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + if nFacInd == -2 then return 0, 0 end + -- se 3 facce + if Proc.Fct == 3 then + -- se forma ad U + if not nFacInd2 or nFacInd2 == 0 then + -- verifico che la normale del fondo permetta la lavorazione da sopra ed assegno punteggio di conseguenza + nFlip0, nFlip1 = VerifyVtN( Proc.Id, nFacInd) + -- se non ad U + else + -- calcolo la media delle normali delle facce di fondo ed assegno punteggio maggiore se positiva + nFlip0, nFlip1 = VerifyVtNMedia(Proc.Id, nFacInd, nFacInd2) + end + -- se 4 facce + elseif Proc.Fct == 4 then + -- se senza fondo (tunnel) + if not nFacInd or nFacInd == -1 then + -- dati delle facce + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + vtN[3] = EgtSurfTmFacetNormVersor( Proc.Id, 2, GDB_ID.ROOT) + vtN[4] = EgtSurfTmFacetNormVersor( Proc.Id, 3, GDB_ID.ROOT) + -- verifico se è lavorabile da sopra + local vtAxN = vtN[1] ^ vtN[2] + if vtAxN:isSmall() then + vtAxN = vtN[1] ^ vtN[3] + end + if ( abs( vtAxN:getZ()) >= WD.NZ_MINA) then + -- calcolo la media dei versori delle facce + local dVtNMedia = ( vtN[1]:getZ() + vtN[2]:getZ() + vtN[3]:getZ() + vtN[4]:getZ()) / 4 + if dVtNMedia >= 0 - GEO.EPS_SMALL and dVtNMedia <= 0 + GEO.EPS_SMALL then + nFlip0 = 100 + nFlip1 = 100 + elseif dVtNMedia >= 0 + GEO.EPS_SMALL then + nFlip0 = 75 + nFlip1 = 25 + else + nFlip0 = 25 + nFlip1 = 75 + end + end + -- se con fondo + else + -- calcolo la media delle normali delle facce di fondo ed assegno punteggio maggiore se positiva + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd2, GDB_ID.ROOT) + if vtN[1]:getZ() == -1 or vtN[2]:getZ() == -1 then return 0, 100 end + if vtN[1]:getZ() == 1 or vtN[2]:getZ() == 1 then return 100, 0 end + nFlip0, nFlip1 = VerifyVtNMedia(Proc.Id, nFacInd, nFacInd2) + end + -- se 5 facce + elseif Proc.Fct == 5 then + -- verifico che la normale del fondo permetta la lavorazione da sopra ed assegno punteggio di conseguenza + nFlip0, nFlip1 = VerifyVtN( Proc.Id, nFacInd) + end + end + return nFlip0, nFlip1 +end + +--------------------------------------------------------------------- +local function TestElleShape3( nIdGeom, nNumFacet) + -- valida solo nel caso di tre facce + if nNumFacet ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +local function TestElleShape4( nIdGeom, nNumFacet) + -- valida solo nel caso di quattro facce + if nNumFacet ~= 4 then return false end + -- determino se L con due facce terminali o O + local nFac3Adj = 0 + local dMinArea3 = GEO.INFINITO * GEO.INFINITO + local dMaxArea2 = 0 + for i = 1, 4 do + local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( nIdGeom, i - 1, GDB_ID.ROOT) + local dArea = dH * dV + if nCount == 2 then + dMaxArea2 = max( dMaxArea2, dArea) + elseif nCount == 3 then + dMinArea3 = min( dMinArea3, dArea) + nFac3Adj = nFac3Adj + 1 + end + end + if nFac3Adj ~= 2 then return false end + -- verifico se L profonda oppure lunga + if dMinArea3 < dMaxArea2 then + return 1 + else + return 2 + end +end + +--------------------------------------------------------------------- +local function GetOtherRegions( nPartId) + local vOthers = {} + local nOtherId = EgtGetFirstPartInRawPart( EgtGetFirstRawPart() or GDB_ID.NULL) + while nOtherId do + local nRegId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nOtherId, 'Outline') or GDB_ID.NULL) + while nRegId do + local vtN = EgtSurfFrNormVersor( nRegId, GDB_ID.ROOT) + if EgtExistsInfo( nRegId, 'REGION') and vtN and AreSameVectorApprox( vtN, Z_AX()) then + local b3Reg = EgtGetBBoxGlob( nRegId, GDB_BB.STANDARD) + if b3Reg then + table.insert( vOthers, { PartId = nOtherId, RegId = nRegId, Box = b3Reg}) + end + end + nRegId = EgtGetNext( nRegId) + end + nOtherId = EgtGetNextPartInRawPart( nOtherId) + end + return vOthers +end + +--------------------------------------------------------------------- +local function ReorderFaces( nIdSurf, nNumFacet) + -- cerco una faccia senza precedenti + local nFirstFac + for i = 1, nNumFacet do + -- centro e normale della faccia + local ptCen, vtN = EgtSurfTmFacetCenter( nIdSurf, i - 1, GDB_ID.ROOT) + -- verifico con le altre facce + local bFoundPrec + for j = 1, nNumFacet do + if j ~= i then + -- verifico se è precedente + local bAdj, ptP1, _, _ = EgtSurfTmFacetsContact( nIdSurf, i - 1, j - 1, GDB_ID.ROOT) + if bAdj and ( vtN ^ ( ptCen - ptP1)) * Z_AX() > 0 then + bFoundPrec = true + break + end + end + end + if not bFoundPrec then + nFirstFac = i + break + end + end + -- se trovata, la metto al primo posto + if nFirstFac and nFirstFac ~= 1 then + EgtSurfTmSwapFacets( nIdSurf, nFirstFac - 1, 0) + end + -- ordino le facce in modo da avere una sequenza ordinata con le normali a destra + for i = 1, nNumFacet - 1 do + -- centro e normale della faccia + local ptCen, vtN = EgtSurfTmFacetCenter( nIdSurf, i - 1, GDB_ID.ROOT) + -- cerco la successiva + for j = i + 1, nNumFacet do + -- verifico se è successiva + local bAdj, ptP1, _, _ = EgtSurfTmFacetsContact( nIdSurf, i - 1, j - 1, GDB_ID.ROOT) + if bAdj and ( vtN ^ ( ptP1 - ptCen)) * Z_AX() > 0 then + EgtSurfTmSwapFacets( nIdSurf, i, j - 1) + break + end + end + end +end + +--------------------------------------------------------------------- +local function RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFaceToDel) + -- copio la superfice nel gruppo ausiliario + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + EgtSurfTmRemoveFacet( nNewProc, nFaceToDel) + local nNumFacet = EgtSurfTmFacetCount( nNewProc) + ReorderFaces( nNewProc, nNumFacet) + return nNewProc, nNumFacet +end + +--------------------------------------------------------------------- +local function GetFacesData( nNewProc, bOpposite, bCalclForBlade, dToolDiam, dToolMaxDepth, dToolThick, nAddGrpId, nPartId) + + local nNumFacet = EgtSurfTmFacetCount( nNewProc) + local vFace = {} + -- recupero i dati di tutte le facce + for i = 1, nNumFacet do + -- indici faccia corrente e precedente + local nFac = EgtIf( bOpposite, nNumFacet - i, i - 1) + local nPrecFac + if bOpposite then + nPrecFac = EgtIf( i == 1, 0, nFac + 1) + else + nPrecFac = EgtIf( i == 1, nNumFacet - 1, i - 2) + end + -- recupero centro e normale della faccia + local ptCen, vtN = EgtSurfTmFacetCenter( nNewProc, nFac, GDB_ID.ROOT) + -- recupero le dimensioni della faccia + local _, dLen, dWidth = WL.GetFaceHvRefDim( nNewProc, nFac) + -- recupero l'angolo con la faccia precedente + local bAdj, ptLocP1, ptLocP2, dAng = EgtSurfTmFacetsContact( nNewProc, nPrecFac, nFac, GDB_ID.ROOT) + -- verifico che l'adiacenza sia veramente con il precedente (percorro con normale a destra) + if bAdj then + if ( vtN ^ ( ptLocP1 - ptCen)) * Z_AX() > 0 then + bAdj = false + end + end + -- salvo i dati + vFace[i] = { Fac = nFac, Cen = ptCen, Norm = vtN, Len = dLen, Width = dWidth, AngPrev = EgtIf( bAdj, dAng, 0)} + if bAdj then + if ptLocP1:getZ() < ptLocP2:getZ() then + vFace[i].PPrev = ptLocP1 + else + vFace[i].PPrev = ptLocP2 + end + end + end + -- analizzo le facce + local dMaxWidth = 0 + for i = 1, #vFace do + -- aggiorno la massima larghezza + if vFace[i].Width > dMaxWidth then + dMaxWidth = vFace[i].Width + end + -- verifico l'affondamento + local dDepth = WD.CUT_EXTRA + if vFace[i].Width + WD.CUT_EXTRA > dToolMaxDepth then + dDepth = dToolMaxDepth - vFace[i].Width + end + -- lunghezza baffo + local dElev = vFace[i].Width + dDepth + local dWhisk = EgtIf( bCalclForBlade, ( dElev * sqrt( dToolDiam / dElev - 1) + WHISK_SAFE), (dToolDiam/2) + WHISK_SAFE) + -- determino la lunghezza del taglio passante e il tipo di attacco e uscita + local dLen = vFace[i].Len + local nType = 0 + if vFace[i].AngPrev < -0.1 then + dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0) + nType = nType + 1 + end + if vFace[EgtIf( i < nNumFacet, i + 1, 1)].AngPrev < -0.1 then + dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0) + nType = nType + 2 + end + -- se lunghezza non significativa, non va inserito il taglio + if dLen < MIN_LEN_CUT then + nType = 4 + end + vFace[i].Depth = dDepth + vFace[i].Whisk = dWhisk + vFace[i].Type = nType + end + -- recupero le regioni degli altri pezzi + local vOthers = GetOtherRegions( nPartId) + -- verifico i baffi sporgenti dei tagli rispetto alle altre regioni + for i = 1, #vFace do + -- verifico il baffo iniziale + if vFace[i].Type ~= 4 and ( vFace[i].Type & 1) == 0 then + -- creo il rettangolo del baffo + local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize() + local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), -90) + local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, -90) + local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt + local ptDir = ptIni + ( vFace[i].Whisk - WHISK_OFFS) * vtDir + local ptCross = ptDir + ( dToolThick - WHISK_OFFS) * vtOrt + local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB) + local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD) + -- verifico se interferisce con gli altri pezzi + for j = 1, #vOthers do + if OverlapsXY( b3Wh, vOthers[j].Box) then + local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0) + if nClass ~= GDB_RC.OUT then + local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 2) ~= 0, -vFace[i].Whisk, 0) + if dLen >= MIN_LEN_CUT then + vFace[i].Type = vFace[i].Type + 1 + else + vFace[i].Type = 4 + end + break + end + end + end + EgtErase( WhId) + end + -- verifico il baffo finale + if vFace[i].Type ~= 4 and ( vFace[i].Type & 2) == 0 then + -- creo il rettangolo del baffo + local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize() + local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), 90) + local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, 90) + local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt + local ptDir = ptIni + ( vFace[i].Whisk - WHISK_OFFS) * vtDir + local ptCross = ptDir + ( dToolThick - WHISK_OFFS) * vtOrt + local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB) + local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD) + -- verifico se interferisce con gli altri pezzi + for j = 1, #vOthers do + if OverlapsXY( b3Wh, vOthers[j].Box) then + local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0) + if nClass ~= GDB_RC.OUT then + local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 1) ~= 0, -vFace[i].Whisk, 0) + if dLen >= MIN_LEN_CUT then + vFace[i].Type = vFace[i].Type + 2 + else + vFace[i].Type = 4 + end + break + end + end + end + EgtErase( WhId) + end + end + -- eventuali stampe + for i = 1, #vFace do + local Face = vFace[i] + local sOut = 'Face '..tostring( Face.Fac)..' C'..tostring( Face.Cen)..' N'..tostring( Face.Norm).. + ' L='..EgtNumToString( Face.Len, 1)..' W='..EgtNumToString( Face.Width, 1)..' Ap='..EgtNumToString( Face.AngPrev, 1).. + ' D='..EgtNumToString( Face.Depth, 1)..' B='..EgtNumToString( Face.Whisk, 1)..' T='..tostring( Face.Type) + EgtOutLog( sOut, 3) + end + + return vFace, dMaxWidth, nNewProc +end + +--------------------------------------------------------------------- +local function GetTunnelDimension( nId, nPartId, nAddGrpId) + -- ottengo i versori delle 4 facce e ottengo l'orientamento del tunnel + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- variabili dimensioni fessura e id faccia lunga + local dDimMin + local dDimMax + local nLongIdFace = 0 + local bNegFace + local bOppoFace = false + -- ottengo il versore ortogonale + local ptN1, vtN1 = EgtSurfTmFacetCenter( nId, 0, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( nId, 1, GDB_ID.ROOT) + local vtOrtho = vtN1 ^ vtN2 + if vtOrtho:isSmall() then + if nFacCnt >= 3 then + _, vtN2 = EgtSurfTmFacetCenter( nId, 2, GDB_ID.ROOT) + vtOrtho = vtN1 ^ vtN2 + bOppoFace = true + else + return + end + end + if vtOrtho:getZ() < -0.5 then + vtOrtho = -vtOrtho + bNegFace = true + end + -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta la profondità della fessura + local frFc = Frame3d( ptN1, vtOrtho) ; + local bBoxLoc = EgtGetBBoxRef( nId, GDB_BB.STANDARD, frFc) + local dDepth = bBoxLoc:getDimZ() + -- mi assicuro che la Z del punto utilizzato per creare la superficie sia alla Z inferiore del bounding box locale + local ptN2 = Point3d(ptN1) + ptN2:toLoc(frFc) + ptN2 = Point3d( ptN2:getX(), ptN2:getY(), bBoxLoc:getMin():getZ() + 2*GEO.EPS_SMALL) + ptN2:toGlob(frFc) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN2, vtOrtho, b3Solid, GDB_ID.ROOT) + -- ritaglio la superficie con le facce della fessura + for i = 1, nFacCnt do + local ptN, vtN = EgtSurfTmFacetCenter( nId, i - 1, GDB_ID.ROOT) + EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) + end + -- sposto la geometria trovata sulla Z minima (era su di 2 * GEO.EPS_SMALL) + EgtMove( nSurfInt, Point3d(0,0,-2*GEO.EPS_SMALL) - ORIG(), GDB_RT.GLOB) + -- mi faccio dare il contorno della superfice e la ricreo in modo più corretto + local nIdCont, nIdNum = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) + -- elimino le entità allineate dello stesso tipo + EgtMergeCurvesInCurveCompo( nIdCont, 2*GEO.EPS_SMALL) + EgtErase(nSurfInt) + nSurfInt = EgtSurfTmByFlatContour( nAddGrpId, nIdCont, 2*GEO.EPS_SMALL) + -- elimino il contorno + EgtErase(nIdCont) + -- se normale negativa inverto + _, vtN1 = EgtSurfTmFacetCenter( nSurfInt, 0, GDB_ID.ROOT) + if vtN1:getZ() < -0.5 then EgtInvertSurf( nSurfInt) end + local _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT) + dDimMin = min( DimH, DimV) + dDimMax = max( DimH, DimV) + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nId, nFacCnt-1, GDB_ID.ROOT) + -- se faccia pari alla larghezza fessura + if abs(DimH - dDimMax) < GEO.EPS_SMALL or abs(DimV - dDimMax) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + -- altrimenti verifico anche con la faccia precedente + else + local nFaceToCheck = EgtIf( bOppoFace, nFacCnt-3, nFacCnt-2) + -- prendo le dimensioni della faccia e poi confronto con il minimo + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nId, nFaceToCheck, GDB_ID.ROOT) + -- se trovato con il minimo, questa seconda faccia non è la più lunga + if abs(DimH - dDimMin) < GEO.EPS_SMALL or abs(DimV - dDimMin) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + else + nLongIdFace = nFaceToCheck + end + end + if not dDimMax then + return dDimMin, dDimMax, dDepth, nil, nil + end + return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt +end + +--------------------------------------------------------------------- +local function ReorderFacesFromTab( nIdSurf, vFace) + + local nFacCnt = EgtSurfTmFacetCount( nIdSurf) + for i = 1, #vFace do + for j = 1, nFacCnt do + -- ottengo punto iniziale e versore della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nIdSurf, (j-1), GDB_ID.ROOT) + -- se versore e posizione coincidono e non corrispondono al numero faccia, faccio lo swap + if AreSameVectorExact( vFace[i].Norm, vtN) and AreSamePointEpsilon( vFace[i].Cen, ptC, 50*GEO.EPS_SMALL) then + if j - 1 ~= vFace[i].Fac then + EgtSurfTmSwapFacets( nIdSurf, vFace[i].Fac, (j-1)) + end + break + end + end + end + return nIdSurf +end + +--------------------------------------------------------------------- +local function CalcInterference( nNewProc, vtExtr, ptCentr, dDiam1, dDiam2, + dTall1, dTall2, dDiam3, dTall3) + + local ptCentrGrid1 = ptCentr + ( vtExtr * 0.01) + local frOriTool = Frame3d( ptCentrGrid1, vtExtr) + local bColl1 = EgtCDeConeSolid( frOriTool, dDiam1/2, dDiam2/2, dTall1, nNewProc, 0, GDB_RT.GLOB) + if bColl1 then return true end + local ptCentrGrid2 = ptCentr + ( vtExtr * ( dTall1 + 0.01)) + frOriTool = Frame3d( ptCentrGrid2, vtExtr) + local bColl2 = EgtCDeCylSolid( frOriTool, dDiam2/2, (dTall2-dTall1), nNewProc, 0, GDB_RT.GLOB) + if bColl2 then return true end + local ptCentrGrid3 = ptCentr + ( vtExtr * ( dTall2 + 0.01)) + frOriTool = Frame3d( ptCentrGrid3, vtExtr) + local bColl3 = EgtCDeCylSolid( frOriTool, dDiam3/2, (dTall3-dTall2), nNewProc, 0, GDB_RT.GLOB) + if bColl3 then return true end + -- restituisco risultato controllo collisioni + return false +end + +--------------------------------------------------------------------- +local function MakeLocalSurf( ptP1, ptP2, ptP3, nAddGrpId) + + if not ptP1 or not ptP2 or not ptP3 then + return nil + end + + local pAuxId = {} + local nAuxId, AuxId + nAuxId = EgtLine( nAddGrpId, ptP1, ptP2, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + nAuxId = EgtLine( nAddGrpId, ptP2, ptP3, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + nAuxId = EgtLine( nAddGrpId, ptP3, ptP1, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- trasformo in percorso + if #pAuxId ~= 3 then + return nil + end + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + -- se non c'é il percorso esco + if not AuxId then + return nil + end + -- creo la superfice piana + local nidFace = EgtSurfTmByFlatContour( nAddGrpId, AuxId, 0.01) + if not nidFace then + EgtErase(AuxId) + return nil + end + -- se normale negativa inverto + local _, vtN1 = EgtSurfTmFacetCenter( nidFace, 0, GDB_ID.ROOT) + if vtN1:getZ() < -0.5 then EgtInvertSurf( nidFace) end + + EgtErase(AuxId) + return nidFace +end + +--------------------------------------------------------------------- +local function AddMillCornerMachining( nPartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, dOffsAng, dDepthMach, + bThruThick, dThSurf, dDiam1, dDiam2, dTall1, + dTall2, dDiam3, dTall3, bMakeLocSurf, vFace) + -- variabili costruzione geometria + local pAuxId = {} + local nAuxId + local ptApPoint + local AuxId + local nNewProcLoc + -- se devo creare superfice locale + if bMakeLocSurf then + -- creo superfice locale o esco + local nSurfToAdd = MakeLocalSurf( tFacAdj[1][7], tFacAdj[1][8], tFacAdj[1][9], nAddGrpId) + if nSurfToAdd then + local nFacCntPre = EgtSurfTmFacetCount( nNewProc) + -- creo copia del percorso principale e gli aggiungo la nuova faccia + nNewProcLoc = EgtCopyGlob( nNewProc, nAddGrpId) + nNewProcLoc = EgtSurfTmBySewing( nAddGrpId, {nNewProcLoc,nSurfToAdd} , true) + -- riordino le facce + nNewProcLoc = ReorderFacesFromTab( nNewProcLoc, vFace) + -- acquisisco il numero della faccia + nFacCnt = EgtSurfTmFacetCount( nNewProcLoc) + nFacInd = nFacCnt - 1 + else + local sErr = 'Cannot make local bottom surface' + EgtOutLog( sErr) + return true, '' + end + else + nNewProcLoc = nNewProc + end + -- prendo il primo versore + local _, vtN1 = EgtSurfTmFacetCenter( nNewProcLoc, nFacInd, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1][1], GDB_ID.ROOT) + local _, vtN3 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1][2], GDB_ID.ROOT) + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1][1], GDB_ID.ROOT) + local _, ptLocP3, ptLocP4, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1][2], GDB_ID.ROOT) + -- se ho creato faccia locale su copia superficie, cancella la copia + if bMakeLocSurf then + EgtErase( nNewProcLoc) + end + local nIdIniPoint + local nIdEndPoint + if ptLocP1 and ptLocP2 then + if ( dist( ptLocP1, tFacAdj[1][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[1][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptLocP1, tFacAdj[1][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[1][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- versore direzione + local vtExtr = tFacAdj[1][nIdIniPoint] - tFacAdj[1][nIdEndPoint] + vtExtr:normalize() + -- versore direzione di uscita + local vtExtrExit + -- inserisco le prime tre linee + if nIdIniPoint and nIdEndPoint then + -- se fresatura da sotto salto la lavorazione + if vtExtr:getZ() < WD.DRILL_VZ_MIN then + local sErr = 'Error : Impossible insert clean corner from bottom' + EgtOutLog( sErr) + return false, sErr + end + -- sommo i tre versori per avere una direzione media + vtExtrExit = vtN2 + vtN3 + vtExtrExit:normalize() + -- se tipo 1 calcolo angolo tilt di 45° + if nTypeConeCut == 1 then + vtExtr = vtExtrExit + Z_AX() + -- altrimenti tipo 2, calcolo angolo tilt di 33° (dalla verticale) + else + vtExtr = vtExtrExit + Vector3d(0,0,1.539865) + end + vtExtr:normalize() + local vtCheck = Vector3d(vtExtr) + -- se ho un offset angolare ruoto il percorso + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + vtCheck:rotate( Z_AX(), dOffsAng) + end + -- controllo se c'è collisione con le facce della superfice + if nTypeConeCut == 1 and CalcInterference( nNewProc, vtCheck, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), dDiam1, dDiam2, + dTall1, dTall2, dDiam3, dTall3) then + local sErr = 'Collision detect from clean corner tool and surface' + EgtOutLog( sErr) + return true, '' + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdIniPoint], tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- se uso utensile cono 60° + if nTypeConeCut == 1 then + -- se offset angolare valido e/o negativo creo il baffo precedente + if dOffsAng < ( 100 * GEO.EPS_SMALL) then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[1][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + local dLenTrimExt = dist( tFacAdj[1][nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + Point3d( 0, 0, dDepthMach) + else + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint + Point3d( 0, 0, -dDepthMach), tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + end + end + -- inserisco le ultime tre linee + -- trovo il secondo punto sulla superfice di riferimento + ptLocP1, ptLocP2 = ptLocP3, ptLocP4 + if ptLocP1 and ptLocP2 then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[1][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + -- se uso utensile cono 60° + if nTypeConeCut == 1 then + -- se offset angolare valido e/o negativo creo il baffo precedente + if dOffsAng > -( 100 * GEO.EPS_SMALL) then + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + local dLenTrimExt = dist( tFacAdj[1][nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + Point3d( 0, 0, dDepthMach) + else + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint + Point3d( 0, 0, -dDepthMach), tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- ultima linea di distacco (5mm in direzione utensile) + local pEnd = tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach) + ( 5 * vtExtr) + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + else + -- linea di distacco (2mm in direzione utensile) + local pEnd = tFacAdj[1][nIdEndPoint] + ( 2 * vtExtr) + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint], pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- ultima linea di risalita in Z + local pIni = pEnd + pEnd = pIni + ( dThick * Z_AX()) + nAuxId = EgtLine( nAddGrpId, pIni, pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + end + -- trasformo in percorso + if #pAuxId > 0 then + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + end + -- se non c'é il percorso do errore + if not AuxId then + local sErr = 'Error : impossible make clean corner path' + EgtOutLog( sErr) + return false, sErr + end + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- se ho un offset angolare ruoto il percorso + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( AuxId, tFacAdj[1][nIdEndPoint], Z_AX(), dOffsAng, GDB_RT.GLOB) + end + -- inserisco la lavorazione + local sName = 'Clean_' .. ( EgtGetName( nNewProc) or tostring( nNewProc)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', nPartId) + -- se flag lavorazione spessore passante setto la nota per spostarla dopo i tagli di lama + if bThruThick and nTypeConeCut == 1 then + EgtSetInfo( nMchId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- 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) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4) + -- allungo inizio e fine di 10mm + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- setto affondamento 0 + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione +-- sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( 0.0, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + 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 + end + end + + return true, '' +end + +--------------------------------------------------------------------- +local function AddMillCorner( nTypeConeCut, vFace, Proc, nRawId, b3Raw, + dToolDiam, nAddGrpId, dThick, nMasterNewProc, dDepthMach, + bThruThick) + + local sMilling, dMaxDepth + -- se ripresa angolo con fresa cono 60° con ripresa + if nTypeConeCut == 1 then + -- recupero la lavorazione di fresatura + sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner60') + if not sMilling then + local sErr = 'Error : CleanCorner 60 not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- se ripresa angolo con fresa cono piccola senza ripresa + else + sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner30') + if not sMilling then + local sErr = 'Error : CleanCorner 30 not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMillTotDiam = 20 + local dMillDiamTh = 20 + local dToolLength = 20 + local dThickTool = 20 + local dSideAng = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh + dMillTotDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) or dMillTotDiam + dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dThickTool = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThickTool + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth -- qui è la distanza dal portautensile + -- calcolo il secondo diametro del cono + dMillTotDiam = dMillDiam + ( abs(dThickTool) * tan(dSideAng)) * 2 + end + end + -- copio la feature nel layer di appoggio + local nNewProc + if nMasterNewProc then + nNewProc = nMasterNewProc + else + nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + end + local nFacCnt = EgtSurfTmFacetCount( nNewProc) + local nFacInd, dDimMin, dDimMax, dDepth, nSurfInt + local bMakeLocSurf + if nFacCnt <= 4 then + -- ottengo le dimensioni apertura, la normale e la faccia inferiore + dDimMin, dDimMax, dDepth, _, _, nSurfInt = GetTunnelDimension( nNewProc, Proc.PartId, nAddGrpId) + if nSurfInt then + -- uso la dimensione minima anche nel caso che la cava sborda perchè la lavorazione potrebbe collidere con un pezzo limitrofo + local dMinWidth = dDimMin + nNewProc = EgtSurfTmBySewing( nAddGrpId, {nNewProc,nSurfInt} , true) + -- riordino le facce + nNewProc = ReorderFacesFromTab( nNewProc, vFace) + -- acquisisco il numero della faccia + nFacCnt = EgtSurfTmFacetCount( nNewProc) + nFacInd = nFacCnt - 1 + else + local sErr = 'Error : cannot create base surface' + EgtOutLog( sErr) + return false, sErr + end + else + bMakeLocSurf = true + end + -- verifico se ciclo chiuso + local bClosed = ( abs( vFace[1].AngPrev) > 0.1) + -- ciclo di inserimento delle fresate sulle facce del contorno in esame + local i = 1 + -- se faccia finale con fine non lavorato, forzo partenza da prima faccia non tutta saltata (tipo 4) + if bClosed and ( vFace[#vFace].Type == 4 or ( vFace[#vFace].Type & 2) ~= 0) then + while i <= #vFace and vFace[i].Type == 4 do + i = i + 1 + end + end + -- se facce tutte da saltare, parto dall'inizio + local bAllType4 = ( i > #vFace) + if bAllType4 or bClosed then i = 1 end + while i <= #vFace do + -- se tutta la faccia o la sua fine senza taglio, inserisco una fresatura + if ( vFace[i].Type & 2) ~= 0 or vFace[i].Type == 4 then + -- variabili costruzione geometria + local tFacAdj = {} + local nFace1 = vFace[i].Fac + local nFace2 + -- ricavo i tre punti per eventuale superficie locale + local ptLoc1, ptLoc2, ptLoc3 + -- punto precedente (punto precedente della faccia [i]) + ptLoc3 = vFace[i].PPrev + -- aggiungo geometria + i = i + 1 + local j = EgtIf( i <= #vFace, i, EgtIf( bClosed, 1, nil)) + if not j then + return true + end + nFace2 = vFace[j].Fac + -- punto in comune tra le due facce (punto precedente della faccia [j]) + ptLoc1 = vFace[j].PPrev + -- punto successivo ( precedente della faccia successiva) + j = j + 1 + local k = EgtIf( j <= #vFace, j, EgtIf( bClosed, 1, nil)) + -- se è un percorso aperto prendo il punto medio della seconda faccia come punto locale 2 + if not k then + ptLoc2 = Point3d( vFace[j-1].Cen:getX(), vFace[j-1].Cen:getY(), ptLoc1:getZ()) + else + ptLoc2 = vFace[k].PPrev + end + -- ricavo i punti e l'angolo interno + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( nNewProc, nFace1, nFace2, GDB_ID.ROOT) + -- se punti validi e angolo è interno e non è quasi piatto e >= 90 creo istanza + if ptP1 and ptP2 and dAng < 0 and dAng < -6 and dAng > EgtIf( nTypeConeCut == 1, -(90 + 10 * GEO.EPS_SMALL), -(180-dAngleSmall + 10 * GEO.EPS_SMALL)) then + local dLen = dist( ptP1, ptP2) + table.insert( tFacAdj, { nFace1, nFace2, dLen, ptP1, ptP2, dAng, ptLoc1, ptLoc2, ptLoc3}) + end + -- se ho un elemento creo percorso o percorsi in base al tipo di cono e all'apertura dall'angolo rispetto ai 90° + -- con una tolleranza di 2 gradi + if #tFacAdj > 0 then + if nTypeConeCut == 1 and bMakeTwinCut and (dAng + 90) > 2 then + local dAngOffs = (dAng + 90) / 2 + -- primo taglio + local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, -dAngOffs, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + -- secondo taglio + bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, dAngOffs, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + -- altrimenti ho un solo percorso + else + local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, 0, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + end + end + else + i = i + 1 + end + end + -- cancello la copia della superfice + if nNewProc then + EgtErase(nNewProc) + end + return true +end + +--------------------------------------------------------------------- +local function MakeByChainSaw( Proc, nFacet, nRawId, b3Raw, dElev, dH, dV) + local sWarn + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacet)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Cerco una faccia adiacente alla principale sul lato più lungo + local nFacAdj + local dMaxLen = 0 + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacet, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + local vtAdjN = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT) + if dLen > dMaxLen - 1 and vtAdjN:getZ() > -0.1 then + nFacAdj = vAdj[i] + dMaxLen = dLen + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) + end + end + end + if not nFacAdj then + local sErr = 'Error : long adjacent face not found' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero la lavorazione + local sSawing = WM.FindSawing( 'Sawing') + if not sSawing then + local sErr = 'Error : chainsawing not found in library' + EgtOutLog( sErr) + return false, sErr, 'MNF' + end + -- Recupero i dati dell'utensile + local dSawWidth = 75 + local dSawThick = 8 + local dMaxDepth = 200 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + if dSawThick > dV + 10 * GEO.EPS_SMALL then + local sErr = 'Error : chainsaw too thick' + EgtOutLog( sErr) + return false, sErr + end + -- Calcolo uso faccia + local nFaceUse = WL.GetNearestParalOpposite( vtN) + -- Calcolo angolo 3° asse rot (da direz. utensile) + local sRot3Ang = 'A1=180' + if WD.GetChainSawBlockedAxis then + sRot3Ang = WD.GetChainSawBlockedAxis( 1) + end + -- Calcolo angoli iniziali suggeriti + local sStartAngs + if WD.GetChainSawStartAngs then + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) + sStartAngs = WD.GetChainSawStartAngs( vtN2) + end + -- Lati chiusi + local bOpenStart = false + local bOpenEnd = false + -- Verifico se necessarie più passate + local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- Applico la lavorazione con sega a catena a questa faccia + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, sRot3Ang) + -- imposto angoli iniziali suggeriti + if sStartAngs then + EgtSetMachiningParam( MCH_MP.INITANGS, sStartAngs) + end + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se necessario, limito l'affondamento + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth - dElev + EgtOutLog( sWarn) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH '..EgtNumToString( dDepth, 1)) + end + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 2) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + elseif EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nFacet, nOthFac, nRawId, b3Raw, dSideDist) + -- dati della faccia e dell'altra + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local dDiam = min( dH, dV) + local _, vtRef = EgtSurfTmFacetCenter( Proc.Id, nOthFac, GDB_ID.ROOT) + -- recupero la lavorazione + local sMilling = WM.FindMilling( 'Side') + if not sMilling then return false end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMillLen = 10 + local dMillTotLen = 30 + local dMaxDepth = 0 + local dThDiam = 100 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMillLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dMillLen + dMillTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dMillTotLen + dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + end + end + if dMillDiam < dDiam or dMaxDepth < dElev then + local sErr = 'Error : Side Elevation too big' + EgtOutLog( sErr) + return false, sErr + end + local dMillExtra = dMillTotLen - dMillLen + if Proc.Box:getMin():getZ() - dMillExtra < b3Raw:getMin():getZ() - 10 * GEO.EPS_SMALL then + local sErr = 'Error : Tool collide with table' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di contornatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + -- sistemo i parametri di attacco e uscita + local dAddLen = ( WD.MID_GAP or 50) - ( WD.MID_SIC or 5) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) -- -dMillDiam/2 + dAddLen) + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, dSideDist + WD.CUT_SIC) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) -- -dMillDiam/2 + dAddLen) + EgtSetMachiningParam( MCH_MP.LOTANG, 0) + EgtSetMachiningParam( MCH_MP.LOPERP, dSideDist + WD.CUT_SIC) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto modo di lavorare la faccia + local nFaceUse = WL.GetNearestOrthoOpposite( vtRef, vtN) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, dMaxDepthOnSide, bEnablePreMill, bMachFromDn, dAng, bAsEnablePreMill, nSinglePass) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local dThick = min( dH, dV) + local frFace = Frame3d( ptC, vtN) + local b3Proc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFace) + local dSideElev = b3Proc:getDimZ() + local sMilling + -- se ho lavorazione custom + if sCustomMach then + sMilling = sCustomMach + -- altrimenti la cerco + else + sMilling = WM.FindMilling( 'SideGroove') + end + if not sMilling then + local sErr = 'Error : SideGroove not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMillLen = 10 + local dMillTotLen = 30 + local dMaxMat = 0 + local dMillDiamTh = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMillLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dMillLen + dMillTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dMillTotLen + if ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE) ~= 0 then + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dMaxMat + if not dMaxDepthOnSide or dMaxDepthOnSide < 0.1 then + dMaxDepthOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + end + else + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + if not dMaxDepthOnSide or dMaxDepthOnSide < 0.1 then + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') + end + end + dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh + end + end + local dMaxSideElev = EgtIf( dMaxDepthOnSide and dMaxDepthOnSide > 0, dMaxDepthOnSide, dMillDiam / 2 - 30) + -- se profondità ribasso è maggiore della capacità dichiarata nelle note o di quella netta al gambo utensile + if ( not bEnablePreMill and bMachFromDn) and ( dElev > dMaxSideElev or dElev >= ( 0.5 * ( dMillDiam - dMillDiamTh))) then + local sErr = 'Error : Side Elevation too big' + EgtOutLog( sErr) + return false, sErr + end + local dMillExtra = dMillTotLen - dMillLen + if Proc.Box:getMin():getZ() - dMillExtra < b3Raw:getMin():getZ() - 10 * GEO.EPS_SMALL then + local sErr = 'Error : Tool collide with table' + EgtOutLog( sErr) + return false, sErr + end + if Proc.Fct == 2 and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + 100 * GEO.EPS_SMALL and dMaxMat > dThick + 10 * GEO.EPS_SMALL then + local sErr = 'Error : Tool thickness is too big' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che la lavorazione sia passante dal grezzo + local dLongGorge = max( dH, dV) + local dExtraLongExtPlus = 0 + local dExtraLongExtNeg = 0 + local dExtraLongIni = 0 + local dExtraLongEnd = 0 + local bStartPos + local bInvertMach + local nModifyLeadInOut = 0 + local nFace2ndFace + local dMaxDistToOut = EgtIf( bMachFromDn, 1800, 300) + -- se orientato lungo la Y + if abs( vtN:getX()) > 0.866 then + dExtraLongExtPlus = abs( Proc.Box:getMax():getY() - b3Raw:getMax():getY()) + dExtraLongExtNeg = abs( Proc.Box:getMin():getY() - b3Raw:getMin():getY()) + if dLongGorge + dMillDiamTh < b3Raw:getDimY() then + nModifyLeadInOut = 1 + -- se non può sbordare da nessuna parte do errore + if dExtraLongExtPlus > dMaxDistToOut and dExtraLongExtNeg > dMaxDistToOut and dElev > dMaxDistToOut then + local sErr = 'Error : Not possible insert SideMill groove machining' + EgtOutLog( sErr) + return false, sErr + end + -- se non sborda solo dai lati + if dElev < dExtraLongExtPlus and dElev < dExtraLongExtNeg then + nModifyLeadInOut = 2 + end + end + -- se la distanza superiore è minore della distanza inferiore segno di partire dalla parte positiva + if dExtraLongExtPlus < dExtraLongExtNeg then + bStartPos = true + end + -- se normale su X positivo parte dall'alto + if vtN:getX() > 0.866 then + -- se deve partire dalla parte negativa setto il flag di inversione lavorazione + if not bStartPos then + bInvertMach = true + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + else + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + end + -- asseggno lato di lavoro seconda faccia + if bMachFromDn then + nFace2ndFace = MCH_MILL_FU.ORTUP_LEFT + else + nFace2ndFace = MCH_MILL_FU.ORTHO_LEFT + end + -- altrimenti normale su X negativa parte dal basso + else + -- se deve partire dalla parte positiva setto il flag di inversione lavorazione + if bStartPos then + bInvertMach = true + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + else + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + end + -- asseggno lato di lavoro seconda faccia + if bMachFromDn then + nFace2ndFace = MCH_MILL_FU.ORTUP_RIGHT + else + nFace2ndFace = MCH_MILL_FU.ORTHO_RIGHT + end + end + -- altrimenti orientato lungo la X + elseif abs( vtN:getY()) > 0.866 then + dExtraLongExtPlus = abs( Proc.Box:getMax():getX() - b3Raw:getMax():getX()) + dExtraLongExtNeg = abs( Proc.Box:getMin():getX() - b3Raw:getMin():getX()) + if dLongGorge + dMillDiamTh < b3Raw:getDimX() then + nModifyLeadInOut = 1 + -- se non può sbordare da nessuna parte do errore + if dExtraLongExtPlus > dMaxDistToOut and dExtraLongExtNeg > dMaxDistToOut and dElev > dMaxDistToOut then + local sErr = 'Error : Not possible insert SideMill groove machining' + EgtOutLog( sErr) + return false, sErr + end + -- se non sborda solo dai lati + if dElev < dExtraLongExtPlus and dElev < dExtraLongExtNeg then + nModifyLeadInOut = 2 + end + end + -- se la distanza positiva è minore della distanza negativa segno di partire dalla parte positiva + if dExtraLongExtPlus < dExtraLongExtNeg then + bStartPos = true + end + -- se normale su Y positivo parte da sinistra (parte negativa) + if vtN:getY() > 0.866 then + -- se deve partire dalla parte positiva setto il flag di inversione lavorazione + if bStartPos then + bInvertMach = true + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + else + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + end + -- assegno lato di lavoro seconda faccia + if bMachFromDn then + nFace2ndFace = MCH_MILL_FU.ORTUP_FRONT + else + nFace2ndFace = MCH_MILL_FU.ORTHO_FRONT + end + -- altrimenti normale su Y negativa parte da destra (parte positiva) + else + -- se deve partire dalla parte negativa setto il flag di inversione lavorazione + if not bStartPos then + bInvertMach = true + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + else + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + end + -- assegno lato di lavoro seconda faccia + if bMachFromDn then + nFace2ndFace = MCH_MILL_FU.ORTUP_BACK + else + nFace2ndFace = MCH_MILL_FU.ORTHO_BACK + end + end + end + if not bEnablePreMill and not bAsEnablePreMill then + dExtraLongIni = 0 + dExtraLongEnd = 0 + end + -- se ho abilitato la lavorazione di fresatura per garantire passaggio gambo utensile, inserisco la lavorazione + local bThroughRaw = false + if bEnablePreMill then + -- verifico se feature e' passante + if ((Proc.Box:getMin():getX() < ( b3Raw:getMin():getX() + 50)) and (Proc.Box:getMax():getX() > ( b3Raw:getMax():getX() - 50))) or + ((Proc.Box:getMin():getY() < ( b3Raw:getMin():getY() + 50)) and (Proc.Box:getMax():getY() > ( b3Raw:getMax():getY() - 50))) then + bThroughRaw = true + end + + -- recupero la lavorazione di taglio + local sCuttingGorge = WM.FindCutting( 'Standard') + if not sCuttingGorge then + local sErr = 'Error : Sawblade not found in library' + EgtOutLog( sErr) + return false, sErr + end + + -- acquisisco dati utensile lama + local dSawThickness = 0 + local dSawDiam = 0 + if EgtMdbSetCurrMachining( sCuttingGorge) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawThickness = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThickness + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + + -- calcolo larghezza canale + local dGorgeWidth = dMillDiam + -- verifico se elevazione minore per fare meno tagli + if dElev + 2 * WD.COLL_SIC < dGorgeWidth then + dGorgeWidth = max( dElev + 2 * WD.COLL_SIC, 0) + end + + -- sottraggo lato esterno lapjoint per ottenere larghezza netta del gorge + dGorgeWidth = dGorgeWidth - dSideElev + + -- calcolo quanti passi devo fare in larghezza per scaricare l'area di impegno utensile + local nNumStep = ceil( ( dGorgeWidth) / ( WD.SAWGORGE_INTERAX or 100)) + -- calcolo larghezza passate + local dC = 0 + if ( nNumStep - 1) > 0 then + dC = ( dGorgeWidth) / ( nNumStep) + else + nNumStep = 1 + end + + -- dati utensile fresa piccola + local dMillDiamFirst = 0 + local dMaxMatFirst = 0 + local bMillInvert = false + local bSawInvertSE = false + + -- se non passante, aggiungo fresatura area della fresa + if not bThroughRaw and nNumStep - 1 > 0 then + local SquareId -- Id della composita da fresare + local dSawShortening = sqrt( b3Raw:getDimZ() * ( dSawDiam - b3Raw:getDimZ())) -- da calcolare in base a raggio lama e spessore grezzo + -- gruppo ausiliario + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + -- disegno quadrato di fresatura + local p3Start + -- se orientato lungo la Y (direzione) + if abs( vtN:getX()) > 0.866 then + local dStartX = EgtIf( vtN:getX() > 0.866, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) + local dStartY = EgtIf( bStartPos, Proc.Box:getMin():getY(), Proc.Box:getMax():getY()) + p3Start = Point3d( dStartX, dStartY, Proc.Box:getMin():getZ()) + local vtNPerp = Vector3d( vtN) + vtNPerp:rotate(-Z_AX(), 90 * EgtIf( bStartPos, 1, -1) * EgtIf( vtN:getX() > 0.866, 1, -1)) + local FirstLineId = EgtLinePVL( nAddGrpId, p3Start, vtNPerp, dMillDiam / 2 , GDB_RT.GLOB) -- Y_AX() + local SecondLineId = EgtLinePVL( nAddGrpId, EgtEP( FirstLineId, GDB_RT.GLOB), vtN, dMillDiam - dSideElev, GDB_RT.GLOB) -- -X_AX() + local dThirdLineLen = min( (dMillDiam / 2) + ( Proc.Box:getMax():getY() - Proc.Box:getMin():getY()), dSawShortening + 10) + local ThirdLineId = EgtLinePVL( nAddGrpId, EgtEP( SecondLineId, GDB_RT.GLOB), -vtNPerp, dThirdLineLen, GDB_RT.GLOB) -- -Y_AX() + local FourthLineId = EgtLinePVL( nAddGrpId, EgtEP( ThirdLineId, GDB_RT.GLOB), -vtN, dMillDiam -dSideElev , GDB_RT.GLOB) -- X_AX() + SquareId = EgtCurveCompo( nAddGrpId, { FirstLineId, SecondLineId, ThirdLineId, FourthLineId}) + bMillInvert = EgtIf( vtN:getX() > 0.866, not (bStartPos or false), bStartPos or false) + bSawInvertSE = EgtIf( vtN:getX() > 0.866, bStartPos or false, not (bStartPos or false)) + -- altrimenti orientato lungo la X + elseif abs( vtN:getY()) > 0.866 then + local dStartX = EgtIf( bStartPos, Proc.Box:getMin():getX(), Proc.Box:getMax():getX()) + local dStartY = EgtIf( vtN:getY() > 0.866, Proc.Box:getMax():getY(), Proc.Box:getMin():getY()) + p3Start = Point3d( dStartX, dStartY, Proc.Box:getMin():getZ()) + local vtNPerp = Vector3d( vtN) + vtNPerp:rotate(-Z_AX(), 90 * EgtIf( bStartPos, -1, 1) * EgtIf( vtN:getY() > 0.866, 1, -1)) + local FirstLineId = EgtLinePVL( nAddGrpId, p3Start, vtNPerp, dMillDiam / 2 , GDB_RT.GLOB) -- Y_AX() + local SecondLineId = EgtLinePVL( nAddGrpId, EgtEP( FirstLineId, GDB_RT.GLOB), vtN, dMillDiam -dSideElev, GDB_RT.GLOB) -- -X_AX() + local dThirdLineLen = min( (dMillDiam / 2) + ( Proc.Box:getMax():getX() - Proc.Box:getMin():getX()), dSawShortening + 10) + local ThirdLineId = EgtLinePVL( nAddGrpId, EgtEP( SecondLineId, GDB_RT.GLOB), -vtNPerp, dThirdLineLen, GDB_RT.GLOB) -- -Y_AX() + local FourthLineId = EgtLinePVL( nAddGrpId, EgtEP( ThirdLineId, GDB_RT.GLOB), -vtN, dMillDiam -dSideElev , GDB_RT.GLOB) -- X_AX() + SquareId = EgtCurveCompo( nAddGrpId, { FirstLineId, SecondLineId, ThirdLineId, FourthLineId}) + bMillInvert = EgtIf( vtN:getY() > 0.866, bStartPos or false, not (bStartPos or false)) + bSawInvertSE = EgtIf( vtN:getY() > 0.866, not (bStartPos or false), bStartPos or false) + end + + -- recupero la lavorazione + local sMillingGorge = WM.FindMilling( 'Gorge', nil, nil, nil, 80) + if not sMillingGorge then + local sErr = 'Error : Gorge not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- acquisisco dati utensile + if EgtMdbSetCurrMachining( sMillingGorge) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiamFirst = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiamFirst + dMaxMatFirst = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMatFirst + end + end + -- inserisco la lavorazione di fresatura + local sNameGorge = 'Gorge_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. tostring( nFacet) .. '_' .. tostring( nNm) + local nMchFId = EgtAddMachining( sNameGorge, sMillingGorge) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameGorge .. '-' .. sMillingGorge + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( SquareId) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if abs( vtN:getZ()) < GEO.EPS_SMALL then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto modo di lavorare la faccia + local nFaceUse = WL.GetNearestParalOpposite( Z_AX(), vtN) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto elevazione e step + local dStep = EgtGetMachiningParam( MCH_MP.STEP) + if dStep < GEO.EPS_SMALL then dStep = dMaxMat end + ---- se sto lavorando la gola centrale setto l'elevazione e l'affondamento + --if nSinglePass and nSinglePass == 0 then + -- local dZElev = b3Raw:getDimZ() + -- local dDepth = Proc.Box:getMax():getZ() - b3Raw:getMin():getZ() + -- EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dZElev, 3) .. ';') + -- EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + --end + EgtSetMachiningParam( MCH_MP.STEP, dStep) + -- imposto invert in base al lato fresa + local bWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if bWorkSide == MCH_MILL_WS.RIGHT then + bMillInvert = not bMillInvert + end + EgtSetMachiningParam( MCH_MP.INVERT, bMillInvert) + -- aggiungo allungamenti iniziali e finali + EgtSetMachiningParam( EgtIf( bMillInvert, MCH_MP.STARTADDLEN, MCH_MP.ENDADDLEN), -dMillDiamFirst / 2 - dSawThickness / 2) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + -- inserisco la lavorazione + local nNm = 0 + -- passi di allargamento + for i = 1, nNumStep - 1 do + nNm = nNm + 1 + -- inserisco la lavorazione di taglio sfrido gorge + local sNameGorge = 'GorgeCut_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. tostring( nFacet) .. '_' .. tostring( nNm) + local nMchFId = EgtAddMachining( sNameGorge, sCuttingGorge) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameGorge .. '-' .. sCuttingGorge + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- assegno invert + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- assegno il lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) -- EgtIf( bMillInvert, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + -- assegno l'attacco e l'uscita + if not bThroughRaw and bSawInvertSE then + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.CENT) + -- aggiungo allungamento finale + if not bThroughRaw then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( dMillDiam / 2) - ( dMillDiamFirst / 2)) + end + elseif not bThroughRaw and not bSawInvertSE then + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LO.CENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LI.STRICT) + -- aggiungo allungamento finale + if not bThroughRaw then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( dMillDiam / 2) - ( dMillDiamFirst / 2)) + end + else + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LO.CENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LI.CENT) + end + -- aggiungo l'offset laterale + EgtSetMachiningParam( MCH_MP.OFFSL, ( dSideElev - dSawThickness + ( dC * ( i)))) + -- nessun criterio per il braccio è necessario + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + -- inserisco la lavorazione di ribasso o gola + local sName = EgtIf( bEnablePreMill ~= nil, 'SideMill_', 'Mill_') .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- se ho abilitato la lavorazione di lama per garantire passaggio utensile, setto la nota per spostare la fresatura dopo i tagli di lama + if bEnablePreMill or bAsEnablePreMill then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + -- imposto posizione braccio porta testa + --local nSCC = MCH_SCC.ADIR_ZP + --if abs( vtN:getZ()) < GEO.EPS_SMALL then + -- nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + --end + local nSCC = MCH_SCC.ADIR_NEAR + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto modo di lavorare la faccia + local nFaceUse = WL.GetNearestParalOpposite( Z_AX(), vtN) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto elevazione e step + local dStep = EgtGetMachiningParam( MCH_MP.STEP) + if dStep < GEO.EPS_SMALL then dStep = 0.75 * dMaxMat end + local nStep = ceil( ( dThick - dMaxMat) / dStep) + dStep = max( ( dThick - dMaxMat) / max( nStep, 1), 0) + local dMaxElev = max( ( nStep + 1) * dStep - GEO.EPS_SMALL, 0) + if nSinglePass and nSinglePass > 0 then + dStep = 0 + if nSinglePass == 1 then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) + end + end + EgtSetMachiningParam( MCH_MP.STEP, dStep) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMaxElev, 3) .. ';') + -- setto il lato di lavoro standard + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- modifico ingressi e uscita + -- se ho inserito il pretaglio modifico + if bEnablePreMill or bAsEnablePreMill then + if nModifyLeadInOut > 0 then + -- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita + if dElev > ( 0.5 * dMillDiam) then + if nModifyLeadInOut == 1 then + -- setto il tipo di passo a una via + EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.ONEWAY) + -- modifico il tipo di uscita + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.PERP_TG) + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + -- modifico dati supplementari uscita + EgtSetMachiningParam( MCH_MP.LOPERP, 0.5) + EgtSetMachiningParam( MCH_MP.LOTANG, -( dLongGorge + dExtraLongIni + dExtraLongEnd)) + else + EgtSetMachiningParam( MCH_MP.LIPERP, dElev) + EgtSetMachiningParam( MCH_MP.LOPERP, dElev) + end + end + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + if bInvertMach then + -- setto il lato di lavoro invertito + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + else + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + -- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita + if dElev > ( 0.5 * dMillDiam) then + -- setto allungamenti perpendicolari + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + end + end + -- se richiesto, setto la nota per spostare la lavorazione alla fine + if not WD.SIDEMILL_BEFORE then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + else + if nModifyLeadInOut > 0 then + -- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita + if dElev > ( 0.5 * dMillDiam) then + -- setto il tipo di passo a una via + EgtSetMachiningParam( MCH_MP.STEPTYPE, 1) + end + if bInvertMach then + -- setto il lato di lavoro invertito + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + end + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + -- se richiesto, setto la nota per spostare la lavorazione alla fine + if not WD.SIDEMILL_BEFORE then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- verifico se devo lavorare anche la seconda faccia basandomi sul valore dell'angolo interno + if dAng and dAng > -90 + 10 * GEO.EPS_SMALL then + local nOtherFacet = abs( nFacet - 1) + -- inserisco la lavorazione di contornatura + local sName = 'Mill_Oth_Fac_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nOtherFacet}}) + -- imposto posizione braccio porta testa + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nOtherFacet, GDB_ID.ROOT) + local nSCC = MCH_SCC.ADIR_ZP + if AreSameOrOppositeVectorApprox( vtN2, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto modo di lavorare la faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFace2ndFace) + EgtSetMachiningParam( MCH_MP.STEP, 0) + local dMaxElev = dMaxMat + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMaxElev, 3) .. ';') + if bMachFromDn then + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) + else + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- modifico ingressi e uscita + -- se ho inserito il pretaglio modifico + if bEnablePreMill or bAsEnablePreMill then + if nModifyLeadInOut > 0 then + -- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita + if dElev > ( 0.5 * dMillDiam) then + -- setto il tipo di passo a una via + EgtSetMachiningParam( MCH_MP.STEPTYPE, 1) + -- modifico il tipo di uscita + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 5) + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + -- modifico dati supplementari uscita + EgtSetMachiningParam( MCH_MP.LOPERP, 0.5) + EgtSetMachiningParam( MCH_MP.LOTANG, -( dLongGorge + dExtraLongIni + dExtraLongEnd)) + end + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + if bInvertMach then + -- setto il lato di lavoro invertito + if bMachFromDn then + EgtSetMachiningParam( MCH_MP.INVERT, false) + else + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + else + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + -- Invece del numero di passi in sgrossatura confronto il raggio fresa con l'elevazione dalla normale + -- per vedere se devo modificare l'uscita + -- if nNumStep > 1 then + if dElev > ( 0.5 * dMillDiam) then + -- setto allungamenti perpendicolari + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + end + end + -- se richiesto, setto la nota per spostare la lavorazione alla fine + if not WD.SIDEMILL_BEFORE then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + else + if nModifyLeadInOut > 0 then + -- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita + if dElev > ( 0.5 * dMillDiam) then + -- setto il tipo di passo a una via + EgtSetMachiningParam( MCH_MP.STEPTYPE, 1) + end + if bInvertMach then + -- setto il lato di lavoro invertito + if bMachFromDn then + EgtSetMachiningParam( MCH_MP.INVERT, false) + else + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + end + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + -- se richiesto, setto la nota per spostare la lavorazione alla fine + if not WD.SIDEMILL_BEFORE then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeByPocketing( Proc, nFacet, nRawId, b3Raw, bCheckQPar) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local dDiam = min( dH, dV) + -- gruppo ausiliario + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + local nNewProc, nNumFacet = RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFacet) + -- se forma ad L + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc.Id, Proc.Fct) or TestElleShape4( Proc.Id, Proc.Fct) == 2) + if bIsL then + dDiam = 2 * dDiam + end + -- se forma ad U + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc.Id, Proc.Fct)) + if bIsU then + local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + -- prendo la linea di base + local dMiddleFacetLength = 0 + if abs( dElev - dH2) < 1 and abs( dElev - dV2) > 1 then + dMiddleFacetLength = dV2 + elseif abs( dElev - dV2) < 1 and abs( dElev - dH2) > 1 then + dMiddleFacetLength = dH2 + end + if dMiddleFacetLength > dDiam then + dDiam = min( 2 * dDiam, dMiddleFacetLength) + end + end + -- in presenza di angoli interni, limito secondo impostazione globale il diametro massimo utensile + if Proc.Fct == 3 and bIsL then + dDiam = min( dDiam, WD.MAXDIAM_POCK_CORNER or 1000) + elseif Proc.Fct >= 4 then + dDiam = min( dDiam, WD.MAXDIAM_POCK_CORNER or 1000) + end + -- recupero la lavorazione + local sPocketing = WM.FindPocketing( 'Pocket', dDiam, dElev) + if not sPocketing then + sPocketing = WM.FindPocketing( 'Pocket', dDiam) + if not sPocketing then + local sErr = 'Error : pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local dThDiam = 100 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + 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 + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- se lavorazione di fianco setto la nota per spostarla dopo i tagli di lama + if vtN:getZ() < WD.NZ_MINA then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameVectorApprox( vtN, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local dThElev = dThDiam / 2 * sqrt( vtN:getX() * vtN:getX() + vtN:getY() * vtN:getY()) + local dDepth = 0 + local sWarn = '' + if dElev + dThElev > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth - dElev - dThElev + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( min( dElev, dMaxDepth), 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- verifica parametro Q per pulitura spigoli + if bCheckQPar and not ( bIsU and AreSameOrOppositeVectorApprox( vtN, Z_AX())) then + -- lettura parametri (probabile/i parametro/i Q) + local nConeCut = EvaluateQParam( Proc) + -- recupero i dati di tutte le facce + local vFace, dMaxWidth = GetFacesData( nNewProc, false, false, dMillDiam, dMaxDepth, (dMillDiam/2), nAddGrpId, Proc.PartId) + -- se abilitata la lavorazione corner con stop macchina + if nConeCut == 1 then + local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw, + dMillDiam, nAddGrpId, dMaxWidth, nNewProc, dDepth) + if not bMcok then return bMcok, sMcErr end + elseif nConeCut == 2 then + local sErr = 'Clean corner 30° is not applied on pocketing' + EgtOutLog( sErr) + EgtErase( nNewProc) + else + EgtErase( nNewProc) + end + else + EgtErase( nNewProc) + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeOneFace( Proc, nRawId, b3Raw) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- dimensioni della faccia + local _, dDimH, dDimV = WL.GetFaceHvRefDim( Proc.Id, 0) + -- recupero la lavorazione di taglio con lama e i suoi parametri + local sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard') + -- se non inclinata o capacità di taglio non sufficiente, provo con svuotatura + if not sCutting or vtN:getZ() > 0.866 or dSawMaxDepth < dDimV + WD.CUT_SIC then + -- faccio con svuotatura + local nFacet = 0 + return MakeByPocketing( Proc, nFacet, nRawId, b3Raw) + end + -- eseguo il taglio di lama + local sName = 'Cut_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_' .. tostring( Proc.Id) + local nMchId = EgtAddMachining( sName, sCutting) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( { { Proc.Id, 0}}) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- assegno il lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- assegno l'attacco e l'uscita + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.CENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.CENT) + -- nessun criterio per il braccio è necessario + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeTwoFaces( Proc, nRawId, b3Raw) + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- determino l'intersezione tra le due facce + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if not bAdj then + return false, 'Feature with two faces not adjacentes' + end + -- se equivalente ad un contorno + if abs( ptP1:getZ() - ptP2:getZ()) > 0.9 * b3Raw:getDimZ() then + -- verifico ordinamento (esterno a destra) + if ( vtN[1] ^ ( ptP1 - ptC[1])) * Z_AX() < 0 then + EgtSurfTmSwapFacets( Proc.Id, 0, 1) + end + -- applico lavorazione di contorno libero + return FreeContour.Make( Proc, nRawId, b3Raw) + end + -- versore della linea di intersezione + local vtX = ptP2 - ptP1 ; vtX:normalize() + -- larghezza delle facce ortogonalmente all'intersezione + local dDimY = {} + for i = 1, 2 do + local vtY = vtN[i] ^ vtX ; vtY:normalize() + local frRef = Frame3d( ptC[i], ptC[i] + 100 * vtX, ptC[i] + 100 * vtY) + local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, i - 1, GDB_BB.STANDARD, frRef) + dDimY[i] = b3Ref:getDimY() + end + -- recupero la lavorazione di taglio con lama e i suoi parametri + local sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard') + -- se parametro Q abilita lavorazione ribasso con fresa di fianco + local _, nUseMillOnSide = EvaluateQParam( Proc) + local dMaxZVers, dMinZVers + if nUseMillOnSide >= 1 then + dMaxZVers = 0.866 + dMinZVers = 0.5 + else + dMaxZVers = 0.95 + dMinZVers = 0.1 + end + -- se di fianco in basso + local dMaxThick, dMinSideElev + if vtN[1]:getZ() < -dMaxZVers or vtN[2]:getZ() < -dMaxZVers then + if vtN[1]:getZ() < -0.5 then + dMaxThick = dDimY[2] + dMinSideElev = dDimY[1] + elseif vtN[2]:getZ() < -0.5 then + dMaxThick = dDimY[1] + dMinSideElev = dDimY[2] + end + end + local sMillOnSide, dTMaxDepth, dMaxMat, dDiam = WM.FindMilling( 'SideMill', nil, nil, nil, nil, dMaxThick, nil, dMinSideElev) + local bEnableMillOnSide + if sMillOnSide and nUseMillOnSide >= 1 then + dMaxZVers = 0.866 + dMinZVers = 0.5 + bEnableMillOnSide = true + else + dMaxZVers = 0.95 + dMinZVers = 0.1 + end + -- se di fianco in basso + if vtN[1]:getZ() < -dMaxZVers or vtN[2]:getZ() < -dMaxZVers then + -- cerco la faccia verticale o quasi + local nFacet = EgtIf( abs( vtN[1]:getZ()) < dMinZVers, 0, 1) + -- cerco nei parametri utensili la nota di affondamento di fianco SIDEDEPTH + local dMaxDepthOnSide = 0 + local dMillDiam = 0 + local dMillDiamTh = 0 + if bEnableMillOnSide and EgtMdbSetCurrMachining( sMillOnSide) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide + dMaxDepthOnSide = min( dMaxDepthOnSide, 0.5 * ( dMillDiam - dMillDiamTh)) + end + end + local dMaxDist = 300 + if bEnableMillOnSide and dMaxDepthOnSide > 0 then + dMaxDist = dMaxDepthOnSide + end + -- se vicino al bordo del grezzo e non troppo larga, provo con fresatura di fianco + local ptMid = ( ptP1 + ptP2) / 2 + local bMakeFirstGroove + local bMachFromDn = true + local bInsertMach + local dSideDist + -- per evitare errori in casi di pezzi molto stretti, verifico le distanze in base alla direzione della faccia + -- se normale verso X + if vtN[nFacet+1]:getX() > 0.99 then + dSideDist = abs( ptMid:getX() - b3Raw:getMax():getX()) + -- altrimenti se normale verso X- + elseif vtN[nFacet+1]:getX() < -0.99 then + dSideDist = abs( ptMid:getX() - b3Raw:getMin():getX()) + -- altrimenti se normale verso Y+ + elseif vtN[nFacet+1]:getY() > 0.99 then + dSideDist = abs( ptMid:getY() - b3Raw:getMax():getY()) + -- altrimenti se normale verso Y- + elseif vtN[nFacet+1]:getY() < -0.99 then + dSideDist = abs( ptMid:getY() - b3Raw:getMin():getY()) + end + if dSideDist and dSideDist < dMaxDist then + bInsertMach = true + bMakeFirstGroove = false + -- altrimenti la distanza è maggiore e se è sempre abilitata la lavorazione MillOnSide + elseif bEnableMillOnSide and dMaxDepthOnSide then + bInsertMach = true + bMakeFirstGroove = true + end + -- se posso eseguire la lavorazione per distanza inferiore utensile o lavorazione preceduta da sgossatura gola + if bInsertMach then + return MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng) + else + local sErr = 'Error feature not machinable (dimensions)' + EgtOutLog( sErr) + return false, sErr + end + -- se altrimenti di fianco in alto + elseif vtN[1]:getZ() > dMaxZVers or vtN[2]:getZ() > dMaxZVers then + -- cerco la faccia con il maggior numero di adiacenze (e minor elevazione) + local nFacInd, _, nFacInd2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + if nFacInd == -2 then + local sErr = 'Error feature with 2 faces with undercut' + EgtOutLog( sErr) + return false, sErr + end + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + local dSideDist + local ptMid = ( ptP1 + ptP2) / 2 + -- faccia orizzontale + local nFacet = EgtIf( vtN:getZ() >= WD.NZ_MINA, nFacInd, nFacInd2) + -- faccia verticale + local nFacetVert = EgtIf( nFacet == nFacInd, nFacInd2, nFacInd) + local vtNV = EgtSurfTmFacetNormVersor( Proc.Id, nFacetVert, GDB_ID.ROOT) + -- per evitare errori in casi di pezzi molto stretti, verifico le distanze in base alla direzione della faccia +-- local dSideDist = min( abs( ptMid:getX() - b3Raw:getMin():getX()), abs( ptMid:getX() - b3Raw:getMax():getX()), +-- abs( ptMid:getY() - b3Raw:getMin():getY()), abs( ptMid:getY() - b3Raw:getMax():getY())) + -- se normale verso X + if vtNV:getX() > 0.99 then + dSideDist = abs( ptMid:getX() - b3Raw:getMax():getX()) + -- altrimenti se normale verso X- + elseif vtNV:getX() < -0.99 then + dSideDist = abs( ptMid:getX() - b3Raw:getMin():getX()) + -- altrimenti se normale verso Y+ + elseif vtNV:getY() > 0.99 then + dSideDist = abs( ptMid:getY() - b3Raw:getMax():getY()) + -- altrimenti se normale verso Y- + elseif vtNV:getY() < -0.99 then + dSideDist = abs( ptMid:getY() - b3Raw:getMin():getY()) + end + -- cerco nei parametri utensili la nota di affondamento di fianco SIDEDEPTH + local dMaxDepthOnSide = 0 + local dMillDiam = 0 + if bEnableMillOnSide and EgtMdbSetCurrMachining( sMillOnSide) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide + end + end + -- 2021.10.08 E.S. in base a richieste del cliente: + -- Se parametro Q riduce utilizzo lavorazione di lato come lama ed elevazione laterale supera il 60% diametro utensile + -- disabilito + if nUseMillOnSide == 2 and dSideDist > 0.6 * dMillDiam then + bEnableMillOnSide = false + end + -- per il fianco in alto non ci sono problemi di inserimento massimo laterale, setto la variabile pari al raggio utensile - 1mm + dMaxDepthOnSide = ( 0.5 * dMillDiam) - 1 + local dMaxDist = 300 + if bEnableMillOnSide and dMaxDepthOnSide > 0 then + dMaxDist = dMaxDepthOnSide + end + -- se vicino al bordo del grezzo e non troppo larga, provo con fresatura di fianco + local bMakeFirstGroove = false + local bLikeAsMakeFirstGroove + local bMachFromDn = false + local bInsertMach + if dSideDist and dSideDist < dMaxDist then + -- se abilitata SideMill + if bEnableMillOnSide and dMaxDepthOnSide > 0 then + bLikeAsMakeFirstGroove = false + return MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, bLikeAsMakeFirstGroove) + elseif MakeByMill( Proc, nFacet, 1 - nFacet, nRawId, b3Raw, dSideDist) then + return true + end + elseif bEnableMillOnSide and dMaxDepthOnSide > 0 then + bLikeAsMakeFirstGroove = true + local bOk, sErr = MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, bLikeAsMakeFirstGroove) + if bOk then return true end + end + -- se non inclinate o capacità di taglio non sufficiente o non molto grandi (80mm), provo con contornatura o svuotatura + if not sCutting or dSawMaxDepth < dDimY[1] + WD.CUT_SIC or dSawMaxDepth < dDimY[2] + WD.CUT_SIC or dDimY[1] < 80 or dDimY[2] < 80 then + -- eseguo la svuotatura + return MakeByPocketing( Proc, nFacet, nRawId, b3Raw) + end + -- se una delle due facce rivolta verso il basso + elseif vtN[1]:getZ() < -0.001 or vtN[2]:getZ() < -0.001 then + -- cerco la faccia rivolta verso l'alto + local nFacet + if vtN[1]:getZ() > 0 then + nFacet = 0 + elseif vtN[2]:getZ() > 0 then + nFacet = 1 + else + local sErr = 'Error feature with 2 faces facing down' + EgtOutLog( sErr) + return false, sErr + end + -- eseguo la svuotatura + return MakeByPocketing( Proc, nFacet, nRawId, b3Raw) + end + -- ordino i tagli per fare prima quello meno inclinato + local nOrd = { 0, 1} + if vtN[2]:getZ() > vtN[1]:getZ() then + nOrd = { 1, 0} + end + -- eseguo i tagli di lama + for i = 1, 2 do + -- inserisco la lavorazione + local sName = 'Cut_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_' .. tostring( Proc.Id) .. '_' .. tostring( i) + local nMchId = EgtAddMachining( sName, sCutting) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( { { Proc.Id, nOrd[i]}}) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- assegno il lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- assegno l'attacco e l'uscita + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.CENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.CENT) + -- nessun criterio per il braccio è necessario + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeMoreFaces( Proc, nRawId, b3Raw) + -- con una faccia di fondo valida + if Proc.Stype == 1 or Proc.Stype == 2 then + -- recupero eventuale flag forzatura svuotatura + local bPckt = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- cerco la faccia con il maggior numero di adiacenze + local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + -- se necessario scambio le facce + if Proc.Stype == 2 then + nFacInd, dElev, nFacInd2, dElev2 = nFacInd2, dElev2, nFacInd, dElev + end + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se di fianco + if not bPckt and Proc.Fct >= 3 and vtN:getZ() < WD.NZ_MINA then + -- recupero elevazione faccia in feature + local dSideElev = WL.GetFaceElevation( Proc.Id, nFacInd) + -- se abilitata lavorazione ribasso con fresa di fianco e parametro Q03 abilitato + local sMillOnSide, dTMaxDepth, dMaxMat, dDiam = WM.FindMilling( 'SideMill', nil, nil, nil, nil, min( dH, dV), nil, dSideElev) + local _, nUseMillOnSide = EvaluateQParam( Proc) + -- se ho abilitata lavorazione di fresa di fianco + if Proc.Fct >= 3 and sMillOnSide and nUseMillOnSide >= 1 then + -- cerco nei parametri utensili la nota di affondamento di fianco SIDEDEPTH + local dMaxDepthOnSide = 0 + local dMillDiam = 0 + if EgtMdbSetCurrMachining( sMillOnSide) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide + end + end + local bMakeFirstGroove + local bLikeAsMakeFirstGroove + local bInsertMach + local dElevToPiece = WL.GetFaceElevation( Proc.Id, nFacInd, nRawId) + -- Se distanza dal grezzo è minore della Max lavorazione laterale utensile + if dElevToPiece < dMaxDepthOnSide then + bInsertMach = true + bMakeFirstGroove = false + -- altrimenti la distanza è maggiore e se è sempre abilitata la lavorazione MillOnSide + elseif dMaxDepthOnSide > 0 then + bInsertMach = true + bMakeFirstGroove = true + end + -- se posso eseguire la lavorazione per distanza inferiore utensile o lavorazione preceduta da sgossatura gola + -- e gola più grande o uguale spessore utensile + if bInsertMach and dMaxMat <= min( dH, dV) + 20 * GEO.EPS_SMALL then + local nSinglePass = 0 + bLikeAsMakeFirstGroove = bMakeFirstGroove + -- se positivo setto il flag per lavorare singola passata bassa e disabilito sgrossatura + if vtN:getZ() > 20 * GEO.EPS_SMALL then + nSinglePass = 1 + bMakeFirstGroove = false + -- se negativo setto il flag per lavorare singola passata alta e disabilito sgrossatura + elseif vtN:getZ() < -20 * GEO.EPS_SMALL then + nSinglePass = 2 + bMakeFirstGroove = false + end + return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, EgtIf( dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, nil, nil, bLikeAsMakeFirstGroove, nSinglePass) + end + else + -- fresatura (se definita) + local sMilling = WM.FindMilling( 'SideGroove') + -- recupero i dati dell'utensile + local dMaxMat = 1000 + local dMaxDepthOnSide = 0 + if sMilling and EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + local dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + if ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE) ~= 0 then + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dMaxMat + dMaxDepthOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + else + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') + end + if not dMaxDepthOnSide then + local dMillDiamTh = EgtTdbGetCurrToolThDiam() or 60 + dMaxDepthOnSide = ( dMillDiam - dMillDiamTh) / 2 + end + end + end + if sMilling and dElev < dMaxDepthOnSide and dMaxMat <= min( dH, dV) + 20 * GEO.EPS_SMALL then + return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, sMilling) + -- altrimenti sega a catena + else + return MakeByChainSaw( Proc, nFacInd, nRawId, b3Raw, dElev, dH, dV) + end + end + end + local nFacet = EgtIf( bPckt or vtN:getZ() >= WD.NZ_MINA, nFacInd, nFacInd2) + if nFacet then + -- eseguo la svuotatura + return MakeByPocketing( Proc, nFacet, nRawId, b3Raw, true) + else + local sErr = 'Side milling not possible' + EgtOutLog( sErr) + return true, sErr + + end + -- fessura verticale + elseif Proc.Stype == 3 then + -- riordino le facce come contorno libero da lavorare a destra (sono una U) + -- porto la faccia centrale in seconda posizione (indice 1) + local nFacInd = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + if nFacInd ~= 1 then + EgtSurfTmSwapFacets( Proc.Id, 1, nFacInd) + end + -- verifico se la prima (indice 0) la deve precedere o seguire + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local bAdj, ptAdj, _, _ = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if bAdj and ( vtN ^ ( ptAdj - ptC)) * Z_AX() < 0 then + EgtSurfTmSwapFacets( Proc.Id, 0, 2) + end + -- applico lavorazione di contorno libero + return FreeContour.Make( Proc, nRawId, b3Raw) + -- tunnel + elseif Proc.Stype == 4 then + -- riordino le facce come contorno libero da lavorare a destra (formano un anello chiuso e quindi posso partire da una qualunque) + for i = 1, Proc.Fct - 2 do + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + for j = i + 1, Proc.Fct do + local bAdj, ptAdj, _, _ = EgtSurfTmFacetsContact( Proc.Id, i - 1, j - 1, GDB_ID.ROOT) + if bAdj and ( vtN ^ ( ptAdj - ptC)) * Z_AX() > 0 then + if i ~= j - 1 then + EgtSurfTmSwapFacets( Proc.Id, i, j - 1) + end + break + end + end + end + -- applico lavorazione di contorno libero + return FreeContour.Make( Proc, nRawId, b3Raw) + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPL.Make( Proc, nRawId, b3Raw) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQIdent( Proc) + if Proc.Fct == 1 then + return MakeOneFace( Proc, nRawId, b3Raw) + elseif Proc.Fct == 2 then + return MakeTwoFaces( Proc, nRawId, b3Raw) + else + return MakeMoreFaces( Proc, nRawId, b3Raw) + end +end + +--------------------------------------------------------------------- +return WPL diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessMark.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessMark.lua new file mode 100644 index 0000000..71af91f --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessMark.lua @@ -0,0 +1,152 @@ +-- WProcessMark.lua by Egaltech s.r.l. 2021/04/20 +-- Gestione calcolo marcatura per Pareti + +-- Tabella per definizione modulo +local WPMK = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' WProcessMark started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPMK.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 60) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPMK.Classify( Proc, b3Raw) + -- recupero il versore estrusione o normale se testo + local vtN + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtN = EgtCurveExtrusion( Proc.Id, GDB_ID.ROOT) + else + vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtN then + return false + end + -- verifico se la marcatura è lavorabile (solo da sopra) + return ( vtN:getZ() > WD.NZ_MINA) +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPMK.FlipClassify( Proc) + local nFlip0, nFlip1 + local vtN + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtN = EgtCurveExtrusion( Proc.Id, GDB_ID.ROOT) + else + vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtN then + return false + end + -- verifico se la marcatura è lavorabile (solo da sopra) + nFlip0 = EgtIf( vtN:getZ() > WD.NZ_MINA, 100, 0) + nFlip1 = EgtIf( - vtN:getZ() > WD.NZ_MINA, 100, 0) + return nFlip0, nFlip1 + +end + + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPMK.Make( Proc, nRawId, b3Raw) + -- recupero eventuale geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero i dati della marcatura + local vtExtr + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + else + vtExtr = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtExtr then + local sErr = 'Error : Mark with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che la marcatura non sia orientata verso il basso + if vtExtr:getZ() < WD.NZ_MINA then + local sErr = 'Error : Mark from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = WM.FindMilling( 'Text') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale lavorazione su seconda geometria + if AuxId then + -- inserisco la lavorazione di fresatura + local sName2 = 'Decor2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchF2Id = EgtAddMachining( sName, sMilling) + if not nMchF2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + 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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchF2Id, false) + return false, sErr + end + -- se geometria a X maggiore, la sposto prima + local ptS1 = EgtSP( Proc.Id, GDB_ID.ROOT) + local ptS2 = EgtSP( AuxId, GDB_ID.ROOT) + if ptS2:getX() > ptS1:getX() then + EgtRelocateGlob( nMchF2Id, nMchFId, GDB_IN.BEFORE) + end + end + return true +end + +--------------------------------------------------------------------- +return WPMK diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessMortise.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessMortise.lua new file mode 100644 index 0000000..860e751 --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessMortise.lua @@ -0,0 +1,303 @@ +-- WProcessMortise.lua by Egaltech s.r.l. 2021/07/30 +-- Gestione calcolo mortase per Pareti + +-- Tabella per definizione modulo +local WPM = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') + +EgtOutLog( ' WProcessMortise started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPM.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 50) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 53)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature: decide se la feature è in una posizione che per lavorala +-- deve essere ribaltata o no +function WPM.Classify( Proc, b3Raw) + -- recupero e verifico il percorso supplementare + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero versore estrusione della curva supplementare e non più della superficie + -- perché quest'ultima potrebbe non avere il fondo e dare quindi un risultato non corretto + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtExtr then + return false + end + if not vtN then + return false + end + -- Confronto le direzioni Z dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante + if abs( vtExtr:getZ() - vtN:getZ()) > 10 * GEO.EPS_SMALL then + return true + -- altrimenti è chiusa + else + -- verifico se la mortasa è lavorabile da sopra + return ( vtN:getZ() > WD.NZ_MINA) + end +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPM.FlipClassify( Proc) + -- recupero e verifico il percorso supplementare + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero versore estrusione della curva supplementare e non più della superficie + -- perché quest'ultima potrebbe non avere il fondo e dare quindi un risultato non corretto + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtExtr then + return false + end + if not vtN then + return false + end + -- Confronto le direzioni Z dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante + if abs( vtExtr:getZ() - vtN:getZ()) > 10 * GEO.EPS_SMALL then + return 100, 100 + -- altrimenti è chiusa + else + -- verifico se la mortasa è lavorabile da sopra + nFlip0 = EgtIf( vtN:getZ() > WD.NZ_MINA, 100, 0) + nFlip1 = EgtIf( - vtN:getZ() > WD.NZ_MINA, 100, 0) + end + + return nFlip0, nFlip1 + +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPM.Make( Proc, nRawId, b3Raw) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero versore estrusione della curva supplementare + local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT) + -- recupero i dati della faccia di fondo + local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + local ptC = ORIG() + local vtN = V_NULL() + if frMor then + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + end + -- verifico se è presente il fondo (sempre faccia 0) + local bClosedBtm = AreSameVectorApprox( vtExtr, vtN) + -- Se curva di contorno aperta + local dLenOpenSide = 0 + if not EgtCurveIsClosed( AuxId) then + -- se c'è il fondo + if bClosedBtm then + local NewId, nCount = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id)) + if NewId then + -- elimino eventuali loop interni (non dovrebbero comunque esserci) + for i = 1, nCount - 1 do + EgtErase( NewId + i) + end + -- sostituisco il loop esterno alla curva originale + EgtModifyCurveExtrusion( NewId, vtExtr, GDB_ID.ROOT) + EgtRelocate( NewId, AuxId, GDB_IN.AFTER) + EgtErase( AuxId) + EgtChangeId( NewId, AuxId) + -- sistemo i lati aperti + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, 0)[1] + if vFacAdj then + local sOpen = '' + for i = 1, #vFacAdj do + if vFacAdj[i] < 0 then + sOpen = sOpen .. EgtIf( #sOpen > 0, ',', '') .. tostring( i - 1) + local dLen = dist( EgtUP( AuxId, i-1), EgtUP( AuxId, i)) + dLenOpenSide = max( dLen, dLenOpenSide) + end + end + if #sOpen > 0 then + EgtSetInfo( AuxId, 'OPEN', sOpen) + end + end + end + -- altrimenti aperta + else + dLenOpenSide = dist( EgtSP( AuxId), EgtEP( AuxId)) + local _, nCrvCnt = EgtCurveDomain( AuxId) + EgtCloseCurveCompo( AuxId) + EgtSetInfo( AuxId, 'OPEN', nCrvCnt) + end + end + -- Se mortasa passante + if not bClosedBtm then + -- creo superficie chiusa + local nFlat = EgtSurfTmByFlatContour( EgtGetParent( AuxId), AuxId, 0.05) + if nFlat then + -- la superficie deve sempre essere rivolta verso l'alto + local vtNN = EgtSurfTmFacetNormVersor( nFlat, 0, GDB_ID.ROOT) + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + -- verifico se copiare la geometria lungo l'asse Z + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frMor) + local bxMax = b3Aux:getMax() + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local bxMin = b3Mor:getMin() + local dMove = bxMin:getZ() - bxMax:getZ() + if vtNN:getZ() < 0.1 then dMove = -dMove end + -- se il percorso ausiliario è esterno al grezzo, lo riavvicino + if abs( dMove) > GEO.EPS_SMALL then + AuxId = EgtCopyGlob( AuxId, WL.GetAddGroup( Proc.PartId)) + EgtMove( AuxId, Vector3d( 0, 0, dMove), GDB_RT.GLOB) + EgtMove( nFlat, Vector3d( 0, 0, dMove), GDB_RT.GLOB) + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + end + -- cancello le prove del misfatto (superficie piana) + EgtErase( nFlat) + end + end + -- scrivo info nel log + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- Se mortasa chiusa + local bForceOneSide + local bRevertSide + if bClosedBtm then + -- verifico che la mortasa non sia orientata verso il basso (limite -5 deg) + if vtN:getZ() < WD.NZ_MINA then + local sErr = 'Error : Mortise from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- altrimenti passante + else + -- determino se la mortasa da lavorare sul lato opposto sia di angolo inferiore a quello consentito + if abs( vtN:getZ()) > 0.1 then + bForceOneSide = true + end + -- determino se è meglio lavorare la mortasa nel lato opposto + if vtN:getZ() < -GEO.EPS_SMALL then + bRevertSide = true + end + end + + -- determino altezza della mortasa + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local dMorH = b3Mor:getDimZ() + -- elevazione del punto centro + local _, dCenElev = WL.GetPointDirDepth( Proc.PartId, ptC, vtN) + dMorH = max( dMorH, dCenElev or 0) + -- determino larghezza della mortasa + if dL < dW then dL, dW = dW, dL end + dW = max( dW, min( 2 * dW, dLenOpenSide)) + -- recupero la lavorazione + local sPocketing + if Proc.Prc ~= 53 then + sPocketing = WM.FindPocketing( 'Mortise', dW) + end + if not sPocketing then + sPocketing = WM.FindPocketing( 'Pocket', dW) + end + if not sPocketing then + local sErr = 'Error : Mortise or Pocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local bCW = true + 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) + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'Mort_' .. ( 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 + -- verifico se invertire versore estrusione geometria + if bRevertSide then + EgtModifyCurveExtrusion( AuxId, -vtExtr, GDB_ID.ROOT) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo la direzione di lavoro + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + if bRevertSide then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + else + if bRevertSide then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + end + local sWarn + local nDepthMin + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + if dMorH > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in mortise : elevation (' .. EgtNumToString( dMorH,1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth,1) .. ')' + -- se non ho invertito la direzione di estrusione + if not bRevertSide then + nDepthMin = dMaxDepth - EgtIf( not bClosedBtm and not bForceOneSide, dMorH * 2, dMorH) + else + nDepthMin = dMaxDepth + end + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + dMorH = dMaxDepth + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + else + if not bClosedBtm and not bForceOneSide then -- se mortasa passante setto metà profondità + nDepthMin = -dMorH + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + elseif bRevertSide then + EgtSetMachiningParam( MCH_MP.DEPTH, dMorH) + end + end + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMorH, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return WPM diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessSawCut.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessSawCut.lua new file mode 100644 index 0000000..5a9ede2 --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessSawCut.lua @@ -0,0 +1,58 @@ +-- WProcessSawCut.lua by Egaltech s.r.l. 2021/04/28 +-- Gestione calcolo taglio di lama per Pareti + +-- Tabella per definizione modulo +local WPSC = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') +local Cut = require( 'WProcessCut') + +EgtOutLog( ' WProcessSawCut started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPSC.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 13) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPSC.Classify( Proc, b3Raw) + -- recupero i dati del versore direzione di accesso della lavorazione + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtDir = EgtSV( AuxId, GDB_ID.ROOT) + return ( vtDir:getZ() > 0.5) +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPSC.FlipClassify( Proc) + -- recupero i dati del versore direzione di accesso della lavorazione + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtDir = EgtSV( AuxId, GDB_ID.ROOT) + local vtDirZ = vtDir:getZ() + nFlip0 = EgtIf( vtDirZ > 0.5, 100, 0) + nFlip1 = EgtIf( - vtDirZ > 0.5, 100, 0) + + return nFlip0, nFlip1 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPSC.Make( Proc, nRawId, b3Raw) + return Cut.Make( Proc, nRawId, b3Raw) +end + +--------------------------------------------------------------------- +return WPSC diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessText.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessText.lua new file mode 100644 index 0000000..a67651e --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessText.lua @@ -0,0 +1,104 @@ +-- WProcessText.lua by Egaltech s.r.l. 2021/04/20 +-- Gestione calcolo testi per Travi + +-- Tabella per definizione modulo +local WPT = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' WProcessText started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPT.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 61) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPT.Classify( Proc, b3Raw) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + return false + end + -- verifico se il testo è lavorabile (solo da sopra) + return ( vtN:getZ() > WD.NZ_MINA) +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPT.FlipClassify( Proc) + local nFlip0, nFlip1 + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + return false + end + -- verifico se il testo è lavorabile (solo da sopra) + nFlip0 = EgtIf( vtN:getZ() > WD.NZ_MINA, 100, 0) + nFlip1 = EgtIf( - vtN:getZ() > WD.NZ_MINA, 100, 0) + return nFlip0, nFlip1 + +end + + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPT.Make( Proc, nRawId, b3Raw) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + local sErr = 'Error : Text with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che il testo non sia orientato verso il basso + if vtN:getZ() < WD.NZ_MINA then + local sErr = 'Error : Text from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = WM.FindMilling( 'Text') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Text_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -1}}) + -- imposto posizione braccio porta testa + if vtN:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return WPT diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WProcessVariant.lua b/ProgettoRestylingWall/Wall/LuaLibs/WProcessVariant.lua new file mode 100644 index 0000000..303be65 --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WProcessVariant.lua @@ -0,0 +1,115 @@ +-- WProcessVariant.lua by Egaltech s.r.l. 2021/08/27 +-- Gestione calcolo Feature Custom (Variant) per Pareti + +-- Tabella per definizione modulo +local WPV = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') + +EgtOutLog( ' WProcessVariant started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPV.Identify( Proc) + return (( Proc.Grp == 0 or Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 900) +end + +--------------------------------------------------------------------- +-- Classificazione della feature: decide se la feature è in una posizione lavorabile +local function ClassifyCode_1( Proc, b3Raw) + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then + AuxId = AuxId + Proc.Id + end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing containement geometry' + EgtOutLog( sErr) + return false + end + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + return ( vtExtr:getZ() > -0.01) +end + +--------------------------------------------------------------------- +function WPV.Classify( Proc, b3Raw) + -- recupero il codice identificativo + local sCode = EgtGetInfo( Proc.Id, 'DES') + -- gestione in base al codice + if sCode == '1' then + return ClassifyCode_1( Proc, b3Raw) + else + return false + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +local function MakeCode_1( Proc, nRawId, b3Raw) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then + AuxId = AuxId + Proc.Id + end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing containement geometry' + EgtOutLog( sErr) + return false, sErr + end + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + -- recupero la lavorazione + local sSurfFin = WM.FindSurfacing( 'Finishing') + if not sSurfFin then + local sErr = 'Error : surface finishing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di finitura superficie + local sName = 'SurfFin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sSurfFin) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSurfFin + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- se lavorazione di fianco setto la nota per spostarla dopo i tagli di lama + if vtExtr:getZ() < WD.NZ_MINA then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -1},{AuxId, -1}}) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameVectorApprox( vtExtr, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +function WPV.Make( Proc, nRawId, b3Raw) + -- recupero il codice identificativo + local sCode = EgtGetInfo( Proc.Id, 'DES') + -- gestione in base al codice + if sCode == '1' then + return MakeCode_1( Proc, nRawId, b3Raw) + else + return false, 'Feature Id Code non recognized for machining' + end +end + +--------------------------------------------------------------------- +return WPV diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WallExec.lua b/ProgettoRestylingWall/Wall/LuaLibs/WallExec.lua new file mode 100644 index 0000000..06b51ed --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WallExec.lua @@ -0,0 +1,691 @@ +-- WallExec.lua by Egaltech s.r.l. 2022/03/15 +-- 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 +_G.package.loaded.CutData = nil +_G.package.loaded.MillingData = nil +_G.package.loaded.PocketingData = nil +_G.package.loaded.DrillData = nil +_G.package.loaded.SawingData = nil +local WD = require( 'WallData') +if WALL and WALL.NESTINGCORNERBL then WD.NESTING_CORNER = 'BL' end + +-- Carico le librerie +_G.package.loaded.WMachiningLib = nil +_G.package.loaded.WallLib = nil +_G.package.loaded.WProcessCut = nil +_G.package.loaded.WProcessDoubleCut = nil +_G.package.loaded.WProcessSawCut = nil +_G.package.loaded.WProcessLapJoint = nil +_G.package.loaded.WProcessDrill = nil +_G.package.loaded.WProcessMortise = nil +_G.package.loaded.WProcessDtMortise = nil +_G.package.loaded.WProcessMark = nil +_G.package.loaded.WProcessText = nil +_G.package.loaded.WProcessFreeContour = nil +_G.package.loaded.WProcessVariant = nil +local WM = require( 'WMachiningLib') +local WL = require( 'WallLib') +local Cut = require( 'WProcessCut') +local DoubleCut = require( 'WProcessDoubleCut') +local SawCut = require( 'WProcessSawCut') +local LapJoint = require( 'WProcessLapJoint') +local Drill = require( 'WProcessDrill') +local Mortise = require( 'WProcessMortise') +local DtMortise = require( 'WProcessDtMortise') +local Mark = require( 'WProcessMark') +local Text = require( 'WProcessText') +local FreeContour = require( 'WProcessFreeContour') +local Variant = require( 'WProcessVariant') + + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle pareti nel pannello *** +------------------------------------------------------------------------------------------------------------- +function WallExec.ProcessWalls( dRawL, dRawW, dRawH, vWall, bMachGroupOk, bNewProcess, nRawOutlineId) + + -- Creazione nuovo gruppo di lavoro + if not bMachGroupOk then + 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 + end + + -- Impostazione della tavola + EgtSetTable( 'Tab') + + -- Area tavola + local b3Tab = EgtGetTableArea() + -- Calcolo posizione estremo di riferimento della tavola rispetto a sua origine in BL + local OrigOnTab + local nCorner + local sOrigCorner = WD.ORIG_CORNER or 'BR' + if WD.GetOrigCorner then + sOrigCorner = WD.GetOrigCorner( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'REFPOS', 'i') or 1) + end + if sOrigCorner == 'TL' then + nCorner = MCH_CR.TL + OrigOnTab = Point3d( 0, b3Tab:getDimY(), 0) + elseif sOrigCorner == 'BL' then + nCorner = MCH_CR.BL + OrigOnTab = Point3d( 0, 0, 0) + elseif sOrigCorner == 'TR' then + nCorner = MCH_CR.TR + OrigOnTab = Point3d( b3Tab:getDimX(), b3Tab:getDimY(), 0) + elseif sOrigCorner == 'BR' then + nCorner = MCH_CR.BR + OrigOnTab = Point3d( b3Tab:getDimX(), 0, 0) + elseif sOrigCorner == 'TM' then + nCorner = MCH_CR.TR + OrigOnTab = Point3d( WD.MID_REF, b3Tab:getDimY(), 0) + elseif sOrigCorner == 'BM' then + nCorner = MCH_CR.BR + OrigOnTab = Point3d( WD.MID_REF, 0, 0) + end + -- Impostazione dell'attrezzaggio di default + EgtImportSetup() + -- Creazione del grezzo e suo posizionamento in macchina + local nRaw = GDB_ID.NULL + if nRawOutlineId and nRawOutlineId ~= GDB_ID.NULL then + nRaw = EgtAddRawPartWithPart( 0, nRawOutlineId, 0, WD.RAWCOL) + else + nRaw = EgtAddRawPart( Point3d(0,0,0), dRawL, dRawW, dRawH, WD.RAWCOL) + end + EgtMoveToCornerRawPart( nRaw, OrigOnTab, nCorner) + EgtSetInfo( nRaw, 'ORD', 1) + -- 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() + local vtOffs = b3Part:getMin() - b3Solid:getMin() + -- creo o pulisco gruppo geometrie aggiuntive + if not WL.CreateOrEmptyAddGroup( Pz) then + local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz) + return false, sOut + end + -- inserisco il pezzo nel grezzo + EgtDeselectPartObjs( Pz) + local ptPos + if bNewProcess then + local sNestingRef = ( WALL.NESTING_REF or WD.NESTING_CORNER) + if sNestingRef == 'TL' then + ptPos = Point3d( vWall[i].PosX, dRawW - PartWidth - vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + elseif sNestingRef == 'TR' then + ptPos = Point3d( dRawL - PartLen - vWall[i].PosX, dRawW - PartWidth - vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + elseif sNestingRef == 'BR' then + ptPos = Point3d( dRawL - PartLen - vWall[i].PosX, vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + else -- 'BL' + ptPos = Point3d( vWall[i].PosX, vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + end + else + local dPosH = EgtIf( vWall[i].PosY < 0.1, ( dRawH - PartHeight) / 2, vWall[i].PosY) + ptPos = Point3d( dRawL - vWall[i].PosX - PartLen, vWall[i].PosZ, dPosH) + vtOffs + end + EgtAddPartToRawPart( Pz, ptPos, nRaw) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle pareti *** +------------------------------------------------------------------------------------------------------------- +function WallExec.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 + table.insert( vProc, Proc) + -- se foro + if Drill.Identify( Proc) then + -- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento) + Proc.Diam, Proc.Fcs, Proc.Fce = Drill.GetData( Proc, b3Raw) + -- verifico se necessaria seconda lavorazione da parte opposta per foro più lungo della punta + if Drill.Split( Proc, b3Raw) then + -- aggiorno flags prima parte foro (dati tabelle sempre per riferimento) + Proc.Flg = 2 + -- definisco dati seconda parte + local Proc2 = {} + Proc2.PartId = PartId + Proc2.Id = ProcId + Proc2.Grp = nGrp + Proc2.Prc = nPrc + Proc2.Flg = -2 + Proc2.Box = BBox3d( Proc.Box) + Proc2.Fct = Proc.Fct + Proc2.Diam = Proc.Diam + Proc2.Fcs = Proc.Fce + Proc2.Fce = Proc.Fcs + Proc2.CutId = Proc.CutId + Proc2.TaskId = Proc.TaskId + table.insert( vProc, Proc2) + end + end + 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 taglio + if Cut.Identify( Proc) then + local bOk = Cut.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se taglio doppio + elseif DoubleCut.Identify( Proc) then + local bOk = DoubleCut.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se taglio con lama + elseif SawCut.Identify( Proc) then + local bOk = SawCut.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se tasca + elseif LapJoint.Identify( Proc) then + local bOk = LapJoint.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se foratura + elseif Drill.Identify( Proc) then + local bOk = Drill.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se mortasatura + elseif Mortise.Identify( Proc) then + local bOk = Mortise.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se mortasatura a coda di rondine + elseif DtMortise.Identify( Proc) then + local bOk = DtMortise.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se marcatura + elseif Mark.Identify( Proc) then + local bOk = Mark.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se testo + elseif Text.Identify( Proc) then + local bOk = Text.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 + -- se feature custom (Variant) + elseif Variant.Identify( Proc) then + local bOk = Variant.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 Dbl=%2d Dlt=%.1f Box=%s', + Proc.PartId, Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId, + Proc.Flg, Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, Proc.Double or 0, Proc.Delta or 0, tostring( Proc.Box)) + EgtOutLog( sOut) + end +end + +------------------------------------------------------------------------------------------------------------- +local function AddFeatureMachining( Proc, nRawId, b3Raw) + local bOk = true + local sErr = '' + EgtOutLog( ' * Process ' .. tostring( Proc.Id) .. ' *', 1) + -- se taglio (1/2-010-X) o taglio longitudinale (0/3/4-010-X) + if Cut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = Cut.Make( Proc, nRawId, b3Raw) + -- se taglio doppio (1/2-011-X) o taglio doppio longitudinale (0-012-X) + elseif DoubleCut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = DoubleCut.Make( Proc, nRawId, b3Raw) + -- se taglio con lama (0/3/4-013-X) + elseif SawCut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = SawCut.Make( Proc, nRawId, b3Raw) + -- se tasca (3/4-030-X) o similari + elseif LapJoint.Identify( Proc) then + -- esecuzione tasca + bOk, sErr = LapJoint.Make( Proc, nRawId, b3Raw) + -- se foratura ( 3/4-040-X) + elseif Drill.Identify( Proc) then + -- esecuzione foratura + bOk, sErr = Drill.Make( Proc, nRawId, b3Raw) + -- se mortasatura (3/4-050-X) o similari + elseif Mortise.Identify( Proc) then + -- esecuzione mortasatura + bOk, sErr = Mortise.Make( Proc, nRawId, b3Raw) + -- se mortasatura a coda di rondine (3/4-055-X) + elseif DtMortise.Identify( Proc) then + -- esecuzione mortasatura a coda di rondine + bOk, sErr = DtMortise.Make( Proc, nRawId, b3Raw) + -- se marcatura (3/4-060-X) + elseif Mark.Identify( Proc) then + -- esecuzione marcatura + bOk, sErr = Mark.Make( Proc, nRawId, b3Raw) + -- se testo (4-061-X) + elseif Text.Identify( Proc) then + -- esecuzione incisione testo + bOk, sErr = Text.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) + -- se feature custom (Variant) + elseif Variant.Identify( Proc) then + -- esecuzione + bOk, sErr = Variant.Make( Proc, nRawId, b3Raw) + -- altrimenti feature non riconosciuta + else + bOk = false + sErr = 'Feature type non recognized for machining' + end + return bOk, sErr +end + +------------------------------------------------------------------------------------------------------------- +local function MoveMachiningsAtEnd( nPhase, nType, sStartName, sProperty) + local nOperId = EgtGetPhaseDisposition( nPhase) + local nLastId = EgtGetLastOperation() + local nInsertId = nLastId + while nOperId do + local nNextOperId = EgtGetNextOperation( nOperId) + if EgtGetOperationPhase( nOperId) == nPhase and EgtGetOperationType( nOperId) == nType and + ( ( EgtGetInfo( nOperId, 'MOVE_AFTER', 'i') == 1 ) or + ( not sStartName or string.sub( EgtGetName( nOperId), 1, #sStartName) == sStartName)) then + EgtRelocateGlob( nOperId, nInsertId, GDB_IN.AFTER) + nInsertId = nOperId + end + if nOperId == nLastId then + break + end + nOperId = nNextOperId + end +end + +------ Ordinamento dei tagli, delle fresature e delle forature ------- +local function SpSorting( TabCut, PrevMch, nType, bOneWay) + + -- ordino le lavorazioni (in gruppi di max 1000 entità se 32bit 10000 se 64bit) + --EgtOutLog('Dati per ShortestPath :') + local SP_MAX_ENT = EgtIf( EgtIs64bit(), 10000, 1000) + local nBase = 0 + while nBase < #TabCut do + -- calcolo ordinamento + EgtSpInit() + for i = 1, min( #TabCut - nBase, SP_MAX_ENT) do + local ptS = TabCut[nBase+i].Start + local ptE = TabCut[nBase+i].End + EgtSpAddPoint( ptS:getX(), ptS:getY(), ptS:getZ(), 0, 0, + ptE:getX(), ptE:getY(), ptE:getZ(), 0, 0) + end + EgtSpSetAngularParams( 1000, 40, 2000, 60) + EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 50000, 0, 0, 0, 0) + if WD.BEAM_MACHINE and (nType & MCH_OY.SAWING) == MCH_OY.SAWING then + EgtSpSetOpenBound( false, SHP_OB.NEAR_PNT, -50000, 0, 0, 0, 0) + end + EgtSpSetZzOwStep( 10) + local nType = EgtIf( bOneWay, SHP_TY.ONEWAY_YM, SHP_TY.OPEN) + local vOrd = EgtSpCalculate( nType) + EgtSpTerminate() + -- applico ordinamento calcolato + if vOrd then + for i = 1, #vOrd do + EgtRelocateGlob( TabCut[nBase+vOrd[i]].Mch, PrevMch, GDB_IN.AFTER) + PrevMch = TabCut[nBase+vOrd[i]].Mch + end + end + -- incremento la base + nBase = nBase + SP_MAX_ENT + end + + return PrevMch +end + +local function ContainsStartName( nOperId, StartNames) + local bFound = false + for i = 1, #StartNames do + local sStartName = StartNames[i] + if string.sub( EgtGetName( nOperId), 1, #sStartName) == sStartName then + bFound = true + end + end + return bFound +end + +------ Ordinamento dei tagli, delle fresature e delle forature ------- +local function SortMach( nPhase, PrevMch, nPartId, nType, StartNames, bExistName, sInfo, bExistInfo, bOneWay, bByTool, bByToolAngle) + -- dichiarazione tabella + local TabCut = {} + -- Recupero gli identificativi delle lavorazioni e annullo eventuali allungamenti e Id di altre lavorazioni rappresentate + local nOperId = EgtGetNextOperation( PrevMch) + while nOperId do + local nOperType = EgtGetOperationType( nOperId) + -- Se appartiene alla fase corrente e taglio con lama non da sopra (sempre su 1 sola entità) + if EgtGetOperationPhase( nOperId) == nPhase and ( nType & nOperType) == nOperType and + ( not nPartId or EgtGetInfo( nOperId, 'Part', 'i') == nPartId) and + ( not StartNames or ( bExistName and ContainsStartName( nOperId, StartNames)) or + ( not bExistName and not ContainsStartName( nOperId, StartNames))) and + ( not sInfo or ( bExistInfo and EgtGetInfo( nOperId, sInfo, 'i') == 1) or + ( not bExistInfo and EgtGetInfo( nOperId, sInfo, 'i') ~= 1)) then + -- non si deve cambiare lo stato di attivazione della lavorazione (se disabilitata errata) + EgtSetCurrMachining( nOperId) + if not EgtIsMachiningEmpty() then + -- punto iniziale e finale e direzione della lavorazione + local ptStart = EgtGetMachiningStartPoint() + local ptEnd = EgtGetMachiningEndPoint() + local sTUUID = '' + local nToolType = 0 + local nToolDiam = 0 + local nToolDir = 0 + if bByTool then + sTUUID = EgtGetMachiningParam( MCH_MP.TUUID) + local sToolName = EgtTdbGetToolFromUUID( sTUUID) + if EgtTdbSetCurrTool( sToolName) then + nToolType = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + nToolDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + else + sTUUID = '' + end + end + if bByToolAngle then + local nClId = EgtGetFirstNameInGroup( nOperId, 'CL') + local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) + local vtTool = EgtGetInfo( nPathId, 'EXTR', 'v') + nToolDir = EgtIf( vtTool:getZ() > 0.999999, 1, 0) + end + table.insert( TabCut, {Mch=nOperId, Ent=nEntId, Start=ptStart, End=ptEnd, Tool=sTUUID, ToolType=nToolType, ToolDiam=nToolDiam, ToolDir=nToolDir}) + end + end + -- Passo alla operazione successiva + nOperId = EgtGetNextOperation( nOperId) + end + + if bByTool then + function ToolCompare(a,b) + if a.ToolType < b.ToolType then + return true + elseif a.ToolType == b.ToolType then + if a.ToolDiam > b.ToolDiam then + return true + elseif a.ToolDiam == b.ToolDiam then + if a.Tool < b.Tool then + return true + elseif a.Tool == b.Tool then + if bByToolAngle then + if a.ToolDir > b.ToolDir then + return true + elseif a.ToolDir == b.ToolDir then + return a.Mch < b.Mch + end + else + return a.Mch < b.Mch + end + end + end + end + return false + end + -- test della funzione di ordinamento + if EgtGetDebugLevel() >= 3 then + EgtOutLog( ' CompareFeatures Test ') + local bCompTest = true + for i = 1, #TabCut do + for j = i + 1, #TabCut do + local bComp1 = ToolCompare( TabCut[i], TabCut[j]) + local bComp2 = ToolCompare( TabCut[j], TabCut[i]) + if bComp1 == bComp2 then + bCompTest = false + EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', TabCut[i].Mch, TabCut[j].Mch)) + end + end + end + if bCompTest then + EgtOutLog( ' ALL OK') + end + end + + table.sort(TabCut, ToolCompare) +-- table.sort(TabCut, function(a,b) return a.ToolType < b.ToolType and a.ToolDiam > b.ToolDiam and a.Tool < b.Tool end) + local SupportTabCut = {} + local nPrevTUUID = 0 + local nPrevTDirZ = 1 + for i = 1, #TabCut do + -- se tuuid uguale al precedente, lo aggiungo alla lista + if nPrevTUUID == TabCut[i].Tool and ( not bByToolAngle or nPrevTDirZ == TabCut[i].ToolDir) then + table.insert( SupportTabCut, TabCut[i]) + -- se tuuid diverso, + else + -- faccio calcolare la lista + PrevMch = SpSorting( SupportTabCut, PrevMch, nType, bOneWay) + -- cancello la lista e aggiorno tuuid corrente + SupportTabCut = {} + nPrevTUUID = TabCut[i].Tool + if bByToolAngle then + nPrevTDirZ = TabCut[i].ToolDir + end + table.insert( SupportTabCut, TabCut[i]) + end + end + -- calcolo ultima lista + if #SupportTabCut > 0 then + PrevMch = SpSorting( SupportTabCut, PrevMch, nType, bOneWay) + end + else + PrevMch = SpSorting( TabCut, PrevMch, nType, bOneWay) + end + + return PrevMch + +end + +------------------------------------------------------------------------------------------------------------- +local function SortMachinings( nPhase, PrevMch, nPartId) + -- Chiodature + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Nail_'}, true) + -- Tagli con sega a catena che sono rifiniture di spigoli + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MORTISING, { 'Csaw_'}, false) + -- Forature orizzontali con punte lunghe + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING, { 'LhDrill_'}, true, 'MOVE_AFTER', false, true) + -- Preforature per fori inclinati + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.POCKETING, { 'PreDrill_'}, true) + -- Forature e Svuotature + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING + MCH_OY.POCKETING + MCH_OY.MILLING, { 'SideMill_', 'Clean_'}, false, 'MOVE_AFTER', false, false, true) +-- -- Forature *** +-- PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING, nil, nil, 'MOVE_AFTER', false) +-- -- Svuotature *** +-- PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.POCKETING, nil, nil, 'MOVE_AFTER', false) +-- -- Fresature che sono rifiniture di spigoli +-- PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Clean_'}, false, 'MOVE_AFTER', false, false, true) + -- Lavorazioni di superficie + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_MY.SURFFINISHING, nil, nil, 'MOVE_AFTER', false) + -- Fresature per gole + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Gorge_'}, true, 'MOVE_AFTER', false) + -- Fresature che sono rifiniture di spigoli + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'SideMill_'}, true, 'MOVE_AFTER', false, false, true, true) + -- Fresature che sono puliture di spigoli + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Clean_'}, true, 'MOVE_AFTER', false) + -- Tagli per gole + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.SAWING, { 'GorgeCut_'}, true) + -- Tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.SAWING) + -- Qui rimozione sfridi (se ci sono lavorazioni successive) + -- Fresature dei lapjoint che necessitano di gorge + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'SideMill_'}, true, 'MOVE_AFTER', true, false, true, true) + -- Tagli con sega a catena che vanno fatti dopo i tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MORTISING, { 'Csaw_'}, true) + -- Fresature (puliture di spigoli) che vanno fatte dopo i tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, nil, nil, 'MOVE_AFTER', true) + -- Forature che vanno fatte dopo i tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING, nil, nil, 'MOVE_AFTER', true) + -- Svuotature che vanno fatte dopo i tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.POCKETING, nil, nil, 'MOVE_AFTER', true) + -- Lavorazioni di superficie che vanno fatte dopo i tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_MY.SURFFINISHING, nil, nil, 'MOVE_AFTER', true) + return PrevMch +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 dei pezzi + local vPart = {} + local nPartId = EgtGetFirstPartInRawPart( nRawId) + while nPartId do + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + table.insert( vPart, {Id=nPartId, Box=b3Solid}) + nPartId = EgtGetNextPartInRawPart( nPartId) + end + -- raccolgo l'elenco delle feature da lavorare, ciclando sui pezzi + local vProc = {} + for i = 1, #vPart do + -- recupero le feature di lavorazione della parete + local vPartProc = WallExec.CollectFeatures( vPart[i].Id, b3Raw) + vProc = EgtJoinTables( vProc, vPartProc) + end + -- classifico le feature + ClassifyFeatures( vProc, b3Raw) + -- Eventuale determinazione delle feature lavorabili in parallelo (implementata nella configurazione macchina) + -- si impostano i flag Double (nil/0=no, 1=su X, 2=su Y) e Delta (offset tra T14 e T12 positivo o negativo) + if WD.FindFeaturesInDouble then + WD.FindFeaturesInDouble( vProc, b3Raw) + end + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc) + end + EgtOutLog( ' *** AddMachinings ***', 1) + -- 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 + elseif not Proc.Double then + local sMsg = 'Feature not machinable by orientation' + table.insert( Stats, {Err=1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + end + EgtOutLog( ' *** End AddMachinings ***', 1) + -- se macchina pareti + if not WD.BEAM_MACHINE then + -- riordino le lavorazioni tra tutti i pezzi + local nPhase = 1 + local PrevMch = EgtGetPhaseDisposition( nPhase) + SortMachinings( nPhase, PrevMch) + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + EgtApplyAllMachinings() + -- altrimenti macchina travi + else + -- dichiaro lavorazione pareti + EgtSetInfo( EgtGetCurrMachGroup() or GDB_ID.NULL, 'Wall', '1') + -- ordino i pezzi secondo le X decrescenti + local function CompareParts( P1, P2) + return P1.Box:getCenter():getX() > P2.Box:getCenter():getX() + end + table.sort( vPart, CompareParts) + -- riordino le lavorazioni sui singoli pezzi + local nPhase = 1 + local PrevMch = EgtGetPhaseDisposition( nPhase) + for i = 1, #vPart do + PrevMch = SortMachinings( nPhase, PrevMch, vPart[i].Id) + end + -- aggiungo dati su prima disposizione + local nDispId = EgtGetPhaseDisposition( 1) + EgtSetInfo( nDispId, 'TYPE', 'START') + EgtSetInfo( nDispId, 'ORD', 1) + -- aggiungo flag su ultima lavorazione + local nLastMchId = EgtGetLastActiveOperation() + EgtSetCurrMachining( nLastMchId) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'Cut;') + -- aggiungo disposizione per lo scarico + EgtAddPhase() + local nRawId = EgtGetFirstRawPart() + EgtKeepRawPart( nRawId, 1) + local nDisp2Id = EgtGetPhaseDisposition( 2) + EgtSetInfo( nDisp2Id, 'TYPE', 'END') + EgtSetInfo( nDisp2Id, 'ORD', 1) + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings() + if not bApplOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err = 1, Msg=sApplErrors, Rot=0, CutId=0, TaskId=0}) + elseif sApplWarns and #sApplWarns > 0 then + -- non interessano perchè riguardano lo scarico delle travi + end + end + -- restituzione risultati + return ( nTotErr == 0), Stats +end + +------------------------------------------------------------------------------------------------------------- +return WallExec diff --git a/ProgettoRestylingWall/Wall/LuaLibs/WallLib.lua b/ProgettoRestylingWall/Wall/LuaLibs/WallLib.lua new file mode 100644 index 0000000..058143d --- /dev/null +++ b/ProgettoRestylingWall/Wall/LuaLibs/WallLib.lua @@ -0,0 +1,317 @@ +-- WallLib.lua by Egaltech s.r.l. 2020/11/18 +-- Libreria globale per Pareti + +-- Tabella per definizione modulo +local WallLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' WallLib started', 1) + +------------------------------------------------------------------------------------------------------------- +function WallLib.GetAddGroup( PartId) + -- recupero il nome del gruppo di lavoro corrente + local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL) + if not sMchGrp then return nil, nil end + -- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco + local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp) + -- restituisco Id e Nome + return AddGrpId, sMchGrp +end + +------------------------------------------------------------------------------------------------------------- +function WallLib.CreateOrEmptyAddGroup( PartId) + -- recupero i dati del gruppo aggiuntivo + local AddGrpId, sMchGrp = WallLib.GetAddGroup( PartId) + if not sMchGrp then return false end + -- se esiste lo svuoto + if AddGrpId then + return EgtEmptyGroup( AddGrpId) + end + -- altrimenti lo creo + AddGrpId = EgtGroup( PartId or GDB_ID.NULL) + if not AddGrpId then return false end + -- assegno nome, flag di layer per gruppo di lavoro e colore + EgtSetName( AddGrpId, sMchGrp) + EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup()) + EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 50)) + return true +end + +------------------------------------------------------------------------------------------------------------- +function WallLib.GetPointDirDepth( nRawId, ptP, vtDir) + -- recupero il solido del grezzo + local nSolId = EgtGetFirstNameInGroup( nRawId, 'RawSolid') + if not nSolId then return end + -- interseco con la retta + local bOk, vType, vPar = EgtLineSurfTmInters( ptP, vtDir, nSolId, GDB_RT.GLOB) + if not bOk then return end + if not vPar or #vPar == 0 then return -2 end + local dLenIn, dLenOut + for i = 1, #vPar do + if vPar[i] < 0 then + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = -1 + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN then + dLenIn = -2 + end + else + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = vPar[i] + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN or vType[i] == GDB_SLT.TOUCH then + dLenOut = vPar[i] + end + end + end + return dLenIn, dLenOut +end + +--------------------------------------------------------------------- +function WallLib.GetFaceElevation( nSurfId, nFac, nRawId) + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFac, GDB_ID.ROOT) + if not ptC or not vtN then return 0 end + local frOCS = Frame3d( ptC, vtN) ; + local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS) + local dElev = b3Box:getMax():getZ() + if nRawId then + local _, dCenElev = WallLib.GetPointDirDepth( nRawId, ptC, vtN) + if dCenElev and dCenElev > dElev then dElev = dCenElev end + local dOffsX = min( 20, b3Box:getDimX() / 4) + local _, dP1Elev = WallLib.GetPointDirDepth( nRawId, ptC + dOffsX * frOCS:getVersX(), vtN) + if dP1Elev and dP1Elev > dElev then dElev = dP1Elev end + local _, dP2Elev = WallLib.GetPointDirDepth( nRawId, ptC - dOffsX * frOCS:getVersX(), vtN) + if dP2Elev and dP2Elev > dElev then dElev = dP2Elev end + local dOffsY = min( 20, b3Box:getDimY() / 4) + local _, dP3Elev = WallLib.GetPointDirDepth( nRawId, ptC + dOffsY * frOCS:getVersY(), vtN) + if dP3Elev and dP3Elev > dElev then dElev = dP3Elev end + local _, dP4Elev = WallLib.GetPointDirDepth( nRawId, ptC - dOffsY * frOCS:getVersY(), vtN) + if dP4Elev and dP4Elev > dElev then dElev = dP4Elev end + end + return dElev +end + +--------------------------------------------------------------------- +function WallLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc, dCosSideAng) + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nSurfId) + if not dCosSideAng then + dCosSideAng = -0.09 + end + -- recupero le normali delle facce + local vvtN = {} + for i = 1, nFacCnt do + local _, vtN = EgtSurfTmFacetCenter( nSurfId, i - 1, GDB_ID.ROOT) + vvtN[i] = vtN ; + end + -- adiacenze e sottosquadra delle facce + local vAdj = {} + local vUcut = {} + local vOrtho = {} + local vBlind = {} + for i = 1, nFacCnt do + -- recupero le adiacenze del loop esterno + local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + vAdj[i] = nCount + -- ne determino eventuale sottosquadra ( dal valore passato o - 3deg) e ortogonalità + local bUcut = false + local bOrtho = true + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + local vtN = vvtN[i] + local vtN2 = vvtN[vFacAdj[j]+1] + local dResV = vtN * vtN2 + if dResV < dCosSideAng - GEO.EPS_SMALL then + bUcut = true + end + if abs( dResV) > 2 * GEO.EPS_SMALL then + bOrtho = false + end + end + end + -- verifico se schermata da altra faccia + local bBlind = false + for j = 1, nFacCnt do + if i ~= j then + if vvtN[i] * vvtN[j] < -0.5 then + bBlind = true + end + end + end + -- assegno i risultati + vUcut[i] = bUcut + vOrtho[i] = bOrtho + vBlind[i] = bBlind + end + -- se 4 facce tutte con adiacenza 2, allora è un tunnel + if nFacCnt == 4 then + if vAdj[1] == 2 and vAdj[2] == 2 and vAdj[3] == 2 and vAdj[4] == 2 then + -- se tutte le facce sono ortogonali tra loro esco con un flag che ne indica questa propietà + if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true and vOrtho[4] == true then + return -1, GEO.INFINITO, true + else + return -1, GEO.INFINITO + end + end + end + -- se 3 facce con una che ha 2 adiacenze e le altre hanno 1 adiacenza, allora è una semi-fessura + if bCompare3Fc and nFacCnt == 3 then + local nCount2Adc = 0 + local nCount1Adc = 0 + -- ottengo il numero di facce con due adiacenze e il numero di facce con una adiacenza + for i = 1, #vAdj do + if vAdj[i] == 2 then + nCount2Adc = nCount2Adc + 1 + elseif vAdj[i] == 1 then + nCount1Adc = nCount1Adc + 1 + end + end + -- se il numero di adiacenze corrisponde + if nCount2Adc == 1 and nCount1Adc == 2 then + if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true then + return -1, GEO.INFINITO, true + else + return -1, GEO.INFINITO + end + end + end + -- recupero le facce non in sottosquadra e con il maggior numero di adiacenze + local nFacInd = {} + local nMaxAdj = -1 + local nSupAdj = -1 + for i = 1, nFacCnt do + if not vUcut[i] and not vBlind[i] then + if vAdj[i] >= nMaxAdj and vAdj[i] > 0 then + table.insert( nFacInd, i - 1) + nMaxAdj = vAdj[i] + elseif vAdj[i] > 0 then + table.insert( nFacInd, i - 1) + end + end + if vAdj[i] > nSupAdj then + nSupAdj = vAdj[i] + end + end + -- verifico non ci sia una faccia in sottosquadra con adiacenza superiore + if nSupAdj > nMaxAdj then + return -2, GEO.INFINITO + end + -- premio la faccia con minore elevazione + local nFacOpt, nFacOpt2 + local nOptAdj, nOptAdj2 + local dMinElev, dMinElev2 = GEO.INFINITO, GEO.INFINITO + for i = 1, #nFacInd do + local dElev = WallLib.GetFaceElevation( nSurfId, nFacInd[i], nPartId) + if dElev < dMinElev and ( not nOptAdj or vAdj[nFacInd[i]+1] >= nOptAdj) then + if dMinElev < dMinElev2 then + nFacOpt2 = nFacOpt + nOptAdj2 = nOptAdj + dMinElev2 = dMinElev + end + nFacOpt = nFacInd[i] + nOptAdj = vAdj[nFacInd[i]+1] + dMinElev = dElev + elseif dElev < dMinElev2 and ( not nOptAdj2 or vAdj[nFacInd[i]+1] >= nOptAdj2) then + nFacOpt2 = nFacInd[i] + nOptAdj2 = vAdj[nFacInd[i]+1] + dMinElev2 = dElev + end + end + return nFacOpt, dMinElev, nFacOpt2, dMinElev2 +end + +--------------------------------------------------------------------- +function WallLib.GetFaceHvRefDim( nSurfId, nFacet) + -- recupero centro e normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + if not ptC or not vtN then return end + -- riferimento tipo OCS della faccia (X orizz, Y max pendenza, Z normale) + local frHV = Frame3d( ptC, vtN) + if frHV:getVersY():getZ() < 0 then + frHV:rotate( ptC, vtN, 180) + end + -- determino l'ingombro in questo riferimento + local b3HV = EgtSurfTmGetFacetBBoxRef( nSurfId, nFacet, GDB_BB.STANDARD, frHV) + -- restituisco i valori calcolati + return frHV, b3HV:getDimX(), b3HV:getDimY() +end + +--------------------------------------------------------------------- +function WallLib.GetNearestParalOpposite( vtRef) + -- devo confrontare la componente orizzontale con quella verticale + local dHorSq = vtRef:getX() * vtRef:getX() + vtRef:getY() * vtRef:getY() + local dVertSq =vtRef:getZ() * vtRef:getZ() + -- se prevalente la componente orizzontale + if dHorSq >= dVertSq then + if abs( vtRef:getX()) > abs( vtRef:getY()) then + if vtRef:getX() > 0 then + return MCH_MILL_FU.PARAL_LEFT + else + return MCH_MILL_FU.PARAL_RIGHT + end + else + if vtRef:getY() > 0 then + return MCH_MILL_FU.PARAL_FRONT + else + return MCH_MILL_FU.PARAL_BACK + end + end + -- altrimenti prevale la verticale + else + if vtRef:getZ() > 0 then + return MCH_MILL_FU.PARAL_DOWN + else + return MCH_MILL_FU.PARAL_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function WallLib.GetNearestOrthoOpposite( vtRef, vtNorm) + -- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa + local vtMyRef = Vector3d( vtRef) + if vtNorm then + vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm + vtMyRef:normalize() + end + -- devo confrontare la componente orizzontale con quella verticale + local dHorSq = vtMyRef:getX() * vtMyRef:getX() + vtMyRef:getY() * vtMyRef:getY() + local dVertSq = vtMyRef:getZ() * vtMyRef:getZ() + -- se prevalente la componente orizzontale + if dHorSq >= dVertSq then + if abs( vtMyRef:getX()) >= abs( vtMyRef:getY()) then + if vtMyRef:getX() > 0 then + return MCH_MILL_FU.ORTHO_LEFT + else + return MCH_MILL_FU.ORTHO_RIGHT + end + else + if vtMyRef:getY() > 0 then + return MCH_MILL_FU.ORTHO_FRONT + else + return MCH_MILL_FU.ORTHO_BACK + end + end + -- altrimenti prevale la verticale + else + if vtMyRef:getZ() > 0 then + return MCH_MILL_FU.ORTHO_DOWN + else + return MCH_MILL_FU.ORTHO_TOP + end + end + return nil +end + +------------------------------------------------------------------------------------------------------------- +return WallLib diff --git a/ProgettoRestylingWall/Wall/NestFlipAndRotate.lua b/ProgettoRestylingWall/Wall/NestFlipAndRotate.lua new file mode 100644 index 0000000..b2b655a --- /dev/null +++ b/ProgettoRestylingWall/Wall/NestFlipAndRotate.lua @@ -0,0 +1,454 @@ +-- NestFlipAndRotate.lua by Egaltech s.r.l. 2021/11/25 +-- Flip e rotazione ottimali per il nesting in base all'analisi delle features + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- NFAR.PARTID = +NFAR.RAW_GRAIN_DIR_X = true + +local sLog = 'Flip And Rotate Part ' .. tostring( NFAR.PARTID) +EgtOutLog( sLog) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Wall\\WallData.lua') then + NFAR.ERR = 12 + NFAR.MSG = 'Error not configured for walls machine : ' .. sMachine + WriteErrToLogFile( NFAR.ERR, NFAR.MSG) + PostErrView( NFAR.ERR, NFAR.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua') + +-- Carico le librerie +_G.package.loaded.WallExec = nil +local WE = require( 'WallExec') +_G.package.loaded.WProcessLapJoint = nil +local LapJoint = require( 'WProcessLapJoint') +_G.package.loaded.WProcessDrill = nil +local Drill = require( 'WProcessDrill') +_G.package.loaded.WProcessCut = nil +local Cut = require( 'WProcessCut') +_G.package.loaded.WProcessDoubleCut = nil +local DoubleCut = require( 'WProcessDoubleCut') +_G.package.loaded.WProcessSawCut = nil +local SawCut = require( 'WProcessSawCut') +_G.package.loaded.WProcessFreeContour = nil +local FreeContour = require( 'WProcessFreeContour') +_G.package.loaded.WProcessMortise = nil +local Mortise = require( 'WProcessMortise') +_G.package.loaded.WProcessDtMortise = nil +local DtMortise = require( 'WProcessDtMortise') +_G.package.loaded.WProcessMark = nil +local Mark = require( 'WProcessMark') +_G.package.loaded.WProcessText = nil +local Text = require( 'WProcessText') + +-- Carico i dati globali +local WD = require( 'WallData') + +local function ClassifyFlip( vPartProc, b3Part) + + local FlipFeatureStates = {} + local bLapJoints = false + + for nInd = 1, #vPartProc do + if LapJoint.Identify( vPartProc[nInd]) then + -- setto parametro Q + if vPartProc[nInd].Prc == 30 then + EgtSetInfo( vPartProc[nInd].Id, "Q08", 1) + EgtSetInfo( vPartProc[nInd].Id, "Q08A", 1) + else + EgtSetInfo( vPartProc[nInd].Id, "Q03", 1) + EgtSetInfo( vPartProc[nInd].Id, "Q03A", 1) + end + bLapJoints = true + local nFlip0, nFlip1 = LapJoint.FlipClassify(vPartProc[nInd]) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif Drill.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = Drill.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif Cut.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = Cut.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif DoubleCut.Identify( vPartProc[nInd]) then + -- setto parametro Q + if vPartProc[nInd].Prc == 12 then + EgtSetInfo( vPartProc[nInd].Id, "Q02", 1) + EgtSetInfo( vPartProc[nInd].Id, "Q02A", 1) + end + local nFlip0, nFlip1 = DoubleCut.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif SawCut.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = SawCut.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif FreeContour.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = FreeContour.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif Mortise.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = Mortise.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif DtMortise.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = DtMortise.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif Mark.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = Mark.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif Text.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = Text.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + end + end + + return FlipFeatureStates, bLapJoints +end + + +local function ClassifyRotation( vPartProc) + + local RotateFeatureStates = {} + for nInd = 1, #vPartProc do + if Drill.Identify( vPartProc[nInd]) then + local nRot0, nRot90, nRot180, nRot270 = Drill.RotateClassify(vPartProc[nInd], ValidRotations) + if nRot0 and nRot0 >= 0 then + table.insert( RotateFeatureStates, { Rot0 = nRot0, Rot90 = nRot90, Rot180 = nRot180, Rot270 = nRot270}) + end + end + end + + return RotateFeatureStates +end + +--- + +local vPartProc = WE.CollectFeatures( NFAR.PARTID) +local b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) +local bManualFlip = EgtGetInfo( NFAR.PARTID, "MANUALFLIP", 'b') +local bManualRot = EgtGetInfo( NFAR.PARTID, "MANUALROT", 'b') + +-- FLIP +local FlipFeatureStates, bLapJoints = ClassifyFlip( vPartProc, b3Part) + +if not bManualFlip then + local bFlip + -- analizzo stati flip delle feature + local nFlip0Min = 100 + local nFlip0Cnt = 0 + local nFlip1Min = 100 + local nFlip1Cnt = 0 + -- calcolo punteggio minimo e sua molteplicita' per entrambi i lati + for nInd = 1, #FlipFeatureStates do + if FlipFeatureStates[nInd].Flip0 < nFlip0Min then + nFlip0Min = FlipFeatureStates[nInd].Flip0 + nFlip0Cnt = 1 + elseif FlipFeatureStates[nInd].Flip0 == nFlip0Min then + nFlip0Cnt = nFlip0Cnt + 1 + end + if FlipFeatureStates[nInd].Flip1 < nFlip1Min then + nFlip1Min = FlipFeatureStates[nInd].Flip1 + nFlip1Cnt = 1 + elseif FlipFeatureStates[nInd].Flip1 == nFlip1Min then + nFlip1Cnt = nFlip1Cnt + 1 + end + end + -- calcolo lato con punteggio minore o molteplicita' piu' alta + if nFlip0Min == nFlip1Min then + if nFlip0Cnt > nFlip1Cnt then + bFlip = true + elseif nFlip0Cnt < nFlip1Cnt then + bFlip = false + elseif bLapJoints then + -- se equivalenti ma ci sono lap joints, fisso il flip per non avere problemi con le aree di lavorazione nel nesting + bFlip = false + end + elseif nFlip0Min < nFlip1Min then + bFlip = true + else + bFlip = false + end + + if bFlip ~= nil then + -- se una posizione è più conveniente dell'altra setto info nel pezzo + EgtSetInfo( NFAR.PARTID, "NestAllowFlip", false) + EgtSetInfo( NFAR.PARTID, "NestFlip", bFlip) + else + EgtSetInfo( NFAR.PARTID, "NestAllowFlip", true) + end + + if bFlip then + -- flip pezzo + EgtRotate( NFAR.PARTID, b3Part:getCenter(), X_AX(), 180, GDB_RT.GLOB) + -- modifico le info del pezzo + local nPartFlip = EgtGetInfo( NFAR.PARTID, "INVERTED", 'i') or 0 + local nTotFlip = EgtIf( nPartFlip == 180, 0, 180) + EgtSetInfo( NFAR.PARTID, "INVERTED", nTotFlip) + EgtSetInfo( NFAR.PARTID, "FLIPROTMODIFIED", 1) + end +end + +-- rimuovo parametri Q +local b3PartInside = BBox3d( b3Part) +b3PartInside:expand( - WD.INSIDE_RAW_TOL) +for nInd = 1, #vPartProc do + local Proc = vPartProc[nInd] + + if LapJoint.Identify( Proc) then + -- cerco la faccia rivolta verso l'alto e la faccia rivolta verso il basso + local nFaceInd = -1 + local nFaceDownInd = -1 + for nIdx = 0, Proc.Fct - 1 do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if vtN:getZ() > 0.95 then + nFaceInd = nIdx + elseif vtN:getZ() < - 0.95 then + nFaceDownInd = nIdx + end + end + -- se è lap joint dall'alto + if nFaceInd ~= -1 and nFaceDownInd == -1 then + local ptCen = EgtSurfTmFacetCenter( Proc.Id, nFaceInd, GDB_ID.ROOT) + -- se all'interno rimuovo info Q + if EnclosesPointXY( b3PartInside, ptCen) then + -- resetto parametro Q + if Proc.Prc == 30 then + EgtRemoveInfo( Proc.Id, "Q08") + EgtRemoveInfo( Proc.Id, "Q08A") + else + EgtRemoveInfo( Proc.Id, "Q03") + EgtRemoveInfo( Proc.Id, "Q03A") + end + end + end + + elseif DoubleCut.Identify( Proc) then + -- verifico se due facce e rivolto verso l'alto + if Proc.Fct == 2 then + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + + if ( vtN[1]:getZ() >= 0.95 or vtN[2]:getZ() >= 0.95) then + local nFaceInd = EgtIf( vtN[1]:getZ() >= 0.95, 0, 1) + local ptCen = EgtSurfTmFacetCenter( Proc.Id, nFaceInd, GDB_ID.ROOT) + -- se all'interno rimuovo info Q + if EnclosesPointXY( b3PartInside, ptCen) then + -- resetto parametro Q + if Proc.Prc == 12 then + EgtRemoveInfo( Proc.Id, "Q02") + EgtRemoveInfo( Proc.Id, "Q02A") + end + end + end + end + end +end + + +-- ROTATION +nRotate = 0 +-- venatura +EgtRemoveInfo( NFAR.PARTID, "HasGrainDirection") +local bGrain = false +local sGrainInfo = EgtGetInfo( NFAR.PARTID, "GRAINDIRECTION", 's') +if sGrainInfo then + local sGrainAlign = string.sub( sGrainInfo, 7) + local sGrainDir = string.sub( sGrainInfo, 1, 5) + if sGrainAlign == "1" and ( sGrainDir == "1,0,0" or sGrainDir == "0,1,0") then + EgtSetInfo( NFAR.PARTID, "HasGrainDirection", 1) + bGrain = true + -- trovo la rotazione ( a meno di 180°) che deve avere il pezzo per essere allineato con la venatura del grezzo + local nGrainRot = 0 + if ( sGrainDir == "1,0,0" and not NFAR.RAW_GRAIN_DIR_X) or ( sGrainDir == "0,1,0" and NFAR.RAW_GRAIN_DIR_X) then + nGrainRot = 90 + end + + local nPartRot = EgtGetInfo( NFAR.PARTID, "ROTATED", 'i') or 0 + if ( nGrainRot == 0 and ( nPartRot == 90 or nPartRot == 270)) or ( nGrainRot == 90 and ( nPartRot == 0 or nPartRot == 180)) then + local b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) + nRotate = 90 + end + end +end + +if not bManualRot then + + local RotateFeatureStates = ClassifyRotation( vPartProc) + + -- analizzo stati rotazione delle feature + local nRot0Min = 100 + local nRot0Cnt = 0 + local nRot90Min = 100 + local nRot90Cnt = 0 + local nRot180Min = 100 + local nRot180Cnt = 0 + local nRot270Min = 100 + local nRot270Cnt = 0 + -- calcolo punteggio minimo e sua molteplicita' per tutte le rotazioni + for nInd = 1, #RotateFeatureStates do + if RotateFeatureStates[nInd].Rot0 < nRot0Min then + nRot0Min = RotateFeatureStates[nInd].Rot0 + nRot0Cnt = 1 + elseif RotateFeatureStates[nInd].Rot0 == nRot0Min then + nRot0Cnt = nRot0Cnt + 1 + end + if RotateFeatureStates[nInd].Rot90 < nRot90Min then + nRot90Min = RotateFeatureStates[nInd].Rot90 + nRot90Cnt = 1 + elseif RotateFeatureStates[nInd].Rot90 == nRot90Min then + nRot90Cnt = nRot90Cnt + 1 + end + if RotateFeatureStates[nInd].Rot180 < nRot180Min then + nRot180Min = RotateFeatureStates[nInd].Rot180 + nRot180Cnt = 1 + elseif RotateFeatureStates[nInd].Rot180 == nRot180Min then + nRot180Cnt = nRot180Cnt + 1 + end + if RotateFeatureStates[nInd].Rot270 < nRot270Min then + nRot270Min = RotateFeatureStates[nInd].Rot270 + nRot270Cnt = 1 + elseif RotateFeatureStates[nInd].Rot270 == nRot270Min then + nRot270Cnt = nRot270Cnt + 1 + end + end + + -- se c'e' qualche stato di rotazione + local MinList = { { Rot = 0, Score = nRot0Min, ScoreCnt = nRot0Cnt}, + { Rot = 90, Score = nRot90Min, ScoreCnt = nRot90Cnt}, + { Rot = 180, Score = nRot180Min, ScoreCnt = nRot180Cnt}, + { Rot = 270, Score = nRot270Min, ScoreCnt = nRot270Cnt}} + local nRotateOpt = 0 + if #RotateFeatureStates > 0 then + -- calcolo lato con punteggio minore o molteplicita' piu' alta + local nRotMax = 0 + local nScoreMax = 0 + local nScoreCnt = 0 + for nInd = 1, #MinList do + if MinList[nInd].Score > nScoreMax then + nRotMax = MinList[nInd].Rot + nScoreMax = MinList[nInd].Score + nScoreCnt = MinList[nInd].ScoreCnt + elseif MinList[nInd].Score == nScoreMax then + if MinList[nInd].ScoreCnt > nScoreCnt then + nRotMax = MinList[nInd].Rot + nScoreMax = MinList[nInd].Score + nScoreCnt = MinList[nInd].ScoreCnt + end + end + end + nRotateOpt = nRotMax + else + nRotateOpt = 0 + end + + local bRotNest = false + local nStepRotNest = 0 + -- se calcolate limitazioni su rotazioni + if MinList and #MinList > 0 then + -- verifico condizioni da permettere al nesting + if MinList[1].Score >= 50 and MinList[2].Score >= 50 and MinList[3].Score >= 50 and MinList[4].Score >= 50 then + bRotNest = true + nStepRotNest = 90 + elseif (nRotateOpt == 0 and MinList[3].Score >= 50) or ( nRotateOpt == 90 and MinList[4].Score >= 50) then + bRotNest = true + nStepRotNest = 180 + end + else + -- altrimenti permetto tutto + bRotNest = true + nStepRotNest = 90 + end + + -- verifico se ci sono fori lungo Y che bloccano la rotazione + local bDrillOnY = ( nStepRotNest == 180) + + local b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) + + if bGrain then + -- se venatura eseguo rotazione solo se è di 180° + if nRotateOpt == 180 then + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), nRotateOpt, GDB_RT.GLOB) + nRotate = nRotate + nRotateOpt + end + nStepRotNest = 180 + else + -- eseguo rotazione + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), nRotateOpt, GDB_RT.GLOB) + nRotate = nRotate + nRotateOpt + end + + -- verifico se rotazione è valida ( pezzo contenuto nel grezzo) solo se no venatura + if not bGrain then + b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) + local bValidRotationForRaw = b3Part:getDimX() < WD.MAX_LENGTH and b3Part:getDimY() < WD.MAX_WIDTH + local bRotatedIsValid = b3Part:getDimY() < WD.MAX_LENGTH and b3Part:getDimX() < WD.MAX_WIDTH + if not bValidRotationForRaw and bRotatedIsValid then + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) + nRotate = nRotate + 90 + nStepRotNest = 180 + end + end + + -- se no venatura e non ci sono fori verifico se il pezzo cade + if not bGrain and not bDrillOnY then + b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) + local bValidRotation = b3Part:getDimX() > ( WD.INTRULLI or 1200) + -- verifico se ruotata resta valida + local bRotatedIsValid = b3Part:getDimY() > ( WD.INTRULLI or 1200) + -- se non è valida ma ruotato lo sarebbe, ruoto + if not bValidRotation and bRotatedIsValid and nStepRotNest ~= 180 then + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) + nRotate = nRotate + 90 + nStepRotNest = 180 + elseif bValidRotation and not bRotatedIsValid then + -- se fosse valida ma la sua ruotata no, allora blocco lo step nella rotazione del nesting + nStepRotNest = 180 + end + end + + -- setto info nel pezzo + if nRotate > 0 then + local nPartRot = EgtGetInfo( NFAR.PARTID, "ROTATED", 'i') or 0 + local nTotRot = nPartRot + nRotate + nTotRot = EgtIf( nTotRot < 360, nTotRot, nTotRot - 360) + EgtSetInfo( NFAR.PARTID, "ROTATED", nTotRot) + EgtSetInfo( NFAR.PARTID, "FLIPROTMODIFIED", 1) + end + + EgtSetInfo( NFAR.PARTID, "NestStepRot", nStepRotNest) + EgtSetInfo( NFAR.PARTID, "NestRot", nRotate) + EgtSetInfo( NFAR.PARTID, "NestAllowRot", bRotNest) +end + + +NFAR.ERR = 0 \ No newline at end of file diff --git a/ProgettoRestylingWall/Wall/NestProcess.lua b/ProgettoRestylingWall/Wall/NestProcess.lua new file mode 100644 index 0000000..5787391 --- /dev/null +++ b/ProgettoRestylingWall/Wall/NestProcess.lua @@ -0,0 +1,2241 @@ +-- NestProcess.lua by Egaltech s.r.l. 2021/05/25 +-- Gestione nesting automatico pareti + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--NEST = {} +--NEST.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl' +--NEST.MACHINE = 'Essetre-90480019_MW' +--NEST.FLAG = 3 +--NEST.MIN_ANGLE_PNT = 60 +--NEST.DRILL_MACH_AREA = 0 +NEST.LAP_JOINT_U_MACH_AREA = 1 -- 0 +NEST.MACH_AREA_USE_OTHER_DIAM = 1 -- 0 +NEST.MACH_AREA_OTHER_DIAM = 200 +NEST.MACH_AREA_IGNORE_3rdFACE = 1 -- 0 + + +local sLog = 'NestProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. LEN["1"] .. ', ' .. WIDTH["1"] +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( NEST.FILE, '.txt') +EgtEraseFile( sLogFile) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Wall\\WallData.lua') then + NEST.ERR = 12 + NEST.MSG = 'Error not configured for walls machine : ' .. sMachine + WriteErrToLogFile( NEST.ERR, NEST.MSG) + PostErrView( NEST.ERR, NEST.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua') + +-- Carico le librerie +_G.package.loaded.WallExec = nil +local WE = require( 'WallExec') +_G.package.loaded.WallLib = nil +local WL = require( 'WallLib') +_G.package.loaded.WProcessLapJoint = nil +local LapJoint = require( 'WProcessLapJoint') +_G.package.loaded.WProcessDrill = nil +local Drill = require( 'WProcessDrill') +_G.package.loaded.WProcessDoubleCut = nil +local DoubleCut = require( 'WProcessDoubleCut') +_G.package.loaded.WProcessFreeContour = nil +local FreeContour = require( 'WProcessFreeContour') + +-- Carico i dati globali +local WD = require( 'WallData') + +-- lista dei pezzi con flip o rotazione +local PartStates = {} + +-- 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 ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) 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 ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) 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 + +-- Funzione per trovare nome MachGroup +local function NewMachGroupName() + local nMachGroupId = EgtGetFirstMachGroup() + if not nMachGroupId then return 1 end + local nMaxMachGroup = 0 + while nMachGroupId do + sMachGroupName = EgtGetMachGroupName(nMachGroupId) + local nMachGroupName = tonumber(sMachGroupName) + if nMachGroupName > nMaxMachGroup then + nMaxMachGroup = nMachGroupName + end + nMachGroupId = EgtGetNextMachGroup(nMachGroupId) + end + return nMaxMachGroup + 1 +end + +-- Funzione che crea il rettangolo della lavorazione +local function CreateToolRectangle( ptP1, dValP1, ptP2, dValP2, vtFace, dValFace, nOutlineGrp) + local dExtra = 5 + local vtX = ptP2 - ptP1 + vtX:normalize() + -- creo il rettangolo della lavorazione + ptP1 = ptP1 - vtX * ( dValP1 + dExtra) + ptP2 = ptP2 + vtX * ( dValP2 + dExtra) + ptP2 = ptP2 + vtFace * ( dValFace + dExtra) + --local nId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX(), ptP2:getY(), 0), Point3d( ptP1:getX(), ptP1:getY(), 0)) + local nId = EgtRectangle2P( nOutlineGrp, ptP2, ptP1) + return nId +end + +-- Funzione che verifica se la lavorazione è lap joint dal basso ed eventualmente ne calcola l'area di lavorazione +local function IdentifyLJFromBottom( Proc, bCompute, nOutlineGrp) + + local bLJFromBottom = false + local nRectId + local vtFace + + local dMinCompZ = 0.95 + if Proc.Fct == 2 then + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + + -- se rivolto verso il basso + if ( vtN[1]:getZ() < - dMinCompZ or vtN[2]:getZ() < - dMinCompZ) then + vtFace = EgtIf( vtN[1]:getZ() < - dMinCompZ, vtN[2], vtN[1]) + if not ( vtFace:getZ() > dMinCompZ or vtFace:getZ() < - dMinCompZ) then + bLJFromBottom = true + if bCompute then + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + -- creo il rettangolo della lavorazione + nRectId = CreateToolRectangle( ptP1, WD.SIDEMILL_DIAM_DOWN / 2, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace, WD.SIDEMILL_DIAM_DOWN, nOutlineGrp) + end + end + end + + + elseif Proc.Fct == 3 then + local nFacInd, dElev, nFacInd2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + + -- se nel mezzo di una faccia + if not nFacInd2 then + if nFacInd ~= -2 and nFacInd ~= GDB_ID.NULL then + vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + if not ( vtFace:getZ() > dMinCompZ or vtFace:getZ() < - dMinCompZ) then + local nOtherFace = EgtIf( nFacInd == 0, 1, 0) + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOtherFace, GDB_ID.ROOT) + if abs( ptP1:getZ() - ptP2:getZ()) < GEO.EPS_SMALL then + bLJFromBottom = true + if bCompute then + nRectId = CreateToolRectangle( ptP1, WD.SIDEMILL_DIAM_DOWN / 2, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace, WD.SIDEMILL_DIAM_DOWN, nOutlineGrp) + end + end + end + end + + -- se dal basso + else + local nFaceZ = -1 + for nIdx = 0, 2 do + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if vtN2:getZ() < - dMinCompZ then + nFaceZ = nIdx + break + end + end + if nFaceZ ~= -1 then + local nFace = EgtIf( nFaceZ == nFacInd, nFacInd2, nFacInd) + local nOtherFace = EgtIf( nFaceZ + nFace == 3, 0, EgtIf( nFaceZ + nFace == 2, 1, 2)) + vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nFace, GDB_ID.ROOT) + --vtFace[2] = EgtSurfTmFacetNormVersor( Proc.Id, nOtherFace, GDB_ID.ROOT) + bLJFromBottom = true + if bCompute then + local bAdj, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFace, nFaceZ, GDB_ID.ROOT) + local bAdj2, ptP3, ptP4 = EgtSurfTmFacetsContact( Proc.Id, nFace, nOtherFace, GDB_ID.ROOT) + if AreSamePointApprox( ptP2, ptP3) or AreSamePointApprox( ptP2, ptP4) then + ptP1, ptP2 = ptP2, ptP1 + end + local dVal = EgtIf( NEST.MACH_AREA_IGNORE_3rdFACE == 1, WD.SIDEMILL_DIAM_DOWN / 2, 0) + nRectId = CreateToolRectangle( ptP1, dVal, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace, WD.SIDEMILL_DIAM_DOWN, nOutlineGrp) + end + end + end + + elseif Proc.Fct == 4 then + local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + if nFacInd ~= -2 and nFacInd ~= GDB_ID.NULL then + vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + + if not ( vtFace:getZ() > dMinCompZ or vtFace:getZ() < - dMinCompZ) then + local nOtherFace = -1 + for nIdx = 0, 3 do + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if vtN2:getZ() > dMinCompZ or vtN2:getZ() < - dMinCompZ then + nOtherFace = nIdx + break + end + end + if nOtherFace ~= -1 and nOtherFace ~= nFacInd and nOtherFace ~= nFacInd2 then + bLJFromBottom = true + if bCompute then + local bAdj, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOtherFace, GDB_ID.ROOT) + local bAdj2, ptP3, ptP4 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacInd2, GDB_ID.ROOT) + if AreSamePointApprox( ptP2, ptP3) or AreSamePointApprox( ptP2, ptP4) then + ptP1, ptP2 = ptP2, ptP1 + end + nRectId = CreateToolRectangle( ptP1, 0, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace, WD.SIDEMILL_DIAM_DOWN, nOutlineGrp) + end + end + end + + if nFacInd2 and nFacInd2 ~= GDB_ID.NULL then + local vtFace2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd2, GDB_ID.ROOT) + if ( vtFace2:getZ() < - dMinCompZ or vtFace:getZ() < - dMinCompZ) then + bLJFromBottom = true + if vtFace:getZ() < -dMinCompZ then vtFace = vtFace2 end + if bCompute then + local bAdj, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacInd2, GDB_ID.ROOT) + nRectId = CreateToolRectangle( ptP1, 0, ptP2, 0, vtFace, WD.SIDEMILL_DIAM_DOWN, nOutlineGrp) + end + end + end + + end + end + + if bLJFromBottom then + return vtFace, nRectId + else + return + end +end + +-- Funzione che verifica se la lavorazione è lap joint da sopra ed eventualmente ne calcola l'area di lavorazione +local function IdentifyLJFromTop( Proc, bCompute, nOutlineGrp) + + local bLJFromTop = false + local vtFace, nRectId + + if not WD.SIDEMILL_DIAM_UP or WD.SIDEMILL_DIAM_UP < GEO.EPS_SMALL then return end + + local dMinComp = 0.95 + if Proc.Fct == 2 then + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + + -- se rivolto verso l'alto + if (vtN[1]:getZ() > dMinComp or vtN[2]:getZ() > dMinComp) then + bLJFromTop = true + vtFace = EgtIf( vtN[1]:getZ() > dMinComp, vtN[2], vtN[1]) + if bCompute then + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local b3Face = EgtSurfTmGetFacetBBoxGlob( Proc.Id, EgtIf( vtN[1]:getZ() > dMinComp, 0, 1), GDB_BB.STANDARD) + local dDim = 0 + if vtFace:getX() > dMinComp or vtFace:getX() < - dMinComp then + dDim = b3Face:getDimX() + elseif vtFace:getY() > dMinComp or vtFace:getY() < - dMinComp then + dDim = b3Face:getDimY() + end + local dValFace = max( dDim + WD.SIDEMILL_DIAM_UP / 2, WD.SIDEMILL_DIAM_UP) + local dVal = WD.SIDEMILL_DIAM_UP / 2 + if NEST.MACH_AREA_USE_OTHER_DIAM == 1 then + dVal = NEST.MACH_AREA_OTHER_DIAM / 2 + end + nRectId = CreateToolRectangle( ptP1, dVal, ptP2, dVal, vtFace, dValFace, nOutlineGrp) + end + end + + -- caso 3 facce + elseif Proc.Fct == 3 then + local nFacInd, dElev, nFacInd2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + + -- forma ad U + if not nFacInd2 and nFacInd ~= GDB_ID.NULL and NEST.LAP_JOINT_U_MACH_AREA == 1 then + local vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtFace:getZ() > dMinComp then + bLJFromTop = true + if bCompute then + local b3Face = EgtSurfTmGetFacetBBoxGlob( Proc.Id, nFacInd, GDB_BB.STANDARD) + local nOtherFace = EgtIf( nFacInd == 0, 1, 0) + local vtNOther = EgtSurfTmFacetNormVersor( Proc.Id, nOtherFace, GDB_ID.ROOT) + local vtDir = EgtIf( AreSameOrOppositeVectorApprox( vtNOther, X_AX()), Y_AX(), X_AX()) + local dVal = WD.SIDEMILL_DIAM_UP / 2 + 5 + local ptMin = b3Face:getMin() - dVal * vtDir + local ptMax = b3Face:getMax() + dVal * vtDir + -- nRectId = EgtRectangle2P( nOutlineGrp, Point3d(ptMax:getX(), ptMax:getY(), 0), Point3d( ptMin:getX(), ptMin:getY(), 0)) + nRectId = EgtRectangle2P( nOutlineGrp, ptMax, ptMin) + end + end + + elseif nFacInd2 then + local nFaceZ = -1 + for nIdx = 0, 2 do + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if vtN2:getZ() > dMinComp then + nFaceZ = nIdx + break + end + end + if nFaceZ ~= -1 then + local nFace = EgtIf( nFaceZ == nFacInd, nFacInd2, nFacInd) + local nOtherFace = EgtIf( nFaceZ + nFace == 3, 0, EgtIf( nFaceZ + nFace == 2, 1, 2)) + local vtFace = {} + vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nFace, GDB_ID.ROOT) + --vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nOtherFace, GDB_ID.ROOT) + bLJFromTop = true + if bCompute then + local bAdj, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFace, nFaceZ, GDB_ID.ROOT) + local bAdj2, ptP3, ptP4 = EgtSurfTmFacetsContact( Proc.Id, nFace, nOtherFace, GDB_ID.ROOT) + if AreSamePointApprox( ptP2, ptP3) or AreSamePointApprox( ptP2, ptP4) then + ptP1, ptP2 = ptP2, ptP1 + end + + local b3Face = EgtSurfTmGetFacetBBoxGlob( Proc.Id, nFaceZ, GDB_BB.STANDARD) + local dDim = 0 + if vtFace:getX() > dMinComp or vtFace:getX() < - dMinComp then + dDim = b3Face:getDimX() + elseif vtFace:getY() > dMinComp or vtFace:getY() < - dMinComp then + dDim = b3Face:getDimY() + end + local dValFace = max( dDim + WD.SIDEMILL_DIAM_UP / 2, WD.SIDEMILL_DIAM_UP) + local dVal = WD.SIDEMILL_DIAM_UP / 2 + if NEST.MACH_AREA_USE_OTHER_DIAM == 1 then + dVal = NEST.MACH_AREA_OTHER_DIAM / 2 + end + nRectId = CreateToolRectangle( ptP1, 0, ptP2, dVal, vtFace, dValFace, nOutlineGrp) + end + end + end + end + + if bLJFromTop then + return vtFace, nRectId + else + return + end +end + +-- Funzione che crea le regioni occupate dalle lavorazioni +local function ComputeToolOutlines( nPartId) + + local ToolOutlineId = {} + EgtRemoveInfo( nPartId, "ToolOutlines") + + -- recupero il gruppo con gli outlines degli utensili + local nOutlineGrp = EgtGetFirstNameInGroup(GDB_ID.ROOT, "ToolOutlines") + if not nOutlineGrp or nOutlineGrp == GDB_ID.NULL then + nOutlineGrp = EgtGroup( GDB_ID.ROOT) + EgtSetName( nOutlineGrp, "ToolOutlines") + EgtSetStatus( nOutlineGrp, GDB_ST.OFF) + end + + local vPartProc = WE.CollectFeatures( nPartId, b3Raw) + for nInd = 1, #vPartProc do + + local Proc = vPartProc[nInd] + + -- lap joint + if LapJoint.Identify( Proc) then + -- verifico se dal basso + local _ , nRectId = IdentifyLJFromBottom( Proc, true, nOutlineGrp) + if nRectId then + EgtSetColor( nRectId, EgtStdColor("BLUE")) + table.insert( ToolOutlineId, nRectId) + else + -- verifico se dall'alto + local _ , nRectId = IdentifyLJFromTop( Proc, true, nOutlineGrp) + if nRectId then + EgtSetColor( nRectId, EgtStdColor("AQUA")) + local nPrId = EgtGetInfo( Proc.Id, "PRID", 'i') + EgtSetInfo( nRectId, "PRID", nPrId) + table.insert( ToolOutlineId, nRectId) + end + end + end + + -- fori + if NEST.DRILL_MACH_AREA == 1 and Drill.Identify( Proc) then + -- recupero dati del foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + local dLen = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + local dDiam = 2 * EgtArcRadius( AuxId) + + -- verifico se la lunghezza del foro è maggiore della lunghezza della punta + if bOpen and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) and dLen > WD.HOR_DRILL_LEN - 1 then + local ptP1 = Proc.Box:getMin() + local ptP2 = Proc.Box:getMax() + local dExtra = 10 + ptP1 = ptP1 - ( WD.MAX_WIDTH - dLen + dExtra) * Y_AX() + ptP2 = ptP2 + ( WD.MAX_WIDTH - dLen + dExtra) * Y_AX() + + --local nId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX(), ptP2:getY(), 0), Point3d( ptP1:getX(), ptP1:getY(), 0)) + local nId = EgtRectangle2P( nOutlineGrp, ptP2, ptP1) + EgtSetColor( nId, EgtStdColor("AQUA")) + if nId ~= GDB_ID.NULL then table.insert(ToolOutlineId, nId) end + end + end + + -- lati inclinati free contour + if FreeContour.Identify( Proc) then + local bPocket = EgtGetInfo( Proc.Id, 'PCKT', 'b') + if not bPocket then + for nInd = 0, Proc.Fct - 1 do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nInd, GDB_ID.ROOT) + -- se inclinato + if abs( vtN:getZ()) > GEO.EPS_SMALL then + local bUnderCut = vtN:getZ() < - GEO.EPS_SMALL + + local dCosAlpha = (vtN ^ Z_AX()):len() + local dVal + if bUnderCut then + dVal = ( NEST.OFFSET + 0.1) / dCosAlpha + else + dVal = ( NEST.OFFSET + 0.1) * dCosAlpha + end + + local frLoc, dDimX, dDimY = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nInd, GDB_ID.ROOT) + local b3Face = EgtSurfTmGetFacetBBoxRef( Proc.Id, nInd, GDB_BB.STANDARD, frLoc) + local ptA = b3Face:getMin() + local ptC = b3Face:getMax() + local ptB = ptA + dDimY * Y_AX() + local ptD = ptA + dDimX * X_AX() + ptA:toGlob( frLoc) + ptB:toGlob( frLoc) + ptC:toGlob( frLoc) + ptD:toGlob( frLoc) + + local ptP1, ptP2 + if bUnderCut then + ptP1 = EgtIf( ptA:getZ() > ptC:getZ(), ptA, ptC) + ptP2 = EgtIf( ptB:getZ() > ptD:getZ(), ptB, ptD) + else + ptP1 = EgtIf( ptA:getZ() < ptC:getZ(), ptA, ptC) + ptP2 = EgtIf( ptB:getZ() < ptD:getZ(), ptB, ptD) + end + + local vtDir = ptP2 - ptP1 + vtDir:normalize() + ptP1 = ptP1 - vtDir * 0.5 * NEST.OFFSET + ptP2 = ptP2 + vtDir * 0.5 * NEST.OFFSET + local vtNxy = Vector3d( vtN:getX(), vtN:getY(), 0) + vtNxy:normalize() + local ptP4 = ptP2 + dVal * vtNxy + + local nRectId = EgtRectangle3P( nOutlineGrp, ptP1, ptP4, ptP2) + EgtSetColor( nRectId, EgtStdColor("AQUA")) + if nRectId ~= GDB_ID.NULL then table.insert( ToolOutlineId, nRectId) end + + end + end + end + end + + end + + return ToolOutlineId +end + + +local function ClassifyDrillsOnLateralFaces( nPartId, dMinSheetWidth) + + local dDeltaRaw = WD.MAX_WIDTH - dMinSheetWidth + NEST.KERF + local DrillClassif + local DrillOnFaces = { F = {nbr = 0, closed = false, long = false, OnlyOnRef = false}, B = {nbr = 0, closed = false, long = false, OnlyOnRef = false}, + L = {nbr = 0, closed = false, long = false, OnlyOnRef = false}, R = {nbr = 0, closed = false, long = false, OnlyOnRef = false}} + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + local ptPartMin = b3Part:getMin() + local ptPartMax = b3Part:getMax() + + local vPartProc = WE.CollectFeatures( nPartId) + for nInd = 1, #vPartProc do repeat + + if Drill.Identify( vPartProc[nInd]) then + + -- identifico su quali facce si trova il foro + local bOpen = ( vPartProc[nInd].Fcs ~= 0 and vPartProc[nInd].Fce ~= 0) + local AuxId = EgtGetInfo( vPartProc[nInd].Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + vPartProc[nInd].Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then break end + local ptDrill = EgtCP( AuxId, GDB_RT.GLOB) + local dLen = abs( EgtCurveThickness( AuxId)) + local bLong = dLen > WD.HOR_DRILL_LEN - 1 + local bOnlyOnRef = dLen + dDeltaRaw > WD.HOR_DRILL_LEN - GEO.EPS_SMALL and not bLong + + -- faccia Front + local dTol = GEO.EPS_SMALL + if ( abs( ptDrill:getY() - ptPartMin:getY()) < dTol) then + DrillOnFaces.F.nbr = DrillOnFaces.F.nbr + 1 + if bOnlyOnRef then DrillOnFaces.F.OnlyOnRef = true end + if bOpen then + DrillOnFaces.B.nbr = DrillOnFaces.B.nbr + 1 + if bOnlyOnRef then DrillOnFaces.B.OnlyOnRef = true end + else + DrillOnFaces.F.closed = true + + end + if bLong then + DrillOnFaces.F.long = true + if bOpen then DrillOnFaces.B.long = true end + end + + -- faccia Back + elseif ( abs( ptDrill:getY() - ptPartMax:getY()) < dTol) then + DrillOnFaces.B.nbr = DrillOnFaces.B.nbr + 1 + if bOnlyOnRef then DrillOnFaces.B.OnlyOnRef = true end + if bOpen then + DrillOnFaces.F.nbr = DrillOnFaces.F.nbr + 1 + if bOnlyOnRef then DrillOnFaces.F.OnlyOnRef = true end + else + DrillOnFaces.B.closed = true + end + if bLong then + DrillOnFaces.B.long = true + if bOpen then DrillOnFaces.F.long = true end + end + + -- faccia Left + elseif ( abs( ptDrill:getX() - ptPartMin:getX()) < dTol) then + DrillOnFaces.L.nbr = DrillOnFaces.L.nbr + 1 + if bOnlyOnRef then DrillOnFaces.L.OnlyOnRef = true end + if bOpen then + DrillOnFaces.R.nbr = DrillOnFaces.R.nbr + 1 + if bOnlyOnRef then DrillOnFaces.R.OnlyOnRef = true end + else + DrillOnFaces.L.closed = true + end + if bLong then + DrillOnFaces.L.long = true + if bOpen then DrillOnFaces.R.long = true end + end + + -- faccia Right + elseif ( abs( ptDrill:getX() - ptPartMax:getX()) < dTol) then + DrillOnFaces.R.nbr = DrillOnFaces.R.nbr + 1 + if bOnlyOnRef then DrillOnFaces.R.OnlyOnRef = true end + if bOpen then + DrillOnFaces.L.nbr = DrillOnFaces.L.nbr + 1 + if bOnlyOnRef then DrillOnFaces.L.OnlyOnRef = true end + else + DrillOnFaces.R.closed = true + end + if bLong then + DrillOnFaces.R.long = true + if bOpen then DrillOnFaces.L.long = true end + end + end + end + + until true + end + + -- identifico la faccia da mettere sul lato del grezzo + local sDrillFace, nMax = '', -100 + for k, v in pairs( DrillOnFaces) do + if v.nbr > nMax or ( v.nbr == nMax and not DrillOnFaces[sDrillFace].OnlyOnRef and v.OnlyOnRef) then + sDrillFace, nMax = k, v.nbr + end + end + + local sDrillFace2 + if nMax > 0 then + if sDrillFace == 'F' or sDrillFace == 'B' then + -- cerco chi vince tra faccia left e right + if DrillOnFaces.L.nbr > DrillOnFaces.R.nbr then + sDrillFace2 = 'L' + elseif DrillOnFaces.L.nbr < DrillOnFaces.R.nbr then + sDrillFace2 = 'R' + elseif DrillOnFaces.L.nbr == DrillOnFaces.R.nbr and DrillOnFaces.L.nbr > 0 then + if DrillOnFaces.L.OnlyOnRef then + sDrillFace2 = 'L' + else + sDrillFace2 = 'R' + end + end + + else + -- cerco chi vince tra faccia front e back + if DrillOnFaces.F.nbr > DrillOnFaces.B.nbr then + sDrillFace2 = 'F' + elseif DrillOnFaces.F.nbr < DrillOnFaces.B.nbr then + sDrillFace2 = 'B' + elseif DrillOnFaces.F.nbr == DrillOnFaces.B.nbr and DrillOnFaces.F.nbr > 0 then + if DrillOnFaces.F.OnlyOnRef then + sDrillFace2 = 'F' + else + sDrillFace2 = 'B' + end + end + end + end + + + if NEST.DRILL_MACH_AREA == 0 then + DrillOnFaces[sDrillFace].long = false + end + + if nMax > 0 then + DrillClassif = { sCase = sDrillFace, bClosed = DrillOnFaces[sDrillFace].closed, bLong = DrillOnFaces[sDrillFace].long, bOnlyOnRef = DrillOnFaces[sDrillFace].OnlyOnRef } + end + + local DrillClassif2 + if sDrillFace2 then + if NEST.DRILL_MACH_AREA == 0 then + DrillOnFaces[sDrillFace2].long = false + end + DrillClassif2 = { sCase = sDrillFace2, bClosed = DrillOnFaces[sDrillFace2].closed, bLong = DrillOnFaces[sDrillFace2].long, bOnlyOnRef = DrillOnFaces[sDrillFace2].OnlyOnRef } + end + + + return DrillClassif, DrillClassif2 +end + +local function ClassifyLapJointsFromBottom( nPartId) + + local res = { Nbr = 0, sCase = '', bParall = false} + + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local ptPartMin = b3Part:getMin() + local ptPartMax = b3Part:getMax() + + local vtLapJoints = {} + local dMinComponentVal = 0.95 + local vPartProc = WE.CollectFeatures( nPartId) + for nInd = 1, #vPartProc do + + if LapJoint.Identify( vPartProc[nInd]) then + -- verifico se LJ da sotto + local vtFace = IdentifyLJFromBottom( vPartProc[nInd], false) + if vtFace then + if vtFace:getX() > dMinComponentVal then + vtLapJoints["R"] = 1 + elseif vtFace:getX() < - dMinComponentVal then + vtLapJoints["L"] = 1 + elseif vtFace:getY() > dMinComponentVal then + vtLapJoints["B"] = 1 + elseif vtFace:getY() < - dMinComponentVal then + vtLapJoints["F"] = 1 + end + end + end + end + + local nCnt = 0 + for _ in pairs(vtLapJoints) do nCnt = nCnt + 1 end + + if nCnt == 1 then + res.Nbr = 1 + for k, _ in pairs( vtLapJoints) do + res.sCase = k + end + + elseif nCnt == 2 then + res.Nbr = 2 + if vtLapJoints["F"] and vtLapJoints["B"] then + res.bParall = true + res.sCase = "F" + elseif vtLapJoints["R"] and vtLapJoints["L"] then + res.bParall = true + res.sCase = "R" + else + res.bParall = false + if vtLapJoints["B"] and vtLapJoints["R"] then + res.sCase = 'BR' + elseif vtLapJoints["B"] and vtLapJoints["L"] then + res.sCase = 'BL' + elseif vtLapJoints["F"] and vtLapJoints["R"] then + res.sCase = 'FR' + elseif vtLapJoints["F"] and vtLapJoints["L"] then + res.sCase = 'FL' + end + end + + elseif nCnt == 3 then + res.Nbr = 3 + if not vtLapJoints["F"] then + res.sCase = "F" + elseif not vtLapJoints["B"] then + res.sCase = "B" + elseif not vtLapJoints["R"] then + res.sCase = "R" + elseif not vtLapJoints["L"] then + res.sCase = "L" + end + + elseif nCnt == 4 then + res.Nbr = 4 + elseif nCnt ~= 0 then + return + end + + return res + +end + + +local function CreateDefectOnAngle( nPartId, RawPart, bDrillLong, bOnOppositeAng) + + local PartTab = {} + -- recupero il gruppo dove salvo i defects + local nOutlineGrp = EgtGetFirstNameInGroup(GDB_ID.ROOT, "SheetDefects") + if not nOutlineGrp or nOutlineGrp == GDB_ID.NULL then + nOutlineGrp = EgtGroup( GDB_ID.ROOT) + EgtSetName( nOutlineGrp, "SheetDefects") + EgtSetStatus( nOutlineGrp, GDB_ST.OFF) + end + + local dExtraMachArea = WD.SIDEMILL_DIAM_DOWN -- per tenere conto dell'area di lavorazione + local dExtra = NEST.KERF + + -- local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + local b3PartX = b3Part:getDimX() + local b3PartY = b3Part:getDimY() + -- se ho fori lunghi devo riservare tutto lo spazio + if bDrillLong then + b3PartY = RawPart.Width + end + + -- calcolo i punti che definiscono il rettangolo + local ptP1, ptP2 + if ( WD.ORIG_CORNER == 'TL' and not bOnOppositeAng) or ( WD.ORIG_CORNER == 'BL' and bOnOppositeAng) then + -- angolo TL + ptP1 = Point3d( 0, RawPart.Width - b3PartY - dExtra, 0) + ptP2 = Point3d( b3PartX + dExtra, RawPart.Width, 0) + PartTab.posX = NEST.KERF + PartTab.posY = RawPart.Width - b3Part:getDimY() - NEST.KERF + elseif ( WD.ORIG_CORNER == 'BL' and not bOnOppositeAng) or ( WD.ORIG_CORNER == 'TL' and bOnOppositeAng) then + -- angolo BL + ptP1 = Point3d( 0, 0, 0) + ptP2 = Point3d( b3PartX + dExtra, b3PartY + dExtra, 0) + PartTab.posX = NEST.KERF + PartTab.posY = NEST.KERF + elseif ( WD.ORIG_CORNER == 'TR' and not bOnOppositeAng) or ( WD.ORIG_CORNER == 'BR' and bOnOppositeAng) then + -- angolo TR + ptP1 = Point3d( RawPart.Len - b3PartX - dExtra, RawPart.Width - b3PartY - dExtra, 0) + ptP2 = Point3d( RawPart.Len, RawPart.Width, 0) + PartTab.posX = RawPart.Len - b3Part:getDimX() - NEST.KERF + PartTab.posY = RawPart.Width - b3Part:getDimY() - NEST.KERF + elseif ( WD.ORIG_CORNER == 'BR' and not bOnOppositeAng) or ( WD.ORIG_CORNER == 'TR' and bOnOppositeAng) then + -- angolo BR + ptP1 = Point3d( RawPart.Len - b3PartX - dExtra, 0, 0) + ptP2 = Point3d( RawPart.Len, b3PartY + dExtra, 0) + PartTab.posX = RawPart.Len - b3Part:getDimX() - NEST.KERF + PartTab.posY = NEST.KERF + end + + PartTab.Id = tonumber(nPartId) + PartTab.DefectId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX() + dExtraMachArea, ptP2:getY() + dExtraMachArea , 0), Point3d( ptP1:getX() - dExtraMachArea , ptP1:getY() - dExtraMachArea, 0)) + EgtSetName( PartTab.DefectId, "Defect") + + return PartTab + +end + + +local function RotateOptimalCase( nPartId, nAngle, nAngleValidRot, RawPart, nPnt1, nPnt2) + + local bOptimal = false + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), nAngle, GDB_RT.GLOB) + local nRotate = nAngle + local nAnglePnt + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + -- b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local bIsValidRotation = b3Part:getDimX() < RawPart.Len - 2 * NEST.KERF + GEO.EPS_SMALL and b3Part:getDimY() < RawPart.Width - 2 * NEST.KERF + GEO.EPS_SMALL + if bIsValidRotation then + bOptimal = true + nAnglePnt = nPnt1 + else + bOptimal = false + -- ruoto nella migliore posizione ammissibile + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), nAngleValidRot, GDB_RT.GLOB) + nRotate = nRotate + nAngleValidRot + nAnglePnt = nPnt2 + end + + if nRotate >= 360 then + nRotate = nRotate - 360 + end + + return nAnglePnt, nRotate, bOptimal + +end + +local function RotateOptimalCaseDrill( nPartId, bCanRotate, nPnt1, nPnt2) + + local nRotate = 0 + local nAnglePnt + + if bCanRotate then + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), 180, GDB_RT.GLOB) + nRotate = 180 + nAnglePnt = nPnt1 + else + nAnglePnt = nPnt2 + end + + return nAnglePnt, nRotate +end + + +-- Funzione che classifica i pezzi in base alla loro necessità di stare negli angoli +local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot, dMinSheetWidth) + + -- elimino eventuali info + EgtSetInfo( nPartId, "NestOnEdge", 0) + EgtSetInfo( nPartId, "NestOnAngle", 0) + EgtSetInfo( nPartId, "OnlyOnRefSide", 0) + + local nAngle + local nRotate = 0 + local bOptimal + local bManual = false + local bOnly180Rot = EgtGetInfo( nPartId, "HasGrainDirection", 'b') or false + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + + -- fori + local DrillClassif, DrillClassif2 = ClassifyDrillsOnLateralFaces( nPartId, dMinSheetWidth) + local bDrill = false + local bDrillOpen = false + local bLongDrill = false + + if DrillClassif then + bDrill = true + bDrillOpen = not DrillClassif.bClosed + bLongDrill = DrillClassif.bLong + if DrillClassif.bOnlyOnRef then + EgtSetInfo( nPartId, "OnlyOnRefSide", 1) + end + end + + -- oriento il pezzo in base al foro + if bDrill and not bLockedRot then + local RotationAngles + if sRefOrig == 'TL' or sRefOrig == 'TR' then + RotationAngles = { F = 180, B = 0, L = 270, R = 90} + else + RotationAngles = { F = 0, B = 180, L = 90, R = 270} + end + + -- se rotazione è libera + if not bOnly180Rot then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), RotationAngles[DrillClassif.sCase], GDB_RT.GLOB) + nRotate = nRotate + RotationAngles[DrillClassif.sCase] + + -- verifico se la rotazione è valida + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + -- b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local bIsValidRotation = b3Part:getDimX() < RawPart.Len - 2 * NEST.KERF + GEO.EPS_SMALL and b3Part:getDimY() < RawPart.Width - 2 * NEST.KERF + GEO.EPS_SMALL + if not bIsValidRotation then + -- ritorno nella posizione originaria + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), - RotationAngles[DrillClassif.sCase], GDB_RT.GLOB) + nRotate = nRotate - RotationAngles[DrillClassif.sCase] + -- se ho un'altra posizione possibile ruoto in quella + if DrillClassif2 then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), RotationAngles[DrillClassif2.sCase], GDB_RT.GLOB) + nRotate = nRotate + RotationAngles[DrillClassif2.sCase] + bDrillOpen = not DrillClassif2.bClosed + bLongDrill = DrillClassif2.bLong + if DrillClassif2.bOnlyOnRef then + EgtSetInfo( nPartId, "OnlyOnRefSide", 1) + end + else + -- dimentico di avere il foro + bDrill = false + end + end + + -- se posso ruotare solo di 180° per venatura + else + if RotationAngles[DrillClassif.sCase] == 0 or RotationAngles[DrillClassif.sCase] == 180 then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), RotationAngles[DrillClassif.sCase], GDB_RT.GLOB) + nRotate = nRotate + RotationAngles[DrillClassif.sCase] + else + -- vedo se ho un'altra posizione possibile + if DrillClassif2 and ( RotationAngles[DrillClassif2.sCase] == 0 or RotationAngles[DrillClassif2.sCase] == 180) then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), RotationAngles[DrillClassif2.sCase], GDB_RT.GLOB) + nRotate = nRotate + RotationAngles[DrillClassif2.sCase] + bDrillOpen = not DrillClassif2.bClosed + bLongDrill = DrillClassif2.bLong + if DrillClassif2.bOnlyOnRef then + EgtSetInfo( nPartId, "OnlyOnRefSide", 1) + end + else + -- dimentico di avere il foro + bDrill = false + end + end + end + end + + -- se non ho venature e fori scelgo una posizione che non faccia cadere il pezzo + if not bDrill and not bOnly180Rot and not bLockedRot then + b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local bIsValid = b3Part:getDimX() > ( WD.INTRULLI or 1200) + local bRotatedIsValid = b3Part:getDimY() > ( WD.INTRULLI or 1200) + if not bIsValid and not bRotatedIsValid then + EgtSetInfo( nPartId, "REDUCECUT", 1) + elseif not bIsValid or not bRotatedIsValid then + bOnly180Rot = true + EgtSetInfo( nPartId, "NestStepRot", 180) + end + if not bIsValid and bRotatedIsValid then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) + nRotate = nRotate + 90 + end + end + + + -- lap joints + local ResLapJoints = ClassifyLapJointsFromBottom( nPartId) + b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local bAdd = true + + if ResLapJoints.Nbr > 0 and bLockedRot then + b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + if b3Part:getDimX() > ( WD.INTRULLI or 1200) then + EgtSetInfo( nPartId, "REDUCECUT", 1) + end + local PartAngleClassification = { PartId = tostring( nPartId), Angle = 100, nRotate = 0, bDrill = true, bLongDrill = true} + return PartAngleClassification + end + + -- se anche fori oppure possibile solo rotazione di 180° per non far cadere il pezzo + if bDrill or bOnly180Rot then + local bCanRotate = not bDrill or ( bDrill and bDrillOpen) + + if ResLapJoints.Nbr == 0 then + nAngle = 0 + if not bDrill then bAdd = false end + + elseif ResLapJoints.Nbr == 1 then + if (( sRefOrig == 'TL' or sRefOrig == 'TR') and ResLapJoints.sCase == 'B' ) or + (( sRefOrig == 'BL' or sRefOrig == 'BR') and ResLapJoints.sCase == 'F' ) then + nAngle = 20 + elseif (( sRefOrig == 'TL' or sRefOrig == 'TR') and ResLapJoints.sCase == 'F' ) or + (( sRefOrig == 'BL' or sRefOrig == 'BR') and ResLapJoints.sCase == 'B' ) then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 20, 100) + nRotate = nRotate + nRotate2 + elseif ResLapJoints.sCase == 'R' then + if bCanRotate then bManual = true end + if sRefOrig == 'TL' or sRefOrig == 'BL'then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 40, 0) + nRotate = nRotate + nRotate2 + else + nAngle = 40 + end + elseif ResLapJoints.sCase == 'L' then + if bCanRotate then bManual = true end + if sRefOrig == 'TR' or sRefOrig == 'BR' then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 40, 0) + nRotate = nRotate + nRotate2 + else + nAngle = 40 + end + end + + elseif ResLapJoints.Nbr == 2 then + if ResLapJoints.bParall then + if ResLapJoints.sCase == 'F' then + nAngle = 100 + else + nAngle = 80 + end + else + if (( sRefOrig == 'TL' or sRefOrig == 'TR') and (ResLapJoints.sCase == 'BL' or ResLapJoints.sCase == 'BR')) or + (( sRefOrig == 'BL' or sRefOrig == 'BR') and (ResLapJoints.sCase == 'FL' or ResLapJoints.sCase == 'FR')) then + nAngle = 40 + else + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 40, 100) + nRotate = nRotate + nRotate2 + end + end + + elseif ResLapJoints.Nbr == 3 then + if (( sRefOrig == 'TL' or sRefOrig == 'TR') and ResLapJoints.sCase == 'F' ) or + (( sRefOrig == 'BL' or sRefOrig == 'BR') and ResLapJoints.sCase == 'B' ) then + nAngle = 80 + elseif (( sRefOrig == 'TL' or sRefOrig == 'TR') and ResLapJoints.sCase == 'B' ) or + (( sRefOrig == 'BL' or sRefOrig == 'BR') and ResLapJoints.sCase == 'F' ) then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 80, 100) + nRotate = nRotate + nRotate2 + elseif ResLapJoints.sCase == 'R' then + if bCanRotate then bManual = true end + if sRefOrig == 'TR' or sRefOrig == 'BR' then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 100, 100) + nRotate = nRotate + nRotate2 + end + nAngle = 100 + elseif ResLapJoints.sCase == 'L' then + if bCanRotate then bManual = true end + if sRefOrig == 'TL' or sRefOrig == 'BL' then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 100, 100) + nRotate = nRotate + nRotate2 + end + nAngle = 100 + end + + elseif ResLapJoints.Nbr == 4 then + nAngle = 100 + end + + + -- no fori + else + if ResLapJoints.Nbr == 0 then + bAdd = false + + elseif ResLapJoints.Nbr == 1 then + if sRefOrig == 'TL' or sRefOrig == 'TR' then + RotationAngles = { F = 180, B = 0, R = 90, L = 270} + elseif sRefOrig == 'BL'or sRefOrig == 'BR' then + RotationAngles = { F = 0, B = 180, R = 270, L = 90} + end + local nAngleValidRot = EgtIf( sRefOrig == 'TL' or sRefOrig == 'BR', 90, 270) + nAngle, nRotate2, bOptimal = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 20, 40) + nRotate = nRotate + nRotate2 + if not bOptimal then bManual = true end + + elseif ResLapJoints.Nbr == 2 then + if ResLapJoints.bParall then + -- se lap joints su lati paralleli + RotationAngles = { F = 90, R = 0} + nAngle, nRotate2 = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], 90, RawPart, 80, 100) + nRotate = nRotate + nRotate2 + else + -- se lap joints su lati adiacenti + if sRefOrig == 'TR' then + RotationAngles = { FR = 90, BR = 0, BL = 270, FL = 180} + elseif sRefOrig == 'TL' then + RotationAngles = { FR = 180, BR = 90, BL = 0, FL = 270} + elseif sRefOrig == 'BR' then + RotationAngles = { FR = 0, BR = 270, BL = 180, FL = 90} + elseif sRefOrig == 'BL' then + RotationAngles = { FR = 270, BR = 180, BL = 90, FL = 0} + end + local nAngleValidRot = EgtIf( sRefOrig == 'TL' or sRefOrig == 'BR', 270, 90) + nAngle, nRotate2, bOptimal = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 40, 40) + nRotate = nRotate + nRotate2 + + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local bCanRotate = b3Part:getDimX() < RawPart.Width + if bOptimal and bCanRotate then bManual = true end + end + + elseif ResLapJoints.Nbr == 3 then + if sRefOrig == 'TL' or sRefOrig == 'TR' then + RotationAngles = { F = 0, B = 180, R = 270, L = 90} + elseif sRefOrig == 'BL' or sRefOrig == 'BR' then + RotationAngles = { F = 180, B = 0, R = 90, L = 270} + end + local nAngleValidRot = EgtIf( sRefOrig == 'TL' or sRefOrig == 'BR', 90, 270) + nAngle, nRotate2, bOptimal = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 80, 100) + nRotate = nRotate + nRotate2 + if not bOptimal then bManual = true end + + elseif ResLapJoints.Nbr == 4 then + nAngle, nRotate2 = RotateOptimalCase( nPartId, 0, 90, RawPart, 100, 100) + nRotate = nRotate + nRotate2 + end + + end + + + -- aggiorno le info di rotazione del pezzo + if nRotate >= 360 then + nRotate = nRotate - 360 + end + if nRotate > 0 then + local nPartRot = EgtGetInfo( nPartId, "ROTATED", 'i') or 0 + local nTotRot = nPartRot + nRotate + nTotRot = EgtIf( nTotRot < 360, nTotRot, nTotRot - 360) + EgtSetInfo( nPartId, "ROTATED", nTotRot) + EgtSetInfo( nPartId, "MODIFIEDFORNEST", 1) + end + + if not bAdd then + return + end + + local PartAngleClassification = { PartId = tostring( nPartId), Angle = nAngle, nRotate = nRotate, bDrill = bDrill, bLongDrill = bLongDrill, bManual = bManual} + + local bCanBeOnOtherEdge = not bDrill or ( bDrill and RawPart.Width >= WD.MINRAWY_HOR_DRILL) + if bOnly180Rot then + if bCanBeOnOtherEdge then + EgtSetInfo( nPartId, "NestAllowRot", 1) + EgtSetInfo( nPartId, "NestStepRot", 180) + else + EgtSetInfo( nPartId, "NestAllowRot", 0) + EgtSetInfo( nPartId, "NestStepRot", 0) + end + end + + -- verifico se il pezzo cade (caso di foro) + b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + if b3Part:getDimX() > ( WD.INTRULLI or 1200) then + EgtSetInfo( nPartId, "REDUCECUT", 1) + end + + return PartAngleClassification +end + + +local function ComputeRestrictedZones( RawParts) + + local dTotArea = 0 + -- area totale dei pezzi + for nPartId, nCount in pairs( PART) do + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local dPartArea = b3Part:getDimX() * b3Part:getDimY() + dTotArea = dTotArea + dPartArea * nCount + end + + -- stimo il numero di angoli disponibili + local vSheetNbrEstimate = {} + local nSheetNbrEstimate = 0 + local nSheetNbrCorrection = - 2 + local nAnglesNbrEstimate = 0 + local nAngelsNbrCorrection = 0 + + local vRawDistrib = {} + if #RawParts == 1 then + vRawDistrib = {1} + elseif #RawParts == 2 then + vRawDistrib = {0.7, 0.3} + else + for nInd = 1, #RawParts do + table.insert( vRawDistrib, 1 / #RawParts) + end + end + + local dMaxSheetWidth = -100 + local nMaxSheet = 1 + local dMinSheetWidth = WD.MAX_WIDTH + for nInd = 1, #RawParts do + local dSheetArea = RawParts[nInd].Len * RawParts[nInd].Width + if RawParts[nInd].Width > dMaxSheetWidth + GEO.EPS_SMALL then + dMaxSheetWidth = RawParts[nInd].Width + nMaxSheet = nInd + elseif abs( RawParts[nInd].Width - dMaxSheetWidth) < GEO.EPS_SMALL then + if RawParts[nInd].Len > RawParts[nMaxSheet].Len then + nMaxSheet = nInd + end + end + if RawParts[nInd].Width < dMinSheetWidth then + dMinSheetWidth = RawParts[nInd].Width + end + + vSheetNbrEstimate[nInd] = min( ceil( dTotArea * vRawDistrib[nInd] / dSheetArea) + nSheetNbrCorrection, RawParts[nInd].Qty) + if vSheetNbrEstimate[nInd] <= 0 then + vSheetNbrEstimate[nInd] = min( RawParts[nInd].Qty, 1) + end + + nSheetNbrEstimate = nSheetNbrEstimate + vSheetNbrEstimate[nInd] + nAnglesNbrEstimate = nAnglesNbrEstimate + vSheetNbrEstimate[nInd] * 2 + end + nAnglesNbrEstimate = nAnglesNbrEstimate + nAngelsNbrCorrection + + + -- classificazione dei pezzi in base alla loro necessità di stare negli angoli + local nTotParts = 0 + for _ in pairs( PART) do nTotParts = nTotParts + 1 end + local nPartIndex = 0 + local AngleClassification = {} + for nPartId, nCount in pairs( PART) do + nPartIndex = nPartIndex + 1 + local bManualRot = EgtGetInfo( nPartId, "MANUALROT", 'b') + local PartClassif = ClassifyAngles(tonumber(nPartId), RawParts[nMaxSheet], WD.ORIG_CORNER, bManualRot, dMinSheetWidth) + if PartClassif then + for nI = 1, nCount do + local newTab = {PartId = PartClassif.PartId, Angle = PartClassif.Angle, nRotate = PartClassif.nRotate, bDrill = PartClassif.bDrill, bLongDrill = PartClassif.bLongDrill, bManual = PartClassif.bManual} + table.insert( AngleClassification, newTab) + end + end + + if EgtProcessEvents( nPartIndex / nTotParts * 100, 0) == 1 then + return false + end + end + + table.sort( AngleClassification, function(a, b) return a.Angle > b.Angle end) + + + local vManuallyDone = {} + local vPartsManuallyDone = {} + for nInd = 1, #vSheetNbrEstimate do + for nInd2 = 1, vSheetNbrEstimate[nInd] do + table.insert( vManuallyDone, { RawPartId = nInd, Done = 0, Parts = {}}) + end + end + local nSheetNbr = #vManuallyDone + local vFilledSheets = {} + for nInd = 1, #vSheetNbrEstimate do + for nInd2 = 1, vSheetNbrEstimate[nInd] do + table.insert( vFilledSheets, { Width = RawParts[nInd].Width, OrigWidth = RawParts[nInd].Width}) + end + end + + for nInd = 1, #AngleClassification do + + if AngleClassification[nInd].Angle >= NEST.MIN_ANGLE_PNT and AngleClassification[nInd].Angle > 0 then + + -- verifico di avere ancora angoli a disposizione secondo la stima dei grezzi + local bFound = false + local nBoxLayerId = EgtGetFirstNameInGroup( AngleClassification[nInd].PartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + local dPartWidth = b3Part:getDimY() + NEST.KERF + for nInd2 = 1, #vFilledSheets do + if dPartWidth < vFilledSheets[nInd2].Width then + -- verifico se il grezzo aveva già un pezzo in un angolo + if abs( vFilledSheets[nInd2].Width - vFilledSheets[nInd2].OrigWidth) < GEO.EPS_SMALL then + vFilledSheets[nInd2].Width = vFilledSheets[nInd2].Width - dPartWidth - WD.SIDEMILL_DIAM_DOWN + else + -- se il grezzo aveva già un pezzo nell'angolo, dopo il pezzo corrente non ne posso mettere altri + vFilledSheets[nInd2].Width = 0 + end + bFound = true + break + end + end + + -- se ho ancora angoli a disposizione oppure il pezzo deve stare necessariamente sull'angolo per essere lavorato + if bFound or AngleClassification[nInd].Angle == 100 then + -- verifico se va nestato manualmente + if AngleClassification[nInd].bManual then + + -- trovo il punto della lista dove inserirlo + local nIdx = -1 + local bOnOppositeSide = false + for nInd2 = 1, #vManuallyDone do + -- verifico se il pezzo può stare sull'altro angolo + local bOnlyOnRef = EgtGetInfo( AngleClassification[nInd].PartId, "OnlyOnRefSide", 'b') + local bCanBeOnOtherAngle = not bOnlyOnRef and + ( not AngleClassification[nInd].bDrill or + ( AngleClassification[nInd].bDrill and not AngleClassification[nInd].bLongDrill and RawParts[vManuallyDone[nInd2].RawPartId].Width >= WD.MINRAWY_HOR_DRILL)) + + if #(vManuallyDone[nInd2].Parts) == 0 then + -- verifico che il pezzo stia in questo grezzo + local b3Part = EgtGetBBoxGlob( AngleClassification[nInd].PartId, GDB_BB.STANDARD) + if b3Part:getDimX() < RawParts[vManuallyDone[nInd2].RawPartId].Len and b3Part:getDimY() < RawParts[vManuallyDone[nInd2].RawPartId].Width then + nIdx = nInd2 + break + end + + elseif #(vManuallyDone[nInd2].Parts) == 1 and bCanBeOnOtherAngle then + -- verifico se il pezzo già posizionato nell'angolo non ha fori lunghi + if not vManuallyDone[nInd2].Parts[1].bLongDrill then + -- oriento il pezzo in modo ottimale per andare su quell'angolo + local sRefOrig + if WD.ORIG_CORNER == 'TL' then sRefOrig = 'BL' end + if WD.ORIG_CORNER == 'BL' then sRefOrig = 'TL' end + if WD.ORIG_CORNER == 'TR' then sRefOrig = 'BR' end + if WD.ORIG_CORNER == 'BR' then sRefOrig = 'TR' end + local bManTmp + local res = ClassifyAngles( AngleClassification[nInd].PartId, RawParts[vManuallyDone[nInd2].RawPartId], sRefOrig, bManTmp, dMinSheetWidth) + -- verifico sia compatibile con pezzo già inserito + local b3OtherPart = EgtGetBBoxGlob( vManuallyDone[nInd2].Parts[1].Id, GDB_BB.STANDARD) + local b3Part = EgtGetBBoxGlob( AngleClassification[nInd].PartId, GDB_BB.STANDARD) + local dExtra = 2 * NEST.KERF + WD.SIDEMILL_DIAM_DOWN + 1 + -- se è compatibile assegno questa rotazione al pezzo + if b3Part:getDimY() + b3OtherPart:getDimY() + dExtra < RawParts[vManuallyDone[nInd2].RawPartId].Width then + nIdx = nInd2 + bOnOppositeSide = true + -- aggiorno le info di rotazione + if res.nRotate > 0 then + local nPartRot = EgtGetInfo( AngleClassification[nInd].PartId, "ROTATED", 'i') or 0 + local nTotRot = nPartRot + res.nRotate + nTotRot = EgtIf( nTotRot < 360, nTotRot, nTotRot - 360) + EgtSetInfo( AngleClassification[nInd].PartId, "ROTATED", nTotRot) + EgtSetInfo( AngleClassification[nInd].PartId, "MODIFIEDFORNEST", 1) + end + break + end + -- altrimenti lo riporto nella sua posizione originaria + EgtRotate( AngleClassification[nInd].PartId, b3Part:getCenter(), Z_AX(), - res.nRotate, GDB_RT.GLOB) + end + end + end + + -- nesto il pezzo a mano + if nIdx ~= -1 then + -- aree di lavorazione + local nToolOutlineIds = ComputeToolOutlines( AngleClassification[nInd].PartId) + local sInfo = "" + for nInd = 1, #nToolOutlineIds do + sInfo = sInfo .. tostring(nToolOutlineIds[nInd]) .. "," + end + -- salvo tra le info del pezzo gli id delle sue aree di lavorazione + if sInfo ~= "" then + EgtSetInfo( AngleClassification[nInd].PartId, "ToolOutlines", sInfo) + end + + -- calcolo defect corrispondente al pezzo + local PartTab = CreateDefectOnAngle( AngleClassification[nInd].PartId, RawParts[vManuallyDone[nIdx].RawPartId], AngleClassification[nInd].bLongDrill, bOnOppositeSide) + PartTab.bLongDrill = AngleClassification[nInd].bLongDrill + table.insert( vManuallyDone[nIdx].Parts, PartTab) + table.insert( vPartsManuallyDone, tonumber( AngleClassification[nInd].PartId)) + + else + -- aggiungo info per il nesting per ricordare che andrà su angolo + EgtSetInfo( AngleClassification[nInd].PartId, "NestOnAngle", 1) + end + else + -- se non va nestato manualmente segno info per nesting + EgtSetInfo( AngleClassification[nInd].PartId, "NestOnAngle", 1) + end + + else + -- se non ho più angoli a disposizione lo metto sul lato + EgtSetInfo(AngleClassification[nInd].PartId, "NestOnEdge", 1) + end + + else + EgtSetInfo(AngleClassification[nInd].PartId, "NestOnEdge", 1) + end + + end + + local nInd = 1 + while nInd <= #vManuallyDone do + if #(vManuallyDone[nInd].Parts) == 0 then + table.remove( vManuallyDone, nInd) + else + nInd = nInd + 1 + end + end + + return vManuallyDone, vPartsManuallyDone +end + + + +-- Funzione che sposta e aggiunge pezzi per nesting +local function AddRawParts(RawParts, vDoneManually) + + local OUTLINE = "Outline" + for nIndex = 1, #RawParts do + RawParts[nIndex].PartId = {} + + -- pannelli con pezzi inseriti manualmente + local nTotSheetWithDefects = 0 + for nInd = 1, #vDoneManually do + if vDoneManually[nInd].RawPartId == nIndex then + -- creo pannello del materiale + local SheetPartId = EgtGroup(GDB_ID.ROOT) + table.insert( RawParts[nIndex].PartId, SheetPartId) + EgtSetName(SheetPartId, "Sheet") + local SheetLayerId = EgtGroup(SheetPartId) + EgtSetName(SheetLayerId, OUTLINE) + local SheetOutlineId = EgtRectangle2P(SheetLayerId, Point3d(0,0,0), Point3d(RawParts[nIndex].Len + 0.1, RawParts[nIndex].Width + 0.1, 0), GDB_RT.GLOB) + EgtSetName(SheetOutlineId, OUTLINE) + -- creo foglio per nesting + EgtAutoNestAddSheet( SheetPartId, SheetOutlineId, NEST.KERF, 0, 1) + -- aggiungo defects + for nInd2 = 1, #(vDoneManually[nInd].Parts) do + EgtAutoNestAddDefectToSheet( SheetPartId, vDoneManually[nInd].Parts[nInd2].DefectId) + end + vDoneManually[nInd].SheetId = SheetPartId + nTotSheetWithDefects = nTotSheetWithDefects + 1 + end + end + + -- pannelli senza pezzi inseriti manualmente + local SheetPartId = EgtGroup(GDB_ID.ROOT) + table.insert( RawParts[nIndex].PartId, SheetPartId) + EgtSetName(SheetPartId, "Sheet") + local SheetLayerId = EgtGroup(SheetPartId) + EgtSetName(SheetLayerId, OUTLINE) + local SheetOutlineId = EgtRectangle2P(SheetLayerId, Point3d(0,0,0), Point3d(RawParts[nIndex].Len + 0.1, RawParts[nIndex].Width + 0.1, 0), GDB_RT.GLOB) + -- EgtModifyCurveThickness(SheetOutlineId, -Material.T_mm) + EgtSetName(SheetOutlineId, OUTLINE) + + -- creo foglio per nesting + EgtAutoNestAddSheet( SheetPartId, SheetOutlineId, NEST.KERF, 1, RawParts[nIndex].Qty - nTotSheetWithDefects) -- EgtAutoNestAddSheet( SheetId, OutlineId, dKerf, nPriority, nCount) + end +end + + + +local function AddParts(RawParts, vPartsDoneManually) + + -- cerco la width massima dei grezzi + local dRawMaxWidth = - 100 + for nIndex = 1, #RawParts do + if RawParts[nIndex].Width > dRawMaxWidth then + dRawMaxWidth = RawParts[nIndex].Width + end + end + + -- valori correttivi per vincoli StripX e StripY + local dStripYCorr = GEO.EPS_SMALL + local dStripXCorr = GEO.EPS_SMALL + if NEST.CORNER == NST_CORNER.TL or NEST.CORNER == NST_CORNER.TR then + dStripYCorr = 0.1 - GEO.EPS_SMALL + end + if NEST.CORNER == NST_CORNER.BR or NEST.CORNER == NST_CORNER.TR then + dStripXCorr = 0.1 - GEO.EPS_SMALL + end + + local nTotParts = 0 + for _ in pairs( PART) do nTotParts = nTotParts + 1 end + local nPartIndex = 0 + -- ciclo su pezzi per aggiungerli al nesting + for nPartId, nCount in pairs( PART) do repeat + + -- conto quanti pezzi di questo tipo sono già stati posizionati a mano + nManuallyDone = 0 + for nJ = 1, #vPartsDoneManually do + if vPartsDoneManually[nJ] == tonumber( nPartId) then + nManuallyDone = nManuallyDone + 1 + end + end + + if nManuallyDone == nCount then + -- se tutti posizionati passo al pezzo successivo + break + else + -- posiziono con il nesting solo quelli mancanti + nCount = nCount - nManuallyDone + end + + nPartIndex = nPartIndex + 1 + + -- calcolo bbox pezzo per rotazioni + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + + -- recupero eventuali stati di flip e rotazione dalle info del pezzo + local bFlipNest = true + local bFlip = false + local bRotNest = true + local nStepRotNest = 90 + local nRotate = 0 + + -- flip + local bManualFlip = EgtGetInfo( nPartId, "MANUALFLIP", 'b') + if bManualFlip then + bFlipNest = false + elseif EgtExistsInfo( nPartId, "NestFlip") then + bFlipNest = EgtGetInfo( nPartId, "NestAllowFlip", 'b') + bFlip = EgtGetInfo( nPartId, "NestFlip", 'b') + end + + -- rotation + local bManualRot = EgtGetInfo( nPartId, "MANUALROT", 'b') + if bManualRot then + bRotNest = false + elseif EgtExistsInfo( nPartId, "NestRot") then + nStepRotNest = EgtGetInfo( nPartId, "NestStepRot", 'i') + nRotate = EgtGetInfo( nPartId, "NestRot", 'i') + bRotNest = EgtGetInfo( nPartId, "NestAllowRot", 'b') + -- verifico se rotazione è valida (pezzo è contenuto nel grezzo) + local bValidRotationInRaw = b3Part:getDimX() < RawParts[1].Len - 2 * NEST.KERF + GEO.EPS_SMALL and b3Part:getDimY() < dRawMaxWidth - 2 * NEST.KERF + GEO.EPS_SMALL + if not bValidRotationInRaw then + bRotNest = true + nStepRotNest = 90 + end + end + + -- aggiungo stato a lista stati del pezzo + -- table.insert( PartStates, { PartId = tonumber(nPartId), Flip = bFlip, Rotate = nRotate}) + + +-- local bFtDown = false +-- local vPartProc = WE.CollectFeatures( nPartId, b3Raw) +-- for nInd = 1, #vPartProc do +-- if LapJoint.Identify( vPartProc[nInd]) then +-- local nFacOpt, dMinElev, nFacOpt2, dMinElev2 = WL.GetFaceWithMostAdj( vPartProc[nInd].Id, vPartProc[nInd].PartId) +-- if nFacOpt >= 0 then +-- local vtN = EgtSurfTmFacetNormVersor( vPartProc[nInd].Id, nFacOpt, GDB_ID.ROOT) +-- if vtN:getZ() < -0.09 then +-- bFtDown = true +-- break +-- end +-- end +-- end +-- LapJoint.FlipClassify(vPartProc[nInd]) +-- end +-- -- ruoto se necessario +-- if bFtDown then +-- local b3Solid = EgtGetBBoxGlob(nPartId, GDB_BB.IGNORE_TEXT) +-- local ptRotCen = b3Solid:getCenter() +-- EgtRotate( nPartId, ptRotCen, X_AX(), 180, GDB_RT.GLOB) +-- end + +-- -- recupero le feature di lavorazione della parete +-- local bFtDown = false +-- local vPartProc = WE.CollectFeatures( nPartId, b3Raw) +-- for nInd = 1, #vPartProc do +-- if LapJoint.Identify( vPartProc[nInd]) then +-- local nFacOpt, dMinElev, nFacOpt2, dMinElev2 = WL.GetFaceWithMostAdj( vPartProc[nInd].Id, vPartProc[nInd].PartId) +-- if nFacOpt >= 0 then +-- local vtN = EgtSurfTmFacetNormVersor( vPartProc[nInd].Id, nFacOpt, GDB_ID.ROOT) +-- if vtN:getZ() < -0.09 then +-- bFtDown = true +-- break +-- end +-- end +-- end +-- end +-- -- ruoto se necessario +-- if bFtDown then +-- local b3Solid = EgtGetBBoxGlob(nPartId, GDB_BB.IGNORE_TEXT) +-- local ptRotCen = b3Solid:getCenter() +-- EgtRotate( nPartId, ptRotCen, X_AX(), 180, GDB_RT.GLOB) +-- end + + -- recupero vecchio contorno se già presente + local nOutlineLayer = EgtGetFirstNameInGroup(nPartId, "Outline") + local nOldOutline = EgtGetFirstNameInGroup(nOutlineLayer, 'ON_TMP') + local nOutline, nCnt + + -- se l'outline non è stato calcolato oppure il pezzo è stato modificato, lo ricalcolo + local bPartIsModified = EgtGetInfo( nPartId, "MODIFIEDFORNEST", 'b') + if not nOldOutline or bPartIsModified then + + -- elimino il vecchio contorno se pesente + while ( nOldOutline) do + EgtErase(nOldOutline or GDB_ID.NULL) + nOldOutline = EgtGetFirstNameInGroup( nOutlineLayer, 'ON_TMP') + end + + -- Recupero o ricalcolo il solido + local SolidId = EgtBeamGetSolid( nPartId) + if not SolidId or not EgtGetInfo( SolidId, 'VALID') then + EgtBeamCalcSolid( nPartId, true) + SolidId = EgtBeamGetSolid( nPartId) + end + nOutline, nCnt = EgtGetSurfTmSilhouette( SolidId, Z_AX(), 10, nOutlineLayer, GDB_RT.GLOB) + EgtBeamShowSolid( nPartId, false) + + for nInd = 0, nCnt - 1 do + EgtSetName( nOutline + nInd, 'ON_TMP') + EgtSetStatus( nOutline + nInd, 0) + end + + local nCurrOutline = nOutline + if nCnt > 0 then + local frSum + EgtScale( nOutline, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB) + EgtModifyCurveExtrusion( nOutline, Z_AX(), GDB_RT.GLOB) + + -- verifico che la prima curva sia l'unico loop esterno + local vCrvRef = EgtCurveArea( nOutline) + for nInd = 1, nCnt - 1 do + local vCrv = EgtCurveArea( nOutline + nInd) + -- se trovo più loop esterni uso come contorno quello del box (quindi forzo nCurrOutline a nil) + if abs( vCrv * vCrvRef - 1) < GEO.EPS_SMALL then + nCurrOutline = nil + for nInd2 = 0, nCnt - 1 do + EgtErase( nOutline + nInd2) + end + nCnt = 1 + break + end + end + + --local frSum = EgtSurfFlatRegion(nOutlineLayer, nOutline) + --EgtSaveFile("c:\\Temp\\ProvaNesting.nge") + -- -- per ogni contorno creo flat region e le sommo + -- for nIndex = 0, nCnt - 1 do + -- EgtScale( nOutline + nIndex, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB) + -- EgtModifyCurveExtrusion( nOutline + nIndex, Z_AX(), GDB_RT.GLOB) + -- local frCurr = EgtSurfFlatRegion(nOutlineLayer, nOutline + nIndex) + -- if frCurr then + -- if frSum then + -- EgtSurfFrAdd(frSum, frCurr) + -- else + -- frSum = frCurr + -- end + -- end + -- EgtErase(frCurr) + -- end + -- --EgtSaveFile("c:/Temp/ProvaNesting.nge") + -- -- calcolo contorno della flat region somma + -- nCurrOutline = EgtExtractSurfFrChunkLoops(frSum, 0, nOutlineLayer) + -- EgtErase(frSum) + -- -- cancello contorni + -- for nIndex = 0, nCnt do + -- EgtErase(nOutline + nIndex) + -- end + end + + if nCurrOutline and nCurrOutline ~= GDB_ID.NULL then + nOutline = nCurrOutline + else + -- se non ho trovato contorno, lo recupero dal Box + local nBoxLayer = EgtGetFirstNameInGroup(nPartId, "Box") + local nBox = EgtGetFirstNameInGroup(nBoxLayer, "Box") + local BBox = EgtGetBBoxGlob(nBox, GDB_BB.STANDARD) + nOutline = EgtRectangle2P(nOutlineLayer, Point3d( BBox:getMin():getX(), BBox:getMin():getY(), 0), Point3d( BBox:getMax():getX(), BBox:getMax():getY(), 0), GDB_RT.GLOB) + EgtOutLog("Impossible creating silhouette for part " .. tostring(nPartId)) + nCnt = 1 + end + --if nCnt == 0 then + -- -- se non ho trovato contorno, lo recupero dal Box + -- local nBoxLayer = EgtGetFirstNameInGroup(nPartId, "Box") + -- local nBox = EgtGetFirstNameInGroup(nBoxLayer, "Box") + -- local BBox = EgtGetBBoxGlob(nBox, GDB_BB.STANDARD) + -- nOutline = EgtRectangle2P(nOutlineLayer, Point3d( BBox:getMin():getX(), BBox:getMin():getY(), 0), Point3d( BBox:getMax():getX(), BBox:getMax():getY(), 0), GDB_RT.GLOB) + -- EgtOutLog("Impossible creating silhouette for part " .. tostring(nPartId)) + --else + -- --EgtScale( nOutline, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB) + -- --EgtModifyCurveExtrusion( nOutline, Z_AX(), GDB_RT.GLOB) + -- --EgtSaveFile("c:/Temp/ProvaNesting.nge") + -- EgtScale( nOutline, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB) + -- EgtModifyCurveExtrusion( nOutline, Z_AX(), GDB_RT.GLOB) + -- local frSum = EgtSurfFlatRegion(nOutlineLayer, nOutline) + -- EgtSaveFile("c:\\Temp\\ProvaNesting.nge") + -- -- per ogni contorno creo flat region e le sommo + -- for nIndex = 1, nCnt - 1 do + -- EgtScale( nOutline + nIndex, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB) + -- EgtModifyCurveExtrusion( nOutline + nIndex, Z_AX(), GDB_RT.GLOB) + -- local frCurr = EgtSurfFlatRegion(nOutlineLayer, nOutline + nIndex) + -- if frCurr then + -- EgtSurfFrAdd(frSum, frCurr) + -- end + -- end + -- -- calcolo contorno della flat region somma + -- nOutline = EgtExtractSurfFrChunkLoops(frSum, 0, nOutlineLayer) + -- -- cancello contorni successivi + -- for nIndex = 1, nCnt do + -- EgtErase(nOutline + nIndex) + -- end + --end + + EgtSetName( nOutline, 'ON_TMP') + EgtSetStatus( nOutline, 0) + + else + -- altrimenti uso l'outline già calcolato + nOutline = nOldOutline + -- recupero il valore di nCnt + local vOutlinesIds = EgtGetNameInGroup( nOutlineLayer, 'ON_TMP') + nCnt = #vOutlinesIds + end + + + --[[ local nOutline + local nTrimesh + local bFirst = true + local bSecond = false + local bUseBox = false + nTrimesh = EgtGetFirstNameInGroup( nOutlineLayer, "1-Out") + if not nTrimesh then + nTrimesh = EgtGetFirstNameInGroup( nOutlineLayer, "2-Out") + end + if not nTrimesh then + nTrimesh = EgtGetFirstNameInGroup( nOutlineLayer, "3-Out") + end + if not nTrimesh then + nTrimesh = EgtGetFirstNameInGroup( nOutlineLayer, "4-Out") + end + -- se trovato contorno + if nTrimesh then + -- recupero la curva associata + local nAuxId = EgtGetInfo(nTrimesh, "AUXID", 'i') + nOutline = nTrimesh + nAuxId + -- verifico che il contorno sia verticale + local nFacetCount = EgtSurfTmFacetCount(nTrimesh) + for nIndex = 0, nFacetCount - 1 do + local vtNorm = EgtSurfTmFacetNormVersor(nTrimesh, nIndex, GDB_ID.ROOT) + if abs( vtNorm:getZ()) > 10 * GEO.EPS_SMALL then + bUseBox = true + break + end + end + -- se due compo o una e lati inclinati + if bUseBox then + -- calcolo box della trimesh + local b3Outline = EgtGetBBoxGlob(nTrimesh, GDB_BB.IGNORE_TEXT) + local ptP1 = Point3d( b3Outline:getMin():getX(), b3Outline:getMin():getY(), 0) + local ptP2 = Point3d( b3Outline:getMax():getX(), b3Outline:getMax():getY(), 0) + -- creo outline del box + nOutline = EgtRectangle2P(nOutlineLayer, ptP1, ptP2, GDB_RT.GLOB) + EgtSetStatus(nOutline, GDB_ST.OFF) + end + -- altrimenti cerco la regione sopra + else + -- cancello precedenti contorni calcolati + local nOldONId = EgtGetFirstNameInGroup( nOutlineLayer, 'ON_TMP') + if nOldONId then + EgtErase( nOldONId) + end + -- cerco la regione sopra + local nReg + for i = 1, 4 do + local sRegName = string.format( '%d-Top', i) + nReg = EgtGetFirstNameInGroup( nOutlineLayer, sRegName) + if nReg then + local vtNorm = EgtSurfFrNormVersor( nReg, GDB_ID.ROOT) + if vtNorm:getZ() > 0.99 then break end + end + end + if not nReg then + EgtOutLog("Errore: regione superiore non trovata") + end + -- recupero contorno della regione + local OutId, nCnt = EgtExtractSurfFrChunkLoops( nReg, 0, nOutlineLayer) + if OutId and nCnt > 1 then + for i = 2, nCnt do + EgtErase( OutId + i - 1) + end + end + if OutId then + EgtSetName( OutId, 'ON_TMP') + nOutline = OutId + end + end + ]]-- + + + -- calcolo aree lavorazione + local nToolOutlineIds = ComputeToolOutlines( nPartId) + if bFlipNest and #nToolOutlineIds > 0 then + bFlipNest = false + end + + if nOutline then + -- aggiungo pezzo al nesting + EgtAutoNestAddPart( nPartId, nOutline, bFlipNest, bRotNest, nStepRotNest, 0, nCount) + -- EgtAutoNestAddPart( PartId, OutlineId, bCanFlip, bCanRotate, dRotStep, nPriority, nCount) + end + -- aggiungo finestre + for nInd = 1, nCnt - 1 do + local tmp1, tmp2, area = EgtCurveArea( nOutline + nInd) + if area > WD.NEST_HOLE_MIN_AREA then + EgtModifyCurveExtrusion( nOutline + nInd, Z_AX(), GDB_RT.GLOB) + EgtAutoNestAddHoleToPart( nPartId, nOutline + nInd) + end + end + + -- aggiungo aree di lavorazione del pezzo + local sInfo = "" + for nInd = 1, #nToolOutlineIds do + EgtAutoNestAddToolOutlineToPart( nPartId, nToolOutlineIds[nInd]) + sInfo = sInfo .. tostring(nToolOutlineIds[nInd]) .. "," + end + -- salvo tra le info del pezzo gli id delle sue aree di lavorazione + if sInfo ~= "" then + EgtSetInfo( nPartId, "ToolOutlines", sInfo) + end + + -- Eventuali vincoli StripX e StripY + local bOnEdge = EgtGetInfo(nPartId, "NestOnEdge", 'b') + local bOnAngle = EgtGetInfo(nPartId, "NestOnAngle", 'b') + if bOnEdge or bOnAngle then + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + + -- punto di riferimento sul pezzo + local ptRef + local dval = 10 + if ( WD.ORIG_CORNER == 'TL' or WD.ORIG_CORNER == 'TR') then + ptRef = Point3d( b3Part:getMax():getX() - b3Part:getDimX() / 2, b3Part:getMax():getY() - dval, 0) + else + ptRef = Point3d( b3Part:getMin():getX() + b3Part:getDimX() / 2, b3Part:getMin():getY() + dval, 0) + end + + -- vincolo StripY + local bOnlyOnRefSide = EgtGetInfo( nPartId, "OnlyOnRefSide", 'b') + if bOnlyOnRefSide then + if WD.ORIG_CORNER == 'BL' or WD.ORIG_CORNER == 'BR' then + EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + dval + dStripYCorr, 100000) + else + EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, - 1000, dRawMaxWidth + 1000 - ( NEST.KERF + dval - dStripYCorr)) + end + else + EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + dval + dStripYCorr, dRawMaxWidth - 2 * ( NEST.KERF + dval)) + end + + -- se sull'angolo aggiungo anche vincolo StripX + if bOnAngle then + if WD.ORIG_CORNER == 'TL' or WD.ORIG_CORNER == 'BL' then + EgtAutoNestSetStripXconstraintToPart( nPartId, ptRef, NEST.KERF + b3Part:getDimX() / 2 + dStripXCorr, 100000) + else + EgtAutoNestSetStripXconstraintToPart( nPartId, ptRef, -100, RawParts[1].Len + 100 - NEST.KERF - b3Part:getDimX() / 2 + dStripXCorr) + end + end + end + + -- verifico se anullato nesting + if EgtProcessEvents( 100 + ( nPartIndex / nTotParts * 100), 0) == 1 then + return false + end + until true + end + + return true +end + +-- Inizializzo contatori errori e avvisi +local nErrCnt = 0 +local nWarnCnt = 0 +local bOk = true +NEST.ERR = 0 + +-- resetto gruppo di lavorazione corrente +EgtResetCurrMachGroup() + +-- inizio nesting automatico +EgtAutoNestStart() + +-- lista dei grezzi +local RawParts = {} +-- creo tabella dei grezzi +for sIndex, dLen in pairs( LEN) do + RawParts[tonumber(sIndex)] = { Len = dLen} +end +for sIndex, dWidth in pairs( WIDTH) do + RawParts[tonumber(sIndex)].Width = dWidth +end +for sIndex, nQty in pairs( QTY) do + RawParts[tonumber(sIndex)].Qty = nQty +end +for sIndex, sMaterial in pairs( MATERIAL) do + RawParts[tonumber(sIndex)].Material = sMaterial +end + +-- +local vDoneManually, vPartsDoneManually = ComputeRestrictedZones( RawParts) + +-- creo grezzi e li aggiungo al nesting +AddRawParts(RawParts, vDoneManually) + +if not bOk then + EgtOutLog("Interruzione nesting") + NEST.ERR = 1 +end + +-- calcolo rotazioni e flip ed aggiungo pezzi al nesting +if bOk then + bOk = AddParts(RawParts, vPartsDoneManually) +end + +if not bOk then + EgtOutLog("Interruzione nesting") + NEST.ERR = 1 +end + +if bOk then + -- aggiungo offset tra pezzi + EgtAutoNestSetInterpartGap( NEST.OFFSET) + + -- Impostazione corner di inizio del nesting (NST_CORNER.BL, TL, BR, TR) + EgtAutoNestSetStartCorner( NEST.CORNER) + + -- Report dei dati di nesting per debug + EgtAutoNestSetReportFile( EgtGetTempDir() .. '\\LastNest.json') + + -- imposto tempo di nesting e lo avvio + EgtAutoNestCompute( true, NEST.TIME) +end + +-- Variabili di calcolo +local nNestedParts, nParts, nSheets, nNestings, dTotFillRatio +local bNestingOk = bOk +-- Attesa fine calcolo +local nTime = 0 +while bNestingOk do + bNestingOk, nStat = EgtAutoNestGetComputationStatus() + if nStat == 2 or nStat == 3 then + nNestedParts, nParts, nSheets, nNestings, dTotFillRatio = EgtAutoNestGetResults() + --EgtOutText( string.format( 'Parts : %d/%d Filling : %.2f%%', nNestedParts, nParts, 100 * dTotFillRatio)) + end + if nStat == 3 then break end + nTime = nTime + 1 + if EgtProcessEvents( nTime / NEST.TIME * 100, 995) == 1 then + bNestingOk = EgtAutoNestCancelComputation() + bOk = false + EgtOutLog("Interruzione nesting") + NEST.ERR = 1 + break + end +end + + +local dXCorr = 0 +local dYCorr = 0 +if NEST.CORNER == NST_CORNER.TL then + dYCorr = - 0.1 +elseif NEST.CORNER == NST_CORNER.TR then + dYCorr = - 0.1 + dXCorr = - 0.1 +elseif NEST.CORNER == NST_CORNER.BR then + dXCorr = - 0.1 +end + + +-- se nesting andato bene +if bNestingOk then + + -- disposizione sheet e parts + local SheetId = GDB_ID.NULL + local vtAdd = V_NULL() + local MachGroupList = {} + local nPartCount = 0 + local Sheet = {PartList = {}} + local bFirstSheet = true + for i = 0, 999 do + local nType, nId, nFlag, dX, dY, dAngRot = EgtAutoNestGetOneResult( i) + if not nType then break end + -- se sheet + if nType > 0 then + MachGroupList = {} + for MGIndex = 1, nType do + -- creo gruppo di lavorazione + local MachGroupName = NewMachGroupName() + local nMachGroup = EgtAddMachGroup(MachGroupName, sCurrMachName) + table.insert( MachGroupList, { MGId = nMachGroup}) + for nIndex = 1, #RawParts do + for nInd2 = 1, #(RawParts[nIndex].PartId) do + if RawParts[nIndex].PartId[nInd2] == nId then + EgtSetInfo(nMachGroup, "PANELLEN", RawParts[nIndex].Len) + EgtSetInfo(nMachGroup, "PANELWIDTH", RawParts[nIndex].Width) + EgtSetInfo(nMachGroup, "MATERIAL", NEST.MATERIAL) + EgtSetInfo(nMachGroup, "AUTONEST", 1) + -- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione + EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID) + EgtSetInfo( nMachGroup, "PATTID", nMachGroup) + end + end + end + + -- aggiungo pezzi nestati a mano + nPartCount = 0 + for nInd = 1, #vDoneManually do + if vDoneManually[nInd].SheetId == nId then + vDoneManually[nInd].Done = 1 + for nInd2 = 1, #(vDoneManually[nInd].Parts) do + nPartCount = nPartCount + 1 + local nPartDuploId = EgtDuploNew( vDoneManually[nInd].Parts[nInd2].Id) + + -- aggiungo le curve corrispondenti alle aree di lavorazione del pezzo + local sToolOutlines = EgtGetInfo( vDoneManually[nInd].Parts[nInd2].Id, "ToolOutlines", 's') + if sToolOutlines then + -- recupero o creo il gruppo per gli outlines + local nToolOutlinesGrp = EgtGetFirstNameInGroup( nPartDuploId, "ToolOutlines") + if not nToolOutlinesGrp then + nToolOutlinesGrp = EgtGroup( nPartDuploId) + EgtSetName( nToolOutlinesGrp, "ToolOutlines") + EgtSetStatus( nToolOutlinesGrp, GDB_ST.ON) + end + + for str in string.gmatch(sToolOutlines, "([^"..",".."]+)") do + EgtCopyGlob( tonumber(str), nToolOutlinesGrp) + end + end + + -- applico flip, rotazione e traslazione pezzo e box da nesting + EgtSetInfo( nMachGroup, "PART" .. nPartCount, nPartDuploId .. "," .. EgtNumToString( vDoneManually[nInd].Parts[nInd2].posX, 3) .. "," .. EgtNumToString( vDoneManually[nInd].Parts[nInd2].posY, 3) .. "," .. 0 .."," .. 0) + EgtSetInfo( nPartDuploId, "POSX", vDoneManually[nInd].Parts[nInd2].posX) + EgtSetInfo( nPartDuploId, "POSY", vDoneManually[nInd].Parts[nInd2].posY) + end + end + end + + + end + + -- altrimenti pezzo + else + nPartCount = nPartCount + 1 + for MGIndex = 1, #MachGroupList do + local nMachGroup = MachGroupList[MGIndex].MGId + --EgtSetCurrMachGroup(nMachGroup) + -- se c'e' un grezzo valido + if nMachGroup and nMachGroup ~= GDB_ID.NULL then + -- creo pezzo copia + local nPartDuploId = EgtDuploNew( nId) + -- applico flip e rotazioni fatte durante verifica posizionamento pezzo + -- local b3Part = EgtGetBBoxGlob( nPartDuploId, GDB_BB.STANDARD) + local nPartInd + -- for nInd = 1, #PartStates do + -- if PartStates[nInd].PartId == nId then + -- -- if PartStates[nInd].Flip then + -- -- EgtRotate( nPartDuploId, b3Part:getCenter(), X_AX(), 180, GDB_RT.GLOB) + -- -- end + -- -- if PartStates[nInd].Rotate and PartStates[nInd].Rotate > 0 then + -- -- EgtRotate( nPartDuploId, b3Part:getCenter(), Z_AX(), PartStates[nInd].Rotate, GDB_RT.GLOB) + -- -- end + -- nPartInd = nInd + -- end + -- end + + + + -- aggiungo le curve corrispondenti alle aree di lavorazione del pezzo + local sToolOutlines = EgtGetInfo( nId, "ToolOutlines", 's') + if sToolOutlines then + -- recupero o creo il gruppo per gli outlines + local nToolOutlinesGrp = EgtGetFirstNameInGroup( nPartDuploId, "ToolOutlines") + if not nToolOutlinesGrp then + nToolOutlinesGrp = EgtGroup( nPartDuploId) + EgtSetName( nToolOutlinesGrp, "ToolOutlines") + EgtSetStatus( nToolOutlinesGrp, GDB_ST.ON) + end + + for str in string.gmatch(sToolOutlines, "([^"..",".."]+)") do + EgtCopyGlob( tonumber(str), nToolOutlinesGrp) + end + end + + -- applico flip, rotazione e traslazione pezzo e box da nesting + if nFlag == 1 then + EgtRotate( nPartDuploId, ORIG(), X_AX(), 180, GDB_RT.GLOB) + end + EgtRotate( nPartDuploId, ORIG(), Z_AX(), dAngRot, GDB_RT.GLOB) + EgtMove( nPartDuploId, Vector3d( dX, dY, 0), GDB_RT.GLOB) + + local nBoxLayerId = EgtGetFirstNameInGroup( nPartDuploId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local PartBBox = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + local ptPos = Point3d( PartBBox:getMin():getX(), PartBBox:getMin():getY(), 0) + EgtSetInfo( nMachGroup, "PART" .. nPartCount, nPartDuploId .. "," .. EgtNumToString( ptPos:getX() + dXCorr, 3) .. "," .. EgtNumToString( ptPos:getY() + dYCorr, 3) .. "," .. 0 .."," .. 0) + EgtSetInfo( nPartDuploId, "POSX", ptPos:getX() + dXCorr) + EgtSetInfo( nPartDuploId, "POSY", ptPos:getY() + dYCorr) + + local nPartRot = EgtGetInfo( nId, "ROTATED", 'i') or 0 + local nTotRot = dAngRot + nPartRot + nTotRot = EgtIf( nTotRot < 360, nTotRot, nTotRot - 360) + EgtSetInfo( nPartDuploId, "ROT", nTotRot) + + local nPartFlip = EgtGetInfo( nId, "INVERTED", 'i') + nPartFlip = EgtIf( nPartFlip == 180, 1, 0) + local nTotFlip = EgtIf( nPartFlip ~ nFlag, 180, 0) + EgtSetInfo( nPartDuploId, "FLIP", nTotFlip) + + end + end + end + end + + -- creo gruppi di lavorazione per fogli con pezzi nestati solo a mano + for nInd = 1, #vDoneManually do + if vDoneManually[nInd].Done == 0 then + -- creo gruppo di lavorazione + local MachGroupName = NewMachGroupName() + local nMachGroup = EgtAddMachGroup(MachGroupName, sCurrMachName) + table.insert( MachGroupList, { MGId = nMachGroup}) + for nIndex = 1, #RawParts do + for nInd2 = 1, #(RawParts[nIndex].PartId) do + if RawParts[nIndex].PartId[nInd2] == vDoneManually[nInd].SheetId then + EgtSetInfo(nMachGroup, "PANELLEN", RawParts[nIndex].Len) + EgtSetInfo(nMachGroup, "PANELWIDTH", RawParts[nIndex].Width) + EgtSetInfo(nMachGroup, "MATERIAL", NEST.MATERIAL) + EgtSetInfo(nMachGroup, "AUTONEST", 1) + -- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione + EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID) + EgtSetInfo( nMachGroup, "PATTID", nMachGroup) + end + end + end + + -- aggiungo pezzi nestati a mano + nPartCount = 0 + for nInd2 = 1, #(vDoneManually[nInd].Parts) do + nPartCount = nPartCount + 1 + local nPartDuploId = EgtDuploNew( vDoneManually[nInd].Parts[nInd2].Id) + + -- aggiungo le curve corrispondenti alle aree di lavorazione del pezzo + local sToolOutlines = EgtGetInfo( vDoneManually[nInd].Parts[nInd2].Id, "ToolOutlines", 's') + if sToolOutlines then + -- recupero o creo il gruppo per gli outlines + local nToolOutlinesGrp = EgtGetFirstNameInGroup( nPartDuploId, "ToolOutlines") + if not nToolOutlinesGrp then + nToolOutlinesGrp = EgtGroup( nPartDuploId) + EgtSetName( nToolOutlinesGrp, "ToolOutlines") + EgtSetStatus( nToolOutlinesGrp, GDB_ST.ON) + end + + for str in string.gmatch(sToolOutlines, "([^"..",".."]+)") do + EgtCopyGlob( tonumber(str), nToolOutlinesGrp) + end + end + + -- applico flip, rotazione e traslazione pezzo e box da nesting + EgtSetInfo( nMachGroup, "PART" .. nPartCount, nPartDuploId .. "," .. EgtNumToString( vDoneManually[nInd].Parts[nInd2].posX, 3) .. "," .. EgtNumToString( vDoneManually[nInd].Parts[nInd2].posY, 3) .. "," .. 0 .."," .. 0) + EgtSetInfo( nPartDuploId, "POSX", vDoneManually[nInd].Parts[nInd2].posX) + EgtSetInfo( nPartDuploId, "POSY", vDoneManually[nInd].Parts[nInd2].posY) + end + end + end + + + -- creo grezzi per ogni gruppo di lavorazione + local MachGroupToTCnt = EgtGetMachGroupCount() + local MachGroupIndex = 0 + _G.WALL = {} + WALL.FILE = NEST.FILE + WALL.MACHINE = NEST.MACHINE + WALL.FLAG = 6 -- CREATE_PANEL + WALL.NESTING_REF = 'BL' + nMachGroup = EgtGetFirstMachGroup() + while nMachGroup do + EgtSetCurrMachGroup( nMachGroup) + if EgtGetInfo( nMachGroup, "AUTONEST",'i') == 1 then + MachGroupIndex = MachGroupIndex + 1 + EgtRemoveInfo( nMachGroup, "AUTONEST") + EgtSetInfo( nMachGroup, "UPDATEUI", 1) + dofile( EgtGetSourceDir() .. "BatchProcessNew.lua") + -- aggiorno interfaccia + EgtProcessEvents( 200 + ( MachGroupIndex / MachGroupToTCnt * 100), 0) + end + + -- ciclo sui duplo per sistemare Q + local nRawPartId = EgtGetFirstRawPart() + -- recupero box grezzo ridotto della tolleranza + local b3Raw = EgtGetRawPartBBox( nRawPartId) + b3Raw:expand( - WD.INSIDE_RAW_TOL) + EgtOutLog( 'RawBox='..tostring( b3Raw)) + + local nPartDuploId = EgtGetFirstPartInRawPart( nRawPartId) + while nPartDuploId do + local vPartProc = WE.CollectFeatures( nPartDuploId) + for ProcIndex = 1, #vPartProc do + local Proc = vPartProc[ProcIndex] + + if LapJoint.Identify( Proc) then + -- cerco la faccia rivolta verso l'alto e la faccia rivolta verso il basso + local nFaceInd = -1 + local nFaceDownInd = -1 + for nIdx = 0, Proc.Fct - 1 do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if vtN:getZ() > 0.95 then + nFaceInd = nIdx + elseif vtN:getZ() < - 0.95 then + nFaceDownInd = nIdx + end + end + -- se è lap joint dall'alto + if nFaceInd ~= -1 and nFaceDownInd == -1 then + local ptCen = EgtSurfTmFacetCenter( Proc.Id, nFaceInd, GDB_ID.ROOT) + -- se all'interno rimuovo info Q + if EnclosesPointXY( b3Raw, ptCen) then + -- resetto parametro Q + if Proc.Prc == 30 then + EgtRemoveInfo( Proc.Id, "Q08") + EgtRemoveInfo( Proc.Id, "Q08A") + else + EgtRemoveInfo( Proc.Id, "Q03") + EgtRemoveInfo( Proc.Id, "Q03A") + end + end + end + + elseif DoubleCut.Identify( Proc) then + -- verifico se due facce e rivolto verso l'alto + if Proc.Fct == 2 then + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + + if ( vtN[1]:getZ() >= 0.95 or vtN[2]:getZ() >= 0.95) then + local nFaceInd = EgtIf( vtN[1]:getZ() >= 0.95, 0, 1) + local ptCen = EgtSurfTmFacetCenter( Proc.Id, nFaceInd, GDB_ID.ROOT) + -- se all'interno rimuovo info Q + if EnclosesPointXY( b3Raw, ptCen) then + -- resetto parametro Q + if Proc.Prc == 12 then + EgtRemoveInfo( Proc.Id, "Q02") + EgtRemoveInfo( Proc.Id, "Q02A") + end + end + end + end + end + end + nPartDuploId = EgtGetNextPartInRawPart(nPartDuploId) + end + nMachGroup = EgtGetNextMachGroup(nMachGroup) + end + +else + EgtOutLog("Errore: nesting fallito") + NEST.ERR = 2 +end + +EgtResetCurrMachGroup() + + -- cancello rettangolo del materiale per nesting +for RawPartId = 1, #RawParts do + EgtErase(RawParts[RawPartId].PartId) +end + +local nOutlineGrp = EgtGetFirstNameInGroup(GDB_ID.ROOT, "ToolOutlines") +if nOutlineGrp and nOutlineGrp ~= GDB_ID.NULL then EgtErase( nOutlineGrp) end +local nSheetDefectsGrp = EgtGetFirstNameInGroup(GDB_ID.ROOT, "SheetDefects") +if nSheetDefectsGrp and nSheetDefectsGrp ~= GDB_ID.NULL then EgtErase( nSheetDefectsGrp) end + +-- EgtSaveFile( "C:\\EgtData\\EgtBEAMWALL\\Temp\\file.nge") + +EgtOutLog( ' +++ NestProcess completed') diff --git a/ProgettoRestylingWall/Wall/Overturn.lua b/ProgettoRestylingWall/Wall/Overturn.lua new file mode 100644 index 0000000..7edac61 --- /dev/null +++ b/ProgettoRestylingWall/Wall/Overturn.lua @@ -0,0 +1,32 @@ +-- Rotate.lua by Egaltech s.r.l. 2020/04/06 +-- Gestione ribaltamento di una Parete + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna parete selezionata', 'Overturn Parete', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la parete ' .. sName, 'Overturn Parete', 'ERROR') + return +end + +-- eseguo rotazione di 180 gradi attorno asse X +local ptRot = b3Solid:getMin() + Vector3d( 0, b3Solid:getDimY() / 2, b3Solid:getDimZ() / 2) +EgtRotate( nPartId, ptRot, X_AX(), 180, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgettoRestylingWall/Wall/Process.lua b/ProgettoRestylingWall/Wall/Process.lua new file mode 100644 index 0000000..c4ad254 --- /dev/null +++ b/ProgettoRestylingWall/Wall/Process.lua @@ -0,0 +1,309 @@ +-- Process.lua by Egaltech s.r.l. 2021/07/27 +-- Gestione calcolo disposizione e lavorazioni per Pareti +-- Si opera sulla macchina corrente +-- 2020/12/09 Come per BatchProcess.lua si gestiscono anche rotazioni di inversione con valori negativi. +-- 2021/10/27 Come per BatchProcess.lua nel controllo spessore si deve considerare anche PosY. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti +local sMachDir = EgtGetCurrMachineDir() +if not sMachDir then + EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Pareti', 'ERROR') + return +end +if not EgtExistsFile( sMachDir .. '\\Wall\\WallData.lua') then + EgtOutBox( 'La macchina corrente non è configurata per lavorare pareti', 'Lavora Pareti', 'ERROR') + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua') + +-- Segnalazione avvio +EgtOutLog( '*** Wall Process Start ***', 1) + +-- Carico le librerie +_G.package.loaded.WallExec = nil +local WE = require( 'WallExec') +local WL = require( 'WallLib') + +-- Carico i dati globali +local WD = require( 'WallData') + +-- Variabili di modulo +local vWall = {} +local dRawH + +------------------------------------------------------------------------------------------------------------- +-- *** Recupero le pareti selezionate *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessInputData() + + -- Recupero le travi selezionate + local nId = EgtGetFirstSelectedObj() + while nId do + local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) + if nPartId then + local bFound = false + for i = 1, #vWall do + if vWall[i].Id == nPartId then + bFound = true + break + end + end + if not bFound then + table.insert( vWall, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + end + nId = EgtGetNextSelectedObj() + end + if #vWall == 0 then + EgtOutBox( 'Non sono state selezionate pareti', 'Lavora Pareti', 'ERROR') + return false + else + local sOut = '' + for i = 1, #vWall do + sOut = sOut .. vWall[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Pareti selezionate : ' .. 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 + EgtOutBox( 'Box non definito per la parete ' .. vWall[i].Name, 'Lavora Pareti', 'ERROR') + return false + else + vWall[i].Box = b3Solid + end + end + + -- Ne recupero la posizione + local CurrX = 50 + for i = 1, #vWall do + local PosX = EgtGetInfo( vWall[i].Id, 'POSX', 'd') or CurrX + vWall[i].PosX = PosX + CurrX = CurrX + vWall[i].Box:getDimX() + 50 + if WD.USE_POSY then + local PosY = EgtGetInfo( vWall[i].Id, 'POSY', 'd') or 0 + vWall[i].PosY = max( PosY, 0) + else + vWall[i].PosY = 0 + end + local PosZ = EgtGetInfo( vWall[i].Id, 'POSZ', 'd') or 50 + vWall[i].PosZ = PosZ + end + + -- Recupero informazione se progetto o produzione + local bProj = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PROJECT', 'i') == 1) + + -- 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 then + if abs( dRotAng) > GEO.EPS_ANG_SMALL and not EgtExistsInfo( vWall[i].Id, 'ROTATED_DONE') then + local ptRotCen = b3Solid:getCenter() + EgtRotate( vWall[i].Id, ptRotCen, X_AX(), dRotAng, GDB_RT.GLOB) + b3Solid:rotate( ptRotCen, X_AX(), dRotAng) + end + EgtSetInfo( vWall[i].Id, 'ROTATED_DONE', dRotAng) + end + -- inversione + local dInvAng = EgtGetInfo( vWall[i].Id, 'INVERTED', 'd') + if dInvAng then + if abs( dInvAng - 180) > GEO.EPS_ANG_SMALL and abs( dInvAng + 180) > GEO.EPS_ANG_SMALL and not EgtExistsInfo( vWall[i].Id, 'INVERTED_DONE') then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vWall[i].Id, ptInvCen, Z_AX(), dInvAng - 180, GDB_RT.GLOB) + b3Solid:rotate( ptInvCen, Z_AX(), dInvAng - 180) + end + EgtSetInfo( vWall[i].Id, 'INVERTED_DONE', dInvAng) + end + -- correzioni per rotazioni non centrate di produzioni TS3 (quasi sempre multipli di 90 deg) + local sType = EgtGetInfo( vWall[i].Id, 'TYPE', 's') + if not bProj and dRotAng and dInvAng and sType ~= 'LAYER' then + if abs( dInvAng - 0) < GEO.EPS_ANG_SMALL then + if abs( dRotAng - 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + end + elseif abs( dInvAng - 90) < GEO.EPS_ANG_SMALL or abs( dInvAng + 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + if abs( dRotAng - 180) < GEO.EPS_ANG_SMALL or abs( dRotAng + 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL or abs( dRotAng + 90) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + end + elseif abs( dInvAng - 180) < GEO.EPS_ANG_SMALL or abs( dInvAng + 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + if abs( dRotAng - 0) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL or abs( dRotAng + 90) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 90) < GEO.EPS_ANG_SMALL or abs( dRotAng + 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + end + elseif abs( dInvAng - 270) < GEO.EPS_ANG_SMALL or abs( dInvAng + 90) < GEO.EPS_ANG_SMALL then + if abs( dRotAng - 0) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + end + end + end + end + + -- Ne verifico le dimensioni + dRawH = vWall[1].Box:getDimZ() + vWall[1].PosY + local vWallErr = {} + for i = 2, #vWall do + local dDimH = vWall[i].Box:getDimZ() + vWall[i].PosY + 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' + EgtDeselectPartObjs( vWall[vWallErr[i]].Id) + table.remove( vWall, vWallErr[i]) + end + EgtOutLog( sOut, 1) + EgtOutBox( sOut, 'Lavora Pareti', 'INFO') + EgtDraw() + return false + end + EgtDeselectAll() + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle pareti nel grezzo *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessWalls() + + -- Ingombro totale delle pareti + local b3Tot = BBox3d( ORIG()) + for i = 1, #vWall do + 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( dBoxL + 0.05, 1) .. ', Wtot=' .. EgtNumToString( dBoxW + 0.05, 1) .. ')', + {'Lunghezza grezzo', EgtNumToString( dPanelLen, 1)}, + {'Larghezza grezzo', EgtNumToString( dPanelWidth, 1)}) + if not vsVal then + EgtDraw() + return + end + local dRawL = EgtEvalNumExpr( vsVal[1]) + if not dRawL then + local sOut = 'Lunghezza grezzo errata : ' .. vsVal[1] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Pareti', 'WARNING') + EgtDraw() + return false + end + dRawL = min( dRawL, WD.MAX_LENGTH) + local dRawW = EgtEvalNumExpr( vsVal[2]) + if not dRawW then + local sOut = 'Larghezza grezzo errata : ' .. vsVal[2] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Pareti', 'WARNING') + EgtDraw() + return false + end + dRawW = min( dRawW, WD.MAX_WIDTH ) + + -- 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)..') ' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Pareti', 'WARNING') + EgtDraw() + return false + 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)..')' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Pareti', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo le pareti nel grezzo + return WE.ProcessWalls( dRawL, dRawW, dRawH, vWall) +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessFeatures() + + local bOk, Stats = WE.ProcessFeatures() + local nErrCnt = 0 + local nWarnCnt = 0 + local sOutput = '' + for i = 1, #Stats do + if Stats[i].Err > 0 then + nErrCnt = nErrCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + elseif Stats[i].Err < 0 then + nWarnCnt = nWarnCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + end + end + if #sOutput > 0 then EgtOutLog( sOutput) end + if nErrCnt > 0 then + EgtOutBox( sOutput, 'Lavora Pareti', 'ERRORS') + EgtDraw() + return false + elseif nWarnCnt > 0 then + EgtOutBox( sOutput, 'Lavora Pareti', 'WARNINGS') + EgtDraw() + return true + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Esecuzione *** +------------------------------------------------------------------------------------------------------------- +if not MyProcessInputData() then return end + +if not MyProcessWalls() then return end + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +if not MyProcessFeatures() then return end diff --git a/ProgettoRestylingWall/Wall/Rotate.lua b/ProgettoRestylingWall/Wall/Rotate.lua new file mode 100644 index 0000000..e12c7af --- /dev/null +++ b/ProgettoRestylingWall/Wall/Rotate.lua @@ -0,0 +1,31 @@ +-- Swap.lua by Egaltech s.r.l. 2020/04/06 +-- Gestione rotazione nel piano di una Parete + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna parete selezionata', 'Rotate Parete', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la parete ' .. sName, 'Rotate Parete', 'ERROR') + return +end + +-- eseguo rotazione di 90 gradi attorno asse Z +EgtRotate( nPartId, b3Solid:getCenter(), Z_AX(), 90, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgettoRestylingWall/Wall/Wall.ini b/ProgettoRestylingWall/Wall/Wall.ini new file mode 100644 index 0000000..6b018dd --- /dev/null +++ b/ProgettoRestylingWall/Wall/Wall.ini @@ -0,0 +1,8 @@ +[Wall] +BtlEnable=1 +BaseDir=C:\EgtData\Wall +BtlExec=BatchProcess.lua +Button1=Process.lua,Images\Process.png,Lavora Pareti +Button2=Rotate.lua,Images\Rotate.png,Ruota Parete +Button3=Overturn.lua,Images\Overturn.png,Ribalta Parete +Button4=WallMachinings,Images\WallMachinings.png,Lista lavorazioni diff --git a/ProgettoRestylingWall/btl_v105.pdf b/ProgettoRestylingWall/btl_v105.pdf new file mode 100644 index 0000000..bb56514 Binary files /dev/null and b/ProgettoRestylingWall/btl_v105.pdf differ diff --git a/ProgettoRestylingWall/btl_v106.pdf b/ProgettoRestylingWall/btl_v106.pdf new file mode 100644 index 0000000..cd6c379 --- /dev/null +++ b/ProgettoRestylingWall/btl_v106.pdf @@ -0,0 +1,11816 @@ +%PDF-1.4 +% +1 0 obj +<< +/ModDate (D:20220504113015+02'00') +/Producer (PDF-XChange 4.0.209.0 [Lite] \(Windows \(Build 9200\)\)) +/CreationDate (D:20190716093112+02'00') +/PXCViewerInfo (PDF-XChange Viewer;2.5.214.2;Feb 17 2014;20:31:41;D:20220504113015+02'00') +>> +endobj +2 0 obj +<< +/Type /Catalog +/Pages 3 0 R +/Metadata 4 0 R +/Outlines 5 0 R +/PageMode /UseNone +/PageLayout /SinglePage +/ViewerPreferences << +/DisplayDocTitle true +>> +>> +endobj +3 0 obj +<< +/Kids [6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R +22 0 R 23 0 R 24 0 R 25 0 R 26 0 R 27 0 R 28 0 R 29 0 R 30 0 R 31 0 R 32 0 R 33 0 R 34 0 R 35 0 R 36 0 R 37 0 R +38 0 R 39 0 R 40 0 R 41 0 R 42 0 R 43 0 R 44 0 R 45 0 R 46 0 R 47 0 R 48 0 R 49 0 R 50 0 R 51 0 R 52 0 R 53 0 R +54 0 R 55 0 R 56 0 R 57 0 R 58 0 R 59 0 R 60 0 R 61 0 R 62 0 R 63 0 R 64 0 R 65 0 R 66 0 R 67 0 R 68 0 R 69 0 R +70 0 R 71 0 R 72 0 R 73 0 R 74 0 R 75 0 R 76 0 R 77 0 R 78 0 R 79 0 R 80 0 R 81 0 R 82 0 R 83 0 R 84 0 R 85 0 R +86 0 R 87 0 R 88 0 R 89 0 R 90 0 R 91 0 R 92 0 R 93 0 R 94 0 R 95 0 R 96 0 R 97 0 R 98 0 R 99 0 R 100 0 R 101 0 R +102 0 R 103 0 R 104 0 R 105 0 R 106 0 R 107 0 R 108 0 R 109 0 R 110 0 R 111 0 R 112 0 R 113 0 R 114 0 R 115 0 R 116 0 R 117 0 R +118 0 R 119 0 R 120 0 R 121 0 R 122 0 R 123 0 R 124 0 R 125 0 R 126 0 R 127 0 R 128 0 R 129 0 R 130 0 R 131 0 R 132 0 R 133 0 R +134 0 R 135 0 R 136 0 R 137 0 R 138 0 R 139 0 R 140 0 R 141 0 R] +/Type /Pages +/Count 136 +>> +endobj +4 0 obj +<< +/Type /Metadata +/Length 2827 +/Subtype /XML +>> +stream + + + + + 2019-07-16T09:31:12+02:00 + 2022-05-04T11:30:15+02:00 + + + PDF-XChange 4.0.209.0 [Lite] (Windows (Build 9200)) + + + application/pdf + + + + + + + + + + + + + + + + + + + + + + + + + +endstream +endobj +5 0 obj +<< +/Last 142 0 R +/Count 26 +/First 143 0 R +>> +endobj +6 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [144 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +7 0 obj +<< +/Type /Page +/Annots [146 0 R 147 0 R] +/Parent 3 0 R +/Contents [148 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +8 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [149 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +9 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [150 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +10 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [151 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +11 0 obj +<< +/Type /Page +/Annots [152 0 R 153 0 R 154 0 R 155 0 R] +/Parent 3 0 R +/Contents [156 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +12 0 obj +<< +/Type /Page +/Annots [157 0 R 158 0 R 159 0 R 160 0 R 161 0 R 162 0 R 163 0 R 164 0 R] +/Parent 3 0 R +/Contents [165 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +13 0 obj +<< +/Type /Page +/Annots [166 0 R 167 0 R 168 0 R] +/Parent 3 0 R +/Contents [169 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +14 0 obj +<< +/Type /Page +/Annots [170 0 R] +/Parent 3 0 R +/Contents [171 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +15 0 obj +<< +/Type /Page +/Annots [172 0 R 173 0 R 174 0 R 175 0 R 176 0 R 177 0 R 178 0 R 179 0 R 180 0 R 181 0 R] +/Parent 3 0 R +/Contents [182 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +16 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [183 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +17 0 obj +<< +/Type /Page +/Annots [184 0 R 185 0 R 186 0 R 187 0 R 188 0 R 189 0 R] +/Parent 3 0 R +/Contents [190 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +18 0 obj +<< +/Type /Page +/Annots [191 0 R 192 0 R 193 0 R 194 0 R 195 0 R 196 0 R 197 0 R 198 0 R 199 0 R 200 0 R 201 0 R 202 0 R 203 0 R 204 0 R 205 0 R 206 0 R] +/Parent 3 0 R +/Contents [207 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +19 0 obj +<< +/Type /Page +/Annots [208 0 R 209 0 R 210 0 R 211 0 R] +/Parent 3 0 R +/Contents [212 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +20 0 obj +<< +/Type /Page +/Annots [213 0 R 214 0 R] +/Parent 3 0 R +/Contents [215 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +21 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [216 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +22 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [217 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +23 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [218 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +24 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [219 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +25 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [220 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +26 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [221 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +27 0 obj +<< +/Type /Page +/Annots [222 0 R 223 0 R] +/Parent 3 0 R +/Contents [224 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +28 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [225 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +29 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [226 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +30 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [227 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +31 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [228 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +32 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [229 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +33 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [230 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +34 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [231 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +35 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [232 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +36 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [233 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +37 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [234 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +38 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [235 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +39 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [236 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +40 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [237 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +41 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [238 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +42 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [239 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +43 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [240 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +44 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [241 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +45 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [242 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +46 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [243 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +47 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [244 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +48 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [245 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +49 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [246 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +50 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [247 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +51 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [248 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +52 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [249 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +53 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [250 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +54 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [251 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +55 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [252 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +56 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [253 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +57 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [254 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +58 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [255 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +59 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [256 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +60 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [257 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +61 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [258 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +62 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [259 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +63 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [260 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +64 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [261 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +65 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [262 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +66 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [263 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +67 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [264 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +68 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [265 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +69 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [266 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +70 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [267 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +71 0 obj +<< +/Type /Page +/Annots [268 0 R 269 0 R 270 0 R 271 0 R] +/Parent 3 0 R +/Contents [272 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +72 0 obj +<< +/Type /Page +/Annots [273 0 R 274 0 R 275 0 R] +/Parent 3 0 R +/Contents [276 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +73 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [277 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +74 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [278 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +75 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [279 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +76 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [280 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +77 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [281 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +78 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [282 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +79 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [283 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +80 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [284 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +81 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [285 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +82 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [286 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +83 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [287 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +84 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [288 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +85 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [289 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +86 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [290 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +87 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [291 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +88 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [292 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +89 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [293 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +90 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [294 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +91 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [295 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +92 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [296 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +/F2 297 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +93 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [298 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +94 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [299 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +95 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [300 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +96 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [301 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +97 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [302 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +98 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [303 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +99 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [304 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +100 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [305 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +101 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [306 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +102 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [307 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +103 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [308 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +104 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [309 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +105 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [310 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +106 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [311 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +107 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [312 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +108 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [313 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +109 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [314 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +110 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [315 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +/F3 316 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +111 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [317 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +112 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [318 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +113 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [319 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +114 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [320 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +115 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [321 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +116 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [322 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +/F2 297 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +117 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [323 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +118 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [324 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +119 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [325 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +120 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [326 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +121 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [327 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +122 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [328 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +123 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [329 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +124 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [330 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +125 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [331 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +126 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [332 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +127 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [333 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +128 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [334 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +129 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [335 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +130 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [336 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +131 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [337 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +132 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [338 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +/F2 297 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +133 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [339 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +134 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [340 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +135 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [341 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +136 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [342 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +137 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [343 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +138 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [344 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +139 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [345 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +140 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [346 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +141 0 obj +<< +/Type /Page +/Parent 3 0 R +/Contents [347 0 R] +/MediaBox [0 0 595.2 841.919] +/Resources << +/Font << +/F1 145 0 R +>> +/ProcSet [/PDF /Text] +>> +>> +endobj +142 0 obj +<< +/Dest [24 0 R /XYZ 0 791.643269 null] +/Last 348 0 R +/Prev 349 0 R +/Count 14 +/First 350 0 R +/Title (6. Description of processing) +/Parent 5 0 R +>> +endobj +143 0 obj +<< +/Dest [8 0 R /XYZ 0 795.550937 null] +/Next 351 0 R +/Title (1. Hystory) +/Parent 5 0 R +>> +endobj +144 0 obj +<< +/Filter [/FlateDecode] +/Length 5938 +>> +stream +x]K$ׯ+أc/k7b;0c%-/_DYU]]-Yㄠb>F/zGSÿ>bݟ;.ٖrtKc*v!ngjSÿV3|j}m9yqin;L/dfja]nO8SRKy89Vfb[Z\v7Oy.õm{ Ƨ3b=vεXL/:?Vp踫è%ϝ :k6ɛNdtM][v3uع$*j.7F@Z^5R6S{Hk({#q9T^zDS]48@fRXY*46d&'(XPmq2ŵjbnXZ,K]3Y-bKvM"_"Dފ~O6Wf,^sr( 5]׹i$Ldfq{/Te>`˼p=(yghrOW.ihAV(alq! '"YO,:x"pmHm(OVmHafdA ++<C&5f#ebZbd&g0T3f&a*+CLc)PS*,( P9(,jd$].mјR1=cg]otAM|tКJZb M"2qfh"=EڴK3 g1U˅fBS[iu!ܠҪqvpVc᥷SdE3eVl$!&)%u^̈́p]-47#*ˏ)LYiO,}sv8Ư/E {J]~)460BsbP& P?Wad}(WMYQ٠H.dIƊּ D֓(6A"ܵ$q7FY,lزQ@]j$jS7YMZ+O.fI':BcyUqd:{N4&^ bh| L4==K3n$߆AԅT[+.⻈"eB1èT)W!'F:Ѽ\/+x9`4DM"%oKj:cFFF)/22d$oCmIp /`nq4'hc坣dɮ\đ1.SS]@ir%YFL0 4`|/~\jb/ٳl),w%?>JT+m2@4'L h ZHgˡ!133i4U8gۀ/9 uKb.[ F b1LJ}قe +)9a}d5ElZ +tVJ%F\,ii| AA5)Fb)gsYj0)[(hP!n3 Avk(%XlEQ3u3\#.ŞěMWw3#VO:b岩6Qb^D)%AjԓA$o48F3̴h_*Eih5qcIA;D@G,5=ٍ$}7O|>g GliA=ӱAZ33f["(-BI^<ݟ~X'`\L4CːEYy_{ ( u!J}!IęC-1oitv5*Ι&DdMjcg$,;D$uCiG^+r$]MuQ9rJv-kG$g@0pOL(ؔe=@&EIi!'>cA#Q锪Ie~5!7o 5DL|rDb]ӡM6T)YR,qjp*VPiJU +*=pjpAd"=|TI<%t1EΐH #͓ )iqpGܘɚbZ5T\^-rwv +Ai'Kxtw @KSY`G!#cq˦G~}xCeHKw&0CtSᤴ1vޙ, >~Ļ׷E s+_.r\Sqe_mw5w+~#[.J?̕A_hÍ18|۹ʋ16!6uVcŭcGͰ?=Ky^%Sdqu#dF=AYUc Rc8>3I8N<CO1I4_̨̄t0r)Kq3+NJCpxz.cn<;FCΎ1' 㔤~jl\PƚvvU#cc9篍'b -X;L~~iy KJ-rШ]?P0E4Gw- BHXo\9\rhX[c98x$ $sa# =>BOl#+<T.;:01сqpFC[kz)B؛( |!Mt {xk0@/ q *qv!P +t]1*lhU Q a.xŦ8[X'Z4bQ +g!v"AD2_+r]|CpEt .Vhf<Y FZc,@a,`u$p V  +' + . +VY/p7 +>6d]wK >rr |ntZVgW@@ +B@=eW J '/XEcik>8t &990Ft51B*+xwx! ! `ӯ}&>]V +x) W+5OυpknGW0+kD~"o`JtF^?JHz/;A^-?LVw 2зf?d]*v@A9C`d6Znlph1.o2|:0uzØB +F% #B#7N8/&A7 v1*tCYw?'M'{n(n<(e_']ٹj窗s"y+yig@Do(@p01U-5b!ͧ+X1w,no4b t !? @u®vp_684+$ ?`aa1 % + .[(eaad@XX!rR p`gꝩ@g^kFT VG͠P`Zx[^ 4d'myMx$hcv5w3"~5"bȳ 7lTw+c @1,kߌe=Gl'OE ln7oGoTBurS> +endobj +146 0 obj +<< +/C [0.752942 1 1] +/F 4 +/M (D:20220326175703+01'00') +/P 7 0 R +/T (Utente) +/AP << +/N 353 0 R +>> +/NM (0daaddd7-7da5-4910-8d40acebb85be2d6) +/Rect [92.110679 331.996216 391.408716 345.54599] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [94.8 345.546 388.7194 345.546 94.8 331.996219 388.7194 331.996219] +/CreationDate (D:20220326175703+01'00') +>> +endobj +147 0 obj +<< +/C [0.752942 1 1] +/F 4 +/M (D:20220326175718+01'00') +/P 7 0 R +/T (Utente) +/AP << +/N 354 0 R +>> +/NM (e8db7459-9d75-4253-8a188dd6e6caffcf) +/Rect [92.110679 303.676209 532.545016 331.385987] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [200.732526 331.386 529.855709 331.386 200.732526 317.836219 529.855709 317.836219 94.8 317.226 430.850606 317.226 94.8 303.676219 430.850606 303.676219] +/CreationDate (D:20220326175718+01'00') +>> +endobj +148 0 obj +<< +/Filter [/FlateDecode] +/Length 1897 +>> +stream +x}Wێ|W4D+;x l`+EiH-IY|})j#D}.u\ʚ]Wa% +/˻4 +yDy]X>-^qqiis[-_l}bϫJIPw:lU`l.$wUAU>vX~yijdZ l)}Ģz[I8;~OO5ޜhPV7ԣƄ{ۙ( -vAI>Ô98fhRd=}iN]?1īZ +Ll7vOnw|֌* 2h*;t]FDi;@Oe9~R̕y"zͯĹU3}圅)B0UF/ZAEȱh--3fE0_ @\ȵ^_5Ɩ8̕(*C +Dy'a߉t#2YM ofd#[R:KOݨ'}A9V_^Gkw,Br +0BD +Q.33 @Bt"[0C~UDgAYc$G?]n'VQ1O_285>sUA9eNsx;qRMu#YW0uGE$Ի9\A(kNkIۺ )HG|V&ljf?'QIǶZd$>ަyҷEd.Ú +NT:ʕtfO &N"nrq*x9syLODEw(3+~5n8h xXqf`%Tw$\Mg)j)H6 v=)K;l$hTG@{t'LTa!Wz2*^++'ovb)0ЋH`hvg8M-K,x!97 \*EgPӎjZY"1ǐE 2tjz}x.ΠlsTfM^k]޹eubQ\Dv)t|]?R'U#mC ^с8Wɜ8wS:NيTHX\Cj]k +> +stream +xZYs۶~ׯ䉚Z4Ig%Kv\[]>$H캿\͝q$w,_=8=J=8{Hד,WF ^ >σȋ\% _fE$n"ҍ 7?A?qQ<.0fa⻞h%U%/IMB3>cw<Ά'}ݫ r9!]eΘ r pPЉ1#D0 B\/\)C}<Wt97v*΀ @Jh!?9c{ɦ,W 2XIۀ<׀`7J$j,+p٤眦៰/p0vE&r.sq6FiZGRsGt +X=Hfv1n &{E^.@an$z)b.iUrHO[aMb>B~E'u6*(d?3+pfꑑMNV\H#vrҪ|"_9De_Q3m.c=#UڂȐ.yfՆ7а؎SHY//E&/%hU*5) O5Aϳ(ur[#z2Z2Č`'b , %^f3EVk$X8$RDjnJ*Z9ɦ#2 rl:! scYF+EK!%hhq+vehςx CUqˇ9O*c5IW䋳4,.lh JkbgĐI=[usl%nP[!q+i(4J툽)$jJZye^581] jb|J?Xdbp{Yu;h',Vϐ_=|źƹMEg\̧{HMY`F"}b@,d?B{&iMJ㺩Q?>`$n_` blhB>`ñLu(BJ:%MhI:{GS"x|Q,( ٕӞ xh +N_I[Jn{L3E%ncmya:Ի#ۯ[t&huʺz"LD{ɚzըASVM &|u2cv@?s +EJ?s.b7/&;ޙ8uoؾfK6|X +AY fTYГG_7X@S v|O~6  cNVoZ۰jyo*#9-,#M.ClUlc\X t s0އ[ew6x[*~WŊ_CvYg$A <-,q`fWxbmTҙ!C-6]*l~(LE|z^ҺRcԦ߈+ZՆy:hM?n)Q"z֘RKı|iw Xk?~2;3ݫO=fRfz&__uJa&B]Qazi(۩Gu6F\;ZJn?}Эl/7l?Sv*}wjU|uW4*ѕ4|K2 6jҋ\~"MK&:1"<ͨTuJ `#AVN 98ak*'Ōd68ԡ{`K x_e:AxG#$tE_ +jTN9o2W9ST4&]D#ސ!&c),fbyBU}8*6Q֙D8k~9%wvz=~F{#r^*JUdUoL:@-c \,l S(ˑX?ay{8'QAZN/a` o4gMm} NHS_ Ck\EV#Ct(vv~F_/?'$Rosy-KSp!4k]#@b#޻г7g p 4 ,ְ0y?d6q H1ŸbG'F{}i_Cq)p#f%N#+kooj1UǛtt ;tv=CblVf5q9*N4ϐo}#E[e=6ceL!0mx?hҁw!v4e_0c[ANݡʦ~lExgqĴw[~MOgI]74FFo,S9(R!], +ԲJw(P+kgdlka46UKv$/Hd>u{G,.)k3m51@ʽڅ&4/pF,OmMCVlYuY- x(EFm፟4)oK6$w0,?ğ8# r"|4&IB?] {?S +endstream +endobj +150 0 obj +<< +/Filter [/FlateDecode] +/Length 3645 +>> +stream +xZr+f VhfNYdYT9Y@$(!&"+_O5z٫[p=ݧODz:)'߅qJfj*'Ta *R>z1~9\O'/o %?4ܗ`JW/җoC^4jgX櫢wJQ9쳪j)60'/ogzD<ɻq]`FvN+XV.ڻ%}* &ZzMF+_Ш\C KU0$QJ,X8%Elmy`4'pUFcSX,V Q'ʡ;|kנgd5M(2ܢ͗bQmuW |Hw%j~}4YQ.` 쩵fϣ%mAɊhLRdd즪ۢpRr9%d8i(aD RZwP% _dߧ["Y7R[l0$`"ozNv#[+}˱/ mVWS8y݈TNz%1wq䢹CuQmuolΑ9@a5rkqqpv< +V!|ʜ"ŗ;]h\Mw +C&g);Nѽ߉rfb0%?~()MtߣJcqN +.cLCfQ$Y +ih 5lTm*>_Yө2.=<[Tr9i%~ !Fl }>s[@uA1[ jA6- >%F F'ףmplkBi +[Åt{Y +)b$(0oczH .LKG[iCqaWe dKܖ =1CލQ: La8g1u0#EXCm{0 j +R`̗W1hiS0XL4rX(;*@?T^$48qtDRd#OG1p$ q)o0!ـS!X#\->A\růNRx F}$(p`K.&[ܠeޭwݫhH tjG@m1.GR΁fN_WdW#H497z$ ^|$#l Uۻݨ]#u)~e :pZiwh{S4Ĭljrs!kwZ|D.p(#RXVOɳ%I O]lПdbMF"Hҗ\.|d;P21%f|r2%2tlI܄j'8CN| KJ3iJ#K:d-aSϚr5gO-ۅ/j=&̨3'Wxr2gm+r%ZdX;oO +bG+|tc 9`4,H R nMh-64 aǙa+e!>aϓBLƷB1}GX(22`cJ=D0H7HЏL;BˉcLJa4a[oy_tCb64_=1~X_QM_G&Fo!hNҀ?{2Ma3VT;$7Ÿ+=^?B# <}B_awpvyy~pGd9cvqɁAX1u^'SE0bSGshC[qLb3PTtV^C[OU!a>YZJj@Rly",K>fW}v)8;frsJxPG}ct|JaT>}Gݎ`+"C&``B!i8G(?fP`]qܿ*F\|Hy-I)O;u#T|c&6Z.ugT`6Dy +$/J@p(*KʁIrPߋK^8ݠkC4!աcmHʈ P5 Bz[WwP4Y'WL0}'R1uEO3%rȹY3 uxQv0֌.v3F¡B8HM8(Y˃=UGKq^7TBwt!<ǧs[EO{I;rs! >!ODĴ$d&%N`S&z|X'Ss,!P!~H+ Pj F^iʎ9by$37tm}dW2+aڜEB$?MY9F#z<3~vyr4{"m7›K~wCj)$YUxׇwYIX6˽Xגna'6ۭ'$.7?ؤJY#ibjb>cc;=9À={^Vqhg+sڸHkbT۹{l* m>: +ڄI@ѓV~1>LH&Ǘ OZXrIӶǽz:2_:d{e^IҠkMk~Uy)hn]o4*V,2@B6d +dl`l"E{r+~kӣp'ܿq(Fn^h'4_Ex)]R1MMP4t@nM^* Wxl +|&(=nkMadk[mR%#'Nk]?x;ʌDC{&vm/YkZZVFϚe0;`ziovǓ|W +endstream +endobj +151 0 obj +<< +/Filter [/FlateDecode] +/Length 3596 +>> +stream +xZnF}W4,;G3@S E*K"e 0fwUuթSu j`+8}٦c L;h^ <[:oG ᇌHF7:çb6, $7tLxKN?H5<}l'"<Ñ )qLˍpZ0 l|%HSq9١Qu9D<[1Oc^Rh1iTiUdYUU*J2qYVU }3tTti(ńnJL ehH?`a:ۉ"Q\($Y. &cY۲&$C<%i+t5 gJnmy:LkJUNI}"qU,6uUP@x&Zjh'wJBT\:R +ܼ%xs]Vznj +Fe*Pzp"PI9i.-?ׄnHt辞QT+2.`p6T( No`8.VIUV?ny Q~]ݬqƟ5ܦO"*{bbr)h:#_f_&!҉13t\FWDH>ڞe|OΌ*?_aZrg-(4gNSٞ55:--˔~H:UVw)3Ε1Kb.6FOl {;u^ ]^ LPw4˄\Tn0^;1)llp +ˤ-oݧqCI Bz, +@]Z|_fE2/$Ѯ1e@x[r2|^ZPJ2&*b\ϩGE0P- XqƪRQ/qdB4۰{x1{;4}u ܥm±B +i%|a<==ѓY&m_tKlz궣y3JaQ_StW蟄Rl6ykAA(6?O)+ȀcBc>Cе!Xka@ OwX = 9_] !!N}9\l sf%BAިGsfhܶgBԥX4Tʈ^HG&[nUmpÆ 8/dJɄ^tJdO@,BZ8䅻6_^״zFZ4tЃG,*bkm׬(9Sn;G<4F!"c(* u$^Vç^RSuCu?j'|!@_.8`^⨖Z+ H6DZ1,hrWSǴkܝ |l+LdY]"Óg4ix41cc0=V\`Ѹ.bAԴKt ~" +)d(ZvMqb~DVzCR:[҇ߠ8OO,_̙#\LXdǷil˝x}_j U )tZH 3Ժ*F9w-;SRR|?~jhaq܆aɰrcv)4?d7H~}\0{⡎s񷴎n70(߸_RXSF! kj6p;ÀTeIXZAES[2]P*F1kXEȳ.ūFܔ[Wf5轼7udτ1B!k]=`*u Drtenu6YB4H(];m{eKN-_޺J7iQ5{.++qhxlū>6oҢs.r6lk;LOאYJ$.U'vء9R#!~i փ Xv]+[H1!YN}>7;m\P 9TTXqSUrNA<Ī3?@WzmYds◡A'fvžb}uxt +ě1θ`6 +4'fzؖgXBޜ|$<"?Tg| @$(("$ß0 D +(r,Kɨ&a75~</*H=Oϯgƙ@*O߰&\4mmego}=[T7PpCZK "dfׁ[] Uj%dG DWZT٭**<PmE(p+RMX\5)* ;~uO9]q&s fn0Wܮ*.Z Ɔ+%|kbוuib2-jTEH\&&eYqn3jǭ:]|{6ߧoejm#K(ZaS4&kv!;҂d'-&B+ys S1T6*41(C:'@bX\5ۊmgFPc|k;,{If[Gqǝb{|N}:e~ Ӌ"g+%m,3%it٢Wq$^]: ;=?-m Ap]SLui7_y6~Bᩴ5I5{@ 0 3~칬o)H ~rCt;+GW6@ӵAԵBԢA_ մ?m_s [l:ZʈfGn;i|x8e> +/NM (87497d9b-6178-4a4b-84eed72317b51a52) +/Rect [322.053274 284.193512 522.280018 295.210999] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [324.24 295.211001 520.093295 295.211001 324.24 284.193504 520.093295 284.193504] +/CreationDate (D:20220326180005+01'00') +>> +endobj +153 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220326180012+01'00') +/P 11 0 R +/T (Utente) +/AP << +/N 356 0 R +>> +/NM (873100eb-2c0f-4ecf-90fac81b0a3dce25) +/Rect [335.963979 272.913514 396.902843 283.931] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [338.150698 283.931001 394.716127 283.931001 338.150698 272.913504 394.716127 272.913504] +/CreationDate (D:20220326180012+01'00') +>> +endobj +154 0 obj +<< +/F 4 +/M (D:20220326180126+01'00') +/P 11 0 R +/T (Utente) +/AP << +/N 357 0 R +>> +/BS << +/W 0 +>> +/DA (1.000 1.000 0.878 rg) +/IT /FreeTextTypewriter +/LE /None +/NM (ba9af7c6-1d2e-4f6e-a4200e1fed7a0373) +/RC (

?

) +/RD [0 0 0 0] +/Rect [42.179528 192.227877 51.179528 204.227877] +/Subj (Formato) +/Subtype /FreeText +/Contents (?) +/CreationDate (D:20220326180123+01'00') +>> +endobj +155 0 obj +<< +/F 4 +/M (D:20220328134314+02'00') +/P 11 0 R +/T (Utente) +/AP << +/N 358 0 R +>> +/BS << +/W 0 +>> +/DA (1.000 1.000 0.878 rg) +/IT /FreeTextTypewriter +/LE /None +/NM (fac997c6-0b13-4a09-bca8e8e9f58cb89e) +/RC (

v. es. Pag.14

) +/RD [0 0 0 0] +/Rect [93.330178 275.456627 156.930178 283.456627] +/Subj (Formato) +/Subtype /FreeText +/Contents (v. es. Pag.14) +/CreationDate (D:20220328134258+02'00') +>> +endobj +156 0 obj +<< +/Filter [/FlateDecode] +/Length 3420 +>> +stream +xڵZIoHWDŝ KG,%*H#ZbhqH* [I$F#~o4‚o_tCeOr~^xnҋz__o:nk׸f5 L_\*yi¶ C M+E,Ga`nzFRȷb5V[|Nd97: x٦ M;Fy![ⷴz3maO}Ob7}`1;$iV- Zݾ}*jjP͗lH4@kABRunfYY|e^(L;8s[cSf|UI7VES;}-Nfd7${6P+HA`J2V8P_/ Ri8;^lY{C_'0-'b-#3K/s~&rHƦ J@K'ɿZC;)" >mvPFI#Q mi̎O@J2@,BP(}0t(C8a#/E1lG:M-UZ Gg|{u".>.Gia%Fu.uMmZG\FU7&2sAo2qÕgkL GB + ylz1FV{r<=c6;߈ʋdߘM82=\pc{a;ʜoVFvH޷b +C6; eNV $Q^$B<lS! Yo+kCV@K eթGbGmϸ*+mZiEژ]09(+4Vw@4m%E`Ew +oL*6/y:<:%4JTLؼ)vi𜗄 +%W4Rnky?&FnÑ4Ḡ|:WsE͈`A_󌮓[0ةy ,-<HP)֮w#(}ܚD/BX.ǂ.dz-iyfbLV| H>gS+09W8c!z336t_݉!7$~/>sV!%^)dRDmv+)Ul$E^nU/tNy"h^&!xy)^G K)}cK~'5K^ąM`DVy,Ȅp$U@oXz\CdVӎh/]<:=g扺N`Hgn@l&t9ҩ(ב_ T siqU\$.9:ZԞlEK|:0V`HIv1u( aH`#ͣO!cc3t']1aZzqC`Z8VrG:W>t6T' +t`-tO`r3*> @RZ$N =ephBCroYA +MY(sP{%%_ȘM/Ni\_ :9~zNo|DkΙm)u Td=cSFf̏A8!HE?[no)OG4Bk,{|zжdLC> +/NM (26bbee72-8415-463f-a55fa41660d805d2) +/Rect [86.160004 580.214966 284.951691 581.214966] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [86.16 590.168001 284.951681 590.168001 86.16 579.150504 284.951681 579.150504] +/CreationDate (D:20220326180229+01'00') +>> +endobj +158 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220326180232+01'00') +/P 12 0 R +/T (Utente) +/AP << +/N 360 0 R +>> +/NM (e2c71132-5997-482b-998b95c521bf6cfa) +/Rect [86.160004 568.935975 231.499939 569.935975] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [86.16 578.889001 231.499935 578.889001 86.16 567.871504 231.499935 567.871504] +/CreationDate (D:20220326180232+01'00') +>> +endobj +159 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220326180240+01'00') +/P 12 0 R +/T (Utente) +/AP << +/N 361 0 R +>> +/NM (9069b461-ed75-4229-960b91b06185adf2) +/Rect [86.160004 557.416993 306.262665 569.935975] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [237.199475 578.889001 306.262654 578.889001 237.199475 567.871504 306.262654 567.871504 86.16 567.370001 238.379293 567.370001 86.16 556.352504 238.379293 556.352504] +/CreationDate (D:20220326180240+01'00') +>> +endobj +160 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220326180253+01'00') +/P 12 0 R +/T (Utente) +/AP << +/N 362 0 R +>> +/NM (a7ef5850-b134-41e6-8300aee29633c4ce) +/Rect [86.162003 546.143982 300.918366 547.143982] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [86.162 556.097001 300.918378 556.097001 86.162 545.079504 300.918378 545.079504] +/CreationDate (D:20220326180253+01'00') +>> +endobj +161 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220326180256+01'00') +/P 12 0 R +/T (Utente) +/AP << +/N 363 0 R +>> +/NM (8589bd4d-85d6-46f7-b33ed10bac23843e) +/Rect [86.162003 534.864991 124.073777 535.864991] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [86.162 544.818001 124.073775 544.818001 86.162 533.800504 124.073775 533.800504] +/CreationDate (D:20220326180256+01'00') +>> +endobj +162 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220326180301+01'00') +/P 12 0 R +/T (Utente) +/AP << +/N 364 0 R +>> +/NM (6a9ed105-7888-44f0-b1d7c365ceede096) +/Rect [129.824769 534.864991 280.103638 535.864991] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [129.824762 544.818001 280.103651 544.818001 129.824762 533.800504 280.103651 533.800504] +/CreationDate (D:20220326180301+01'00') +>> +endobj +163 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220326180306+01'00') +/P 12 0 R +/T (Utente) +/AP << +/N 365 0 R +>> +/NM (86d9eb9e-3de4-4b13-95e5f4a952f1a757) +/Rect [86.162003 512.065003 276.425629 524.583985] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [86.162 533.537001 276.42562 533.537001 86.162 522.519504 276.42562 522.519504 86.162 522.018001 147.065535 522.018001 86.162 511.000504 147.065535 511.000504] +/CreationDate (D:20220326180306+01'00') +>> +endobj +164 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220326180333+01'00') +/P 12 0 R +/T (Utente) +/AP << +/N 366 0 R +>> +/NM (c724f377-0264-4ee8-a548eedaa11d7eec) +/Rect [324.239991 432.853974 493.276398 433.853974] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [324.24 442.807001 493.276386 442.807001 324.24 431.789504 493.276386 431.789504] +/CreationDate (D:20220326180333+01'00') +>> +endobj +165 0 obj +<< +/Filter [/FlateDecode] +/Length 2330 +>> +stream +xڕX[s۶~ 1q 9qĮ$hD$}OHV|N32{ۅ$ ~.w/QnC ) J ܋[/JB6⇡H[x3g#S&LCDh (AJݣA6)bjzt$FD 0AZxNQQQw)JG^,tG06~PH;JR +" *+(ENɖLɖu_jҁ z":zg" 8kvg m e5 _L!K͝lj""1=}`=J#nB֠T0LJ$A=i$LD@ /}#4/ۭ)s>U {;D C6_xTO\ǿBtJS+C2zy/g}F4|۳ݷb:gUvgUS~csHp bV"<(R@g~"~}v$i*+ǑLfM+۷2B-"ty T*-T4}@A[;#_I^cG~.UЌ kL茋*&R4kPoP?g~Q8VԬ4Qfғ .ƥjDfRDcz +܂IȂ-_4f6e#D]vM|G'QrFo3Cs]A@0ͤFHV,2kȐ5!orQv˪ ;#R9W {kSץ$;;#Ifo 7Cɛܷ ~e&v`0KdJGKzcQ {VV&yQy4pO"7n{j+|i8+H5$uo*-Y NS5$q@^e^6#\,2[)u̟L)TAI8Y9 + $b2&dԢ-vayI,g ?%yl.:F0uuJkb*m +xB/،Kxؔ+F`fP)$|Έl2„U}aYdǕmm3{[n&#[g_Ɇ/{p6oXSsLGU3t";bCrg91HgCeqm,$4q + B 6_禠Ӝm͑Θ8 :7>tu*WG5)cPpJO&&u[Rʶyyw4vL< aƨSArͯ` 3IF@2qz.~mQU? <}_q.Ђ! $LHGhi6{g5H+5ǢaGꥒ8fc:GUnhuMF]8 ghJp5f5ѵZ\czkOz8]hǨQ=M4B*Pa涡潄vQG+{F>項d2p.|o~V^˖&Dޑ +k`McûK2z%/b`T[n4ٖWniKI>O)&Gq`&(ӫ>'>Oa(sg&C}8~{7G_{F=o3j;GY9NjɎx7 żw[R,k "kn0 7=m''Fk #+N{Şh&v\-݈.8'Dkx'&_[ ]R@ޮR1{sKWQjK7Tc5,E8X =x_G +endstream +endobj +166 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220326180502+01'00') +/P 13 0 R +/T (Utente) +/AP << +/N 367 0 R +>> +/NM (91bd7021-7811-4f61-b41f07c9cc9b20bf) +/Rect [324.239991 410.057984 439.410767 411.057984] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [324.24 420.011001 439.410768 420.011001 324.24 408.993504 439.410768 408.993504] +/CreationDate (D:20220326180502+01'00') +>> +endobj +167 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220326180504+01'00') +/P 13 0 R +/T (Utente) +/AP << +/N 368 0 R +>> +/NM (8cc8a1b9-a21a-40ed-92de56d7b44de49e) +/Rect [324.239991 398.778992 537.723633 411.057984] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [445.101191 420.011001 537.72362 420.011001 445.101191 408.993504 537.72362 408.993504 324.24 408.732001 424.200275 408.732001 324.24 397.714504 424.200275 397.714504] +/CreationDate (D:20220326180504+01'00') +>> +endobj +168 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220326180524+01'00') +/P 13 0 R +/T (Utente) +/AP << +/N 369 0 R +>> +/NM (7ce5890b-b69e-4375-aa7449e63f305192) +/Rect [324.239991 262.701996 543.363404 274.980988] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [324.24 283.934001 543.363374 283.934001 324.24 272.916504 543.363374 272.916504 324.24 272.655001 379.109647 272.655001 324.24 261.637504 379.109647 261.637504] +/CreationDate (D:20220326180524+01'00') +>> +endobj +169 0 obj +<< +/Filter [/FlateDecode] +/Length 2571 +>> +stream +xX[oI~WcjꇑHYhCژ,tI{ΩLFJH;́r_?KlT"bDH绞\x|I_ [`l~/2ry$۞T!w>hhwo$b ځ>%M['V BH\C䞏v)TscXhTVNqW ';"<kꟕXvy+0+lӓ{BTi/7HD-ҳv:qG(/O A6!S\Ia_ S5ұ6-}[rgs,O|N6_&[%6+?Y +pKl@#k^|#_jIDI]壕(WsU6mHN۔&YʴN@-Bk瞕!6.jr6.$&;̉_N + YHL%2퓊8CG!g2j˦ viE&$]_vAAPԬ4ƌRJy~LAgxV~_f8>b"Ǐ52@d[_ ȑN׆XgQuAדUz{=SY ]_l)]txa{g-O]υfpgȸe:.K &e1-j\rJM)smJF@ΎGkc׮'fJ`[fʀ}aA m#}/X(|i2*;pCl| |s:*Dy~pxmЅD qCfk{ߦMp}ıc" W27`,$d47jh`% e+LJ&\ mFzrMZ&`yY )XUXPG+$V>D=N暹c8 t+`n=\$] m7eH ]-x/@>M

'db`AZbѷu!g<7$@xjM +R!w+, iL/ >DeZ&VWd 4*ڃ7* Deu?qTjQS[2NhlDrb=%ȩnU cSM9ھ!5c86=\-g94ZJ ~mtPԛMQFqz;"'ԩ7WG3ף9V|B^FuP"78Ll[A`ĨVSTk3wOoi!|jt/w +=5+bb,304œuv}iqaan95u0Gˮ !k>ֵzl#1'+n<%TCRv *h:^}+Muԥ}LCߞ 1:ݖ]ă9+!07rAtfbDbj)~uVw<1i t5"x6 ;d<1*^Z]Bkv3~NQj݉xi]h>b)=ìNq̘ +Pg]]miZNr֤o]'E`F!}tVӻdmV|quBE+pBzsew{7\uJO% XUۧjj:/ (pvʶF.5lڲzJSV`^\&4'?oXwT#Xm}E BO{G45ulu&w0ӊ5=?X8U#dG>ߠAU> +/NM (166f7d62-510f-4c5b-a6604ce41adaeddf) +/Rect [83.974276 511.000519 125.938028 522.018006] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [86.161 522.018001 123.751302 522.018001 86.161 511.000504 123.751302 511.000504] +/CreationDate (D:20220326180545+01'00') +>> +endobj +171 0 obj +<< +/Filter [/FlateDecode] +/Length 2492 +>> +stream +xYnH}W# X=@X $cɃ yY^[&E 3EjrTuD U ' 8Ux~7:CT*`|IGR)<sXƏc1O'2c*" A Se"#)SR_N8'SOƚEF'5{A~ Y. &cC-}-8:jퟧKOY}RLIMh;w?yH.W)Dy +I?_ +䗷J o7/Ցi];;jԮJ4Nxi@9r}pU'_ӺPobRl/U +W|JO9iDJ?*/)h+)371Әjo<2u֨#rvEF+u%6>Ϊ*Y<``j;ӊnkׇȻ'T/mV첦DT$>]V.ŝJAjӉ&!tםyաJ0IzߐY8e fͲBG(B 1dƸhAZTaAAeADH|m.`pUFB6jmQJH-]BAN^)r#=b<2?K|b?I ȣf邱XJ +e/tKh)Bd8D< 1h~ŇeӴm\k߄6bhZ_j+lN0\|Yi@U݉݉O`V|Y`po4csh@lqH#|3[,H>aUܜ}/>A6yC@J|=f< *q~^]AA@bE u^eOmgJ o6K =VdT&Jq` "*д#&>{7pp3p*~j]6% {6x&;X4(#)w6 t\%۔@UULC6EþczL2d!c~ֳv<> ;zj)XnIqsVipT(K"׶ٿ۹DSFC M;L08;6\#C~Dg#:8qMn]Uk[f[ @=c q23N82 GBfͨ:Īhî.YiHgߏVBRǁlF :Hb .?P EԎX*Q):'YXbA +fe?YS5}vEo}#ly'`M+/8uC+6̰/[8() +B]^+{&[(Ov9sgnuB~2:uE>d=Njv"e^.itnS.,l]Op/;pxJ09߫{cUsVQ8 ތ7+ +YV0LFuy=^c|.S`. +f銈˓ }qK?A $zv|gc^ +ı"NEq2G2^G#4s Q@0 @C%{hcm۶*AO'G;=[lBH&@5piڎ5OvI6@|taK .O;^<>ɑV=o[?kqG{SE ycV]$WRuz7CVCgbwOxCr$ҭmfHh>6SH43>| +,M+`>W{; ֘}h@#p ){{Y58p\ܙ3=?~?k?6~G5TH`Нt^ԧ6 =<7o;<jq9L% kCWKXtTWw7\LG$GM,3X0dt +NܤqS0Н'Sh1-'&U! +endstream +endobj +172 0 obj +<< +/C [0.752942 1 1] +/F 4 +/M (D:20220326180853+01'00') +/P 15 0 R +/T (Utente) +/AP << +/N 371 0 R +>> +/NM (f398f7ec-e898-4013-a5c989d4e94a6f16) +/Rect [83.972275 726.518494 136.098319 737.536011] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [86.159 737.536001 133.911595 737.536001 86.159 726.518504 133.911595 726.518504] +/CreationDate (D:20220326180552+01'00') +>> +endobj +173 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220326180556+01'00') +/P 15 0 R +/T (Utente) +/AP << +/N 372 0 R +>> +/NM (8dbde30d-527c-425a-bfad7e51cad530ae) +/Rect [324.239014 704.784974 523.999268 728.583008] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [324.239 737.536001 523.521709 737.536001 324.239 726.518504 523.521709 726.518504 324.239 726.257001 523.999297 726.257001 324.239 715.239504 523.999297 715.239504 +324.239 714.738001 415.357644 714.738001 324.239 703.720504 415.357644 703.720504] +/CreationDate (D:20220326180556+01'00') +>> +endobj +174 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220326180600+01'00') +/P 15 0 R +/T (Utente) +/AP << +/N 373 0 R +>> +/NM (4168caa6-a103-4736-bc0df12ab60f41a6) +/Rect [324.239014 614.30597 518.70282 626.584961] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [324.239 635.538001 518.70283 635.538001 324.239 624.520504 518.70283 624.520504 324.239 624.259001 476.230708 624.259001 324.239 613.241504 476.230708 613.241504] +/CreationDate (D:20220326180600+01'00') +>> +endobj +175 0 obj +<< +/C [0.235295 0.701961 0.443138] +/F 4 +/M (D:20220326180813+01'00') +/P 15 0 R +/T (Utente) +/AP << +/N 374 0 R +>> +/NM (c065c431-0ef4-4749-b89e9e3e0497088e) +/Rect [324.239014 251.414994 537.786622 263.694001] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [372.522059 272.647001 537.786616 272.647001 372.522059 261.629504 537.786616 261.629504 324.239 261.368001 376.49692 261.368001 324.239 250.350504 376.49692 250.350504] +/CreationDate (D:20220326180813+01'00') +>> +endobj +176 0 obj +<< +/C [0.752942 1 1] +/F 4 +/M (D:20220326180908+01'00') +/P 15 0 R +/T (Utente) +/AP << +/N 375 0 R +>> +/NM (5025064c-4bf3-489d-a322863573ff8752) +/Rect [83.972275 261.642518 141.769512 272.660004] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [86.159 272.660001 139.582791 272.660001 86.159 261.642504 139.582791 261.642504] +/CreationDate (D:20220326180908+01'00') +>> +endobj +177 0 obj +<< +/C [0.596079 0.984314 0.596079] +/F 4 +/M (D:20220326181035+01'00') +/P 15 0 R +/T (Utente) +/AP << +/N 376 0 R +>> +/NM (2fa389f2-8559-4cde-ba79434d9664148e) +/Rect [322.052275 216.269501 371.486949 227.287003] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [324.239 227.287001 369.300222 227.287001 324.239 216.269504 369.300222 216.269504] +/CreationDate (D:20220326181035+01'00') +>> +endobj +178 0 obj +<< +/C [0.596079 0.984314 0.596079] +/F 4 +/M (D:20220326181041+01'00') +/P 15 0 R +/T (Utente) +/AP << +/N 377 0 R +>> +/NM (7ee6a47d-db43-4f3d-b9b4f3e07d561666) +/Rect [322.051268 182.2025 357.514193 193.220002] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [324.238 193.220001 355.327466 193.220001 324.238 182.202504 355.327466 182.202504] +/CreationDate (D:20220326181041+01'00') +>> +endobj +179 0 obj +<< +/C [0.596079 0.984314 0.596079] +/F 4 +/M (D:20220326181056+01'00') +/P 15 0 R +/T (Utente) +/AP << +/N 378 0 R +>> +/NM (421cf882-61dd-4b2d-bf6b9154586a95c8) +/Rect [322.052275 148.110505 468.469332 159.128006] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [324.239 159.128001 466.282601 159.128001 324.239 148.110504 466.282601 148.110504] +/CreationDate (D:20220326181056+01'00') +>> +endobj +180 0 obj +<< +/C [0.596079 0.984314 0.596079] +/F 4 +/M (D:20220326181221+01'00') +/P 15 0 R +/T (Utente) +/AP << +/N 379 0 R +>> +/NM (f00dd1bf-191a-46e6-9fe6401464725232) +/Rect [322.051268 125.562508 413.376812 136.580002] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [324.238 136.580001 411.190081 136.580001 324.238 125.562504 411.190081 125.562504] +/CreationDate (D:20220326181221+01'00') +>> +endobj +181 0 obj +<< +/C [0.596079 0.984314 0.596079] +/F 4 +/M (D:20220326181224+01'00') +/P 15 0 R +/T (Utente) +/AP << +/N 380 0 R +>> +/NM (fe76cc40-35cc-4bc9-8f8422aebab7b8e7) +/Rect [322.051268 91.483506 405.368441 102.501] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [324.238 102.501001 403.181717 102.501001 324.238 91.483504 403.181717 91.483504] +/CreationDate (D:20220326181224+01'00') +>> +endobj +182 0 obj +<< +/Filter [/FlateDecode] +/Length 3817 +>> +stream +xڵZYsF~篘P%aVF, 0$dYyڟ_@In,KtE?z$Ocvm:ZV~q0e{zv/ym'DKWDZ=G/ni~q-%sޥzOhCK9jẹ~~j67̹NTt +P"4:ԉb&4Ox k_qP$NO@yPD6uP8 ^*˵:I\RFNA0L[iRx|9sGGd8! p":!X;ENka@k R'L?.D9Ax>?L0RQ,F*U틒: B߉q +:a<HWr;~޴b߉ K +q^k#&:Jf7"&魗/t\ĂD&lKb&_uQtSV6ɪOԂ% ^bm7ɗOL)_"Z,Tݐp[Ӏ1"<=Q3 i/=|XNz41ec>W,gP 1D!RL BUjkio]M4v}mCE{N li1WqYOU>~bھk Xc(«+`ea%Ke/>H93ܥpw`'ODdzy$5h #Ю,T)Wd45/j8IB[ +&75Ag%UZwr,X|l[|#9x-#lB+ٶ#Cp( *`d! UoX^(tCyYhjذSD֔}*ar\,6䷂XL>;89G\`; +Gm DȧxOPց5O04jXTL-XDMs28/!LCNAd\Ns`o m*(7֠ؓ2#>?MA0c+0" +E BQ,(F(B +ӶV_a2=]39p> +01c{p/ϰ|w5ߑlh [Ŧ(DbFWdЮ6h֛5rFqmy##6LkF |8 &+$$׋$#c,s9hH#%O?VB䡐+YZ}I+~DiToRk(:Θynqy]?mp}uJ2&Cp{0ωt +li}S#-6N@c`(9<φCp3؟1t} re8筋2Fj64;uԸvg%9﬋v]7i\_]f4'j&e +pKQ%X*%[){O.6; Ka)Q^~b+hv ؁ +Wmcth+.9^s1Y,4j灺ɹX䒸Q/$3EG׽lVS vwԋ_8~vl5gn +£>)?dCmD>j>~LË )i!qxOZމMohr(8;btkoUU%*Zr).z4K%T1PTs(7<[b(SerQHt.Ȳ\R&x" +Cbm1C}X!o4NI{B]/ℼ()tm`iVv8ங5*'pǑnit- zq;qҞwZM*W. n2ޭk0Wڰ@wSEa*k*j- (#z+ƏOG +TMa`W+xʚIer0Z+jjDxYj- +w*ͿX4 Ù݌y!`<_.Yjl4K< 0̈́1@ +n -K(Q{*Lw^E ~ؓqSP.=5E=J>209rg%yHf^ BNjă[GS}j՘[Tu|HO ~ N"cya%Zƒ0(g,X:ۂ)xIgUv#_\Oq衱"<7Tגi!K+{JC!? +աQU28G4ni_nwvVaBY2-Q`l ;@qP\=nhݼmS8*&ޙ\AZa[)IРUSi'0`"gTҀi̸3 .JFp\EҦnjLXPKy|R-ml~<9AVEݖ nbZՋۨ&fne=vГ︅xٴaf0|Svd%q^/ K ++%!l<hwհ&no]qz^sʯ{ +OL&crH3*Yi CvUMڴ 6qƻd>H̺Q@5]|e>Յ*Is'<Ӫ57́^rg51. +u,tVQ8| Ob/5a0Gu&T=k6:gO[ߣ'-]U//à ɀǙM5,1 #__ )^'ٯ[)M `T4`Q(;AxM{j 0O 0^dwj%]f\&w>h& |` Y.P+V2&MCzH٢]e_!(势A+NM{{_c)4R'EJOb47=Nݳ3G7պa"*dlnŒݳ7+sgY@<qyOъ<῾~F~buG (?u"/B8'odwfbI)&_8i{l;w +endstream +endobj +183 0 obj +<< +/Filter [/FlateDecode] +/Length 2328 +>> +stream +xYKsFWLTc ([*dJDB$S$ʯ8JmmU.Ip6,swYu>pgbgukSÅ84S0qŇُ݌'l(W)ŝE~9W|(H@ps :F +nEퟣT*~89Z<,cyĤd2|pJXb42>B:ùRCıL x)y +V‹8@G-%:P PO`,z8e9F D%&Ng>96ɨ"T,`Qg=!P}Fq4"_D:y2G}Cn,sHŻٛkcp*v$.0v[W,"Vl!$B* AC%BjmW"Ih/~WEFχnqen A˃ې-~F\@C'Ӷ.; +qwe(U":Y?" DUkuq &$1ec%P-d5 2f[M`Xn|Y#`aP(䒁x* 2{P" 3 Z)D'x2i'%wYPw69JG@k8,\Ap#"Kk˶a08SGnJ$h,aAEl2Uٟ[v(nWb(zXiT 4wET56I}}dԎ + Ldka7UqABa -y× 5ID't +6( +"OxGkIƂDCȿVOKr7erU4,|quOA,.r|P-&NVkMB=\׫.e%0߽tSITzՇMfvx|hO{vI=EqLēuM^zph,/5}Ko/ϼ t1ܬrw gqg3pnCYeV4kLr"xVdml'_ŲUU}ݟQF=֏[  _Xk +z, ۮ3֮q?F| tX qBTD57.ݒhCs,lȷ屋#ߪ=&=![PFVWA(w`o.U*bc'k@ef#b:%vTՖ޹5_ +]Q5X}v:/zϴQW-NLe3OS銳ĸS\2wC2&up^Qq*ʟ%K|gCm=0Ɨ+,r_MA阮^p(޶Q("Gw Ž+xYK RA-'[V9\v6OEHo&& z+\ҫf?'¿ùQ9C#n.5뻛:v@ XTre^ kEb,ߩ+2s?^9Fy/Ew/} 0g&NQ +endstream +endobj +184 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220328140012+02'00') +/P 17 0 R +/T (Utente) +/AP << +/N 381 0 R +>> +/NM (e0dddcca-dfbe-495b-ad9934dd324ad94f) +/Rect [356.132284 703.712525 453.338046 714.729981] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [358.319 714.730001 451.151318 714.730001 358.319 703.712504 451.151318 703.712504] +/CreationDate (D:20220328140012+02'00') +>> +endobj +185 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220328140018+02'00') +/P 17 0 R +/T (Utente) +/AP << +/N 382 0 R +>> +/NM (c90eb1a3-9458-43f6-bbcf8929c4182d41) +/Rect [455.220968 703.712525 535.710543 714.729981] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [457.407692 714.730001 533.523797 714.730001 457.407692 703.712504 533.523797 703.712504] +/CreationDate (D:20220328140018+02'00') +>> +endobj +186 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220504113002+02'00') +/P 17 0 R +/T (carlo) +/AP << +/N 383 0 R +>> +/NM (88aba5c8-aae3-47f2-8335affea4f8023a) +/Rect [186.213277 692.440491 244.162075 703.458008] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [188.4 703.458001 241.975351 703.458001 188.4 692.440504 241.975351 692.440504] +/CreationDate (D:20220504113002+02'00') +>> +endobj +187 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220504113005+02'00') +/P 17 0 R +/T (carlo) +/AP << +/N 384 0 R +>> +/NM (fd07c86e-5aa0-4bdc-80e74f39699bdf07) +/Rect [356.132284 692.433533 461.352397 703.450989] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [358.319 703.451001 459.16567 703.451001 358.319 692.433504 459.16567 692.433504] +/CreationDate (D:20220504113005+02'00') +>> +endobj +188 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220504113009+02'00') +/P 17 0 R +/T (carlo) +/AP << +/N 385 0 R +>> +/NM (0517397a-2131-4729-9d67c7a09ed34ad0) +/Rect [356.132284 681.15448 471.599642 692.171998] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [358.319 692.172001 469.412911 692.172001 358.319 681.154504 469.412911 681.154504] +/CreationDate (D:20220504113009+02'00') +>> +endobj +189 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220504113013+02'00') +/P 17 0 R +/T (carlo) +/AP << +/N 386 0 R +>> +/NM (4c969a75-25a8-4122-aa55392255cc7ca3) +/Rect [356.132284 669.879517 408.982769 680.896973] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [358.319 680.897001 406.796049 680.897001 358.319 669.879504 406.796049 669.879504] +/CreationDate (D:20220504113013+02'00') +>> +endobj +190 0 obj +<< +/Filter [/FlateDecode] +/Length 3380 +>> +stream +xڽYIoHWD&*Cv$auD[HBRvܧ"Y\$U[m$¿9ѷn+][Ʊe`Gaq?-lWȒn`; ?lNڑз>tCʃ;@XB7`b;}ieR0PHq(Rlh%F@:u7I!D~A?i7xu~Нw}9 + ܉9<:\fu .q-CnS5bv/ >ogSMKRcYm=ޥ&fRFCeUrǻ9$f=?J 6K +HJY5UɶJDtE3Y3 0]DoD sӍu^ ߸w]#LJ+V, nymExP!5/) -3'wh2Y#R +^AAVx*7͗|^)({nCHxΖMYΛrnwA{$ 4wN}sqFJy2ӁGC6l ƎBtZdlV9]PAl`O=#*W_ů2VudASX˒񇀲B+ BWn7!^eT4l%7sqƒx_3igfAyɝ\x܍P|Str{Na1>BO@@Hjc=p_$ !|| pnB^Gﺬsz3u䒼L6M}L 23BVv"[5ÑP_J4AA|\sE'n纰r +endstream +endobj +191 0 obj +<< +/C [0.596079 0.984314 0.596079] +/F 4 +/M (D:20220326181738+01'00') +/P 18 0 R +/T (Utente) +/AP << +/N 387 0 R +>> +/NM (077da728-99be-4692-9eb980fc4bd9fdf7) +/Rect [61.411278 564.993531 108.845979 598.570008] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [63.598 587.291001 106.659257 587.291001 63.598 576.273504 106.659257 576.273504 63.598 598.570001 91.869495 598.570001 63.598 587.552504 91.869495 587.552504 +63.598 576.011001 84.451766 576.011001 63.598 564.993504 84.451766 564.993504] +/CreationDate (D:20220326181738+01'00') +>> +endobj +192 0 obj +<< +/C [0.596079 0.984314 0.596079] +/F 4 +/M (D:20220326181746+01'00') +/P 18 0 R +/T (Utente) +/AP << +/N 388 0 R +>> +/NM (ae7c45bf-6319-42a6-9b0a2f1d42526c58) +/Rect [110.186746 606.839539 150.27659 626.579163] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [114.111061 626.579193 149.10197 617.804384 111.361365 615.614357 146.352274 606.839547] +/CreationDate (D:20220326181746+01'00') +>> +endobj +193 0 obj +<< +/C [0.596079 0.984314 0.596079] +/F 4 +/M (D:20220326181748+01'00') +/P 18 0 R +/T (Utente) +/AP << +/N 389 0 R +>> +/NM (315c20b4-f209-4492-a460a93a3b1fa301) +/Rect [213.572275 672.989502 257.060283 684.00702] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [215.759 684.007001 254.873559 684.007001 215.759 672.989504 254.873559 672.989504] +/CreationDate (D:20220326181748+01'00') +>> +endobj +194 0 obj +<< +/C [0.596079 0.984314 0.596079] +/F 4 +/M (D:20220326181751+01'00') +/P 18 0 R +/T (Utente) +/AP << +/N 390 0 R +>> +/NM (0e972291-722e-48f9-953e3a90bb2afdff) +/Rect [311.511165 528.342591 355.443394 545.7865] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [314.884808 545.786516 353.853353 539.627354 313.101201 534.501768 352.069745 528.342606] +/CreationDate (D:20220326181751+01'00') +>> +endobj +195 0 obj +<< +/C [0.596079 0.984314 0.596079] +/F 4 +/M (D:20220326181754+01'00') +/P 18 0 R +/T (Utente) +/AP << +/N 391 0 R +>> +/NM (7020498b-1ca4-4c64-a1956e0b9a1ae2bf) +/Rect [117.52459 510.056 159.362727 533.88794] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [118.255877 520.807188 154.781121 533.887961 122.106199 510.055993 158.631443 523.136765] +/CreationDate (D:20220326181754+01'00') +>> +endobj +196 0 obj +<< +/C [0.686275 0.933334 0.933334] +/F 4 +/M (D:20220326181822+01'00') +/P 18 0 R +/T (Utente) +/AP << +/N 392 0 R +>> +/NM (5a047bc2-7a1d-4207-ba3397c767410b9d) +/Rect [61.411278 564.993531 346.925975 598.570008] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [301.678 598.570001 317.956329 598.570001 301.678 587.552504 317.956329 587.552504 63.598 587.291001 106.659257 587.291001 63.598 576.273504 106.659257 576.273504 +63.598 598.570001 91.869495 598.570001 63.598 587.552504 91.869495 587.552504 63.598 576.011001 92.169433 576.011001 63.598 564.993504 92.169433 564.993504 +301.678 587.290001 344.739257 587.290001 301.678 576.272504 344.739257 576.272504 301.678 576.011001 330.249433 576.011001 301.678 564.993504 330.249433 564.993504] +/CreationDate (D:20220326181822+01'00') +>> +endobj +197 0 obj +<< +/C [0.501961 0.250981 0] +/F 4 +/M (D:20220406164210+02'00') +/P 18 0 R +/T (Utente) +/AP << +/N 393 0 R +>> +/BS << +/W 3 +>> +/CA 0.6 +/NM (5a2c0111-b221-48d7-b06dd1a397d9b53a) +/Rect [190.899247 527.593086 214.213686 543.095944] +/Subj (Poligono) +/Subtype /Polygon +/Vertices [192.399244 532.527831 207.963706 530.090204 192.774292 540.590753 197.649906 537.778106 192.399244 540.590753] +/CreationDate (D:20220326182019+01'00') +>> +endobj +198 0 obj +<< +/C [0.501961 0.250981 0] +/F 4 +/M (D:20220406164215+02'00') +/P 18 0 R +/T (Utente) +/AP << +/N 394 0 R +>> +/BS << +/W 3 +>> +/CA 0.6 +/NM (9b5dc1b8-c764-4a1c-a6ab594f2343a28a) +/Rect [216.909301 541.182113 253.163467 548.356879] +/Subj (Poligono) +/Subtype /Polygon +/Vertices [225.403403 543.21589 233.654443 546.778576 243.405672 544.340949] +/CreationDate (D:20220326182031+01'00') +>> +endobj +199 0 obj +<< +/C [0.501961 0.250981 0] +/F 4 +/M (D:20220406164205+02'00') +/P 18 0 R +/T (Utente) +/AP << +/N 395 0 R +>> +/BS << +/W 3 +>> +/CA 0.6 +/NM (7c1e1c33-a84e-48e3-be98072917b61f85) +/Rect [231.740785 633.928279 254.85554 647.097256] +/Subj (Poligono) +/Subtype /Polygon +/Vertices [233.279396 645.221221 249.406428 641.658535 233.466919 636.033241] +/CreationDate (D:20220326182037+01'00') +>> +endobj +200 0 obj +<< +/C [0.501961 0.250981 0] +/F 4 +/M (D:20220406164158+02'00') +/P 18 0 R +/T (Utente) +/AP << +/N 396 0 R +>> +/BS << +/W 3 +>> +/CA 0.6 +/NM (7f717e77-d752-4668-bb5626eb67ab88fa) +/Rect [187.16444 625.689474 213.456864 635.704883] +/Subj (Poligono) +/Subtype /Polygon +/Vertices [192.774292 630.407947 201.587902 633.970633 208.526276 627.970319] +/CreationDate (D:20220326182044+01'00') +>> +endobj +201 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220327190658+02'00') +/P 18 0 R +/T (Utente) +/AP << +/N 397 0 R +>> +/NM (9034a5d2-cbd2-442b-82243b2ef63bec6f) +/Rect [67.439003 78.37999 260.316407 79.37999] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [67.439 88.333001 260.316404 88.333001 67.439 77.315504 260.316404 77.315504] +/CreationDate (D:20220327190658+02'00') +>> +endobj +202 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220327190700+02'00') +/P 18 0 R +/T (Utente) +/AP << +/N 398 0 R +>> +/NM (8868b56a-5660-4c7a-8f5e27d9257cd4e1) +/Rect [260.251557 78.37999 416.075715 79.37999] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [260.251562 88.333001 416.075712 88.333001 260.251562 77.315504 416.075712 77.315504] +/CreationDate (D:20220327190700+02'00') +>> +endobj +203 0 obj +<< +/C [1 0 0] +/F 4 +/L [194.056332 193.313899 290.204024 231.342862] +/M (D:20220327190723+02'00') +/P 18 0 R +/T (Utente) +/AP << +/N 399 0 R +>> +/BS << +/W 0.5 +>> +/IT /LineArrow +/LE [/None /OpenArrow] +/NM (f8e642ee-f956-4e0a-8f8d9b324beb91ea) +/Rect [193.872435 192.848952 291.133893 232.496426] +/Subj (Commento) +/Subtype /Line +/CreationDate (D:20220327190721+02'00') +>> +endobj +204 0 obj +<< +/C [1 0 0] +/F 4 +/L [189.83006 245.427664 199.691361 235.216183] +/M (D:20220327190729+02'00') +/P 18 0 R +/T (Utente) +/AP << +/N 400 0 R +>> +/BS << +/W 4 +>> +/CA 0.6 +/LE [/None /None] +/NM (73aa0c3b-9e6a-4466-a6008161e75b972b) +/Rect [188.391397 233.826856 201.130027 246.816989] +/Subj (Linea) +/Subtype /Line +/CreationDate (D:20220327190729+02'00') +>> +endobj +205 0 obj +<< +/C [1 0 0] +/F 4 +/L [183.138462 234.159823 208.848285 246.836144] +/M (D:20220327190731+02'00') +/P 18 0 R +/T (Utente) +/AP << +/N 401 0 R +>> +/BS << +/W 4 +>> +/CA 0.6 +/LE [/None /None] +/NM (5f202e2f-0fa7-4ef0-a611d6f6481cddc5) +/Rect [182.254014 232.36601 209.732727 248.629947] +/Subj (Linea) +/Subtype /Line +/CreationDate (D:20220327190730+02'00') +>> +endobj +206 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220327190747+02'00') +/P 18 0 R +/T (Utente) +/AP << +/N 402 0 R +>> +/NM (20c1ec61-a0a6-42b6-97a97ca5d9b1ce20) +/Rect [67.439003 68.540986 496.878968 69.540986] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [67.439 78.494001 496.878965 78.494001 67.439 67.476504 496.878965 67.476504] +/CreationDate (D:20220327190747+02'00') +>> +endobj +207 0 obj +<< +/Filter [/FlateDecode] +/Length 6632 +>> +stream +xڭ\YsƑ~_n:,?HNlhd9$G&fY8 8]@YYygsMO-5]_w]nWKS!m]Rn\ݘeו46.nɸnC;BׇI1wӈc7ҀGQXiS > %Y1}}kvtHpvjǾʨ۞VMPAL̖iZ9"<ϵ&z\53-cO²e%OI6nTϺ Ƭ0CJl]HLyCyރe R޸pzҜ"TƲEWs  j+-QBC&a4t+4$Ҹ% "s `zL!ZF!=됪2XPz̋l731}L&8J2nx|qH>Kw5,H@juG7I3z!i'I}6.7!5@'?ٛ["ד`牓$JX~B$Sivj_AQl#FXYGPaI*_ġ:mo19zy/^ r׻y~o;GXɯ^_m.[Oaĥ^HV&FS3Ms=ʠ?^::GcEdEs.VX$k(I^hf1تgb灃}-G&/3aŪ[bAe<eQ:*2B+xlB+"ӑXfn"X')-AYbX~ENKm'w{&cU)Jq.{('Ĩ cE_Yf>a#"R ]pD:t+JC1`U,ߋ >JcucS+f +8=A e'Imp_4I5ш'Ԧ9~|& *}1PNbbI,aIS%,mn2N:+{O҆Zj0bkLcwB̵Y6K%ں4hL\fA"Fcs4xv5Sj<q# *+A +JO8` + L QuR[P !MAE>j;H+5Wrtn= Y577U?Mk:%BOY͙YZXrN-r*=* A]RK!58Ga^8d{@y@.CҪ+$* pG[+ae@Y&^ǨcH2G&nz/ϱQoXvȎQX…Zg2+Zhb>[dD?X +7=ZYYvNVhm&qMV$EMVhAklx&c̯)|G^8GE GEIPD- MA0 #A)F1`#Q_=Wh{ňy=0R_ >TFqPaM4W͠f6Xi6GeڄHA3{eBmV^h +F[#-ZH~bimfYfh6-T (mf=[mVQq1̷CaW[д*Y;{yڣe'z3S{(a/"HΚ05kb֎P:?=ցfX8d"H_4FvMG-U[%? AΊFuI +ˈDP@<~%)gk  $uDK1n _{s{RJSMK2Jl3(m\x`&b(hn:`Q 3TIu1"R XK~Gsx P!};yMH]dIݯ;NJ]bQ爚wXE 7.;z<%/Ӽnz]{^y!M-  쎦}~'֑yn +)aQմe"Rd|p-M1խ[yIR!V2= +wywy2x[g u7Y&y.m@[ ]bo[Z'N. ѭc%y5& +\u핤*ui\z +Cpo[Ĭ}e:`4Ca_nG T>ӄN'}3BU/4?6w"ďЏ~suwhחk],IT̑R\{|h~=< byzMHS}) L\!mςuZ~e/,գ N㷇G>n([7MF^|\5"Y1YtKMؔJZZPϠrg#08˵ /)X* d&z /i{TBW&Va(1W| ~HNZ-taK g/dF_K!ń3bdZҕ.,oOɦ8a8ewiD0enRR!1oP?P3 Ow +>zc~>,/ ,?4B_@ݞfA~syW7nM~|Jy +S;E# 0:@F2F;x0=srsbV(Ub0 `d;WdopdcD' @#F,)X`8E1h13//*EH Nh +$3[&! w8V :/Wo 3ߍ$'ڌ,nqLotF/P8:9f9I5 +ȗ++-NF^4iޓIx8a@wr-:.qn 0&2\\我8H;*ZوeY}=iWdΩFo+Gx4k|24GlgfMn6;5MF֤&`Z5OCޟB9;U?7 k90E%sˏBF $8;9=zg dj]YN74zfȨ,>WlԢߟWԏNk:!Vwp8srnŶOG'gu)nhA#)W-N ((oNOWg5U\`rgS,yL"yD^:@jƇ|ϼV7x+̐p)ނNn4|,{z7iDCVQmbn$8VBU D{5'G8_&n8DžV%6ڿO56O iB3ʣG=7@;P  V +;2i +|hi~a2i <">3ZfDr$QȰ)|#ĆͰ-#ք̷t")UW9#> xρH)  ]dIR#P\ +</2H 4T3B;=~l޶ vщZ(fy7H KF4%R`J_F2ik?j~!guզS˪k(+fΪnr@+EPJ^KS>{\Z5%uz\"ewNIJt%'pFfFi]ēgӷEaN V$b9pv`vvjFZUqLN E泣N w ՞CwOK~?9TRE`Ą4n>-0b=YEGZ-9EeTr+1֍t~x*{!45.4מYS~.;nT3]r W ӄ:L5~!3:5\6\A9SόS`E4Z sJ5|ռpz6Mw\ȹUt"0ː,)&3'0fh?۫kd5ܒqȒOO}{% rv#Bڷ7(p詡g@'V{u8-x_1mj.OpjwpSuJ)~$vȥO:ή0_'!r\0q(Ρ;o (䴿NTyYJ o~!+UiؓV]krE*_WN2MqKTҾRrfa =|OgHs*zꗫNM\ZV|BWg@iZWQAl#y#љZui/n'Uh> ~ [xH4aR{ mmrmǧ_KՎ~kEE '[ RkP ug8{5` +$-/(8*Q"1X,P:oNV@z]+j^eh(>i6V!nz#/ޝ98+;=6 ݴ( _\ÿ) +endstream +endobj +208 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220328133755+02'00') +/P 19 0 R +/T (Utente) +/AP << +/N 403 0 R +>> +/NM (5df2aa59-6609-46c2-8a361fabe0f21c4d) +/Rect [71.464745 512.05597 394.998261 513.05597] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [71.464748 522.009001 394.998248 522.009001 71.464748 510.991504 394.998248 510.991504] +/CreationDate (D:20220328133755+02'00') +>> +endobj +209 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220328133909+02'00') +/P 19 0 R +/T (Utente) +/AP << +/N 404 0 R +>> +/NM (2283ea5f-f7ff-4b1d-9839bc210832306d) +/Rect [143.039994 342.138978 454.063599 343.138978] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [143.04 352.092001 454.063614 352.092001 143.04 341.074504 454.063614 341.074504] +/CreationDate (D:20220328133909+02'00') +>> +endobj +210 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220328133913+02'00') +/P 19 0 R +/T (Utente) +/AP << +/N 405 0 R +>> +/NM (f1ab15ee-bd98-4f6a-9ea3d6de3cc75257) +/Rect [275.56201 341.074494 320.316653 352.092011] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [277.748741 352.092001 318.129928 352.092001 277.748741 341.074504 318.129928 341.074504] +/CreationDate (D:20220328133913+02'00') +>> +endobj +211 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220328133917+02'00') +/P 19 0 R +/T (Utente) +/AP << +/N 406 0 R +>> +/NM (d782cd5e-7daa-40d1-b50f16d3926d39fc) +/Rect [420.886412 341.074494 456.250338 352.092011] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [423.073143 352.092001 454.063614 352.092001 423.073143 341.074504 454.063614 341.074504] +/CreationDate (D:20220328133917+02'00') +>> +endobj +212 0 obj +<< +/Filter [/FlateDecode] +/Length 9687 +>> +stream +x}msw +}j^{ /B9v>̮8ffG\"fjQ&e'3$[=OXK"$Ld~ẾϷCW1w^ҐU~ϚǼ +ԅ\//|؍+W]n5J%*ٗ߼X*SjS3UHIꣴ==zKQ/5m9]X%<W}ijq5=5nY.L?+CzV8UK)H+G})P1PiK; +Kl+/D Z dy2QBF + ])y".Iv^Nr+tBcRTy(@+/Gn`A kGˁ]X%X#",FEdYd",2dYe!̲, ,d1,t %KնBc d`%jy$L +MBI,B"9arV#}dU4lF S?tK'tK'jg}PE:Y:#K'tdeNYMQ~l +d'aq]zH 65MP&7Mf0v 䦙D,'FdiȀXg$2D%`95d`f60]n`M&{S`XӉsvrq h%(X株2EH# Q *XPȉef9 L(cCaJ6ޱQAX -kEA\ՎB (Yv!4~pEb;`G " rKjJewLkI"jzQ Б#f,=z7!4ž +ߐ"4N|3lj =zu?P|rArv؞fMqn2Nf>")Gӭ^&`+K{}%8e4p^Y(T-H-k@kHF #{5:L ˻N!^00` d9PY+=( ׈\-k.lYXf#W. + =oU=`y2: KgcA`i^F],C+߇n)qF) OZAVbMOZ +4's'#XР|Eȫk2'։tI6x;oy%a#F G 2Omv0%z/i}کN4[/'HnL$}y":}]wz^ԝ~*2hOE܍e:NuSQ?.ª;I;oֿl6W'eZvg'-nnsݽ_wo'nZܞl>&Nܰ~G?ݜmwRD\w(\cvY~ʮh㏋꾾jn&njŸ 6wﻳ,U պGg77ןVZeBP\bTհN '.-Juyu'n\D)+,Ruk#7pM)7w_Ja/gׯ ɢK=E7gqqٝ_o뫻rCl*i}I?Զ8aD0'-+=]{6JP)7U_~٬?J__Pf4ꜚbټn_MV88T\DmRZo?\o(Ei? HjݬsBܼ]WXE nn?AyyF:Lj*?S e\\)_);CJO2e dxP+ N3ͶJ;J\o;iqwxԉsֽ~6κxx v +2f +yսg߾cX|) =)GCq]yuqB]W~]_O+=5f˜(v'4N!QQ_w(T6oQVԱ(oQ߯7{* H#q\tCU!:G44'\/p~Y"o8 sO4-L:FɌĪ>^mCfsnhUl7Ԉ [:93 uSz vAlެeԑ*wA/E}hu+ +]SAmr_uT~Qc7UDb$aJ{umM:haogwKCMPr~IjHMnrE{Z!κs͍ޝ]߼nWoow|~ ִ1ZWEi#te2tC+PZܭD?|w|Gnsi{X˜B\$pne ʴ Xnj:о/bڕNaEo|i[D[h:(*ʋROk{J$rU{s)V}Rgs 5)uWX+ʽyR8YBk]\ӹӣ jV[AÁAL;=/yzMc̓Uqfq2JH -7gQYCV֫c,!"YQ/vX ً뽩[1RDfd¾9ћ=wNd} g:Iz]Y`HӖ솈( ʘSDAidO1ĐLbFDs8DD{FWL4C k%jx(; )Z}L5>T_Poq +_6tJ]jt֝fsume$E0ܝ<ۥ`[MIU'm pүR jI^Rx_ +Kw.KE; +a,p5I+: ӊA+V 7R՟FWimr_c틅;Nc>b lL?H=0e2jS;AI!^rS̠ exT0=[+򛊐dė#p2MMLI7_OJ ,+FwCSo$]f2H'!nv*ҍ UyCiPHj~Ò9P;bXQ J ?b2g,)ұ@)47;R’xkHi*mAɻd +fqSLJVNd +kX1PP#^i^d!u@IJR4@qܑjK\X(!#v-P(l!Q>D:ɣF;qRH',>&U#PZTǪrҮŒ& j+1,+bO +R)E\aGI.Th(utoC$[du0UjdSfe'Ϙx#ȡ6Τq6Iz})l( hY;@jI>O1#.{1W-lVGB.CHqJ[)3̡ +e$*1(.GA5Lm?'V24 YYS≌rҌy6 yOО"pIdh$rD\˜!7]t՗Co*ZRQ4ϗ"K彽ֺW첣[ZhHx9<o< &|^h݆bɳ.ZA^o(8DIK Xzb"EqtԶ A a,F܌dFVj:JmP희;xri皶Yab[<.ޞ>#v7w SȜۛw֍ +x**v+WvG/ޯ@kT[8fvn}Cf$mnŚ'vǫ7HW'ߜ\kD檃8wt/.^P"8)WGܭ/(8r0_~U&no>`5)&Xݝnq>axRҪ;kdw=mG N G\vN_nҗ5[lj_ܬ)f> +~ n|uQk'.!q:mU3< vKsE5z A-sr-Գ˃eGnIH[iHP/55I"8O#%ߐ$`3mtUor~GsT G{*֦@?UzNCteP[ i1 xg ^5șDs@sLI YD-^s&븘lLmpEFqAÇKR=k wOyіf]XCb̈Op1ygK8ptJѧ% F)![:^f:Ш(ǩMv(m:d2#bl6"-"(ueK^ӧbp%S`uC? #y=C㈣ ?ܵK')`O_ͤ`87ISݝX E!1(j=3g>,,< LTj29)r:n~(T'zY,!P OSsVQhH)34g-&v[ &= y񫓂U ÑL:J[@BDppOACvat4;PBGG<)oPs5 b*`QV vTk9RA d!80b8e? 3@ +hp=!槣=mlCdyK a:ؔOD0zɂ7QA)L{x |Kf~[[(tG-þǮ(bcMWY[F};'+ټ3C 8Č| C~Bx31e5wmq|oB}qbQRҥlc^[b^#x,D( PAug[.'G) 8) 8mqMOpzz"Dc)2D<$Z< 21o9|vSGJZ%x +ބe  Vd/3zF]#*#Q:u)v5A&7IDlFV7}l v(0RRFZe-<9drdpf3ՄhD Ue WƓKIP*Ar[ۡ1嗥n(ܨTT By:Ȃ.[܈`pF_r?vNx;+ylzJ^%Qnz$|L֯b{ tNv6Ab +Rn]6 V32fdCHhYJ0ڍ=1#M(rx*b6_m"f7YȜ³!31oƗ8efvSͼ`'"8>g88B>7nμC9c3ؙ?iGhrX*Bh[fu>=>f;JgyH'/W—69=-ftkXGݳ~7 rƍ{C7-d s?'Cp7y^*k/)vQCར,R#6&`<}l_ڭ΂LT)7npa&GDSIG3'1ɟ`M>SE h[=LL.lxЖCU#{YL:ƒ1KsL2Q`gY2~6cs̘x`3^5:?v]|\^|4D/ើd?>BW={< ϋv={NHؼ!<{6Dg=޷ˡlkmH^zlW] +ȣd6 /솺?oBT`H(D+-A'?݇_<09>9H$}$b'Gb 0"cHcqA<GԻz$yȵx0('D +D +I>'B `{J~ T(&&hx(|_ؿgcj|xC4r\ȟ`C!7~7sǝ$(hA~$~!?/FzsYnySe fMAwMkW(O8f5~2DYƵr#(R +˶U˧geH)z/7δg-0rw8s(N*15e.6}?YS7PrݹPѤy :FSL`CI THbR%9Lvso'AcK>|j5G]k^EONONGD'𾧇'?L-1&“B㑁9ԨlၡJL>Rq;qETŽqѠc^.Spq:Ga9:"8kExc [Dӽ؉ћ ?>{ 3DMxd܆1}!x bL{_lqx(PI Vbo#s GG{6mSlxi֓"oÉcyXbo#qA3+jSh;+ (X|'~{>NOWe/WN%t(#zs,͗rzeQ +6yxy9̑{2z725f+(7ɜ'&BpJjZZpzא~+i]Mv5 +jW5:W|,2F8i|ףg{NDU|n?ݵdl'Gf-i ƙg(SvـpV3q[q`)|*gBㅖnbe fi-+$GX+B>ԺywYn+jU^6r&&!qdRVЮ]fjRA)TEB 9Ի:xƅ͖=*agQN &}vpv4jqY" g̡*l!g7gj兪ThiUj=V7DgVg>hpiwmf0ͬ zp8Dv`pE7Ghg58DfKZSAqdqyXmw*WMz R2.B7cl)LJ9Ȉ SO?RN3n-2v1UEIweQi jXo1Jqv7?x +(@W'>ف8%d^ŝtznIy@܁R6{aG^w{}o7'aXc%A\IM.-ŕl(߽MՓcOqwL߾AMi.Y՚ =wN٠th8]1Bf#t54Yt@eMO_H^sspuƢɂXaZ\-k~7&4"~{ZLn tjsoy=Hp>(i1f$ IzUe?*c>~Oƿgfŷ}n.ԠkhzfF{ +>v}[oUWzYn4Wm\ԋB^\}.q4Q*U&cY(eqؙ"߬ȷTa}%ͱtK4tAJY-^?tS{]BS?֫qҲ ɑLs2?ҽ5 {|}j%r+5^.x!q/tJ07.xb56ߢ/7̧ 7Wݟ]k\-B١;gOt_ۻgS^m݂ +endstream +endobj +213 0 obj +<< +/F 4 +/M (D:20220328134825+02'00') +/P 20 0 R +/T (Utente) +/AP << +/N 407 0 R +>> +/BS << +/W 0 +>> +/DA (1.000 1.000 0.878 rg) +/IT /FreeTextTypewriter +/LE /None +/NM (f60a9570-64d8-417d-bcc1600de82fc204) +/RC (

?

) +/RD [0 0 0 0] +/Rect [478.625326 693.296428 487.625326 705.296428] +/Subj (Formato) +/Subtype /FreeText +/Contents (?) +/CreationDate (D:20220328134822+02'00') +>> +endobj +214 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220328135027+02'00') +/P 20 0 R +/T (Utente) +/AP << +/N 408 0 R +>> +/NM (1ec64cc4-df3f-400e-a57b6c12d78ef055) +/Rect [211.440995 190.934983 436.170167 191.934983] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [211.441 200.888001 436.170165 200.888001 211.441 189.870504 436.170165 189.870504] +/CreationDate (D:20220328135027+02'00') +>> +endobj +215 0 obj +<< +/Filter [/FlateDecode] +/Length 4462 +>> +stream +xڭ[n$GW1PD0=#@B @HV')5_?f="7fkhV/<[= o;+32<0H?_}v1S +e:[DO);z3'nG;c?oc}\i<34N4qnSVmOz"eGڈ + יLv_yWnލw{y%S1^^\lcal&EV; vę~* e'hi]{%s A8qJ5Jj]Jxp4)1D*zXY`ɕyV +S\w0$սEX(9.#tdw"` -xa5"Nc}\MFŴMVE*RS;sĜd48?cLrJTF'!Lxsɞ0/]2s9 q,o|ԗ`fg,L5͖ Gfx3|x: NArgz\&W™jkh1sob YXX?|k/M#RV{ޑfG35J?#V♷):Eú#^nݲ'\a!\n"vrNp,`#9jwFykvnlȿeѺ{3N:rf=\_%N%Q7.ahUF#%}Ud44ljTY4Fuu+`@=i"f2d&hc)Rdb2ls|& +v}tQXZGXu⢹j+F:g;!>dDD; ZcL<Ҩ#yȘgxɢ[%]pRېJɸ䆄F-둦j}{礽7^VELDMf[zrOLT K'\C*ЩV7m"$ms?:n2Gc'Nnh- v(ȷI%caJeJ%&8-%24'({BhmAm3$;+K"Sk |qZ`nl*S& + i~[j3&+/ IYMPEhGveV#7p^1:լ"#i$$i)WlWW&qKECl}5YBon}PgfS󄨦 +-En2ΚkE$hBy@<[U{3@hVnf. uէ)gj i"Uba1zUX( /Lh_ף`F.8$`ѬQ_9KEv5?ㆈ VUd hWvN +yw`9Eϥ9_ltUpu֓b@kU0ŒM'Q* O~-HYIkK t#p'`6cUbNu K ~ +]q=8 (dJLe6-F9~o)YGM90I՗bg(r-# k~G@h乨ٚ'iֺSF,;ci%Pkc nתz=QP}xx 6 "y/hL`gTECQg>Jl0bgV$NRlXZ:X7 C4 b3C-vԌDJGlٳ:vxxkevGdxu:K6] Zuy*v$2]~ڞ"/|moS%h-9ƀPw@Sb~mm^&cp}K:\?#EŦ!G1뿯ޭ~]S7|q4\Qx?\ٲ7ϟoO wۇ+ן?>mn->ZNŬiMdMXŅeoo?_9Ӻ\s_Kzi#1/*l}רyS[~ Hdc#yؤ,1~l9Z3erq_*Ÿ]ݼl֛Aؔ7WhތW3QywûvzLm娧ʢ>^zتnh5I#x/gXdBflga x?uz!!CѠ8]((~9]Pkg3K" +5w*ߜ[pEb%IeE\^._FWB)d_̈^&,L$/9&K +e|ܜ.p0>G$TčKN%蒤h).!Wj՗V n$f,j^$0|p߭EKf='%j%JUȷвavtuۚ2F*2U/yyz#Vx#5{R Z2Ur'Tͳ;+RX6 /rQz˅$+WT7RY}5GZV/bpdYcSEҽ'ЁԔ٘N±swYSr!ܛW6vr +vD*m +bv]t_:(&Shy]l5JA"y=F$%ms}sv&4q&0˙uN,YjՑEt}hs;PH bAqv9ڶɚ3θsqsp?}ApY%lIJ\\K m_BXX&u +q%9kWU\/Ş^]||IعJl۹SlXŒLM=GO(% MY-=>OǽNAZo$n)Bq #?<ϑ;s+EIdl&d;$OBmr=@Gf?[t91KI ysGn7vso^|ts/ۇ[a(g=2+fƌY +]5ˏM&&ĭ\b3W!{@ ķt7Nl>oBS&I}}fQ"O\.,=q/[[Q嬳$m;GO2=V,FAfz*rR(e<|xiۛ[VOK?iGtXgsf`8gI?BD]4&"ڑ>52Q]I!{|#o]v*Df|\J,ʕK" +u`Z9> KV THD +endstream +endobj +216 0 obj +<< +/Filter [/FlateDecode] +/Length 24807 +>> +stream +x}}K%S߾?E/gsGVVaZ /0 ꋌ[|z="ms#2^cimW]e.Xz?m}?~ @@7cZ?1-cڷ?|ӎ?>az~oO/,o?/?~~U__ ӷ*o˸}Y>j??} ^?~5nTQ?Zۼ]ylS/yJ`D`4MTDz}WY>Ec ~ͤ~RP/-gǾvAя`V[J78mǍ;>"qE5h›X+S:lR*HJx SExn>|vmzb,69PіGz69hHWf6S#/c]OwʁTl$UM>m=򅄜7bOaIɎv'*8k]^jcfG ~>/`ރvHmWێYGE1_D 3X7@DPf X|q){Ĕ*ԨelI`/pRsxADO'w8 BHQ~f樂9ӦXّ6ž R̠\7["0r!Ht2uU SW5bJ.h3\KXv#t"2xZ$aRce}ީyB$0Se+D?Ҋap2 +CkvN>rC{^ͷ,,ٳ0INi=O.Q-z⚷/kV|R": +":1̥A/\JO횩]Lf E⡚bDWn\=9?"clD3;X^3˳OTqowf_Dqоq6Gmދa9`+:[ʜՖh)ad d +m# os s/-&E)Y)Q`7 +!<!Fg WG(4|۵ EnApe#"KYFP1LkF?cG#0xļf>yyԢ E[!K[ Bj̜"aePd`ZWC_!Bv +fv AM˼37jwi}xۗ`asD[Sa[?' +Ć%qOabZ6@N"$;?LMՅؽ ֞$H_XqaN1`jkt:go, qF{sJv- v~dCƇk猽Mi aچ3}S }QŤ9Zqel1Ǟ#HīIqN9+,\'NBWMƩxz&ZH({̋Y8&,ecKbxC ,T`oo8溂DX%gc58yp!̋FjVLbcuXx7&l1UGbI_R f$g$"H1'fKbN{,ZF1%Z8Gr6S\Li[0SaD[J ٯG#*BC0n):͒C䜛Ī_qn;1L^yzI_%@8O:7\RO-Z].vLŀu- r GP,v,L7[tLQYC=.D1A$N8s<G uq6Ay#Q@gLyA?Z?řg1kf;p:T3s22b!!! +LC 07aȋty[uw(hV"wcWX<@Bܡ,-"wO5 #=#I3"e;0TR<"$sN!XqU_]=r1X-| kLpno +AS-]1sRDcFbuϣ!:u e뙻\u!Y2ѭubڑnNjIL%A*@;(ҙ(*Ǖ +$ァ4ـyB$h1P*t +0T7! 6oibP +| 0P4|=]v/w W%'D8-ι'l|%Bw-bd, $O#QIWl+rc4,k~#"Jdb˖aruIV"5=`ni5;лn-" +iDK+r"$w༖d*83-?`&<>YLUi~9a 7 DGيDw{chn(S]%*V >ҁZspͪϙ.Ҿ!ql>̓g"Uʡ(uڬ`V^pu4Q /ǟ9E˒-wT'BŎzɔDJŏi>~+* x{2奯 (K6b;NAYJt&zox +lL8HQ:7ry)?G׷pZ]r{mT5" :PHLPLP#Nᢲ,8{2>n@H.=@2yuO˖evbҍdN&S/ɋtzK}h#( #yKU+`u#CO+w~H+(Fggz)[!yx` +<rR f9AV{ +?9yI Oz4\}t+{7y#Lo/91%%7%h9Kܽ(=E~[fk;/cbb6`#=lG +Ng!j#P>y?%PH,ʴެf!BH8 +‡r#> +l& & >/j*nM1jMKhdU"PSjH]\s\1 PLјT*l=DP!6b\_ ˥o7?g}vy/ ]I5!TH$ə* ̌3 ~WY]'e0?}:E?ܐq6de:˪!Jr` Szs3}RrlX[Xg*2o_%uA$M0 >EP! *wmԢdpmP-"Qv.,T|/Q2-x%S*V)bx1qy2NC.m(:9quޏ4X؃&^elGy*ĭ8~L\H}FxT~ x%1%qoߤo}مQ{9Au̞;{r4U߫C9&{sGcn'_u}"1 9 r9θi=2_3ܑΧ?ix8M %$.Yz[gIm y֩}~ =0Y%da&*OFy1Ar_Xs!bl ]za/eN(蕶E+e/ +!sTQi-Lsd6j9YYm10TN9tkqSZ25׵.1=%ڃֽ =x%!lj.264 HJr"Fn%>ӑ>@*Mi/J(ǃr|(Snss&hpO ЏҢ5A-|:g;>lAVߑf8ʯǫE&!S /¾$&OtH66@ d GR#hq˵VU^ǰ.|cMGŔ|C0׋ǔނƢ` >8PERPxLQe/G=d#!y2,ۓNH;F$@aZO?k7,] +?Ev-c^$8,jN?n"2# oxN3sƟf'3)DTnՈ/ېɄ3 *&<Ƿ CN{#9d(C#r%ΈXH>J$H~vdu-텷N6\K-g/fz +>kIOp4B'E=9eBN3F:,Z \$A{lU VrZ)VɅHɮ됵weqa\9!RR7e'W:ɱn̟]JNb|tTUUϋIs\Q9|O&@g =Um`G1Q/i頻[AaspgQ8PI +{~8.^2W a|Qq;ܖ M)uyYɖ>%pUB"lCn"aXKG6'zfDK\U8 Y^J,2RBV dml~$c45fr&6}8-O`05EE[G0\#dSe@&q˒tjKJ@!ҰV0}ӏ 27–, -y>EVDuv +ܣ'1'a#1BDj=k"r|\%ӳ^  "+r[|clR K V$T&B@/kP>`MIRcz6{ *n,O=[F=I1R\[ޕ%ˮЙܱl0P+S9ǻa@Yᖜ8%̽ 7l=Ơٴ˕GϒQ f +,Qjڜ[!caڴtCu&yHRҡ^ѰEl}<ڐr +%{3r M8'S"L;ĠT`&"V{dZ! +7^RuR91X 3Z)Uń j@,|tR +vK0t-7hR:@v;6T +2+JA;o +xp ÅJ.71Sx55{Sڙz}/ Rhխ[î\1&]3EcSpI^0J0FJ@{"=,H(SX=" nLPƧ%5,Z![:G:R0BNa:[}: s^Rjt2j'gtA !^J/Y"ܩҡI Y|`XZpRHt% o[z[L Eñլ/7ydy[ցsp&BÁ +.%7=Q5 +gp{oX"SHRчvS-p$p=|8ztBZD̉eO]QCXalc.8 l$Y2)n?{6X6dcu4=eй˙x oO Y=s?s_!LHo]Q$P?˰7廓#cls%ڀPፍ6?WYc TkB`7Aj4IGPK^Dc>X]8V:zY5qUMjOmn:&9eGMVad0v +nd 4=mԟi3l^Ӏ"˹jnwÍ3XaKK^U<Õ鉋8D&v~Ӟ1~[v1Zi%r ?'tsiJi#;P%ݬvssDj h|K]PAfڔp[{w-\hІV_\dGߪr;eJpœ+a3\[fP. [ gzΨvinOK^H6gc;o4rD -P5TH)S/s29s)++K*R q>Fa3JtlO +RZƩ 9S;I=ωTcFᜧ=ib91%8%)9B/k;=L՘a=2IrcՍ0[ޔQ0:c  ,J`w9%C{#LܘQU8;1#Vy50Py}]==!(zMZ}8οX%™8+'^(kKc$- ┊%is`p#"5>'G4'˜] +F7,y9l|P)YtiǑZNS0/q:vzwVFRoh#Hu$P(,G'Id!C$=?.F.!܎GY5,Z" 8L#i>FQG^\=ګ`^!H|HG^o|-)DF_ DX d5S"ŷBd lDLn +AbI$12=HeԎX[˺+kKj3S9m).Ef`*0܌"ooD-9TI zehiJuD!;{X +AXn!Ē٥zkjOdc +&lI s!Rܪك<)j-\|eC*hs ݒATo}_k b,9F<>?ؤC`HIJR!,92X39&EqndG-bG 1ot! s'>ivУ%]#>^%S`#I c 10AN +!Q`#_0N~#f t9R9"أjU[oW\'wlSgh;Db3艡d3w%h޿Ԡ:qaK3¨@ږ"EIv9:( 3vG ƍ{Hԁ[onXiOݯmH<|I0JNa ϙ9 \]A ]O.J@c8?IS9aI0;kP(g + +pw@,rxu ~8gy< dzxޖ5bp2}x,ܥ3y{#=v 9v;y$?\G`.s܉ +*ajrFtDP8Tä1gEEjx8%*s/\}ha!xDHx⭶FLcI],cCFDXNXo2֛ވ׻9Y%uO``uO31%1£&Y4; +E% Α,1GAs-! DH<3$!+9Y?B0&7RBpȯ PKx1eD\Hzx (vwlĒEH{h5Db3=-]`c*6L` gXE$,w7Z1΀~F⠜=i'Ĭ@uɷ )}{V%Ģ#Axy ƭ/(B\\fA,0]NĬ+i%C{^0ZꄘӅ5*>BF 8"61-g6@qc;y{kQH]Qo8FJBXoH(cg!'ao Aeztwv[8ސo @̮*$}]뀜Yʖ^n 'Ly?Ga9@,~9˵ ILY( #W$] +gxuKi€a/fi,1JzHn!gHlOä灪R Ðڣ S$.qhSCʰJ$o6bݚ0dcߎ09e2 ly!#^^>9얟5 u+^7.z'+R9d)^^eZ͏%yP߲-SPԞni>2 +%CɀO<4(@dbbG]՚g= ފ|u &0q40E29Qk6QY96AG6(E !tR^ Qa{q:k({yD>=-2#{*g¢3f@ +vuh~_MyG\JLAt*-"BY1?bx*B 01 +r [4Z4tDMZq +[(fUYnYV2@ +R2Wxqt(d7^EXx!=J+=bx;!뮣[iN 5Dm'`4Q$ڡY-^{&nj&9-1&B13oC:]U`zsx!eQL#X}E3]BeS3~`!#0@,dU=zEwwj:d=ZC +,G 增q AO^@T'L'hgًp}/0Us":aadgRPOQ FV2jy3&u +(ʹOP!h!o2 ]~Lo`[#tx٫J>4ɗpl89ρFQ0<G%mF~f93rDD@;pMi+-DwK(ѩN ]QLh5 # +kǣml:Y*)( e0u2S aѓKFFYM b({(<" +* oJzzg+}41)%| +żm\IYz1` .U;#bᘢBh9i+BODMÛzF=)z“>a9k:hu\#Zr""h%,nm,A*ތQ(1@ڎ7Mq`ĘrXebn;#D17|M#u9{:6un܉Q8=P + qkqMwMC)L{n!HjUC#5kn\|8|ӏ=oܻz+|f*$3\(>"@Ģ ZS[ Ib/UL䑀{n9Hhۂ\h-an EpZ3OL M0 +/x/AăZH_gG-l'p\ 2 +gĐcj0b iRM1 +j]p۱ h5\!'`I:3wc>Hϵp4VZ!dx!A +|?|c }!*P9zzǧL +*R`虚+WX0}dUV1\VxDkTWlD+_ЪJ$7dp 8-b%= hf}Oͅew'.&.hU@ubjlr UuI]A# Re[$95a4a`$!-'T+C &p쵞Qo][! <\\$ *5Écz!pr +\1&sEM 7)f8C|ް9oñItfعP9Nã, D0Fl S˰uKd|ܦq WOѶgxņۨeAәv:G乁fZ 83Ԡ̻=|Ui 2<4$h2g`6aje%A#[nEL|+n-}<8,38e|!G8,2qD:ь?JZ[Z DP0`+ր4p zq8DLbG,>J|ұc߾Rb@1Y[o=z-{~gUdxWU*Õү2?0[8Ne/BW/ՊS`P~fu4`~$g>&\[bRzW!SDJoթ",B|={Vؘ^- 5?$;ciݷ;LvP8 ^:!=J KBXɊȀqhkH *'p^I$+xKk{-ZxRr K[DaJKް@# ;#/P9rTT8J{h4tP TGK,@|w3BSA@Fm0CY!g+?y}H0; qkF8=޴wP)4;DHo 9 #hx@E*,PG-^Лޗ9۟ED@~}b~A̠ i! K@t!*QxK^m@ X۷AjLiމv/[!i_. #h\rŅQD0r.,zIóXrQY&oRyID賗Xh(JbѸ:DSB@ ;tV'܁:D. ڭԖHX( Zlt'&**U8}T90 Cb?R9oHa)ٹGN*wɇ^6 z &@?Y{$X'RI 1WA^*(#\;ۦ@tMy|˟#I ">)|MVJDQ :mMpbXWUQdb'nPe!6=N5{ RXՎp,1K6 mQ s- _S1F݈k{3yDH!5u@-6\ܽVkp`#zgT?#\ Ji?ޞ>3 7 NYhLzН#Y."bbpE'|.s ^Şp_)!PƬW1P'K8꾴㎅ی5m1@1->Ð7{eGE^6G6{G x=Z#ϔ~(HLpȿfU!2>mR!sjKԔ.oI@~҆dwti8= + DMDB3L歄ʹ0,UIĚ.lv`oPZEW G'4xA50q/p 5p xԇÌ@3+ +9te1^?0؝0&=ǔ/fҁI &Îf`ʈ݄Mw@xl_]Su7W#GA7Q:r* Ø7c'Qz#Fa"x˂-s[Qnb[@^#lbPhXJr{ SB2 ^$.M_p^m~dB2tщkyĈOTeZ/Gr#3*"zgV=VdcaYÈ|35M`m2Ɲ F()3ߒ/BO`"NܾAA1XMOf= Tֽ"Fpd ´ R< +\BŇ/ s{GSBkVejݸ NE,ҊOK(K&2d[j)[iq1WsdbV쒉y5Ck%{bؒB4"r1"hun[KBp]OeB|!stM6^w(CÈk~!}Ib;# +L$l5fW95%=쏅: s/5D4 iA'x SzFr=6`*V#|!d1B$lGd`]j A:nD-n{~7=`$m +!㘪fAӳ=vAZ@̀+p3A DĬS0zB꾥3xh{@8ˇӓZ,O2>R,j^@a0}\O[Ŋ.&B\6Z . Z]q%l5 lH b w6rIkQPF@A(ZxTG&TrWIZ]00xo\-\i>0LA.S =VCZ]0i +هLB#X´+2OHՖ9^4XW=] +pm0yg}kgέK=PciɤQ :^5 R*њs*9ƅÂ5{k.F; +nVI8Yp)7N>^֌_@79e_%Ѥ($1qb˴s156 埥*^e,A腙'8s#9HhkeLeKZբ j=سՈ^fl e–kF vm +Mj%4ڣEH$C(kJ]9kvV%{0Sv%U=ipVV[œlYy+-zMKlsMJEFD.N|BTeeEZ\V%mӪZ(]( _KJWm0پܧVG5稗ьd%;*7jD(d;LIQ%ȝ{:.ͧM\%G(MMc}xN|i+)rٗ1V,M,wHhٞ lBIl)}ޘoFsϹ(=բ蜳ujvP9g봔N+[\BYRz_B%[G (kK]tu:KjgEU쥤v&vH"J0% (nU.&y{΋ᦗ-g2U_P|nWlLZ?jֺhhQˎ:Vm*뿁FrD":mͰ$zw 4ja.@2^'lP~̚״j(ˍHBmeMGoEγf3M[X"7ֺ>6־lm 9 . ͮ=-aȱOnuh[fui{OcPK)0T S]tHIR W&O .L/zl5y +(56{I֣{$OբkpIY59sH6Ѣs-z1ג>Ug#ݹ^(~˹9yEJ5Bb${a[ʤF)Č &Wi.Ԉ ?tWF- (m?OUˆb[nPv~tmv5E7ȗ”qPo. DƔL= 'eGIM/L[IkPRg>Zj1G (nyZtaβprVUFYYNwQ&)%b¢gQ +(kL*`Xl%O4P~|F"μxhI׏䩉1kP0P0cxz0^=Ip5kI/DGpkp>`~ y|a ! #2Ci0\G?޿E;~>OJ0C8*f4c@0|eETv1_bD_0{FqCHI/-6ZH]/|1Dq+=|KZaA0h¼/d4[1P48!:my{Sيn}/) 5dܘ5zBUvrPai'µnDeᢒ,o36xԛpx~c )74lxjq~b#s'}x$gŖm.ID E%CO0 ZR?ÖIL+}PH:6%k+$ 3TŶh֏nommuf-~y@m1o2hѳ5qO;xIh"mVy@1w2(ږmnQ-O ~v U[ⶹ< RRw4тxx\սWnڎVPᎵITYm{!1LĨBoH\G0gO'] &*Ś7m7nQk) l5mv-s{|jKܖ9K$&G%(n%y\B-qkܴ-gEdy'VsEʽAP\>F.T[&r0#cjʻulIe.oh*[ ֖-y'V@m))6`^0Psԉ7v7-||jMJ=!Jj5jz:ȴ |mފCwa[PinbPB-qCiCܢZ\0O׮ A U[N;.>N<6F[ GIښ  Jd tGpv@ʼn |fՖl.Q U-|@K]Zs_ӆD`~O|'+0$qfD=}*WE/xK?>I}&X򛖶`>Ren̉ B *{#V@GD󖁻}7e%[чdlL{#\ϷJ↾ +W-w-t/{z~> o̸82HBC^g7'xr*mPg07[FlyE0=0D{8bRМۖ4w|`ϽW!H]Π(%SF6aQ4*0Sm'f<]l?Qnt@,~{uMÃ5Zw<# +7× R~_Kڟ$Xآ Mᠼg'm]}mWC0>ylcl=l1LZ %LDP=a6n91 +d*dvh1"m G̞R)wap6r.ڜ^z#7^`ҖUz-Cձe:+e^9}DnMXb k†u>m]&PI=aL@Q +IŃmPyafOVy9z<4J(lG#|& l[l hv/l6qo isYyڨ0za8e Ei3@CGY*u(?ykK0qbќu3Fq'L` q4;26"I5.` _X.`Nζ.h: Sn¢k`*݅rw4)-g+lH\3jQtFj> Jk&[g4CV?ju@Eӏ.|t}Nc^۟bJ0e[hގGz[*~dc5ͧh*~LAOs8f¾%j|+G]o^VuYD<`.֬Vu% jY- +cd]<` ['Tu&`P0 R:u$k;K0fS5 %ϕUV߶8hDM/7_?co }Cо56յM>c;AG!`&@X1RrK8QeS +M0B4z^O0xmɪCoe¢p$!+(au:/, +p<™ 0_'D3*TH] >`TQEB0#,jYFL}{6]x}c<\ZgIgFϒ>,SagxJIAV8`CWlImu!T0O$ʵ%TFi]ohZCn=OSATzѠ,F>h"5z>s7 QVN赂ʮ `D>F'y{Y k +LS_GMU`f~6`N&>X0uZ0u_XFe/`;z a6`(/ϤT/0g IJ{Fħ~aIx\ w ]Ԣl-%QG5ᅁ` 6g =cևD Kn0A5%Xθ%]  ^-[~oڏv^ˀm>}ܾcxg9-w߿o|?ۿ?_o41͗ڍ\U \r%U5_`/~$ +endstream +endobj +217 0 obj +<< +/Filter [/FlateDecode] +/Length 41684 +>> +stream +x}ɮ,6?Oqr6Lfrj OdY%%@n Ob|MDV$l.cڟeڱ۟9~s^?m9ϟeDz0?ir?\,?q?f@\ 4Okx?}LNhPz%Q)u]M$~o= QM@_lmLskiC}z'A][}~b"y̤Y/vW4 +fF-ma~ elM]M^~IZM6`fe{CFwy:jP +s&3\Tټ Bo?]iI-( sЮ/͈DTf{7 6_] ,l9>J\~λ2u0!7)gRR`;N|߿ͿCEsO(4ǵͦ?+c}7+ L:LgYvtՁ:ic&z:f^{`ِ^W[=)@vfR+yA? i]׫ZA1'Pr\?ۮ\W/zŒ޿_n0hI-{[f(! BS =@3!J[{{W`7xg& [S߭tV'E&;GhZ~VG&bg^S~nVe^;Fd!\x,Dg6^ٍFZ#{_+W}Y[}mA&$\?+}pW ^_r9?[ +~ bbڄBeB=ÌV?ݪ;6zYj|{Oގ&H!oҩ1 +B\<-$uyzɄ$AHs<,4Apv%(_8=%v(uJ+ w{&퀄ǥ* mp4D8&9&YINi\ ``ß h^!T[+jBAN핱 N FU܀+v]낆}(9Z 8}ۻS{UC[ l 8~D}~}PWrs J$ ن5RCkl]Vˠ[kt;]9H 0RN|jӶ1?P5 AI'~);}vM`?f΄2%N0RYp#p#<,NˀDܭ7/v/~oxHX3[G-z%Y)3Wkh;f1Y4AjɻRn=5 a2k `Ik] ^g֜e?Rpvr1g nNGINl*qt ~K4?j4Iz&>fFEd7ܣ4hP=bR 4 7my~MePh]!@ͮ|ZF!BTE16Lgns+¶﯈`8ܜ +rRF!03X9ɑC!0}L) ԕtI_?R>feb\ >{"$18lÍx g2;wAJgjCz!w*Y{ z&"$8,Y$gnr~B +.n#[?J/5y?KDPX`žg&~!JV܈Bm`mM"ņ∢Qei Szg$t /1r놗Ԝ ǚf+p/aQ@pm:_F)Dt`GDw!-B3bL̤4XBkC 禨UzٝbNiYZT^Kqڤ)D6dyr; :jf[in^@ aD#yە's%ux9Yk[S`Xs՟ņqdF^i9< &I<_WluKp`Uyْ/;ن>}м*3Rry_e]xTlwSSR!!-bÍ`h(KҪGoKvQN~۞R"$-ۑܽ}#BeAtgֹ_Er yP/&yP{[R:#ږ<ep#vۦM`*JcBo g{“1~WLv[o-"tIJ4#BX8}uH] p匶gχ,Lh{itDP X`FkpK+S="$-bÍyE+!%#McqG>Sf`bM0!ډ%!%B+N;%}#}N A}啎MُᑏFmʂϵ;e]O\gn|9*laI瞛ݹgKrįͣ3m&B/mtt{KNQ3uB<=yiq3T Ѐ &T Թ"49aQ|P@s#B̛vp}<9 y\C)5@OC(0hzt=E0Ha\}Ȋ܃:4⑺-}Xk"y!G (` _fa(s % d f_>1e,=(,D*RtL&J@T$a 5W È7'f9Bf]+_.m#1B҈ɲD'ҙjQŲ;aTH6y1VX&IDKQ"!}pw=A!xhǖ$DaKzs%1a4!XD|/ѿ[Gz0#uL +THh}B"W98c NqĂ#H @P{beb%Cn<"및^)H(Lsu\aH<`fˮwLG^^6Dt<:L ݳ һx$1w(/)W^rQ#1jv@濧+&>z1Fٗidtv83|J-:4LBtG.1[!iggi{_u=U(Ao=nM^%4|hzt08t`"d M9kɋ +=_䧫q:+f̛>p>uPp¡rF1>fGf͎Z3q(jPYssy'p!d2wA2Ra%y A?OEq'8eAoFj&%9s HZ'ӐaL#r.CVT8@u5pP `IRBK:, <4F +`kAf>u<5+* 6 BDQ@LY+r҈1'ا@\I^&:'}dbM|S8`025$2}>Q9yG&Q ɡ+|Qzج-F☋$ ,O"8:oKiNYĩ*7 +'A`P",@j_?qż}[M}:I~㱽>NCP L"d}XC >h4x˖l]x`~P \I G`D F%/AIOSPό'pJB ͱrK_5DVC130Đ4q.P^@t@ 3x<'"*B +36!Fa6Xޅf+yyT9]p'/!^^sDׄL#wҽ'#(,5+E kvhQ?-9D8x(@P&X>Z/2 ;f/I=CQZ!Y>ėOD+ц`X YVNÂmEq@?CaA<7h𒊞|H1o l7˞ t@Pfm.[XZ!o ,L"}h\,"(U0DғP$[Gi'3&C[0(9UoG~h,;Bj!y8Q*d[N>DABa Y>[a;4k٣gdG^K~8GGV(r˽|DW $#ǞX>Zaa;2tB̸r[k~i3E 05OCv~X&g.b62r"(p+leF*DɊ#;|z*=;|bh,"QEB\E+ܿ N(#lC298$!F8K\>vR,gZ!;-!+Y@'FQŇ)V=Ҟe(eWhU{ݫdS83 = o#bg$+bl>/QdJdǙ=?=Èhi=L _#Ȟ9>[oq}x}L>ز8S!]zvu{GD(5pozc#G0.vtYT?IXzqjhfNn_#|$/9 C%e\,Wrږ`)bS+ViEd"M ['b.ђ|SkwzgG\:Q<-' )!Lqv{i:4i"/jȓ^ $gQ=6W7(o![zB&9G$AJ2O}lq]yr 'O{nI8fS<x2C<(D@1@>1P@+IuLk$ǠT15:HY[(P*0++c\18~(K5ެ{`Yy/ G0=1胢D1 ̓|O*0b8́h ^t7W4o898N cHh\[#њv말C!i8&^=7Q:N0uN|bh+@mWUjZ1UGaeY#zbdkuLjX}{_Drc'C& h*a(ba!I*Mᱨ8NpطqȜ ,R8Xn,@YGY;c[bJ$d"{0j Zh82*=s'?7b 4XX2gNb[4 "'zOZzsv0U$P,r$3 nkGq]6].sxySr#Ϯ2ojq]j 1sǜekH55=Td> 蹒%LLF oxCxD1V1!,x*IL ؛!7d(AwWрcz#jה͸]!Q n[9r}JL7(W=͍-N)30p(b.1 >ȩ"@BR&:$" J1{rLHzvD=` Ѽ6A |@QiZe!f>^O$fBYGY !q}KcN4!Վ롊nK2C\4g#B}k(2,1׵="X)D-rY ˪B)$ x2[,?h>Ϳ_0s(fyi=́St҇GbnV}0ŒB넡"$T-g K̂0TD.rG\+&b#(sg + We$FB..!t}YAPTZ!S{qfv*`Eq*On"J!.< 8rj& +cfaO2zAjrֶpeRؾXa[Yh"m"*Q %C6b(lpb.ߙbvзq(9% '1Ǧgo)7Bw=GX F\pF=˅&RыuDU:0(LJ~- 2@&X( `c#OS챐]Y(*(m0=sǒhbz*X=s aJ>늟0ɳz 6ZJU虆\J E%cO1l]{A}vuQVfjƄ(X̮Y8P4ǸX`Gm ߕ(ax_.R2t=k`ljL\^2x=kvS 1TuŽyHJJˀp-B@xjdQ{,2,L$t\uKBHp,'pGmYqdD~" g):tDw8#!I H._*By`s9z1 njv ՉtT'Tth8d@Q9-bGqQ8 v1Ġ ;2c =KSv$>"Ȱ|9JR|-@V̽A~@(3X>[ajQ? +P{Ğ.0AA\O4?" M <=΃bj, _-Ąf5&j\ m {$E:&؈R9J-W+`E8g%]eO3`_T|qNhYDّrLahH38ŋV)%H5 kD0X'TlLQ]^}s6pDD7$Dj8H6wB=h t4y22I ‚W b׽$5H(PpwpQpi `y&?~D2[nu=~ep*L@<$Qópmi+Z-e;{U@r5P֒$Q\U +;MTdb4Vq ރ*6Ïf#HC)c Jz-F=, D'߻ue + X)bOkKO^ֈB:`&=^7 1pPp?Wh{#yZu0A[8dt"CȨT!D_5 QYbҁrADK!Dž"|GO@<$ҕ%1I?#hɡ aHz؎dwc?B4﹩)KD~qf,U <lK-6 j-5ʔ ]VJO N"磥J?1kμQPۚ|-D%l((bS">` Ն5ij-V&LS +!GYx,e-Z\)k&1 _3AGŶ."3 9״/Ԛ*<#ӄAp=@& t51eL_2Z֕aVE9&wƆV]daޱY*$L#kFbGmn i _JsVkbգ5x-&U e]@ n@` ݄eHVjqeIqDH93XXunX6m{*o}h!,&(6F}H&p66 әҳؖDrY\H(sjFIPky +,:jS_3DE&]pa0_'\.e!CLP+KƶG4 Q'^6=,#&Ķ4,\HV[^cY_AuB2`(ZtrfD̖YPTcy\~2UUoxq>iV\^H^iȣdۅZf(ǭ'Q]^q}'ԩ%X?) aB_ͮ! +ɆD&;^j_z4T6n88%LzT]]y }ysŸi$5 *j >-jZZuP;H5P3-(RrhMuyq=0cb^P{ֆ6VgƆ7R=ѼlJ]U- KvR;?=ڨ&{tZ#fPP>^%=Zj_g滧9{}{Po(Y_BlNp'Lf~= M%IśEӋ+.nS +1kz`U6{m^PH^[ae\>#;^ Yf?cdGp\T'2{QL`@O:i{gӂ'5PgI<=^N$q'1h\6`?/FQN8ʌl(33ă7E'p81z?hYd4ʖCӤ,)fXv%H>ʗ+Ėu8APaQ28}tSD*jD"7SςF81#"6#I#73ēg7F:T# AEIyIQKȈsQZ$02@#TxK͢yC}M6އd?/\;J#x716quqp]BCc\ i:2X~Bol +$ +&S& Ok܈+ @!|@⚂+:oR{>gHBǨY19#̲!JiBFϖ4^ROoκ,:HRXQ>`J.T +hqxlhIkۤIV"j(z`ypbaTț%}zGk 3NB]P%ƙ7%NWq[ω|1Du1]F=dx/࢔:h㎑$%A _&" *0\5;0Hf7] #!%s`e';CRNC>N8h/ n*V'fb9%?&`~Q)R&hEu:`7Cx:&A E@8J쑾'ȐP{KQɰ`۱h -iH  +DSUw%*¡+QU)\ EHO6"Y ; \Ѕ!n `!{HP3jۂ%\ +VR Gtܫ5ol0{F#D28>QP"2K-6$#$Jɽbu? ls[r5tonX5*҄zbRڑȋkΖNeD!  m/[y-5HJa b"T& g+c\Ebh/Y g: Дbe4'A q11̒9a&dY>㖑 /6;)Wb)b +"B"9#=Z `1ą{M7`J<#l +`Q%D97a(έDU (f|PgLp0KPMaW31.c.~څw͹SSĀyNbV?55٤jxkفвo gr-jZz KH 5J+@нE#9F݃C ٮoJ~pd;a1 +Ng9E< @hHs@`H@r\[EC7֔`e1gbWFF-@0eZˆ!=uPd2@|$YHy$/F}>gc3gm2\~-uJ#n<沥2 BԐS$ aZI ic2Ⱘa.Ri\:F%r%^N-<Ȗd 0;t`7Ll$6zLqNMw )`AV G~mň=mq~ކA`85t ?\d5}`TClsbytKDr1Ĝ#|GC8~29,Д駛t| 9sn_%0m@߿YT?lg(^HNkOkdχ1er\S~yr,hĹ /|%&U`,<PH^9|xLa=]Hciǹ4/k + A.Y+*H./#J#ݫ/ze,$ H7>^mAH>ҵdpoNHkP$nظk$5Dt&7Tw"rx'UDȺ_y NűTxeK~VGУaDC?b <PӼ ~\1qk Տ Ix n41J- L9v*#' +P08WzCJ=T-zv-wxH{ALa2HJO / RnOwuչ{Zii{)XjXH@]3HÃ/=$[tNƩ !q+CZyͧ1ϑ^ou=*eL"shCCo~A@$~A;eH&xΑ @83h{g댫"3zt4XG@rm Z6f|!؇ȭ#R;f-6ZEiB1o͕feӕ!jFҘ+ǨI"|ʔèHb"b"7 #>Z8] -`6}4rB/y';݃l&%z)۶0&axUAR|[E2ՠ?=;CR٢S}R}YY+,,ذ ,ɱpvȆ7sQx&)b܈iQ +G%="H3O@$AD2GKjtUpU-2ax3->yLPe]$A)+>ppnd"اO{b=Wp'=I;<@(Ё+ǐ@MFW~wԀ0Ymnt4#ܤhnDw6LSyz3s 腮x+2k|vc]s|rE: P-=#sIֈUpr,x8u!=N)94imwHpHi _ft~mm/-5:]ͅ3YH A'-1[2"-b iD'lb{Kf Hę DCؗU]r_%]$5;o' FFj.ueRS7LxwRS#J#}G+`Q85ǤDhcƑ +&:"eɕ͓^a]ta/wϔy&Bf 58jez팢k0&NW +&./J*1?F?x~f{bQ QP qp rlu#5IPS='C3ڇQGi}5 -H_5 CHA\X#ѱR[7<%ɻȺߠn +OJ0%lKrR:$ʒ5c'޿3 bloHHnqtY&Vل@eizx'|;sf@ORܚN#A4G&Kv5fp'Efyp/\dom5 O؍KރZEkd-eo@zaD*bOeFuI!&iͧN YsK$ @@EOL?6z|G1)p`c~:H}X d<ȦĮ%\P%}lBJ[:6*A\Sq>9g[CO_Dlk5U jl1Kf6+0K +1<'v B. ,_lxK0Kѓ g0Ǒ</Xt}kƈ8J<-GC\0}^ZR+7cg!]Ղmi8(9ڊo5͖f^O +dB8jI?\,k+w|A#3yؑa-ʺW)0Z(T4L̊ s>Ҫӵź|j~&`hcFjfo#3`ϡ`̽+Etda,3|G~tfŨz9N&X|) Xy)NC<N݀raJ'*;F=!00NU4eO +CM5Q<&uv`Ϳ-ƌ*,2*펣xثlb'q@7w=fJp1L.H7(3_cMW4^\c<$u(<*dx.FY + XZZ-d,-0G1_Ӟk9YXxbi/3I@LCѡUg"0."0cZyp(cl +( K `Qe C1@{Z DLr<$9NBJf"ΒObʈ)tc`QL8!ĕ"Z$P:8+ +Q *B[P NSP X_yvC$Y1TVTT"y +E\G*HlsbysH&yQnixJ[%V>鍎f4[k ?S"XOpL;*AİG+In +MC\@EypJ%Ef镊 +sCΓ`)l(3Cm/-@[lD]0Ie8aBD]-Q$Y5}aQE5.S\^2pDCGɈl="*d n۷jKWے^:0Ԁ}3ʖ>4x7pn "++a/tc drxh& ?GX# eYs$hiQH?PɀڡSܞpP5kW05\Q;S5D ۂziTe6pIQI7?BxKq>k)\T$,-(Y|T8}sr|JgPWډ6gcuL3,>i1-=(| (K%G-.!,mw9fy,r zQR9~ŲIcP¯2D^CLfS]B;F2|p9XΏ +K]dەJp?s.?~[Eፑ04^n+fL̙i= +͐sAxm;rl\-=RIʂJC}t=?%nɶ#QRg̑ Um1[X L~| zxP5#ya­~#8]uIiH iEi"/X^&8-fZ`iW8RPӤˆmKk`1dEb ;M,Q4`;3 `_`7D9MXzc%s d^8.&:0c!JrҺ-r:B{3Z.%,ԙ.-75ʃ\舒+rM|O`$L_qo#)@HQ+EG'P+p=7S[ 9dA,vm52Ou>m#ܰ= sf()\{ +=2-SI{ cԎaLtR"`chb0ӽ7T6'!A{Y!0nn/Ϧ)B P!tAh$:C)wOW{2f{hH +߅|yS`J@$˕0'~cM:Zb))5N~Wqz+,=+S{yfK_,;2:”A fV%b­}\SX2!{*6RwPi]xХ!^sCEa>%D?&&ZD 2 +T[A `Hy<d2$0sJv~/oDC5`%VZk˽ V-OSߛ}FnJ1&Z2Cܘ LbMŗm) |"ؖ}|ˢ2VECJub8o[3)0rbil˙~DHn5/̺C[ c +#[j͍yg'=xȭhPFR͎{Hu/㯥3 bښ1Lg57JS?.Im&Œ`$uc7fI0C.&#F[m^Ş3PR>Zs9\0kʄ`r}9P^ #]=BHp/Xs/er:n +CU2^<ղ[,1scrW\GN'ol!s1L0dlcHq$ /j|tzc$pcE %_o4'خ.HdQ*S("$Ucq7:TD2^#BU7 57HCSb8{#lJ >Z*gUtKVZ}120Vg~HY}Jܗ4"$*ZsBoO1O#ȣV~0Jcܘ EVI-;FiHI;<þ㯚EC{Z{ޖN+3ћ]e FCɧܤJ{b]wͦq 4Z?q^JVQ&{ZwwT>9X +GU+8O\ejcwnI=7W]߻-_=0g:scA͛nN܁s<ي+(vf~Ҍ:wF{i*ŚZStcJs=z!rќk9 V"q}Q"a1:S_eC){[r:<4 U֌EXjCowyX[ג}HsqӐ@9)} :Kۖ'o kw>!X-K*  آvnA|l 2nGnK?~߽'|K7}Q'P0Ys&\C*pɜ1Edm:Vc])TAZheATKnL/Q{,io)9jm0M[)Rկ7h hEG$lè`^{'8k +q=>9Ou:IUTV>|<,l+b#Tmìq bۋl0X1W[ݞN!Eo<[ 3Kf1Ւ +/ǐR0l vrQ~Ʒe`C @!L9M1RD +6bS yhv&l„`2}F2C5r]<@l/m,[b;޲["`'0{鄈ح6bﭫK=C@uYƍs TEYڇB[ Dc BhGA6mD-I3Kb"hk*֥G\ߖ $Z_a y5RzRBjY-oCaCH|@,ZbӲ;$tpPM .Zifv 9?UDrw 9ny>(#!Z! +.T}f}\s ;' mɥ(fN7%3,:Ƚni|D ~Sxh 7 ]#nҦ,6칽M*nH{a!x31^І؈䭶j2uufF6=i,e AI< (@r aK+!-w' ĎE=,Mj6C Jq= +7?QQ z~HkF%$DKWK*=@uR90Lb 59G6/A=W +jZ(cOJV6oik[ZIKPg;"q}hnc0\_imqJjeødQM@r[2EPg۲e\_-i3~!?H  3HE;\ifz30n'1S(U6t͍ǼNv0#0H pƒ6 1nEB"pUy !pH;Lבfov%7Dfz"~?m,N%(`yDOK`=(;<܈uևHw^}OٸM.Ϩʙ0I!"`X}ƹ+*cBw[ $QCL)}CF"2LrJaέSt5VdqӴ_YŢyTaV^)o>g:*۬9vxMgOXpe㛻d B2S#&M+!B>Sn|DX[dm,x4&(-` X2]m+)GrHv`ϖD^*b75 #Okn!(<_,~*->I! +޸Kѿc{5-7O]J" Iz& Wxʆf P'GLaD!\/@yb;I DTA#y%mGmVg)Wۻ`X2j'.k|<1, zI"+T,3јAo2Wbb¿Ov JCHiʺ^!FxM1}7[i7{%D(L2ѴN,E5@;V1'\b8rWR*NGmL#d`$Z'}5qwX×1؟XBa_Zу #.,49X#Z&4'L2[T1}iMQ9q3mڛ&c&/1۸{M1E^229P-u,ï6iV^U[U2#]B- WQgEjYԖ1mF#=mSEi+n}PЕ8N߾BR[|S]e`ϢP-$׷){_{˞!xY/{}2쭗ŋ{k&{hsޔ%;ܘ[j>KPPv ?[!$UTMq{Ń%ڎm[|?q7eF;24W[|#]~}Unn3![miW].{ +zNDV +гxu~ BnѲikK+ܘ7BAYYy ͻcd?:YmA=eY EgvNDq^ !Kx:knPL\a !$jǨ˺. +F^aijhJ%[/o0xq BimYY85٩&Sq $n2LuI9k/bY7I hb)L~^CQr8!DZ"Ȁ"2H +xzy0\:cecG2^,8m%۲k + m)+29v`tU XT s%>^Q1:,1)- ;"X M?86dp, xf#KLBȰqa^YlP`%s3Ku B]NIrŰ-[윖x.)"f0%- s[5- lDgy:LЗZpOR.4"(³IЕ}9C.M$CāYriMFcYCL_fJjTtdT4.#&&$h)9Ě +@y0c|X]1!e-h3-E)GP[cp"Mj<&6g,< Q(2!lw4B9+mRZ<މtĝԟGjJ"'b#LcH81~R0Ok 3*Q+)^N b1֖q^F/;dS5"Gt[pɟ`vIAAN,1tޘ2w"ӑKNGTAb@&@L@aMghTUG%݂G@T/(UD ܠv2P̜ +3Q{p4=e'NT$ML#jǺL8>+i]kފ֣{$BN|a᪁X$L^4\m4DFD` Dkf<*C`cy{<Q$'6Cڐ)>b(uU,(Dy4 Th(A{(p D"+_'FѨMl,XD0Hz%cDŽP#[mfŢ蝉EGIYB՛2̃aFw.}2QP$#K!WT\21 s6b(ZhF0JJ$k&i(c.Ycia( +4T3rXPB0,oe&aiPuk+7O<62%FuI-/r0cVi5a8؊ lNO-pI ɥaVJ>ʒUC!e(PDKCmglpHZ8L93+.3+Slu*LoXH$a5&H0P]=) k?m:븥KC'%_U{<\{Hklo) 6V7PeW3d[K%{#:>+YkZL +rGmi[꒔6 Ջ3k>3[LZ?ziwa=#! + #j:6 EoeQ9ZԦS^ַ)(^a$۫EI=snSG6Fw8|CґC{>Ѥ9lM 2곖T0 " n$OeS-hO@SZ]R iBD>j}9vG /FǏ/\ +IA ΀sbj"X;8ylYG&R/IT`]`GsX(K9X#O/G&?sA`âFL2s 5&r +@1*8K#HDPYIA NcJ$}`p+N dqхYH T'" ˙?X\1$x#9;rvqw(p HXD b`#mL1Kn `0Wi?)G #$YuxgfZ3&+%k!f0Y͑W@{Pu{.T-@#'AU:0. =IB(P[jYC- a&_g-(d{$cenTϡc`t tC&%jahöͨ<".莪h^=A:Ie6~σ~>R1:c.g!"ȫW׃%@Pb @ly=,%r7`oy%遐3g#{"Dw;$(dh ޻#!w%_.5"{zcUFp$j; FV,pŜT!`z1 ,-k|IiNA3iz Pmc>$ |יOY@> ۆ^>cEL@((?J?Vn'r=)636D 'Dk }p+pܲ`YIn DNg._͜FwP9L;CS B6 G.TD$Aj> ;8V&cbfEC;{޳,x~͵D ݕ܏[̨׮Lp,rD_@ 2TUZ%1r*n +Q*J'Vsn4g~-#F˘qܧbcw!K=v!t c8)8dKf /#xue8`Lbxd(4cԀݏ=|^4 Br Ct34( +sɰC8vâƱq.C<976 7k "ty2!F^h238c6\CȢVgNDkg`u`-m g(NȐۆީ9 9q8 +f_L m10"F9P ƥSdB ;cX"5t4te5Z,ƨ"3&H  ѝ#%\$Cr7JaEG0vh +oVym/ϒ%p2mZ>S"EZ $:ymO + zlV +0c1PCW1[$c<Œ(,L=xD%DWÙ5p=)4emĨL/{2E0ĹIONptoHeHqGd0YPpt`|FBB:~8Ed/YcA˽%R`W-:̡҃! /VXD*QaFE5>!U{~a$x 3&L4 bCDlADԳH$@j1 +>oNj?9Cs8WǔD|w LytʕHSG9eЖz{ɘ'D[LpY0oua{=Pd1^u]/l(Cm MQ {Q;sSL.gڅbX:eD18]#F/uOIFVFCWmH& dž0=0Hr PEAЏ5Hv[hIzOBGE/! +036 daQ |U2%F>B ёf1Lv11_$΁(T*UjEB1jƜQLSiRhMM9ï;yDD#_np2=&;11}(3׊"H9y{jn +#xp⽑b`tc +c~QD<1XRS較WwF<2c Y3DX'I*0*fp2ќ#y +i3%USY1qLܰ +Q>Vq| +SQ~\G20Ή:"QiN,DaLZn<֥. 9g0!RP 6E#daBzVzr榫u.c"JbZMYbZ{CQظ*`8"pxd}k;MQt%65;V{RX1NB*LWgLDItͬXs( 1yxFgoT+D&>f5LJOɭ⃍4zgCIۙ*1ʆ0|FWme-r Ʊ>;0|P&.$D2yH#mdD %u-/F)ZJZU"j?rq{ޭ"*t>fbf=, vi:;017$rckYPFZxh5)9fl ŏz$"f6G£V~;򦪀) ,>7MFYbDWG%2]ׯsUj 0xv|W߅0u@v]-_*'$CUL q0Ux=^6ҺJǰ5CZЧ#`pjRUa9bi.vt[4Dw8q, %\$hNpq湑HxK^7kuwΤ;b$BpJ6]Sfp+1"ӦV\UT}pFԧHҨ(B~&1!|0.S謕z8^% + ,D :"uԣ*)饏¡ĐfKo*y&+hF AL9ΐ&m]ڄ0!gC=G0DNg.yX4zq{zq0FwqzqW1/11^L-Kk@_w{qW0*<#"I ҂~؋0b wίBg*GLh E]rĘ'#ӋwU9FQ(G /Fg: ~MWqXp*3" ,TNþ.Q8KFEN>,Z GKFcm2)`Oz">Qf"X +( +J%A?n2SyDJd3) a&0HY(j\أC{JOR/L,LC ǜqV@P߅Bbd +Ñ5#1.N;9-†@?rL$"nYS)K-h\H| Xj&'*!Dy {nx ;4̉X(޲!IP0q>}K DgJAIKGMљ$%+$*5Z VLa!eXI%~D-Er70*^?4Dw&L򕇂b ceB/JKnL"ĘV*)٢HA3D%!@+;?A4gĘdp} dZQ(`&>&zBzLSJY"_|=z #1lfYɫ +xZIlvV<)Wg!#/OiaBS%Za5J(Sbz9OøK i0Yjɞ J)#Ld͑y.8-)r,&3-_>Kk]=‘,z")HtP( u4,kTL1 e)YPسՀ^2ٮ܁;7[i Ck6i(B- PdEiyOi)t 3jƣݒ-)iB*ў)l@V[ K)-jKm46$|, GوKԪ++>KDse{iu"9DX l4Pdť-Y0l`aCPDgM{tD2". eZ&AѣiڄSdE}>, >s/'mR5#GqZ.ӃH +8ٞڼg6ktDHr(OSxq@Esi6#]=4Ӊ#J"xtD:,[3ӹy}HqڮX1q?(m>{ Vf t6b}"/ǀ!i;NÌHJۏq+bHJeڍE٘+VߕF [Z)_(Vi^=_LQ^Qu̍=DŠM.(8 Z&2QD ȧl2b঱eGT,rRV"peZYbTfԎ?D}ɢ'ǀt&`).37|L"'# jZR:nӦ^6P&#Ţyھ=GRDy:P&|-d1_*;teD ?[aF0,D fhO3Q(8Z +H -je ug]@$r 5K6e.ŝ ˺f7h5-,zLƔnS(SWڋKxcK( %6ݘ6$飽N]2ܾj[iy°Dٖ6~ H(*mSLm_k'JeeqcL-l]7ΖCEEr-G*α8x>aGW 7%80vE DO uIoC9-:$?s,(:Gi"&)$y谷O86$Uʕ#qbZt.`ָHp[AvGJ@捥Qrqz8*y0ΠTuq6{pXxq_oG(-/?[~Q['JȰ8,if ./"Aa緀D7m7DkBWP1 n zӞ,~eo܏ fD{œ!w1B`X[zةO'xb>oX#}PXӣ&-[C@J;gg@HYܛ_bZ4o{<@AD`RX5@P$Y>p/FM@.u4W +v2@Hdp|$ܧC~ !`AB5 ܾi(Xo9`vAK m'qaF|msl=Ļo$$LaEr]Km2 ..70LM  Fչ?^J55,ӎwJ G+}6E"җޒ@ +y/|1qeCDƆn #'{Q\p#7f5ab"Ko, +(Qk !=V| `Y?`Fhb= ǓUInn5to~Cʔ_^ԴdwZi]J@o$͇{޲u̇*ǒE2 e>xΏ>j#.LVb'{q1Ug)>G_P&*-5[-\ٹEjQsϳ^g\?q^,?}ew??^}q+x)zoI> +stream +xڍXn8}W l&^$Fc>(hۑ2==_")Q6]mQu=UJc!?Ljcɯ?3#,+& +/ #3T%"~UJn=DvZf!/,Y(5~oWTL+7z)J&LiY1]R2cP+]RX +"햲}CRkWV+х>|nmoOmW$)Tt>:Uj}Z@p9b%|PCkGyk&+n\8RI +PLI_R˕tXJCH'a/|@%~]7!(m +Vr,sWA3}ڥyWJ +$d 8Mw%̷/K+MA6RZ:lGU n2nܒzGжRf%H\2?pq(L>Ӂ8>o#QxF^ïp*W |!pۡq_,B|Ǻ +ܷf 7S?o;G( +Mћ[h85UOplM8>k\*`eʕ`P?o`]X&b!`ehݹ4AFto[z#[v&mhDdvOMy+D@Q؉7$bs_?>6J eI ZB3VtN{_mgQ1b](LD 㘷-cs b|"kdm]QUz+k^g͟SҪVg-S"wGĨ_o7SEl@ B]աGh2Qa6&`r `:l:@?ШW +@HSɱ2;w՟p6bgsq!Ss?7ƙ*,Wb쬼|&)2S=^J\iС\!>pړ,\NQ&wtzRQ,ә($g'9Փey#SxΊ:˼/l%CE"6=5_Lwr&H ]멠9a&ڰw a283*x~6B2h[ G"0k4oJ%!m;6 xѿ+8hܒCSqhY.U03}w(M'0 `pǯ*>s`N$)תr1y&"BXd>"KQɢ$ +#-V:R^uM + WT=?r#GEB\&t T_%a+XY$/]͒yy  {duGbGfZnYe‚9Iiܲ[tJ!2w*w.9U2g*MFgY9CVet\lnyr{g%3:UP3!x?{^-Ws K5&sE[`UЃ?5]}}_[ +endstream +endobj +219 0 obj +<< +/Filter [/FlateDecode] +/Length 6376 +>> +stream +xڵ\K9rc@^{fa,ahe5Y _oF|A23ԭ!@bŵskσõrM}?z]K.Jw%֫ŇpZtLJڨq0k|0\$n<ɲ~*|NP*puTFK[_,L}hm]8EgiԠ,!ku6+̻ED&fj)F|]ipY*-oאZk.!ѷolQ5ܪS5Ci+mN_>Nﱣ⌠8*3=E?S|=Zyruu%*K;6Ht,&D`ϲ-†KLE$HT]7O`uS\+GlYXy)  migM/ xzR5&ޤyXDQ`z·k\HcO35nKbw{ 0`{[aλ}O )F"HI(V̆ |P`*(|T7ԆG%iM{K/bE$z4y`" 4KR> ^E֑a%iܲH~Ӏg yK<=yQ}@_Xa:S>(?plz3M ݛ۞{K +>@ގ0y+)XWED{t>0rhfNJ6Dl +[[3.Jm2T0,$o5He=hdh&8A7"4+ `H7"NFǃfN DnkÝ ~X'RIP$ea`Db +5O!"f"!?+A$` oq ,9m C|'bea+~)@R QI;5xSr3" +|@T|ȇI$)Hm'oO=3SˈN@Ax@ mAWT/&c\SD#ݧwҠ;{W 794¥>cM߷ohڏу6; mX2zd`|`D[.{QFmt$u):MT v"L6p +:3HCX& pHM~E18jao&& }rBI uPmT^52krQ ƳYV1zD!I al"UCodJd(mkAʢ"ě{<#!/ιWǩ9aU^tu$LV, WO9Fď*-lٽ,q^XDGc)[)CLٛQ1ɪ4&[4hwt@"P|RL+i,ar `cm127"MbI7Kj.rwF!aZ(KX0!.0XqЪbY}>tN Uu.bē㤐IAiCw{.W4bč!JM /3p~4bI'ĥAgmNR07]k|ѵ\%i Yb;)كPg8~N֌ =5p+ރ^q@ 2*^qD~Ci^~HHejѱdŲR0Ebyz|yj]}ҧ*iyy߇Bdk?ݓ\~z]~q{n?/ӻy,ɠˊS6hOԁlEEƧˢA6HZRyjm#lnFm]jAX-A|F5@N蕭'2JKcYMiHԥ0(t0n+,":LLG\Ne=#_)\ap= s+Dc!F,3B3UŽF.Җ'*(Z壥rN$C*KK4)ޢoJ4vTuY 9UAg6WYW/I0RA`U tСHrHUPK#8ņ}VtIP(i\|.rbB xH&( +#a 4qTU]ZRoƅa63BW(f_BE K?eNpҶw$&ƕ%hPl},k,Iښ}{s83YJ6i@8xb%/בF +&{o#+]gzB hK?ki4ίh + u5i6!0-=bX*M6w'zw"7 =.z!r\J02VQZX8W|9ß +ƪm{V Su*CwsA,!*HUc:f_We22-]"Uu +wO1j1eVg0jOi!v:c΂j+ߘ}xqEUuې= bRa%amqzfPƒKm!eg(ѹBf\D c:fɵn?`ymJJlK0I)']֬{|KVhTEDbiYq]oN1m,'5;:Rd,z-f02[?Od$Gw-bk=¼g˴_C뤵*ӅO< fQ¢^C3) tcRKq+QCŕ7qQF/M/E E`js!(:")ܳ5TNqUEa&;9"c530u79GAGa)pPu#Z5r +«0R8rYop %}?24TG6ma ?J~J#TRէP(WUy9 r^$=)kYlHw@)~6 "M{H <pn8;!‹TyJpB@, +؜_aG͹~Wm.x dU`bscۺJL~ABXÀǑ<"d9ױv ,z, +6m/3>rn4} +0B?kpPZtcc:؋o)K l|er #=8n.]p&2} j&I zpR\:|Bt됤)BGkKEXΡ]@IțI +(c:^\/QNCN]ZRIT>; rER/-Z*,!Ɋ{+"M&1"?"$=mqGWC9@QU4w%V5ao$W amԔܤ.(ʢMsUks|Eu~t]$+$UnVI'"*UZc7Y[ۤ&m}6ć7T]Ao:Z&鎫'k]WC4⻎ Ծu9 "8j{yjN0M\Ȏ;=YV_vd̥k{W 6JhqWM-dI"@y9 \J+yZ6g8fVNK`[yc1ԷIҰlrJ) a8W$y2P~GFTRSAP;S=D\c =v2pwގwhXHn<2;.+1qzM/ba!sꮬrpF}ͰC;n!psrs۽Cc$"C꯱}[ ΍8D?M]i11/[*fJ a!z,=ari}J|aW.j1Oӭ{Y\Py=l9`s5Ր A_z;!M+/4z +jJ"mY0OXL5 {|u7nQ*9i+X?YӢKnb?wMUEHrɃE;o Uf<͇c$Rll+CUX1BwBExv#ԧM4VP֦'VIp?=.w=~%<|yG3nOCYwK?_r£oGw-vd1lيҒV4w'w\Ib/ +endstream +endobj +220 0 obj +<< +/Filter [/FlateDecode] +/Length 1059 +>> +stream +xڅVێ6}WB!n[@1I6U`Y|}"ْ7]@f3g ៟#~̴ +V\2-~>]:eLAWmQ8tZOb^T +z~EU{{U?[L&Ұ㳰VUbUB0}{ly tOnL< +HWV-t, *ڹxArV RT֨0i]v+5`LU4qfB03_ﳟיP&+R/YUXɼS^J![}c7M[+cR|LڢG W'SRT^a vA%yʭ;-ӐZ煩\ֲ[套p +F +e;$ s^nyhOJ# (beGSwC^R]ȡW#OZ> /SJvbl6ISʎ޷OqL},dnYqVU2 ի 0>~T!ic"Zni0ڎq:L@h]OG񘚣87:$'2N>.XсikzdrEF^hsȰrx0jKhB:L@`W |70Zf).c_fiМܱ㎰"}`ٹ% !:q{j̧}L`0ICDE阬ÇswԪ)mr> +stream +xڵ]K$qc,%I^_#iHXd|`fVU.mf2A2`]Қ~Z\~7oO.krS֫u/O_3=iI-_irYu×?=~~(viO_J_ljkmGӷFo[>,Xj#+36tO?>#D5,~kgĔ|= }7զZH)VB[ڦݱ~q[ 4p.a/5 ($ˌ,rudI!p+Zs4i9W,o, +I>C'MoQvy"L'vkE,E6d.Xbү)]`}RI+c;1G6( AS8AXٍ Aɵ-a [ XS?dh.t S? >6tlg:IJkcMc p) 6¾;կ#Xm{J?)fOlX|="5d}wЧcTcp E ::!a#a_(0VqSEO|U=2_@8,v2%b1 iΰHy__b3@<1o;yVxf\A3L8 :'Cs\9{̈ +ׁJkX3doP ?DVRsk6 Jl3yH'G2_Z3*H`CDBsDNi^p_G@s+,m/KYGx^~EK`*;  J.;~>&M{.vD[ DWuᩃ;7WLV<9'huSsފKwFqӮszb;;8j|wAЪo4+ЊD:w&pL!lS^{\/o71vP_O!_+.h1NxylP=>\6/e0^># +++'i 0Ar/^;O;Nr"ǐ `uOQ&}59D#] F^8ȣi&m< ڎx-iR[Q:Q"nQŊdRI ,r{gbLjPVQ3>90&Mv(/0X% |':@ĈB:/^f8|pS|x1pnܓ=H{lэWWk"^~ ;X"gx9a+$+V&@drŞ\b=༖wtUAdHN`'n;yD?{Iig9ЙX07 p<T0$1Nn?'il.c lac_:t=<0?jdlI*2*:_ؠ[ߟ{>YώO.()p{oX >rB,o|l%A3ΥCr T㌰66¤7+ơN(jpBzҌݕW`9RۘM6gLd7C@J ΅;3R6S8Ƣ89QQ햞L~2CGr۟y{F;FRao!߈s5ƁN̍Ƿ!N|O _?[Y>o@q-k?=]t>|vA.)Z ??_E}kw?~>\\euٺWZkoR+~X{;|˧nO|/ȯW ¿R ڄ<䦆wowOak +-)*4UΌ9X,qٮTXYa30E}x7Cqs$S9d,CO e1r=LT@\j"Uu2٫ q\XG,"RDQjE#hëF\9̖_1\\ PVY@O )) 8W[> Cp;W;12 y4d ,x+|֬<9'NNpwyB7FU45̆? tr +%v>F`b &6O FUiibe0\F'cVR1]^_Fmc _Z2L8ƿ?w&I!w?˛fTGo%'rm Lf1 E튴]2}"kuFhLjZؙxgt} + ?ey_DY0SC@S&r +#0ZHof<YoPݦ\U9osI9J/-ʞTXKT9~~GZGRAHi)""&,_L"Μ &",~N5߼Xh_eaZJD=8\A< :2c?H tR"~q|7%#y 6k γ7'گݼ 1vSYd5ҠF/kx>$ iNx3j's)aвq,P}9mxn䣧*vjށA /Xd^`ԲRnRŒK0wFcP&I,ՏUB09{PR?'CDZ4_CxRmDI+l|DhY)+ow3:Zkō! +]ϜbYbPe& H-2P~xQuBYZ4Yp_11 VQxUum Tڏa.l"xHlqת~ cTgً +IHߌ?F$SĒsm&t/ (V:FʂZ P: GG=a(Z[㇔B!bag"R5PrD,E"xbIuPj?zIU>7r 7C-x4(JA lYrA-=]3M[&)XJa[ϑoFe%' )o +u@S]٣[Xg5 U'4TPJ":cQcY@ϕ-lir{ݕ537_ɓ7"?=Cz!OmzY͖o^&`dz'@x&&1WP-s<| 3X;i^b$䙕iI{939Ϙ 3ɳydI<-VWOYQEk4:Mm n['wU'sIyy`eIܙcNh܋9Qě4&i'JMQ<&M)ǡ)4q.qbd`vCLI̳lLAKfq`ӓG؁uv#qP:q/G^.F(:'B3u}јsWMN5Aj;} +9*g͋xmrE_ߊ_JB:}/Uh]`!a:A'A/zϮNijL[0l[M4YBͼ 04'FHaZ%jQcU3[Ǥ/?pٙQDhZu?ԮȊ +kE Ǣ֤j1AՒ7~gZ[5Q;f~kHnaA~!JhMWVqe<(\r(co vQ dfHG)`\Nd8Ѹ]IUL#պZޕMWs*3JKDh^=ҡYZFQ@8~mFϚ0| +IckV Ά٫_58r7Kr!E—Gf**{ I5J;n"QVbQWŋwL*jf+eM IypZ1eqV=xtEpY&[OJG*&%,_ˤeCpϯ7r|| 盂8SH߃a mS'+~~AhNMh?'ʥdD-SF/wb~L-~ +g(ע܋ݦ]oeK+SHXB)oB'Wҋ;M,8 q׫ϵq?ӟYjݟF=w( {{_RL=F֥1ԋ#=Ro{W*;-|*]۳ g'D3ihDh  hfM,Z M"8qxJ͛+A/'Yq=dFiIS)4ad;нgJzkz:`skESkOke\{eµfHjTHj-KudHL} r>8߻r_Z3ǵJSr n'IjՑ"}%טk%&Dܙc&dN o]1p ٽzCj'==tgns.gRԷ&O. JVDfu9+xv'$qǢY5|rpȇ7<?jG}R8oV/Ap% +TR'4:oSuDrSu$Xmєhh9DJsuDiqYbёWS6?8ְQ!8 -~(6A-R cp40;VϓE\aNʎ^}9ąo-J\K1atl/I㶸u_uj(d5]P?\=K eo|ww/}XBy_rڿorϮkƈuu}0&?N3Do7Np <5O> +/BS << +/W 0 +>> +/DA (1.000 1.000 0.878 rg) +/IT /FreeTextTypewriter +/LE /None +/NM (80eb72b1-6b80-47db-928b4a6b82faa6ad) +/RC (

vedi tabella sotto

) +/RD [0 0 0 0] +/Rect [408.10295 621.042702 506.65295 630.042702] +/Subj (Formato) +/Subtype /FreeText +/Contents (vedi tabella sotto) +/CreationDate (D:20220328142116+02'00') +>> +endobj +223 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220328142315+02'00') +/P 27 0 R +/T (Utente) +/AP << +/N 410 0 R +>> +/NM (250dbb25-002e-48dd-864fdaf2c2c0ad68) +/Name /24162e1e-8a6f-4143-a3ae5ed96f22fc2f +/Rect [-5.065147 4.002361 127.934853 75.002361] +/Subj (QUI) +/Subtype /Stamp +/CreationDate (D:20220328142315+02'00') +>> +endobj +224 0 obj +<< +/Filter [/FlateDecode] +/Length 3393 +>> +stream +xZmo_6@i3~ٴ@I.elE33;o34ެaLgUO3KMRg6GJ^LjVY]5*/23k?NMm<cy-76LO$f?N<_ **[m'pZ(F/ k0ev'M#:]kyMgF\UB 'WW +yE\_@+򨈫ɮV''(=ӞzXOq8ת9qz>֙Ŋ4ï/0ĚT iŚ߯/V E"e<~tbQRs<G}Ҿc;;lVa3s9@ *`땴 l9:LzO N1^Cu%d|'A]ϫ(3=MV1D$2$XrDtёƑ32Lx5bPTA2OL.GԞ߳z>;3+w'V +FRf/Ň9Bf&uY.3PoyD/bn]Ry<غqdqg) 0ީh@Yq&*N}Z%5A^<`\nPj4`N .!)~ G/|@ʹ:+'j ^laؗm7$p2U3 ^6-aE?Жc:ǜ `P1݁RUoqSh2c?r|kK~Aq#_Iۃo  +7oS_qP'ݧ߈f qgd=?aL&:ղV@?*)Kπ5Rt7E*@g4` Pз-,UQg ƆLq:zzE0$}CCޕlDV&F"8s!^4 ݳ! mOhQ|dp#0 N~ 44E}s|#q+ChcEs )Q}f9hT98se˷El_k@y_,tqM$BqXc;\s`(L`.z%ܘd2T8W/[I.: 'G[7W4"NbGGi|W ri1g ;z9lxeԝ>No=L!AGМS?"\fSd{sJGʱevppgU}Lυ~Z) GZkKJ2eieC1m-7;YmF,̘=f)1H }w5?zF8mCs]bjo'?""S[u74:{񀹛 #?!ӏZrӂw[{ػnǍqjw{HyzVEӊ}_ǻϑNc!g/@'M:8F\\11}.50~ߚ=v~ +endstream +endobj +225 0 obj +<< +/Filter [/FlateDecode] +/Length 4553 +>> +stream +xڵ\M$Ǎׯcy]{Wo4 dYmtka˂%ʪ陱 22Q_߼Qozoﭓ~Mqa~vuMW_KvkNq5cYC.qߩB29=$kI?\~LӘ[JB_/iuo\cV^77,^/E^Vsk9hUqv.k^~[](껌L'}@,O'Jyw!U5d l5]C]7Qc!5:Hk=jp;҄K׭\#ai5b;9*ۢB{9zwAR]hexŖE/IfH,*`KU"))qk/2ѩيڈZjDxЊV^ܛ v0f +9ĽǨ7=<>%@Z(oRaL喋2v:Cc ? +5|I?6w2-&X:0^X%&M=\9㛝H?z5H 5>vn\Nao=Q[FiOri2y냞ӳbՄbBk 3K 2J j ')}Bgrf5C8,yĪjd;JTH7noRDEڜJ>oH2aȖv_%/۽ +[ Z!KSV+6vKbluY|ӊ(_ +0rO[Hk=v- XBPP,ӛp` +d=.M\V+kd”I0m@rТ/8s.Ij u(wk {} MwpXOoWO>< }Ȏ8x\,T?Ls~:4~s$ARqwr_p6AAdx:тNH"8M7H3>Iv󲴼|&l*<,^bCۘhTA97 y" wj 拡;Ǟw7T)驤,hpʍ tpY"GiMfnr[sv֙vx `V_ L_$Mg:x3 ʠ49Ą]e>p)\uXI4+IK4y{q{ +Oqo?47"\V/轗9__ŵrݲdM/x9_Ozy>O_kxቿ[~oh˥" o/9Pse23.NN5:c=@53m[}UAk+yekiL+z]j/[ٳd_5I֙hw7 (-'PP2sšm.=*Zq-cm_r]vCYLh^T6/RkۋR32ZbjHMyԩ_9z(jXj#}:U:{ W'#MI졕5qlGD-tю\SwYZQ~sڤhKk;ZRk=3'mM^Na3{9ڂzM{ K$ iD(IO'd|~dNf}hu>썴$FpRrQfmg>-Cba`,e|XuhpT3ٶ PK2F*v` "Ϧ[Z^) M[HmI$#S-Mk1w'*aڞ oPErR;.PH6E6L6Wn Dlwfy]hCj[>IM֊mdU8i@k/EjjܳktvmMY rX]A|.YbO6-5\JY j)6/\S(hQuph< UGT#vjaAJ۩]U6j9fo4o2 +n|3 +Boʸz~FnLpӗoUꔑ[8Ɍ-7RdVεM!~ё#ɮ03 P h PpOtn%#ζ(S8="Wǽn`u[H.<%^vyq@26|Iߞ[% u5. c)ksѹmXumo-5bg3Za@{T$>ncPɥwnƥR`]v㕬 WEf4C 12x bu!RO>*AT,nUr^/(|D3_vZڮÃrӉ->cTgro1ҲuW_Z,f&*=CZ_L5:A3ԁii::'b)iL/G QRH5eCrDO +Mn h?NG`#?JP)Nf灕8RwZsԁJ=/KL]<'U/DKsUs-/T4/ϓ YOh0' <7 }94q0RhYz*q$ni [h维&PndwYtAκ ĉtB9-,Nz:^9==J&HI'ü3-Kg™.LTs;xG8LK&Yπ?3p2H2{C\9KI}3,w IN+*&cM9_u~i__~{ef3' +endstream +endobj +226 0 obj +<< +/Filter [/FlateDecode] +/Length 1067 +>> +stream +xڭKo6΃L1 ٞK&EUK&ٻ̖xϬBW씙 gV]o%IC*P0:5[2J#dc,3뿻 +H»˜̈́UB!z`K'KА4Jh2`ИI Β +RfhQj:1Z "^8Z>Ы+>$ .+۵eKkQ;e3Rxή~QBk:d7C^(Ǜ_Oa yFt|#󎞁)~%eй +bRw-^\{p=_w-!%'6}&ks`l9_]? 3^W\k~ 31ds5Vx13p_hNu}3ulhr5bu?d5q? +`UpBl(caV1wFGJH$wb_Q_$;@Z| +a"<'}63wQ2w&}E蹉r՚LCJ&h>uQ|W(!LL4_G5&&/<`i\ 0=dZZ-9drF|=Ta 9ur_\jM*]F'g@䫦ExE~vbr:j;$ 4/;b{ىA_sg&Ѡ1vp,ȸpf9\[N'鵥K)c?Uů +f$ShsEw&{]nL⏫+</O?ڶve^O67>mqO癪yViϜi)@X<` UԷŧ$9Sd~zz5o+[X$m]ru }cOMw_7#`*<`\6 ?AKӦhů$E*ţrKby꣥Ả,.Yȟvpu.u +endstream +endobj +227 0 obj +<< +/Filter [/FlateDecode] +/Length 8539 +>> +stream +x]I$q_Q̝̫7I >G~20_K-ǰ1t$|/z/姗krM_䯥uwmb&_˧o^d6[ |>RxH{%W9]=znR-)TV.]b\/b^+a4"ӯZ{ݵ$R[F]B"/|+<ꮍ؍A٧ź̑gg3*EiqF-5|K +۟OUkw[t|E?U;b"x߬vɽgݗ.D+ֶ'ԕiPek` +z }:eFs5a?xyWyKLOЦAwK lj`s_(kh/Qhl]NVyo"a3TW=ևY?jc$ o?t[Bn.'KٸZ.4)K1#$޾!% ٌS͓Irayx{ x_@ .8g9 %PBΊtmP+qQ4+ۏ˳Fqw9ea7/d?;`_2O0+M}8o/ՠ:ߖ̌a_lW40żQ֍~Anz@Og)a; 2pŧʄWc;w^(.G: k}ռUPҞ$DvF(l'wFc=8(hゥ(aN'nf29= +ahjW`/ɬyn= ZAjc Džp6eHT= dW [`1o;0W, 5ǪKI`n泐+`.rx׾;fPE*ڶ wGZnXC2+Ki9&oF@FvY܋gb;>? FU=iJ +q +8ň"ԍDh%v"@IKzG2XB.܄Xd<*m.3W;IbMBo[E4Fqw]9ui"qmWa;#rl4 &XULqh\] +8)sG=-i)@gQ8(t&p:Y ;̏%"mDl!7":Jk"^' 6o{5@u| g(jdt"luqЬO T+M˭ngfxʐAP1SLH ;ԏgA} sa/$#i|r`rmPiKe$2`щۣr8TJ^Iq {_2"냭e*&3ogyDDnX GPkL%mKe(MNRj}5<"IS8쨈d*l砪AŐ뿳[UkHsc$ytz&4NӻQt6W6nʧnL>ܘLc˨:5LStE4;f AƈFNl|ec^n,iA;Ӱߑc@7]Bkǩy.?d.33ysلtW=-ulYz'u"n1OfR|n\5IQR$sOoæ E;>BY7b"ex:0o# r4o7Eتp$H/KJZ_> ^_©y jj6 iCr9%?Q+*q&c@Q^%BDbf`LrSfƋ'Q,:,!"%j2>Se60DTFmoڸ1Ms>[ + SVOg3PǖwNmK>NFJ|%T$MKS|7\nm phvynAqd~6*+Q +f/"Pr!J /l+rKC^ V蛺):{5Ѱ*5cmd-Pp@͚3Ll͙ՏBnRԑV=zWIUR=?Qdj >l 6wooiIʚוI¨D,qQu{G|;ДYa燨S>NxbT3[.?~Z{} +xxqR2ub[ͻI/;Q2ϥd;u)5A8 'Pvh;9l~ y$qA}ur\/ xKjťSf`Mߴ2v+gAM o%i&:7mLvƄēCCH/ 6bL|TXVXC)nRv:D! +JOPz{쥘㾽 u8r^*㚯Ns(H?W~\2g,fZ‡-m2_?f(LFsL9l'2t*b$2a.4>#pñra[tVV-ySG\~%b0>TJfΏhW=6r}yt^.@DsHwYMl_l:Pg{(gإ)_hm)|w4doaghg'*!@#I!(e`fnĢ +[Cuh0mr͕F]pe$/D?[춥{g"=Ez'3ڦ;i|S'|r4nlFzCV?uh&hI%N-QnԳG'mkΔ ͤLR}Lc&.DN把Qњ+foF+kPԐnTK ]z҈%Fsop]RZQ V/|P#5eڷĮiʸ%lG%DR}?Iɼ4sb;g {LES؋alfхAݵM?q^EHJ +)]EWoEoq;R +|**+e \I E͡#sY\ ._9qs9jsȹʃ2Nne^R'. 3)i3W,A6(7yQyml{:6r^Y^n PC߅8IRNU{&5L,>sM_'4o٤|ϕ-s7M\7=MSfy0yÜ H]0r4aM/IR8"l`\xZ~.nZ }"=j5EemWo!} 뜬@Qu4ȳvfD/dsu@XOo6cd % bMe<3ralJ X7N` < +1n u]g Q+LP:-r> fۀ< [b=pB{)Xl%j'A %;"(ܨc$*DŽI̮܃Ovv ^xYtz> K9W =I1"^sHJ]#Ra{YDJ|)2X=SNO{}+f=fGfsVfz=v/shϛ6>܏Q1uDԦޟ N˼>/[:,a(;{B l2Uw$UX95zS)f:7wRxzyN104_=3/'E1>m޼tqS,Ň'(>9$u m @ZSiq-w-^6[U 0o5Ў2]ƍ*D!7|F)_|動RK*x5Ja[Zq*Q*c2ȼȟOۚ9=ķ:? x8oTltsya$ד$1gI틊-HWiiRjK>{I&5qq9_^YeR]7IqY=-񞵛Ӡzqq_w&I{;' <&;imR$y6 +ϊ\$Q(]F9L݈rm0ꟷJOxzgyq>QU$=!\0mꐒV!ǥИjdIFh"P PäB sre, 1op s -om8 }4 +E?-^OL5u}덲2)f QwNn{!^Zxع*4@=ߕ)v Pš2n݆jɞ8V}N1!T({7eyTp+Z82NViBZ'e˫8E1a֔f$$X3 fxhH؝PO-W`̸762I.*AghgFfztasNм8FᜋB|6Z㢚7\dL5[\N(D1!!˝ 7uNyUU㔓|e\Y&t[5->neF: 5ކgl}N(u vjd܏o~{ +o~{^nhp^.왆{b?o^߾}XB{׿R+!W_ݵl?.± Ÿm.OD.ľqp!Ͷ`"KT0eRP:bdr^&pү~A/_a +endstream +endobj +228 0 obj +<< +/Filter [/FlateDecode] +/Length 3580 +>> +stream +xk>mC-kڠ-~jx5)REp^ut/3U]egVs2uq?k&Ng5k h}Ѫ^߅lU[/)iT]M0yLg?Sx}Wd}mݺJL)xV0j0C *t]um"@΀dZ&V7`f=F% FBW&˧@ŘFtO%h[m>Gg)]qB1S dU5>>of+.L+~D V銪n.[BG[W(<%L1a8#c1`tF$#N@_O: *bFKHmN$PټDa ɷ>pbUUⰒa Њ*ϐ=Rjž\]$%_JPJY)s@КUL`;٢#d!,T X}[A#BGsV&vz4Jo@iLt3J3z1#njL;b.H^v\D1'(HO]P:]2㥗o3?^y{xLjN"Ǒ±3/L&C5xj+xҪ)<W`w]6D٫Cn`t;P]֗~-Żvfnly۹y9\{Va pUA +YkaQul ok1Rn׫b\VMu?|{rSoW~ \v ]yMqDoŮ O~g1!A$D +9J]/:J _= Aop-pmcx=hd=3dt ;&Fz;7\5pZwo叫9pjZqnrL[?;Lv#?V5ܝ׻TcTs"߭y%Xrw([VIa2HE mv EH˪K&Z!>,y@$3(Ѝ\y[4[Wy&im{~Ê n{ӛ=أ5m<+*&eH?=K-9~؛bfFVw:/edUnE aCX|xUBMOIٷt|C@Me"o"viB)~N뮠͞9?8nwrQ,]}]^^IJZ^vlQ|9`M?_dʑ5iS$ .5]HNkq_䳐wcKeg +endstream +endobj +229 0 obj +<< +/Filter [/FlateDecode] +/Length 5907 +>> +stream +x]K$c[g f{g^t `WGRzdػ0+("?Q??鱓ִr'+\\v.5*OOK kITV?+Tw^VWA_v^SKYs9SZS^]lQ +iwkT>[: +iuqk "X|Ӻu9K*4n ]B XS/~M깱L56{AޣiK,)@.4%DO;wtx<޶5pWK{KKZjӸ6Ꞓeо= lz}-$g*N$u:5E}+?z;7{ A4##Ms ?(,Gtcl!gDh)#;CLTV6lܾ}[cDN2%?!K^0]C@]]m,I;? +Y%%UHn0|9pק$ȑǑH7E=0Ŋ}["{< AtvЫPP};h:$}ӻd$k +*]*`>V^$*ZPM3bck{{QTZ+bԊ%5v~(:F3JVx\w~Fo}NRw!zطNA1}dzޣY-_~bX-K< ՝Kua#.NMNZ+-l7K0"=eNņܠv:[I_?uߋg=W]?'|sT^-ylC]Ρ:LHCEHvqi)A;fO@ދ, @>vwrs/3a%ՌUhjwZ +`H +PfUCޡ20). +jV^@A J0[/(P-,fbS v@Lh6 bOIyNq츎Ҽݑ*;:K1Sҍ}mAGɓÔ;ݙjbm鉡}7]~<*QkA%; +&8+Cmn~ʟ3{P1 '_qn01E|G:f cPzͬE +s:˝CYڨjCBF lx,}PGٵ;,1c|,9X0Z9סeoZ2ɨ,KE]+ٙG*@T/$;&2tlQ(sxh`)Ȟ)8e!)xV'ʥƺ\1#FQي~W6^$=ָ#}?/4 a N4|N"!ȓU/4ޫը=B Njr@L}]ߧGE;#>0;rCec{ڞwCגުC_vbX> +-ooGOx]Æ 0N۳ﲙG׍=y$w0 9@9Drl?Òӽ>|/=_*q!R BqYQ> +Ȳv|VUG_~#EvzME]9bjW^.]"v/w> ==UO)ZROsѭOQc= n;x|aVHjm2gz-^䗯Qŕ(ccg +?֪[WY>X1Yg| '}Ѹw]^սޞuՇV[ҽ0pg_Bam|MUڳ.ppؔqUtأgO +}=NGN)O{E7bfn?%|<"ċ/wo0%7Ex1z>Hv sG`' uof$^k˔PYЍ^jHeK$ƤE/Lun]OR=8MY4I=\.G6n LO'P|-U Nkyq>O=N)6/0+|R/JnJ6ςǨNbn.񴬮O|';?5}os"tC6Sf}Sol[uo6d$}|L&Z fj +  EV+ahjFQ(Np\I.݀$(5N5%/VO!gǩ LH4^zK8Iډ}h! ic @)kٔoi5ax_)}u) UR@T[ +(DVSI + !CtHDQY騄`ՐTDkѫ}&xv,~az#orKHf_̛a);k- ڢ0 RJj4fs"@S(DGVJ~C6 +rL49W$EF"i%uU9a9(03@ +h)L5Zi"yXh|E?|Pa +YH{Y.NÝ$0rNz.:ǑME/Mp㡶|]88&L(!Cf?AE[(,(Z7HXq3amr7Ђ]j\WT(t"'^jQݬcĞos.$RsiԙP[B" >W1vhf9Ŧ+ГKY5ݾ 4[Ή?FaNUBE)(o#p1eo1y/(pN&}X}.$1{yDIe%9eĈ3.ϲDa9^, "aBhI֣H 9J/U]݆*HVlPdgm )B3 +"2 8\J$ؙDzN,c# n9f$(u8tr&#4t3BL2\2tMycoXR1[*ys9jfs(#TX0p6l6lO%d893öPlWeQkrRVi +QWj}o!ʈA@cÊUo|\+ ]1u:q"deՉlqS6]i&eYDB@{YQ1!QIK9AFd;H9ԻrD.C:$ebGPft@݁f'e҆$j'Ibsq-e3AZ*FYܶ 8]}EeJ*q;E?p0u$F 2sCh&2~jG +J eC40끅dVW +T7QQys֊~o p BAz96=0q"57NgGѮ jHKC3gD)^k,$|1"<ZGX>8'$|d+G_rҐ wMQ֡B@zѴ: ?)ʗSu22 [Vt5 o 2@oY*zu[X6D9Z۵F_htC.[P:+%Ν!O|K&_ky1ۨ$cArm;JdWȰMײ)Ye1+Ͱv,HJ͟a׈k".:AX/ )ӀpF?.!?)Dn$. .rD=0cnL$uEc Ušx!]- 4>YێbZ>׋fk%q ]]Gl,]in&0DHbp4ZW6pGX@wtkZK\W$ ` +P;M] ea>p2 gd%3F~AڱĹbَ q8H~P|L}6ʐup"E72y o"Pƨ qL|Cnqb JAbh`gZi( JU:-!Q,`F{V'w ,q{=Շ#m!*t.> +stream +xڅV[o6 ~У͊.d=n6{pS7A$.2_?Ip,GI_2$jϙ^S&ٗQK+lh +|Z@͜A8MTXQK}4n +q;l&.ӳZX;`PR)sRY/rt8ρb8 HWZaf( BT$ Ԯ2 +bECf ô$A34ja4>=-j% G҄ؑarL/Ye&$4c +\ɖ,Tb˯XcJ[dJh և\k^9}}b??lx56z* +j T.fP^V۶v߱~MsoBtat>ZB8Eq%\0./z۠[Oc݀Y5O| cddڳ\JS*h q k|5QsÚ?X]>#\Rn Zoht$4ա}ATs +Q*@AGn׻9+u=ʢ |E\_F Ѡ1tl\EXq wNr݈^MKoJũu۪;?ғ5! Aڹ"ZIX}O\AI5W*s 2V;(hx&mx|t yN|8M|sy0w`Tͳd?ԙLTRiE0!OX4I;$kJb9tBYoqe>N DF;WݵS}VUҸ]S9(p39/x2K@PYLrHj_KEP+~0ku&Va ѭBhj+^}і8%)Tsa)\. tMǤd; .^G;-SW PL3y964mC*a MLs3H1\pbܓ iHdXUZG`RT-KHɏjntPUz#و&UCe +)ʧb{+ +@`C)Oq+ V +mS`>V݀]XUa5#k豪B‰RKpyewhRPJ U@UCBF|(r12{u 8q[W%@ZH4q`Sv(aȰGUeA1AmUCa9AS(B5ӟff.+&7-_4G-iqoNb!jQPD^5EcU6;vjx;d1Wje]y|N!vAD/`t5D)Nj#E!UֽF\@AZ d2UH|Sk4hT{Q 0 +]9b@36hu`kX?qf1@F@*G1Xa<*k ^c C +%xC*gFA j^ &fUeG0) >ްb vMQ ?c0:MAttj{%2 X +LcluXx*\AIQJ b,4m&DND 2F + ,V3t/PQ4>:I>yC Á:]ݰ[8߰?J\LN-%|%k8 +Q[f[lDr^W(AE) P ^GMcWSLd6efhb%Ɩe*qRڅ ®Z!ݱ=.fK/Nk  +H)|XH肆?XD~P& \[*b}IS_WSPik 9_<ƜfO4IZ}wCLɦcƦ+#=a~UOcrLQ2N)qS26`VIu!@63b- 9iqRNRIcH@ I a>'勛@C3|Φ]QVX|ls@O]WA=U} >ԙ԰|4\ڿvEs't_Ċny!{,`)L 1@^wsPSZQ|RN6*gtcbw8!K_G +O!@O-{kL9 S<XE"hfXS..[eҁlT+\ ^B[ u6Yy<}<( "qB8 i$HJl!."aD.wWV/La U}C`EY ,=A܉wӳ#aUzizF{2ё &:XIg:hhvÒ. +WMA-؋MWO<) "J{&0(aT!=Td;H#9fxM_(ƹ%JK|*ءKMyè2ь/ hSbt㠾/uTu; %Ft6}"^ k![BwsA>Brba:*m:Qf0GAUT66p,M20XB^_}I!-q>&d@N2u sQ)!A.f2OӒ!>Vmڄ 1(긍Lщ-etx KqfH"_W$mII9B5N1{G\#cA +}W I{fͺ5 >#F@$ {!|WX翷d\>4k*vucעD(L`ˆgvM {UYW!fNQYCKeJ(T6L硎iu ;Āz'sLM\9gd&_c]Ps`g#TK*ab VjN NmԒԎ&u˘ՂHJ*)"vb% KLqg0H'@ *|\B,4 @?q 1=="L2ӤBMF- F-\u$1Y|ɯlA|x~⹱ R5+/MꖻgiYjpp +RYR+]Hl=r~#Mh,Y2D Z"hܦ*Jqrsee1:Ɔ!=u1fQl\?|=JDԸw#>}k.zf&hG/INrSm +yLB\+ƧؾS9ޤm_J)yQ?emf3PVPZ-0zslBSD"&ѸP"5\Θj24Tnv9@(n5.*g؈a<*;AۅN4od*AǦł$O,+CPDECvE68Xi' w$Ro@YMco PC h%t`6;b4nY*D 4;8wj7u|OUS̋$;ǫ ȐjeL{ET =mEG4P=u# JTfkm(uRW@: ?1Lit=E=BpiNؑ{d7ð wz <mw71g' VFr))Fnrƌtg l@)glx̀EokZQт.t5,|nʝ7 \n* g=Y.1FmNm"-_s\E5hqŒZQ^6ZP;+#}m`+4Y? ;{z-eG!\8-V,*թ!bj%4|*N\w偵0?!?ˢO>/GM~wmeHS7rO~ $r)WD;$^|+6\ug!f,Rӯz!X +( ¬LUIl 9"[;m oq +=Zǧ㗧۾ c\'u(}ӿ~!}{~SPǯii G +Dž;RqwMY,oO2QSKJa4pj<!Z&]쬀[1L9 Y"FR][[w8VhF@4c0}brCHUo#Z3W#FS"ov_Yw,iciNi6td=.#,ѠR--# /)\4AV<5Yłڗbt`b^gWXwz6~lsgk_f +KCnsv9(t[AE +Q~GO¨`U]=^DyRzUp: LJaP&'A~煾T۷z6#/M eqݱe{L`J]Q4Ce^=1\7jd^ k݅hvZ>a!Bjqmͪxsʴ;ifuIu5Owcq*[e_fma^I?9t0{C+ >r"6Ȑ[+؎O˾ԶcFean +|wd!xS`QEVCʵj@_x#x4ɤdПfݿ{A529ְ[^In>?nY{!|<;[aQmv* zg5E=v힧n-G[܇ws_zsN5؏9rCZ T:&3/=ӫsR5CLElL\)kU 1&QyOzjrnƲJ&5L;rGL}a9k]ZZ;lVYi?%VH:ۗeH?ӀÓ|{hc[mSSTrөO,U36rUyVjI ef%K +o˻_jK;Yvd9O1%J 'Vw%$#ؕ g-I<-f;977! p۱17uҴd[Zl6ߢ6SĜdYLGBӜwYׂ ʣZ=9#ɄIQk†INS]718yYؙ EgsM>i4Yk]_chvzg7Wʭ^&x/wK+Ht&D=@֗\@yvYTndRf\cxڙn)]LfpܱFbqzAԶ Ol;:=g@҅%k;s[_w7rl;R~碄sBfq Ocj[A33n~sCU+ LuA;pl3z0M'~I 0MKktQu& N]н5Um`bn.W8av9sy}wٶ!5| +2&=u C 3–OK`9 i6eX5 G`Z?V |ILI+`fS?8ļEaxZG;g g+b_,9\vcCكf $›5O75n{a~>Sa$YMK;<\ؕΈFǁL ]y^ Y/(BN2yMsGpm-%q>r5b,_D! "aO HAk1R-s(ϱ|7̠U3f֏/XޤOnj(h 2dpw,/m}/ミQUw~;Ӂm&<{;_aTWDG};TZ}gS]䅟EU?N@d~v/K@cqki~/o@hw۠ie^˩{9T~z>>_?ooJeЍ?bib}(V ]K"'_b}z:HzcEtVƭ +p|,V4?XT |OWhdG8+grN@3>@g"уb_7;,Š9A\ "HnPer[!6 +VS RӸGt 粊S|l_vTAqNKij{!QF/ha71@u#a<%S&vnMm|(5ǁ~`]+Gi}3j~rscW]qe]Sj]BxQ޷pw^ɝ'fb{N +7_-O  +endstream +endobj +232 0 obj +<< +/Filter [/FlateDecode] +/Length 10030 +>> +stream +x}I-u>E.1Eo xg7\eԕ`wg2ՍB F28;Cכ{ono9K8_Pc(V=ruky qNs]^=?~7oMB䮩B1^Ree.\^ro{kjozܵ,#q5JmTz۲ZOis)_B~jeytv-Zy.,Kc1]CťZ[h>.Þq_8eƭJkRnn@uJ_+JZ=~9%m- }>itx_}BʯNa~iw"Li~{s#a;?:X7{GmDwfpV~C-zm~qne, lZa&zvIsڃK"˔tAj u3+g +'nYqI=UbhXyWX }<;ZWW7lLWC 5Hߓ6 v\,1 jek6m~KJ={ /hP;SK`$[3uOQ5vBe־| j;ޟBg)>݁U|ǹg(JIJfMXr;_G߮~L;URzꡭmWHJjH7~Ng Zfm͋b3f.|z0Q}'^%KVsrO9r =TY2+庣E둩Er^<ք_'-Yz,tdEU s93@QP4P{ӑBֵJYPv'.\-J޵0F8ܸ~r|w@¯3KhXs RDS}`8S޸ggE>[};k'*͞r_[ŀDD"/{K#Ǎ'm>Ĺ1"Ǝ0p&ЙЖN:Aڙ +\e"\J"Jd/ QxoU7|f]o]m}[mjo"k.'{34L#'pom>!M,xrߴY[޻6Xm)757TVRKw&AyBJ}Eh'As.fgc?#9?p~ʆXκ +) wS~k9Y40f_<5d+w?;x2u?x&Yϟ;~bOzI(tw/iwv~~=r(ge+ \e +MV1t .^:~{ۿw߾ǿoao|sۿnZ\Kˋ24]/_ǯ|vqǿ-O-o7}"2釷vcN7;#OޔyP_&4U%v.JڋKdW~#;#/"}߉U5It7)C/BjRKג Gdd,tBSpqlt4ZMt聺UDl3 aO$+ʰ}Cˠ0v|G`:nJVSXzwd*B9J?~"kYvۮ~!#IrM0B;%) :'SD%2U6i+/M!J| B1 KA_Q#gղ+F^UK&Z==$jsW8>:;#cΈ2^бz: +ądz\$n-R)1rMӡ-TF6_\O|R:DA \'Sknf 9:ڥހtdz&VJ~?5ٛRZ+Wڤ5OԊָډ"%ŭ*x*8tkxH8x2­cGw(%N tcg:p?0l F!e +s/z̢&;|$Y8y\u<ihD㙚06FJ!ށw!\u@ͺ@yqz +'PM@/ӉO!a*Jyɦ2;WaOE.L2V۟ms ą ?$/v%a )䰷:ڄg։_$b$G)f+Ta%XHTNX1Tؗ;CEfN8ؖ7)+z.+)/ pXV2pԼL +*g=3e ȹXHBP2Q0cÀ + >c w9v^ŗ;xG.:|:|:J?3Łj-q5,jdInMsb䣮/)]TCdvQ vzVdYrQMUY U.Y^dzvYz[ h\~ސI  FG-\(I6{-JUi%^4_4t$gʠ{!zQվ2G90>84\,"@fttDಱgaD:ʼnybl P:V5gbݞ̀3Ed" . g4,FCFtZr")#ԑ#4haJCf+%ynRǮD> J-Z%T5@gAvbfTm8  As` HgD9t >gxsp5#5G'4YE*xw G/nNG1#P8O;H8 h>mq +%P8nNY-4qڵGLC(.++0( weVhA&)VItےq`u`"Z/%}cTD[TDS?DgK"y/#RV#xHvTb0+Kxk@¼=`^'6>E2KvвPVXWF +<\emXB\J<ʟgk܊plFY~ӡ|,#Gh0i,,GbuzB@a&uV##6X[ w68W(d6o#OaѮb"HZ7 d%}s8 P_a#K}jo/mq@ۀw޷(s>(53 [ac|< +\ˈeT#Z"jQTͯcL-> y`a8-i0pd7P3JL(,('~K";6Y[N8pk^T!NuC l+"N=&". @D@O1){u (.3 B2.SQN0""0uRq*"xU1 jxp[QO"L=ʈ@yR|G>ƞU?ED"umMiK'#27"ńJ++UlBn\BFiF*)6Bh&* HR+R@#l( dbIҋ Y}12!=?(@n@ؓ9Aج4k'6x-0g='8Uߺq(򵐘0ejI'ܟ)'akAG椨&ō"䠰󪃛"=OI(^Əp#m7Z$Fj)s1\@s)>؍H!Q܃rzE/iBʾI%{>!{fmf%HGoGf% ĭxJmSKN_FCjТ/27z:Y1c.QL#r`zlpg"%)/̹aM?]rLa.ߨKۯi_2gVD{^ux^J1"v2HHz*7 I4 :q/89|{WPo/rs`(^r,#B}$[HulA&I2g8NÐQ( /:O0LAP,vI_wba.O&䮷pMgO&`dv.fgbs}4`l7]*1WqR5.Nkoܽy'4fK`2N |F;ǡ$6gkڸ0DᚏpDƜ@fqoωinF ;}H8i4'pNK3w#kok%}dX7W,'fJzhNyN첽JsޓNWf,ƬhP1C9L**JĪdTTRb Rz_,7d r$ΘC;dCAS,{vcq8d_8;cPJ<ɚeșl.|ُga(eQl'۟VB)w(X9-uE1լ<8͎}'r"Ժ]@Dc;bJOZe%fzlFzn0!GV.QC3TjDXC2*p !2pI3R54-8SJ C7K7MOC Of17rxlz$:y}$_5UPG%HU70#SݘI8`pwo秌-] t>f^?#8_| c<5@cԸ 11FGsɯO*% @T(;CB4P34DY73mNɼEH,W$yz'HʫM VT,u v:,$Qݨk.HxJ^e^NrM{i<<(TbLnἛ3+|Cr6 H#fL\L P> +stream +xڵ}K9޽~E2EN2Ik6'&1lv7טZz}"3YfoG˃;}<`yw)ltyΟ׭|z+_cw}pyHwZO?w["=dÕs:Èk<-|}#l72~.xq‡6b0[[ϡnh>5WvpΩ1z!e>Ú::L9ڳ;jž96shx[%@1cm{!֕m'yaߥEr2"l2L-bMqog +ҮطښӜ8qLmowlS&~'$*$5nk08~`wCh. np)=*g]piP8~Nm,lQ~ra*}\ȗ­VIT8+Tfk.D*繟naON=.o|gL:KnҚr pI,dl[}D-z|ikMɌUNcڄ|&adc 6 #@k^pvyD_r*R 9YQ![΢Vy[j8Ոϛ*!soXV^\:1wa22≂_i-B|gn=+ӌa[A=hZl**XY,VkErڊ:a RQ +.ӖէgjXQC9{mH@,DeyV*mܱY;^_h9& 2ȿ==*uitliƩ+x,\恼_np8H Ip{&ڶd P፧~S7x5So/Cpih_?tɚh(H +`pSY ]}5W_.i,QŹZ><`9"S59id7FOp uU%L/%݋0eT0i 4JJ<@cz4 ֢@m{Z끭@QXu ۂcPЖѳx툻Az}:09a\2q\g┫2FtѮY?_ɇSQ.Mzm +1mm0q\]OO[䟟tզ~c0.Ѥrbm]}&w4l/?^kA=@y^zn۰u +0Xd-ԙ1R,aэ8*YKk2^vd7,J^jŧViE,u}ا}`0ꤪp*ޛOw$'GjSק,Ħ#*3*>L͵aS`SO^˛\MV*ǹ}w . RqK|=5 _*͢i)8mi8&,0bBq͘SC ~]loY6<ǧKn:|x,;}?-̻xE><}%9zmw Ƭ&GWHƞnЋ 41{'~J[zM_"k6xoKa"fĚB +QCUYkksnK(Z3W8əM "N\MːbA4^B ̑K ^5}6dOzS%)T4]ٺ=A֫boU +dGYr%3TCR#EЖvm- #-,1$q[c{,⺗ %YS% QwU lgS I]cm.!hHpS%u2h@|b[)WlԆ (3CF +`Q0_̗VjPHS wЖ5`8>f݁FJw;EUD D=s8vv4 IwŇ!@HM!ᔑ. 2=ӎI^hMvXί'46jHpu7LwaF+ t6c-3>jp1?B7J.HlyZYVRe}!0E'E&B"$5cbZE(hK);J +3@(($Aa4$'"yčDt%\VV<~yeUSPNb8Aŵ@21\-U4A$i fh}"Kd| z+L֚U)9Gq"mL+~ u&iU G%DWQtqop~pUuUoGwĔx/=K$Hm;V:]ayV[^:➟9w=.f]>/JhgQgZF>s# %$&9,$^:4 r|9C4fTh|ċ$@XI}Y4KˁeZ̰kq@LCc-* }ë^sj̔16:T,)CrVk5˖]-iUaS9iyWe +i%hel"^,㴳(ZvZzyLH啤GzQ(eZrsCZg<M[Ҋ&XF \ƊyAMjVSrXjJVNGBYiB8" ZhaiĆɊФ5nΔv!wpB鰗&f,4e3TEȆI"JheB8hb4ZVh,سqQ`y6y-.cX-|@#tq`$l:TX[jCJvU'vEGZ$HBexoI`Z.:i̹Y0P=/+Y`* +yp9qZXq^T$6zX($^DC .Mmi`~ۀh'\bTBY[|-/^؎.O KڗT&8PӪeLJ=d~K^J왇vܱd ! i HOQ$2G|GEx\βs] + +GW[#jAio= +o(osb([X?]+^ip"7r/nSFR`؉7aꦡembDW8AD *B4ZpcS e"SŠʼnְN*(tcC A4 M73ϯ@ +Y+3GQp_Jj,(課mp#0ׅ\uΒ"]s'8CGwzeyJS %`@pe4#jIJ[(RwM' ζv"Csv2M_0 #`uGdzyč +\9EK7hCH:b,ɒW\oY7s R!iW%ܲ3qp4w9o܇P἗Rb8=KGIj!Ӈ @Kx7O[nhHB'~𠽫>7N9t:+njQ#vM|zDhe-o:@UiSKPW]ťA1QsviANH=^@6#vi rv#] ,YHBRa&ZUk }t% t۴jFZis dX-Y6<ҷH\_nӜ]Ȩ84R#o&Q^ 7Y w/s0\1O 4/< w ~Hw8i톱 v-[Aij[fs SBr~Bv~JRJlg*$ QWLj (u)7+`+ߎW^ߖ(=6+{ǭ +7 yЅSqܨ89,v,K|VEKF6&j>"hWҀ~퐐.6{5~ %CV QӿD/3$eZq0$`'w.]ҏ$` +Rg-h_"Xn~+]rMa\G"JT5;KĠx"Q^w>M ChM3d4UEoz%Kw/NqSlQ dwɁ\tXsapLzg&A~SDAD0gBnB7IؚxQO*89k|:='`C*>pJ/3731rvs\}LYjϼN֗Qٮ:Ї $}o/uGKڟ_7L^VƑĮ$ǬfI>=u$M ܉wdy(@!nr姼SfOp>>a:rdgs8y#;v(zӞK KX/V21yh7ly2+I*"ʞyVhbQCSnKiw8$#eӎ^pYBbu(ۼ [vU0˱ܡK{%Vwt֩ı jc։F׵qvøυZ{'o_xK['l6IiJq^Q XP=dWlVBf>/L'+?4C9Bʶa-nvm(%;D5䝫pYݏXVkA 릚477}6^ͥ}c𠿧w tlc .@+WdEQ5ziB^5kJ+p˖FIio ޾Z 2})|r5ޕgdTCDܱ xO-̀۷a;I25{/h%™B\{kAo5~VF^q7B|0T8BpI־l^Ei]wGNeP4y"o1V̳*2V~|2.{V#7LW-S(zj92@N[1;h)mlU9pN؊{6O\'jD"黲؉%J ѾjPAVF|!m*(/5^2E E[#yJ\=L(ogh|a;cϬK6>ڮ_-r-.i/KHDCT`,c  2 iLׂIOCkEwxw4{g{ ! +/Nh5 YJk^3y1qg1 $QEW4{s}#XcRt#*ۍ4}8V *L[V~k<鿹=ޜ}nKBZ}zۦ>Fv)nn`+$=?ߐ-z!Ow İ@ߛšYcz7~cս%8yi*r(|6 Y]8vqUʏy{dw^(/:ǾY|JJY˝_|*9 ^*YtpB C}3;W~<ʆ&K٘CR +8-ߟ{`W> +? <ʻg^5ʒ/YȎ?Tlf~x4J7@n/ϼBr"[iYexAhn/߫c56ReD{Mjtq=L4C qҝ.z71 8=aI#L~4w vX\D.y/7n@}O#4{mAq=#9]]`{AKKzϡd͐TI:O7&7?5{Bp^+߾mىNK[=1}+j[4p{a{÷7a}gy7.?~:H"K=r Pp/T}yr;sƈyum0W-ݒFc06nSw^y(bܖNoRS\:% }Iiֽy=n&oD7D;f6+\RF7 + Fug&=M|~SE/ +__b UADvv_~e\۷?vEV2R1rA?%~7Ғ`a[QM[ >û ^ј7]$4ɻBb}_{Osj͢X ?{4N>}~jN/~SlxjXWNǃ~x/w'Oo?税߿&-|n޺si`žMg(zj_>~~7߾}6"Z1(eַe_>* + +wٮM=M`|f7pNږU]~v\wwA!rC@{d}߾_t݀Yt~g:g-+=<_~@Ck=N(}lY!>:E?*,VQ]￯?*E*DdUd +endstream +endobj +234 0 obj +<< +/Filter [/FlateDecode] +/Length 1675 +>> +stream +xڭXm4A1HBUJ]J{ݔTgf$ξI 53<όܧbߛ~\H48I#h;/\)iaS2 +#c2v -+k ocSx8Ęjn[8au&є[,`yF64Myb4 4 ++dNƑ0[)ΆdeN^cZ 3_0$Kf UiQ9̎,|2HP +8FB3F:EcF4sJ$ T^xӋĜ` wV !a"Z煯xk3RxV/˟޶a}̊u_g㉽}2exV?/4zVRAjn _uV(c+te%_cB^Rybcv7ZZ460/e~UY^-yw@Ǡڇ "QCԄege5!7!h?*+Yjaj7OMFq'xMUd@%En J vCw? )!;ciYf9A€K1lCϥɡ"TJ%4|DJ=ձx(ce e&T; + ~$ӁA{ `!šo2J&>5V>JXWT2FN{EJzkҰ݅P3swjzntC9jJ5js|E +5ۜ[Q}Ck6@RIު֫O ꀴ#e bƺ'E0Wmck@WTXc0"<,EAhD[vNۤJ 7F> C;-TM -:kkٓ7Y2SO4Mw N b 8҃ÍA lTV{RRQ]nY $~v.0YX, +DLK:‡arU2gY7F<Ø wh6T·ϙԪ~hNٛZ˥7Vo }Ī›IɻjLI pU;%jDqPx)1nՔi|L\ߌs*_sf  )˙t70Ȋ;MU7—?H+sy8mڜ\up)"rLC {XJZȥ-ǵZ" +M.Aevu8|ZZ}Xotol끦ݬEn~pF7e']q_Dŷ|E)M1}y* u?= +endstream +endobj +235 0 obj +<< +/Filter [/FlateDecode] +/Length 7341 +>> +stream +xڵ]I$uׯcHwj4 ÀXHF@|Ɉ̬1@W29}qw~ٯ^~|T/ט_寣 K8!G\u{.o/U_iڛ~p݃t)^]j-]}n/߯UȠo/]}r/nǾ&W/aCǫ-k-bA}b/\d.#1:.g}raπ|}3Xmw&w,#*^}RuLwpu EJnU`vb7\O"HBL/Ql +D|2MJj"r!A}ޱ/'Kev`d\厷$jߵa/l0S(j8C~7Aw7qΎkx;O|=DEgSo*7 N2U1\#Z[@ oڻnkǵ/6J&657 +qg_)cdpVHC 힆6[߈.%ncosEg/8-nxߖXlS7k.f#1< {wxa4J6*62BkWj(BPz\'9oYTؠ1u>$l.4s1rqܾB\@A%=ZDϚ HP7'c3nHE F9Bo[e}XZB[ +t4~pptq<(>P1 +65 {>n3?DiUHLp4]δaY7||9 & K@dg,Cmtk.E;nlU  ' u!2_G—sK _k5 {HIEy5CeؒHnxܦ>Ϙr0N PWOC"HIjoB+aldgqމwU0ѰYS:k܊;vZ-tSAH<q>CKUzz?v_4 +7I}gd5cp2 @(clMPB&'c)c2 a(6o׌`}\>H$խ%uC'|VR3s{,AC7Urׁ/ğAE =Gbcc8g}O3ž "sإD:)|X9: ofHokuB!AHҍ'qU H횇f̽Fuf}iŁi$dc N ֜;0XMG F_Ar KJL<_2SX#iLVHqxFFztk_4+q z `o_Zχڲ +q*762q BDߵ>>dKdǢH#^FҠ +PV>>#}PԷڥ ֡k_,BNuup,mPEhTޓyO]rm  * P{Yhz˚Gq+;nٌ#GYMM-akcV*kGZjy);D}lVNE)o@32>=]FnfŖ 0"mccSR3iEԣ>EN5[U9*RvxA]dY58<+ 9X/JIL=nL=E?f #W%-X-Q (P:T2<#Z%o[ ("}WptC3ZLQ̋PBuI.Jq(lDqR0~B?[Q1 f1ۨ4W +\XjeA^2)vL2K9e!n@g:VфFIhK`t&IrdY(SԄ$Q@cQzkə`CP4!AN0j+ +_(u7+? z+cXJWf+,B偳\Hv;gԸe %`CAf 6bfvozæ, + +3 NDa2k<ќ8 nVBڌJmFjП%2"yɆ"PͰetQ;z:dlu topHGh+*$!A>"%@QpYw]tYl:=L?3'EpCFjފ>AZ4gP!, v|weWXҨhiûcۚ)oD®wK3I.Fat #&+ y(k% +n@I>t(OITQDdhd9)GV)ܿ!4 Dq(i=1N +G7owLM(:* J2=ԅ9H0JO+dύjɤ~g,lua&%X.cQ +F  O(1 쇉D-ο-& QѓfGo:[:rZ&f FX)TLѹ̔ǒ9SbU)%1CMlkj¾8 +NsJsfH< uQÉ(slHji{7ݩJ倳ȂCGHT؟F]]1txBwWk d[׻KwX2ps6qZעP&$Gx~(A SD2J?VLHkgw=([ฬ7ˍz5O.0:Jѷ}rX4ursw +vwu d}_tv膕?|_.a?yo%^>{w/%)Uq/Î}@f.-(R CB*DO7xO@?4kQ_Ajš{0 +뉾&A ϭG+Kh ;юX.A?ڸr( n4O&dC˰Y]5GXu@Cb2-8Hevc#=NaB6-6 y7Gڗ*z!Qj@Ҩr8fJteH5{,|G>bDQdSMxjh ba֌'ᗽ!vbcծ f?[S&!c} +cB9U]fXmW ȕԞGPĎ-S0迄݋}8K!/m NDy8{GE丹:C]\Jm ~\3eOU9OZoȟVTX2h.ƸB1R<gy$bO^` +ڛ4 f𐄛Z'V2DE=JI91$\I*RDH:,qʢ=5O8,B<:L }fw, +GmdQh6&v.ճ $ 56,S  bn9x)hGM:2,FPd¨ `e;Z`JJ:۟0 n!~,?`5\cC{<2kr>GVLÒt~J~~oKwԸaX/Dȶ=C:lKukkkX 0apB.-3>mX ׃]0^j1>Cd^xN9;L -A=vW aCv#g]Jl\泘?QQ^ ̈Gƞ +"ߣOYRK/^zu;}+@BeXyL crrsK Ө](bCv6mbuj3l̐xK 3Q҈`HyE^!/ыQĴ6u&E7x)-Jjm"2AjB{p N5@}ux_O "ϼ +\ivSF +l̡˥a2gt +ĢGcfjqݫ?r]3Xa[[t2tn/+xB>'hMC5Da]1VGSOZ/Œ=U+J[uCbܳ<3pa#bԦ J~N-!犴]g+syH6Fsd_SqWgkw^Sk1vgL`Mm)Z[@9~I"buN1i$~L,. bA6&3O1BŹHLd9Mi_ـ~k0(4)vh3`N[K?[ưۮpѫ [tU W֎E<.y#C)TrbO9CAg8'WĝmCPx`J@WKKRx}]ç˯/߽l>uxy߼޾||}is +uG׎x̸]w{;it },*ON[^e'!||ۉy A +endstream +endobj +236 0 obj +<< +/Filter [/FlateDecode] +/Length 9582 +>> +stream +x=َ$qXmjy'Ӏ%xav` XavgBWj&b0:X`E& q+1ݡre|2\U'I]-k* ioX~]Ŵø qḰ;gByj]ltW{oaD+pj;rmߝs8yk%aq#: U! +S֖\}ڛNUCjaoR>hR~r. \sqWOA˪Ŵ3SS2~ы{6V/Hu>(OJ:e<oVa&^kA)@ؗL9rއn?[OlЂU[SǗ!vҩ^}y r~G).le9;BLm8݈v m_<-wޯ=-axNhDBX2IwE4\D>żهXw2y{[qo n:f$t3"qsޕ^u*I켁v2+ +V䝂Sl@=f;oӢ_TN <]ٲ jGzWV*R4Q!@jDWeZUO_3zL|mg;S9Kp+~ǴARk2)B,a'eh:8 &U2'#[XL}llSJMq'*#W{i[FfMeuV4,P~)ȭeiNҀ܁07hm6O*s¬`C0+QEC(_fTG\x3-7h֪Wv-6\*~hk^ ּH+3-HSƅѧ*Dޛ״!sƢj%UU{qaR P8;"ϑ0)/IܩF!ؓWzgKΆ1yg^-?J5'SN#EklC>4`ذ⠀%>S)j/7ߵa5P` :]KAY5ր9lַ[:/zd׫4+S4a[61 n%-e>߃B7q RZ@No:`m]p pK~n#ވO2A8ކ؄qКh2VKznhE(B&9gM0"]hU@?:L*dR3Q6>3nnZ| pz#8oK/Ӳ-50ya0´bٽgsrǐO-j6Ę?z;~ףEsJ?:S#FG_yg8ѕ<9n?Aװ +~&_quMegɠ_0& c`Fy)0Aٕ2J`FC |O3?ycoURE- '$ #q +"cFq<"4@?BH<)}j'?4mrv)|-6NO ĀXK+BT>S +& vbB ;UW,+dsf&.2i-d~Ҕ]@V|2s6P~,:|% +pǀ)/( w@EC/tPwy`ҴpsCt ~1/bޅD0$sl T2ߟ^k^j?4葮ƞ}_D{"̃k0r wvBk1lF΄v8` X!.LrlWCvHs*x! @ ;f}.f8)" xϥ +NR/(Ϥ_<}"~_"M߾**ƸyS,ۼr5րݼP*Ӊ@o~uͯ-z>\k]ھ=\;}ϛͯ]Pkg=@ܼ:hbj{^ 0&d:W7?=z/0Oi߮wv_a4]j"?.n_a+m3"!2T~\!yRl7thfspoomWi7U.>=|hts<}Cٺ*vSw*loϲ"tWT|*Plۺ4T{- tt|x{QZsѠaY>xpTJhuun\Ƿu>=6?޼ nϏo?=n*rv.v3?=4Tj,Ծau NJMVؖ^y DށqӍo_;HKVJBVHy$UHHeNοPS]/7@'7绿=nJBo65eB/RvT`(U>l/3˿޿+dYשCv[gqY +u~pv H\q.in @Mguic݂nM|x/͛·;7a=k~ߛw:5xlJ-h,6.q%T%&IձeFF~T/`>'"H)+0r$ɂh]b PjR?+;'2E<9'3,?pճnM6!v'k]PPV ,ɏ䓢Sk P.3%JO[g|֨j?1FLv=<*#Jq,Xcr}/h3 o3B~&޾]XOuF5u|麯''=QR +Eq-mIO48/o&LXebVv$g;<nMN9Nǐ㇫r,fx"CsYu~xFJM`sp?|`xih)`g)9?J'<+ta=ș": *A=\ys#؅6 +0hq'O>Humu2 *D nԙ.YBpBL[ɎΈ;N"#ԔQN ;YMRt t]{w4b-UKK2Jphl*,6ĮH! D-pj0;ͽsm 08 (|A,aY:AIq-~ʋ%ex8M +ᄡ: Xd{\Д,>6*V+ `5ooAw~,tˍlʿ( ɮmz-׆T5hQͣ}=?+3ZpAq[7)GB8Et-@qKs, 9n-ʓ}2Dh}lu]y^确arտɿ1ǎ@1յlYLn.xگFƿW[}p"᭚ +K^Ȟp5!F)xd|j=aNpái+tX('%̱F +u.J nꑦpHz$CS :a=_]A9w(8hDDбxEG+ϠďRiR ~B*fFR|(=O`!1/8}T+@H]ʸ"2^ꞗB PӠJ)ضVT;aYѢsWeD x&z4hqhsZd>8Q6P;e^#(N`p /3R4͟xM-\yzR旺d0`JP~KA['Kl7qxbox'`plȀQ' 5t.\Lشɑ)γ5#;NMX)=171Dhze]$SYz-FV1Nr1Iʦ31>YQIS;_<_è$mې) +?YڶSd@%"x$2D(@&ym*5Ş!ASI9X0j J^N̘2!SؾÜHIy-4S퉞ƪK /P P2Op9Pcqs (0c+%b`܌i.TP^ Iz;5@kCc2+S"]cH AKHn2!T2fP?6ً#J"8ל7Yk^89z`WġӁ+oL  +E%ׯU~,I|9d",P5ǎc#ʁa|eeѩZQ ^X, (cI퍚tutw)# !ɺ-el/5l`bʝ_^Ҳnb0lB 7\g1 P@#C AL&E&<9[M|0٤d44oYNjG?tR"Nt"l!FeK^ʎQ,?T|EQ>TĐa|'6-2Fqb bLB<7`r&سF:!P40N<Ⱦ6$J(|L^ۇ6%_87%NA˦AS^IOvJJ\ГD/ZâIk~?Y$XH`4oSBMluѭg`[/[':J_ d(Eu2ˏB˓/һwS2K(餟O&"|:ZlrZlu|8L9Z6ݧ5 FT:kjWP(S$`-s9゙E> Otq\+s^ dr2Y +YעtQ1x :Lkʺ0 +XLIBzctĶu"R3|6T=NOz=;0j oc[S&}M$b(4(u:Gi)q( +hہ\JڞP`g=W=D[v`vG[h&:ıi dt +E3clڽlQ f$i;#; uPGZԒ[H 2El)s$+YW€!JZ)08& Xx-:a":,.'E\T?48m<@/Tp$8YEpJ9| +`fC'MDԁ2%+{,8*'SmE_RI3ebl=]D4e0L}\B픗+ 54*r'Ў^CK;*ԀQ),Ѥ;T˝PjY˴>0 R#Ǭ.}ag ePRX?PDdg aa4%\iиz<pC*=(4p|/Eh&v]h U;HKqԱ.ht X}~&UZ7gU@GsEԪ:hd@ הJaY v.K! mWEi8Y,gQ67(] Pb^w-M,(5rAu֘Sn]IY sXPZ)H%wQ@ / + X|uZȂWJQVg-D AA%Р +[zmc:NPx`4Y@8WXz@8Z,E & NzV`:t1Y8z4MUalϢz-vinw"v J5ۡNz7E"= G,3XW=^4rge0gX'U!P}.ѿ.*.jv$B[Qx1SFѩٜ(YgQ +ީ80LMA(q;v\qsvdzfXF5- 5`j>#5wiJӤsOh瞺33OI:]DS郷]NRegF!rgHy1TbUAܙ9HGXar@Dt +Rn +}zGȯ{0bQN7ʝڞ/gLr(qZO>uq"UV8IB:KϹ}v9\;`&.wta''v8+7w^J.ŝ8?j!&ƫ/r",X;`OW  IjzV睬ȯ}uQ'TVP4ݙ '. Cet*3Y t:e@fFwEn]SRPح-RiDc2sl<]g,(_K>)6YlL:oyۮm0 t9yOZ)o4p*5MԩjGѣ ;,~IWZРSMWǽ(Yyfe62_% =ԖY33UT_6 4Q?:*lHfU8h;U^df**T|֩d5jK&Aї]+LjJ`y3Һ3Ų9ievCcMIU-թ\R]P7&p$SIf#[Ē_U#Gd;ou~a!+) #R7m銛%NnlpgzO=]pyNIgkTg4jq4q$j[I1ﭔlnqsj|$gTQ", : +weR?$0bIjoU~ Z=5D,ӤisS)Ij~аKEz#O&O*ica/iwڄ w/blּLJO77}]嘹) +圧gΊLjjmaaj[,YN7O~v{T"*r82 cQI8_PM]F勜z&Qir;iR;Sک܇vzt}hW3n/C߅z."k1Lh^Ja>)V.khw,zR=] ]'s'=t=tܭs7IG+|5mĄV൝\uzgJEEZu<;g3rLꛏ|K{bȘ(Mːs[I3t_$.)n4HyEҬ"-p +Xaa˫qML oPxkw[܃o.ı7G_Tx;&2:18$g++0 ߚ9{}ɟN-e8ڦc,AʺHSV5m˰i2/?+قj%ɪ^,!5Q)6(6@Ղʜ:O* C?_=^ O7wizOl铩׬lX ~,t B=ƓcO7oꗲ1aIт;L36ϝTN܉1O_S,ޫ_#/?KA]rTgQYtmP_Yw[dzV;;ЇsMaZYZ̨7_qngKuS)\oW "{" +endstream +endobj +237 0 obj +<< +/Filter [/FlateDecode] +/Length 20516 +>> +stream +xͽ[,&E=I2I&i`^6 ?ȭe4@z'#/"Uk_hz/Hf0ƍ!ݶ?og|^JaZzIc>[[}I^ZR1Rmg=۽|Ҏq%t\^ (s?Z?dGHjc{َ wN{yvs)]$}j;{)|oK{n2s0U:ϥM:'x;pVoFhA??W$՗>7G9Ƿ /XDnsW4{\v[>FfR]_6fsgY ) kj*'Y7se6lϝwCO0'i2Ϣ;=Ώo/_zYۜKr-56>'Uyfݜ~Cl%e&KCwNjȂ($_c'2Nį7<,I{{Inj$aAvN0 'pt&_kwzLfiO$q.]Qisl/ +S/K?Y| A}U( AB>q&X-,N2#@)86ŹrUeg'uyH}2z!=Y{Y/g ܛ"󛠾oR??'=_Ms<&ʯJU*E~r!MX &?7Y:ޤ\fʔr4K +1,6Uz޳i?,,S,vMQ~QzJv٣nu]} +tڶkY6Zaum,vV}+KO9 +;)w@ <勮v~J Ϧ+WD N+O!sImRM'\t04LZeW + 3(2_:B%lﳙn)tr6 惓ea0a]ݸ +/C`|(R㙃XwwN)>'۰aWrbx7+I%'ߕw kKHꅼd.n^ZLld'09+Ts:QkzfI\"v`a%Y#hKډBlڴG&rHj`9t69I7~rJJiv))gQYE![I.gyeΜֆg +gЮ/âZ +Y=OR@ҐM_U1@F h*XL,)GQS(">qj 6Kx*A%*gHz,%yWa[1MH\U5ܹS+ P?F$zB;S/$؛2RUfC/je%!Cv-V8D3@ '՞"X.թ[Ț*̵!JY-j6QQXwg/؞_onte} `)eKǟu̢l:YДvcvyijj,~|0eU 1†O&嵋բCNez +ŎɲҰ+ hb10=F%}3L**˫Jiۡ]^٥)kW=S&ߞ.ڥfav0<l#-a`Yڿ.mr)2eXrE-iJǭ+hopC3]ai<(YX/FٻN[HCz|P?}TT8' ѝ)N:2i5J(q|}h88s J}8ꈚLΪf +.R}r&S¬T v''@!y=x}r +V(rgr6;x +9=mUUfsn1%>"p֌5!PGQb89˰HA E嬀\Խ2eqe``b;TeEy9l: 0 ++S0(&~tUFXUu?*1uM{8ή2Y*q3oBt0yU%j`>t9fCS7Eup6mX6JU85N莺BZpBVMChπl\-(u0) +YY3K7T>Y&Y)'jιbyTʪ/EZ0%L b |({A3hb Dj^y >ܱ zDЧ^zWFP DOPZ"]W HQ-Ȣ/wG@tWwmS@nE17P/JJP^i0-" 5e}u]^x`G9o$8day[B+udr|bg[3RXc.)򨬲(Y*epdXI9`/^Ā!?ѧfjHFpdAɢ#*Pf$ fTU C~3 ܫ@[ +F|#+U{rNRk5s[s+7S>6cB'Ŀ< ͈XV6aYQ= )3na3|]{b134|*;4΢_Vew!h6lra;ut+m4S`ᐰ `C 8{OKC,R1m\7~\H`]ߔߨ869. g#G +Ww{2 +Lx @1 +xF"ځUy@8sIxPđx@*B>}HjBh>%ÕjUC}T.jovcL):F%q'E? .]X%$b; c6!bx%hbKp?u84i0Ājj^)Ll~]-YT 0D6iXlEDAӐFFwu 1|%5ABi8`WQܹuF] 6{@h7UY!!e(2돪g  JW1Z5C˲X*,`>t^̛{ȱ0u|'\\pa0ituzĠԽ0p ++m\ ٛűVƝ3Ddw% Auؤt A.AD̬{طmv#]AkߤEC e~3"R,# jh~ĿD?\`B$F Bm|anKT$E=0 }OAӎBZ< eeM1_r;3|rv1S"(/M`3a©cnU~)W.oX)֌lR@тU٣Mحʢzղig,᫰!@d*,`aĬCDJ KOOhgN9ؙR]8S`nyo#sx*N9@j >[Noǻ%24BbgoB2VKk3y}esxŅ֗gU!I ԇ@yexst(H>ahc[_X7HHd4>hg uSkrgp4(fzu~tivIA1%JN1V"Ac"gjߏ`"4s'85rvԴyFvD{XNIMzSLKb RWhʭ|#q&'*Lhev +pDprliRZƽ\hjݙ /6G&vafxƋУiM钚*9!'BitLnҺN4/].FJ)Jэނl@{WIU^Ev' $o eĭf$e5֥n}贷䤹Rֲ$ӻ`jE ʋ]k퓗bsÌT8 H F%.aw ᗐkPaK ]p$c;RAB2⥑W +~vqzҺRj'd=P5 O +{vtzW+3:%鎇N~&25a~=.Z +Ϙz7l,{T1*!eQat EֶGN/Vl&?[).V"J*N<CGk驄j~={sb?;4bAN޶eO`t\} + ki6>V?sX/z~Xz=r9 Oˇgv~x9g8'D'1tCG;: +< +i &-c;O2PZ,Ygbl~sd?ld}[/G5<򆚿[W oG)lc )l3 ++r/:3 +Ct`% D{^~A (K &r lΏ)QM>sȊQ?&Mi,>?uh>|\row= kmN~OSd3Qx:J w#d*r3龊=fVͲ9Ǔ!6͍x ؼ[S饡jpNjju1Z;!?}74I#KbHT<⣯Mt跔Եw{aQ}[\O/ZvSa5"׭./tvoNز[_0Y5~SJa=A[Ƀݕy[tM +?)ܪ j^#<j$AK3N= +mhC +Ciq`-E4u ]=^=zy66`M\Kg`k'OzOR͗^ȶ ShB$:dM[S_iwIz?k%]x4r6l؛lcDА\{r%4W*`vhRLHIb>/mV6&jyhi.bi0[:Dz|@=Sۧ ԸDy(}JMPTGV]b>j+ժ3AfLO-(.L'eZ]}rO]uC`!if6Mmff*yn6Oa~ T]K D=#:e9A-?=Q$-|V>8;@z ȶ=1 }\_<ӈj6TsX47+u,Z9ES-_{?+oTq^5c,9/>'Cè*| wRAQOcѿP_c(2+x wX\Pyǧ-GRPaXx5é¦knUTizuQ?su=>8XU4VeSzR4{f[g~zGJ}:}~G_ѷ>/nRho=%[0" Tc3 {a{@)yf2>6ȇA`ۭs"+۔M%hzgt-G. +5.1ϧިCb7S&eԋLt3&{yz =`9ч|6fQ4bxx;Sb{5WD%gӴ LY|Ί {H_ ƒ`$݋tp斎Qo[ n_|F~H] yxi7x޹ِ)󡊪wM)a4Oۖa{b6ՋLdb˜>x ipZĦ>J-4\YeQ{Av +߀3ȿδ# 0dA ` `$F' ؐ(,`| p l#ؘ| 'vd+ȩY$va9 +f0˭f0;ɹ,CJ;o +r2c s2 O0yĦ;S9CbX2YCbJN TcJJwx\ze b3. +xm2nژLNvmibV`Y0!aflcbE_C8p&5ʣ HI{O#\%C~lФƥ6$ ӄ/;㭧a^rf%5CŘ鋇}h2gQ< j#M[2*fq5}^l`-X/4{h{Ozŗb=IT}9zE`y? ;WDHŸSyI\e$j=&W)x8J5<[LLMɌ647s`VߙNYŔ8҃vlSvKZ}ːVOG2}/7ƌ.g{ړ'zfZ}0쥔ˏRaO :'bI;:y|b*c=G ~~|@#:ؗo=?fmo7 >F}FtaC 󻐗f9/|d}"%MУW|)J?ҵ\e6??,ō]>cMIBg@s r/3^*Vx/3,viyU_:|ir~O-lP.:1qEO7ڡ^Aw6QlF}4>ghY8mn{X_;ww7taG32a\\aZaB{zD`mԯ.tvKuhR^CHPQv#7 Y#3E,b̐}s2jðhHnݰXNk >V +d%U^Ab!KWjHyX(z=;_*oi¨l⒧HF3.)^=a dyb,f:wnu +k@^,,lqVo&s._~Cs3]ϤjYYYé|,u940(22`,,uŲB2R3Wc WfV6{fͺvhPYCD +Z72pnbm>;wpit|s7@5 +IP7\FR +f"&6eVrL 4 9Ƭ1g,/{˚5ͳ>1$!Y_</2me(q 3֏IqBPxC0|5 -3Yg?kE A6 !)og1 )+󙖡>E8*$3s&|koEuUxs*bxaH|?+j,ئvՏ;.q/%N(J B_$KCEM&Åc.r_kE`:-J0G+ Ȓ͇ړf6! E$ S8!:U eY䞃=UVYA>me6S|p"5J%XbO ZU!ᛎ'͂T򮓹7 #מVsOS?B߅uXi0%bf"1@dNVXX5ZLW5n}»ķw}[^7>mI1wگ_ﺷ#ȬiƧԚ4okffL In8|5HCj]v~qU%XVYe`_5XaF{ bhh>b,ʣ3p~)|" ߑ[qYǝk_?L0jRrqѢj*|} BPB-KߔR3ICxE- /pZ5 z@]U̇/-CB> a\;E9*B8+07tPa8&?| +;4|h슡 !ƫ[vaFњqj|3`ժl'xGn^Z.5:es'~r#63Jg1rGz?cKl ͛ॻ/ڐ:]XG:2ϗƂju-mg5EC/}< hB~Űp\力\|VȔBWCV9r.AF2۝L[oZ LJwOªBb؊7O>P8mãfk]E6վ&KPw#-I"Y`0 ~"Q6G/yֈ +OGT@h)de77Ͼ86BH̻ +Ƞu>2@Oj{iPEWFA5-KMԥМ^9Kt9d^jպqw v}h x Rȭ»f$iϴzM:'6NrŚ\N 4>l֦`%]eRƚ.g!Tan P)>i=CSMC5J4Ҕ4>r~:f"lFVw'CFDb>yq 4'ϩ%#'XɾZpXFi΁ _\T9P1e%m.|;B/Q +"*!JPcsB}^+.̥,xPfȃlc)ki gZ0^wN +Sۊ5·hvð%ǯ8b0}=̝, +lɗؚ Ȥ_Ыp2_$_$0#UY +6hl~׃@e3!UU&bܚ9ƫAMC5ywxglBV-g9:02ȭ+Ta*/ǚWtd ow{V@W'g;RcP.qA%n GyDU'Ì[Ln9NīN +FP:BT)ʽ_4a*}:V8=<1ыL{`[3t +_u[RA`@ .iզ鸷iݹ` aݸ`k/—a&QA'st0>r3e9Vyv<._?)!| ]UhMxpȡMgR$TI |]-XTT87jνphC;RF=+6jc} +amۖw#Ǟli@P Va  |yDYఛxIN֡Payp"xpviP35 ƪwA>WL8a.|ER,,kmxaO׫,vqn*pL~7NˎDGDW8l֭>ӎ@#@OXC 02}"֭B dYR +ʳ#rPWC֗NM[W;6y<b΄tCTډbضkv_[B|\&a ++ :1Yea+Of{Vil#U,i݁(Jnaxʬ:F6Ķx5X:2|P`V) b*2 o1 39QlB}w,:(|WC P5جAܿ `,พƜ=eQH[sEyVl->ꎸ2srdY ?ן>>܉KtKF32`asJ,- g#F1pYrsk5-k #XNz@V+Fx; 9<[HE\0" @X8%Z>7{3Y8[زeS5K){.&Y9M(H…t5 7-`:C2)Vn Ko>/nq/H_w_4L{GY{cMt˼[uެPSgTcx_6ZCRY%A95&xIkNnt^'jUiaI0$4!)%*)spM<4+jFe-ޅSa !iÚn"rU &BEY|ӧx̬:^M8*2F*MVQ4%އr볰,꺃j+;r>8XǷ ӰS@zgOm? D$5DZFLm8\rZJ3 eƽ;3BQ/_֢QwIʳ|XAmeJ}lHl!4 fc2$j,TL\Wj=ǷHѽC7tymxR koB :.] ~8@ҼVMRhsYVp#3x g8 +l$NPBn)향 o["Ζ;&^cblZWžm֎Ug;R}>ZC={iʻ +7':|*FZu O9*`24?5fCw~o>s}}U>L~ao_&n?w?p" Wǖy0?z?~84+E_sMR /߼=,NTK?9?pbO)V(>e67A~bMf,Nxnl[7ANƱum{fySME,39\0i O3#]a>9墱=j!OټYg:f~_ѐ< O o:0 +K.e$|WX1 l'6>dYK҄Y櫁x|Nt$Ydԟw5/>܀1F͞K`_>E/J#: zt/P`H:6ٸE>gPTb"i'*f3,zē!,ʼzOB}Кl9kF]Ŷ +2Ya.6 ِkxItPtgIi +iL4In-Iht;\e,i?,RLhgz6'KZ#}?D!|8_fwϙ/zfgVf&=kݒmko^֤Z :gq@!R撡<3:yZg5O-~ ި/D#,n /0yh| vjd^ӡXb[ptٮxvWzv3D2g/vBM2nBd4œ4j9b(Y",ʘd7}o{Z|t]QGdxƃ μ2a,MP- (lFRSNCb*q;a9|#R+{Dg_-ꅖǀG*q%xdRVSw~Ό5Q+A j$S>JOͤ|^3 fmn"MH[y}A6EGN@~JSV@okÍT8ʃWfEaxE] d`x)*3*Tyۄ~i׸ :+RNF#+CY2eH; ,,#g#XPδsX: F:+tBO 󻼫bNw˖9aׁ!OPz-؈X/.׌ƋYK'ovlie(]هwr5;cM# )2$FUthH ՙH^6 D T<1a yY kq<҈'\XsZ#$1~ +sX=`9[ l5Ll0yBY,6!" $Wx g1/3Gkm(dvo$?2?lsp/+`‹Sezs#d ڗ]#& +#""{9P<^Zh:.Q lsUQ ,x /L._b{2̌<+&.R,xf-Pw\8``2`w3iL \L} ӄ3:\#wWg 0O8/$gJ7~COmsC}+ЀfL^cp޸榖4kxvv㍍ +˿|o&x˟5n/IۯOJ`]f#2ЯY?,!x?s`Z??:kPPPPUSAY|X1@{U$j WJ3ruLq;TY*_ EʋԿT *p(ՁJ1jP͋}}t0`7Xr]p+\snPp,#TF8'2NV1>9>Ĺ2 +T +B*/Ryh eom[y +/: 5r,™mA·YFG 0VQqθ0"Ngd(5t09"gf6Pz|XU#Kl/[]p_Uvj kȰ/@ӡb{Y0naoK\bOkazq_W׃{8j9s~p)cű*;0hB߸[!r.-)/UTEn\*kKPs<£p\ +uLPa\eSд}.:h>a7'OjۼA8Y˲m)/?@߯3^3rt=26V۽@PYYI׹ዬ\8:OlńW8& wi>Lln>jb`z̜ Fs|㺫V#4z$cŨӻ`;na+|s28|8?fI-Ż'1-| +T!6톤[BMnHܧğ>K-v]! Uױtgp%ໂC^ +ӽq t+U+6wN+Zop筆ǜz ֟:ox=h~7S lmZa|`9l}p0x1j|JKjkFrkJrSj]zѸ{*Z sP8/a-? + [%Y!GƊ VMdLjs5jл׈H X$RmM!~ ьU5 dP2zҦ 'ꍮid< d_ M +f{vn#{ bRrfxp~?Ѯw}e0l-!Q= I$q3I DJ܆n4;z4A1K{[i\n}.St n>LWpӡFwF +LC>bM +:[F qeEzk4T:h޿l Mj5wgAudz9OIx,Zp,^IpfzW0 "si)Nqȓ5w-{Rl0x,6ːrc* CEz~¥.+f+gwwovKP!{,jfw,kX!k#u%#]B5]([dhշ`><2˕dWm2}\*TL`^Vpt8Q6NRz*l+/,sTPtb&ո[ڏŝ#&5Ҋ!NCeĂ[u'sk|lwC(7VpS^-Pu8 YI0,n 'Tb=> +stream +x}ϯe9noY<: o$F3l,: &_#Hґ(({IO~~~xy)ytZR;^/eoc?sx/yymզu>Ylbf ry;~Ly?Lz3c; %~ 'ȣ ZYxx+'J{F*=׬kB~8wi9ǩ OJ'uWؗT[7R'4~Ҟ:F@ؾSھ[B۳zv= n˙qV@'%N4^èon9*i[YiyԻxY,U{-E]ȽճM$ݚE/pR /B'&rۅ꜁`t%X`8c 99W/X4Jʴ=0?Ɯ?c&'5!@ޤ9o8Wr":c9Gϕ-mo8 Bߊ|MI8Ab +M|fz̦SL7+k4E+_J6;_lK`vL>A}6䘩C5EiLRVEt~; @Cb1QL;9 h>$=C+Ĝ-H4߫͝C:_޺2;3˘<1~HzʙәLcL2 7cmc'Wqt"\teua|qriO HX:t?+}Mop~vI]ԓ(snUU{Mskb;S+ms̅>|f#mXsj7tv+tIhs>oOX]cf &&(=$㜱3k_,YUIYt4T&ѥiet[,ӄϽ|aCi!9gx.>!?$9A!c~ߵM*bm Aj &&S]T?j)4?*d3%ܯ!)Y@׮;2f5:)Ƞi"CL&)ȸ]=|w{q?3dmoiV6IvE̘DX[Dp3&ӤݛNidzn8&7a02Lv6&5_cE:=Ah{(1)C2֘esm2oPҦ pVu:έW&&2Ȯ03f.҄)ѹ.Ĕ֩ 3g{(}j##M^H DaE,´3[stoc"tJ擼f&MUwйw#H܊vbe%siN4KZ烳\ R)eoGYY Pb4+ -Y&J/'ҕy~E\w&3mHe -2>))BX!πpC&5s*wS4@2tgŶwėr7$B]hGE)0賓g +Uq`; ki u͊hK[hݲdO + 0d qCDIjΨ"1QuXTRj7! 0':RH Ky6:Gm )(.&»)YzB- ,Ca珙8ה0JaSl; 7&ZZVϡUj0s +q̩iI! %J<]А*y(nNj642uR;ٻ*@T@: '*8hxX; @8ZEǖIK7JZIEpS J[RQK-Sg8ȪX0u0pl7rn+:`zD%`AxQm1GAJ)[Rtڹ2=Ci۔b +ag) ,6jz pqXnSyʜ"BzB:?Rm;e?&+{>Yvżns_}j_qX>ChSMMUmxZ.X_2.Kr记5w]#`*N$<QZSlBIzjq-z?#`Es6Si@w\j^fJ!M]'VDCHSħVlT?L +:&¤|Jc3"xvDLÒ(X0&vwJٕ)eWv +#6D9փ6,fۣݶ`5!)BbycB%0d~A2ަ#8"80u|<;A}@̓4GQQ]gќN|Jså +1Qܒ-$Zf&-a%Ġ#PT|y 3!Ou,&Ԃw) 0S(k.LX:oj¬ɲ.@t J:9.9;6Ɲ㮋dcn;$Mzࠓ< +RKs70KAaЇ5kͧ&*CU.O-NZ]^Sʭ*23CUUmܺEGЙ7s uәia;`[5o81ͯ6ZJ~`t +Ӛa5)v'np`nZQ5jDݛSyb))n;wgK;-*3"MHkwOdn:ޘd"cG]2T0~жyl@P0Q%x56$z^0D2:tQa-a3 8ˠQQ"S37n< :_@;{s\tjɽjH3 :[Fyœ =D̗eT)hXwk:hj bu(:vbVSu0W2me>L1rZK[v5A*T]PALx~Yy5y`P1؛2l>d֌Nġ&퀉=,&~`OC[j&i16򜸰g)or,jyn9Q0T̓>c΢\̳|2Ϲ-֢y".z$tT4ϣ[EifI٨i\gEl*˱ϧef3e8=[хmP6k6Dc6 A@y]D3r6.7@5G[} +2`ڡzm.]Uu\`5S)t~;X3>&UHl?Y߻Gڕv_uaƴ^ \ՋyN ץi?E?LnۼǼ_FXo{2Ǯ9ՕɼwfXZ\/a:3{3W93fƎ{Z[߻.ͰiNũ9K3<ԧY:5gۛfhռaKWl|n bd5z|ky63Q8d8+̮(i EC-1JXbu6zC9<p+2>pBuUgqt0ɾD7:]%tMZi0xp +Ƭ*t + GI{`Zc*2/^͉_nt5٤TEEleWeGڕpFHSmthu3F3bշm Rf}&rֹnA^`[q21RؾnQ@eGu^NMȗP :_h!*/]V_7gXx~)|r^KG|J'i@3b79oi qvwgKsZ ނùBw,aCh,IMĂwC]v:,ha䛩lv_Whj* $ucڦDQ3S ?eU2 -bNVvNwْ(^ojlͽFMua^q9;;1d2H;!RE)QVSыG=vxoܨ;$Pީ_t-MoHvʉǠ,{30 [,&#@ٓ閾+mU}SuA4<渽v%mCUz]?#v83܎+Ŕ.(3Zf z~,i(YZKΖƨMr[x>4*ɿY*)l&ӢiK ݜts; +(fĸ"n +v!LgqPn)7C`XY㴇z.p4B0jҔں6#8e)@L,+`ItPL +7ŝZW%Aϻlj6"4FUCÇn?>хNԆ2F*v+v= AЩrEyH8,|=WPFR XgwE]\/ sF(K?V$Qʂ7;]*܄A!#/+Y˰{nC5zW& XIƽT e=n +}{Lgm[3(*F-Ctu"1縋0(W_ȕ[GˠlX)hij[̣#*-6_[{ 7|t5ѺCgͶp- *Zt}vו换Sgj:갛ua.P.A LBn0"gcj u;@ +m#CfX&r(3Ҽ-4<ԜO+Z3&jR:B޲hPl,VjΕԦ &c)crvh$D 8y۔_%''d,R lfl)f{):ꭣsaì,tk})`N5rUFIQxN} Z,t& î'~"jr6rW8͜o1qQKƞ2WcaR 5@էSc ƯUcٲXhUa{Hpu: +cr +KG- TS.<tOjҕa.vnFw +iE)0k/Ch2űZrOa5{׀ 7#̷cU1fg3o%e6oU1Ã8+*07-.< 7S0v983]? {@xNG fFp-nř<0`2Q88g܏t:aniPVƌL ̡RWuNA 3PJbL "DK+3`n29ނ{}IcukHlЫ4dYŒk}r<*v)_v욾)ޮSx5c|5Mޮ +AO3Ɠ`lGYy:!ׁn$48[[N58np67@p ch3:U(6J[sRK6ַ4hIo\a$dypw}xd=z؋Ln.ܝN3xGl~]]U=˼ +㶛8Xw^tNO`c`W3,n[Kߒ/,WQSyXwbp`0_yx#]f Kped*q9jǵnvT9K$H{R<8 ЏRQnqk[Z _f)~8P%?-!|-.4Z_Ks-}5da0s?+xbIgRn},PdbAW̐ +iAv,w}r o3{,-q,IgC QsV@vr`HnKN;b!:Z,kN*2̯ॆ Bs5΅h[]jT'.Utq!"~qqǵƯn"r#VoŌgl`n>A@^˽r_roj3$Cժ0g| KG.4UUǵ` +O^#XxRz0Rb$=un +?E~Eŝ)x n),ԣcuuX{q 4&Ynؤ +}^-nL*RK&NnbK#âk䃹84V q/X2_baG|:mfԈ"jD(kN@ eWDpstGf 5>G#/H`SŅX6~kd<$C˽ZW"](hlK˃?6Z;n,)vECſ5P1^ݚ2%|#l}N[l~Ka1=TQ GҗRN?dkG*djC8Dyh6l]7s"ڇelv~b`0,4L1«=|\`7ۧmis!F*KQePXñK{YU#LfΠsWO4v3xuJpFxayQX|ν ~Q.*DYC7uOM/SE9yUŀ@e&Q +u?/>Z_gӚN+M]VnÃfT+?o;.fl>FsN.\Хx~ֺ>"2>^,{hs?/{@,5Jr +BKt;bkK^k3˨e#߲5[+ܰ UDm|~JvWBm3_WX#׋tdB2<\2ELga"e!}'Pg}{^wC2Qz_{$E*~mi.:Goއ34;.wYy4/&mS 5FP[.-|mÃr%NB"t4ZT{2QXQ}?Vt>7߷ Q(Ʒwx{< /X(`\NpC~BK~=Fgg腹=c-ci=pF]fDO([0#Kpn),>c-l,|,|CNdtCnq7协{dD0zMw\)sݩw۝-Ƈ K^n~Z·CxR¬G ȱKn MO Z?9”ͧJFT  XuPY=7%󧚆;R}4n>Orc-v2]&`WBitʰt9 t,oX>CV(g#@Du8;#p~_s +]CU5A;1~m`-Xg821O>hհ~6Sv7M?B[/8gN^2 'M0ߊ/D'и{ ͨ#?IL ʽ|c#$ӭVBUޝbuMC 5?+oTc|IU3dᕓ-ݴ-ze%J_٠Dك ށiIwѮ+Wp{W1H# -gUG:,ï+֗n{wfy{eX:mp.bVo-qCn\nP!贠 f'Fko7tiv/߱ĺ-vAt{ճqI*$($F +qX#$(J"n1&iP'\bnr#Qj zS8t-۳C? iJb4<j}-At}}t>%2JY l0cg+vh@CdF e-aW^ b h>Dا,%ƣcZ wB_>)/׈ZD32TԄP SvJ8GmM,]^Ǚ +x4dF3jiTLPSC +n::P܄,a/N Ic f#HQTŤH3Hz'ݢO?92o[*!oLAZiq PġɃ!4 3_qxt{™!RrKY^;_x$2<@ZG Whk ްaFadq'ݓ N~Ox|@7Md'R%hb//+FRFoDZ8mq}jm2ʺa zvvCki}F5r/1ILk 5a;@J3)#EWj"a+J*byP_~CnG 9/i7 Ɏ!gcHz7o56 +,gg3GD 5W|w9@`/crcWE O3Gä'5t) kϰήcMcJ,G_k23ZzC73jkBy ZIFU!|Bo3UQ lD YW88%*BA3xݐ+,l5:u뜃l;py%M%fiQ 9u9VOt(x.;y# +^>iO1H >kۼ$@5icXy"s{%=`WpY[ %"or)g읋|iߝ)E sۇ37ԁM僫ېDBL61:(#  4̑0qV^ON#XcHPpy[ kPh1s7EKlSOtMA{ *Ñ{CniaoJ̇)o|מ6+-S~ӀZV+@hk8G[i?]FNHk%<*ձL +!::A e˱Zj6X$_6fۙNO ΗEf {! @pQa-b&@4ĺx&̜eFr,+Qva5{K@kTx adlJj-тF3w| Bf0>X'e^RzH4 q +вrV.pw+=^pY#uFE$F~E9^2`3d'B6ȑg]'11 Sb׭Q#usQeHd;q,}uI,",KjuQuDe/XƷ<}6>fj}y 7N4uMVZbhr ?VC=dp 6c3De,mf K4VTfYK 8x(q2<8U $A8rb9VhNTFhl<@fTx篱 +8 +8 . 66٨"Mk0Ue(V"|†ĞO?GQ:ͦtW54PoRr@C-PWCtu =rzNArPAVZgۚrX:e@l؉eyzZ}ڨ-zyCgOipX(•LCl, ԑ! +ނ_sp5i B^lֶtj&9Gb!iYlz_BwM$2BuvZGo%YU:ۂx3<'J*K_'LGo9u`LJ]5*z0f +m3ғUy˰ʼnƧ[85ʷT2*{NDzvUBee CMuw)0q Ogh\Fo:y x6;wMgL~IT:`γnYѿ2ka6y17հO?f>x6næFnCe#oT[}|Mʲ +w8¥C7< 9.5odd{Hb?7pdjCNld"nk$wBkW_DJ9zɷFb5r( 9`RHΑh Yu'5HB63 51l:-hfQwa;V.`&/l*v>ki U=\ԩ4wžڊ+6Cwmu_{(mqǘ;)B{ts.#ۡ\6q=2=c_5<qIK_sPP"-e)- f|xѶb2 ~v2E4KMek+fr 0i5cD4K`eXlfp-:)9+Zsf]yz [+10=? 0ؚ*KVf) oGLs!vz|[Mudjbݞ%֞Mјv/ Pv3,[+,'m5}.`\qҞː1|$tS%~2&0ya\܍/Yǐ™+}bf ;΅p?=baxZVAL͕Yw)t-T,19~(d9Vg,xzNvx֣l@9ղhJ3nDWOw:F&ipYk%C7v<aYpJ7ִXgzU\ie%Gj>a0V@3d];:'zTZvZ +DXv]aHq~(Zm׹'g z<2 li,%g8b5}}1 n}1 :C2 ꅿGa1n֠Q@,8 yО1,;^`1}#Y7 7AhZ=_tfuUTh >%ALVG^cP`چc:ToרyAqQόÓF#au؉#vmA{6uĕMRGX S6j9_ 3.=jR{c>О!N&& Ɣ a˰J6۶n9vEȻ`қwd<{Xv..F|+D1 b^;/& @BH 2PJR'.>= :W~V;jM3x&YcZmJYޡJ'Ey!*2^hR\U+mA&഍*<C0/Tt}YʊW8*9-;d9&mئd WtL<´I_VkBm!9еDj;xePpmRq/hN;]BwʺW~yij/O'ߴ&_EYW;z;cͬQRL + c! {2:fI`Hzg9dz9u#fyf1qDvlN!# 7B9 +6Q\.@ Lj𓦉8>&ф\hCI&ԣγ8& vPv8(eA2!frYO +YV|mmK?YBUsNƚi/?䙨o_Ƨ߾v?m?_.mg3YΖR-?M1+yBO')/?t?}aǧ_^ϯ_Oӧ?\;QC ˬf g lO~#hN`vSf1_?HȦif(ix'J nVGӤIr}UBpVJC~Yz?X;;L u,>=Nt9,$}g?snUF5|>0MW/]^gip}s'j: +׿zs\uae?w.h `W䩹/_z&i%U}n `RٞchbA%7^W06{%y#uC5|֮5>'}CW5c[RXY>PHZRaXѳ؞wv4=Y.23kŽҸ$m(z{Z:Lo7|0Gmy+T +Kãc]-b3l<?+8*Bצd :Qǯ㶇nVTn޽__4_5@LQ;dGd 'Hf04{R]' X$4"x]c7dz7N?lbl= \+o; 6|p_V#$]B'>xY.5>hdzl4b^"Hl00HZLj\06{,qcc< ^X7gJSߺ3k8KUo@žm80XS{s0DF{Zpu{ij,Dv}%>4ߺ-/Nژ0H>r4]>zM| )*hKP*K/VGhVJ +Z[hJB+ V;wu5PHߎ㥩W}d|QOeBg|.bN }kDow=Nm iO@ xoqQ,;wKx5$c@0.Pt%47VG+yDEe-?-/tj!p:()dبgby֦U_Oi)Ǐa6fX>䌕& bDaBvʅU\ +]! ޻"*p> +stream +x\ݏ9n¬UG_%$9q/<8xvITtۻ XbIQ?*0^FO\),=mRvq_.s/Jx:p")~.m_RNᯜe\6RΩ ۹}v6zzn@ܶYɡ3lӚr<ץsF֘yOˠRaY6=1CyHKs-qNlFGcL:(-qx `CQU03!cZPaq&70%_eTfgpyCǮ-Σ@.J|K?<4A2%xd]n6S3,`-q,^ycι:Qc~D71f(F{L}#`f;欓5&nj4wE.6EAp++Jɛ`(:*YmCXS(S9ek d,%)/t'`Kp7 ;b`$QckĹ 7:$c0qN8#ė#AtmLЇ&O^r5\M{@3sAZc\8zMr]L)@!!jd7^zssgុg8钁Ԝd)pv67Ee;.2dYS&f}?W+cX$\K9\力뙢bD<)n]ʃ_dϚՏb(6vFW9\pJPfhC &N3 וq,^04r}UNRLP{#܎Vֽw&k (i 2pL*PmdeHb?v^\7zZkoQ{֪/#gu>:5 t8BSA]Gm $\J0= h,ܯewTGJqþNS9ɥAf%Z\1 `$ߒw(LC|gƳ9;D#0 gLyri͸2-J͙x $g/Y&dHI#jGڕ<-<;Lj< (@¥_c`oAuGS4?\^m͵dWt5-Y(rsie]qM'jwB+) +i[܇}v)A֚N)=0XGk-+u:ZZhx-PV!M3hq!-k!-RP!ݭॆ2C.9|nUM?y22ZkE+Ys.8heTFR6,ex_h-oѲ,7EUVE|ķ*ZQA|WDKE"EkhZ%"Z^-luduZ͊m;Ӥ,h]9NLqU<<|,Kܗ겮;'sxޱD?:=!& +:+Puy;`oWޚCP uNr`-rIr\TI֘=MI[%cEcG̘q] W\r @(=8U:ā!(AIͪWx]+T] 8ЁLXv`~z[^)E_ 2v:"p'$5t0 `j > +;yB Woh0g4x\#/)y v`,>U GgLj~gՔsKBḢTRq(wŮ @JZ UmIb6A7y0VӜ&cept}\n Րq$XMWrs=f6Sy|I !@qbaKFxtbmz;kr Y6tnLK*)U}s,s%~3[Ca&4TUXHajo/ +M#/_ ׂH "g,d.5]C>O@dVr轢 Ĺsm?\#7?KlJԯR Yv;59oS]Jס?xRikدH唜r5\~I+ 6Cs/\`_^~=R엶 +cfK[_ҾV w6k&o .Pmv;:p\ q^tgxАL-wR|kO~Mv;m }ToGezymr=tӽƫ8$K%`kˍϿ5`(۫Gx}/pp ʿ2rm76T S޴N ߉q6,Mʖ!6|Dm:VN-9Ϯ4u\)9T|zUdsw"'~$:F5~*O /۴㭗 oډ^ Id iM_tqblЉN*/VHhHCmP'iX1-k6Tg>̷&6w#ćKWy<\0M'oI҉#\eН|۪WY0<cVY$dcS(H%icɝ1G ;] T#BYaHB1B͠ A|i!>bz;uƍ'ԨfQ|r0^ .> >V * +FY3.R 'AOQ'^OoACgh w9h=Sku>rB@$DPc.x .LJ'נ+n:)}[/ΑZBUȱBLr?֑TE2TyD7Fa|OTp:r t&C+5x;lqXƌGGK'15Y[:e@yr6X)&蕨:VJ3g~ +̷S/ȓX?2TC7B& k2LIa3KDY;y =yާ]=:-i.mX$W\NNNp];wE6䎻32 %K3jyu36^0S/f̓ {;D'm7p8 +vKOV \=p2Y8䦘ʔK6|(Y.8xFP(@!՝FJKS ([t6;D.c{D/E"DG^0X~pr%\5nCBfZ⁄+|S.RȁoW9 +] +XRHel3ASfqE,WL9#Jp{QWx,])39P9 +}2-ӏ쬜=E ;_xՇ26''򧞵sAFf92l +ܴMBk*g&'﫶*Q,&-ֳ2?f!k#gXlyFɐ䮘RbSL%B%r"A.3+n2eO@6TKL p8/4 ) R2p,|@ YRġNIPsr/2̈́ôgfA +٨`HuQ0,5yVR*q W(NJ_)}PEH6?b5P#էi4H,ՌKv]mf,%Z %Ep65ZK5xB%)ު)*m^gNqB q>ȝsu6 +f<kGc^FڰLPň4'ζ#nѧ4$<9?mLtL)I WfW2,hEeCdX~#0> 2$?vB}[s~i0K:|PdS%I"Nh+)  \JP-b&:'5j;ȈF g +.h֥i2ik]f89P;3$At$ +7ᦁTNM#U!CF bFI$cxwzQ +̒E۾$ظ!6TsSHYc?A)1*[=VkyA_Ǩ4@ӕHqCg +IEkF 2 Ѩ+ŔT>1$Ztz_ +E\#)(J!ƗxbK~XEt{*C 3d:k,KHF Ir [![rȠq#ʧPU0F:G>l0ʏ/SRkWkVRWOdKiSJA7FiK#,g(>Qmv XIG`sJ)[vX׏֨ +2S)jw[(X/ +Z\PukHllt#2'\T}I3RҚeI$ (ÕO-QfnOta_^=S ce V;?4N|Wki/o|Zc{nͧ7/>/o߇_pq~w7l>-e@ +cqi#?<=>aRzj?<{8(y*Hv^׸[q2pߣh%$Ĝ@B$ˏ^ ->/O{޼<]W<' O?]mÛ? 2?=y~z-˿R  wC̰-y*}BGGO,ΞJ.<_ +pCct2GXxj?y}J+O_syXAK=x5nd^h'|?Yohh 3duX:3`F5۫5dHOw\}H +endstream +endobj +240 0 obj +<< +/Filter [/FlateDecode] +/Length 10991 +>> +stream +x}]9r{Z䣍{>^a_~g{4ctIc띌8 2[__h3d+"x"w˖oɟ?9+CZyO|e˒sZ\Jα֛ Q}v~ۍTgO/{+Sx*]|7V6l ej~8afcēa@M1^:S:n9-Qe д5oLeG9PS|ד[Kͻ:[5h.'Q:'"R:Pw 8o*j\9T!OV.h +8͗[2 T.;-WgIlIğtf<L99*sŞ9662y*?0)/~?m:0Ǵ?5;Ҭ+7\ +X_)g3ugJ6*>#ju +wU8.'lRZ0xn;u{8;kRrUz6\׻f d>L]׳-3VҮY&MZtyM@2NV0 ]q=orDƭ?6|-775޿<v4+ߔ-ovmެG62ٔZT1eUaO E 6oL)"<\ΛUWZkv4P}CI&}>Z:*޸1LUQѠKm&=\D mӳ@>B 7-B Br"cbW0/v6HH`$s㗖2'4c +"j/->.piu1_b"ںٶ#@ۻlIfKKF|iIGHpcmmH +PT*|u6[@_;O_Ӏ +^3ׅU~+Z*җsטif%o'ꦶu&s,=TE<Ȥǘk9Ѓܵŵ[-]3!_ ]CB1z75 Ѓ#aҷFKX&V. 3-qZ7]sma"$u'7[!T QJ4J5l6$D8T +ļ^ˆ[PZ#tmi he"."2e,N{ϫ +LWDbRdf*"4} WL6rEt62YI*FZQ4xhg>XJWD ]샥aE 9l;WJύrbHb2ġXAFvCЃ&| ;w2׾e7u7hbsngd0#7F gK(hd`5xS'y=uى2?v9Ryrzq;r_5ӕXzQʚς9%2kN躨I}2O$3I +fUI2j&%>qȲ ƴfkD,=!&q״JesUDXxKMeId76ljWviNZ =ho'-t+@O{(3hGxrQS%gt0-_MX@!h}yGIA)n\싦j- +X w }%JE?2k`=c_ 4[s=_t`p +ӡrG\T9vcI`tWf ݶTf<ڙ%a[.n7I`N+ԡ~Q:AR?q+wA/jƲCswFr~ 0ȃex,>߽a풇h7eWJ%_"ũ Dږc|aVS<9Xϱ0k>-@x<$` +ڻ#D߳֙=Xw k˿E +&MW#he/[V؄a=cMN˾@;ͪg݀cbGyoV7VacbB ]Êc`C^tji }OƟ&;浿9 <Heka]y-Gޔ*uҝn4o(iLdӮr|Gf-/ X^Ʉ)}MK3p In@񫍗c!OѸw:Z#Ɲ^.zsky$+ۊSS8sbX~b@,(mKn|Q #Cї^AКC5ocJl!uV/oj:1n?<y f8%^J| DM"k3vg0gP.&DYmrlyp(0֦ugxG9xC)l^h"r/@!iXL4 >/,Lq`ҼAZ26MZz䋥Dl)8$-]$3>X֩D<.%JEX3" P:Яw;;Xb4]1[қ'ȅ`cסּY%~0 }7sm?ϣu/#!=0ܘrcdշpwR6e2I1:ar6 C[n^\` I(O|\dɄI Hd=5@cuU Wx~ R^Q}B(B~|`+dۄ\Bw%V5iӽk8ݭ(B,ū yN/LYm1Uq b^#1G߀zԭp2>Ss,$-Es`^oPVo~.{N26CgT'I +kbߋg4N2:8N4Nsr8d׺5 S<īG4xN%>._ qqpBnj)v>3.1EgD8~w~Yer$mIz'1[V[:Es-/7& qtD~;1n(Eo%m{ ow07tt: *;Cj4dBJWCFq6du54u6=}dbD#9"Z瓸7b)Upfy$_I~.x)_uɼk'z5YՂf?&k^)` +9BT,iAWeAKqSJG4)k8Gү9{kM;UB1D-A+"zdol2/:ueMZנW$RLd7-;r=K.1!ɆyVGiM;J# rM~ҥ\?b'16kg>;O߁f:$7%ؿL]3X(cW;cn\xD 6>Qe5?bpd8AdPR#ATGP튛<:oz93["@)}×w.=~R>|}eo孒Rwfӗw/?>}yD~x:=u{<~|:sY wcKMq"޹BdlDq#_OM1=_Z杈?҃o%E~EV.L*?x??v|*??pf'%@y '\;ҕJGM1e#]嗭FzmAǯ?Qm'??Vʷfs_.OXGPE?,oaEZC<= f\A#LXNcʷ +@_@?8Z6N~Ag͖]R$1kDYY<۔su 㽀DO|CT"!TO +B\"#)gtLlClGHz'I)oFH:tH%ĉ!/0lHCNnP,(B<}f-Rʃr|C&ɳX=ΰ" =$)<)-h45kjœRr3Ag|6),A!BmAB3\0}Wx<Ѿ_"nћ͡KģuK7 CaV۴啩MLxe9jpduj eR \Ru%4rEab"!k;١䖢ӜlǖRrR>AI'xF"`02<\/2Leު'B'qFPE\4jDҚo61)yg3!S÷)F| + +C"b& NH +ÀIvJ1ؕ>p :.!iIپ*nh. +Zu!SFV2J +Fye ~g+G,m8 0d'i\[Jȳaah% S/e"[>4ʖ&MF͢)JV<1o:dBۦ{ºV-l2O~ey{G2ݴ;ψ$~184:LGc7$k hϒ0\O4X\eU8G8.H'~SHQ:&2;tiOCW%(ٴ%1MI);w.2BB勆uK +=>0p4qRġi +6r&E'(J,GJb{:qE5+dz+h#x5|Z4ZgR#'XUٽ[hb:-)2b\QRU*Mjc#27ϊ!'-/w,$8!F^fAR\}K|֒l_ H(h!+1, 9P3(1E@fB;9ANI755 8xӿ~s?֛9lfU0`6VLMIυ'09n9'J۝V;@\ıQNr(,^4jW e̅gv~ 9Գ"ܵ]IڔF:Pո86rVQ:đ/Msr`7*22]ZQZ"Jՙ/DoM}&NB3*32Ѩ2(2M#paLh{l9UԳQ+vڣߪ"!"\MDMGddԫ_'k>WE8xDmD߹#awDW#ktͭ8,]arA!wjn\yկD⅒q'RT,M0X8B$J^aqwT #$CNf^.Y1C\pF,E̬|XJv*x.bVO#n$V4F]tB:BTI9X̘B!N>J!Y\Y1DcVmHjCpFd$dfc3Skز1~Iâ>ѻY%[rX..%h) ev]BŚnA# I V93YCwy]l8Jϭ@js>UO/2;| >[d;v8?dxrtǣxl=ˆY˃^X᳄W;psЭYjK&G~k%e{;k^i(JelJ-&Xm;ۡZӃa--,!;VDKL^SHl4ȍpZ7u9[aW[AH!^[Gã"\{ K/H$mDqUҋPdi6 U _sfvph-dUtMm槓\QD?>h6d/%L/fWP,:>' 0&5Lj8|ʼn.|y+y\,PϻO"⁌El5!osg jDļtmIiՀ`HjA= mLiۊËS.,sbCdvzKPt^o2k[*[ƶqSS[9-(.ی3"{4.8:XIT!GBn5ks\!s<Ѹls81 is\[z1=qzw(?y%QuwGwrW*8+qW| 4c %B &C'ExD+`$7(E{3/%2KL +Xu Zb D>uj|Eo%8_N_Fjx YTV^x#-=[QONC@DA6r]6}5vB`}_la:[ڃ,kӥ_;%vJla؁mF JٜଁЍa?s^i@er^x +;-Z !Hao "g {pI/Fh%jT\[ԷXD +NMnN$gjlGB&⼜y$H_qGK@ޓ*{*\Q9[ZP,峿\#%SAIP]OdF W)RGۢ EZھآj+qCXyaÝƈ¢9ˏo?&>ď'ٱ<ΦF C>G^ n!bZb{#׿V# Q>A(+,C`鶢,5Ht`ΐW`Nlw_ygZ{8gsUCHm/H*N8/}c<j>ZM͋!z.]smd}@nWRї'E TK` +W4bMl{>@c;hzg^\o^Yb|mmĹlyήTQ ߸΂y*[y= 7zEܾP} JCnxW,tw7ldXG_ +~5yjyɉ+^'N;tR*ѤzCA.IJe.\:ԫ*lVhacFM$ȪP$/FE`h_Nנ=-,Q/`]U.uK@ HZ萼BVA$0ǝdbgh aG\gmDAPF1V_o6X^s+t23|.<*pp8ԝ9g4b U3cl\g5],v>\ke,=[ J|+Ye6d<ҢuBn'}}{Y}engsc㍾猾c9}o]eJ6r.{9nȚ+S_{ZwK6x,ތs~bk%+AR4U^uqcԘ6l,14_KE!d0~%O7Bb;ӥPk;DĘkA&`l SYۍ8-^Aŏjx&^ 13^beZX*\lGg=#)l~T|igs:56V=;-;;)ٹӱ+T츯a%FĻMݴֹ׬ ҫ#/\CIH_ySR)o9_ƷY Bҡr1.@rd +ʭ&;H3swe_׊og0\;nr +U-r{lshp_9m{نn+gEP}@]p?AfWzG ~2gǴ ?)mؐsڼx :/{RB)HL>4ӡwL`fG|z@ͩ+Ҧtnd}[I61DGU ۺHxKABs㧯S_>\ڵՈߣt^|5hc+[J]^I̬qYPjӯO"OORǭK|iavt)~;n-\?Ѵ#w^Fo._P@ +endstream +endobj +241 0 obj +<< +/Filter [/FlateDecode] +/Length 4207 +>> +stream +x[ݏ_RI. Mܤ-NdiN>.:]|Kt9Kj34W;~?ӵw3]}1 M.}v3uSv:k2i@,qd;Fv#a=@wr>[SD XoR5pU!}7.I `<_pR6HJK˪;bU: +`I͒ja$gwz6!BNFdGj`pVIb]VdFz,HkRv!fR7M*+Tj@Vb܃'U] vUrhuh :! mE2E<1FXi .BȻb%~'"j{2m#L F +`T_1V@9/sP]͊jQy2D7TDrxRl.ypW=H7Xli&㘠'FTSUSUSg%K4:.i#6tM( j +j )`h:S%czyA<0) 3XUS\UgΐUA:Vu ]3|USUSUUUUU%̪gUDZUB*VMVhp&xrUSUUUU% )G JVV% +דK$V9Zfu]U;mZ92 +P:цD&|r$1"3l{ڰCQzF34)~FS8ߏ_f**gex7NZrd8%)8f 1Uz Rw.=&zOV|lo#\z>:,˅53dB'T>ݍTC7H6|.MdCGőH &l"c4.R=#1إ16X)ļ[jsv6 +)L>nF3+zA{MYl7+ 06xu@j7+Vq6?m9Yn$9"uvxHu_d/XSȆ M'058\vyx uY|k5ZƜqLCb73"tUw=?mʬ7AURǾZAo֣Gamۗ`- +"UdXA).)a=k3xh D&9<.`]z +%<Bz+b>PeGh1ʫaPp*gOu-}a'+\@V%I3O&8$7pYĦ'r]S(ɝL:z5;:4eـW1Px3{3Y5w/5_ aWয়qΏ P~~&oNE?6=5A OzZbH(h3+uگ9qfv8`_,a +S-I$?~@ŻzHFgLdRPhBM `n6(%*z'"3;M%>1 f6’<|h#6ᦢiauxܟ`^_Oq8<6΃'tW:Ow~h-`ٸlh%!0Z .B)OGC +x|5UZvǝ6˰;Uwհ=XHYhHfnYM2.vX4~EʴȺ<.4b +Y<شZ?jIᒶ{ru +B8Rmh`Kn +z8*X6ڞ^5anQjx6MuejP4}9ՏPHLJ[vܮqҝ'izSԧih7_SzMԕO4@sL%ND4Ccit F#piE͉g&ނ÷sSrK μn-ƢbRB+k8F+ D8-0 jF1]XӐ_,#bn?UFFNn[C6~R[D_;y@-)kNdq^Qa/q)Tw5J0ڞ}.d^+Ej}lLo긼a)|Iv2j8Ac:_@3BII#]Vig*Ԁˠ˾neMsF[޾X0ɗ3n*L^U\ "o+4ڦb %!#5Bb4L4lTg5Ed ٛҽ;Q Zl a/4%.r8VLJ_剝)[DN*d Ґh6 cp]kXb8I8#>UXLQJ^F<>2)9 u48\20+ N!FJ6-Jʴ# +T; ܡ7^sy +ܥƹLVL޳(IaW +G<ɸuvcɮ bjM +>1+G-}}?s"\ O_B‡.Gr +Y +VE-Vx"f" dꊈս'`<^e\ +ώWʹ"^%Xk@`2_^g)K^qΊc Um*CoJnmp=>P|uL~Yo0Rջ pPI] )6a$*}Ii;`>…(dҁj!gƇ׻3ZF7{$爢tYU>> +stream +xڵ}[,9r{zSf|X/rle޼!FmX Dך?YniqmLm#XaͽbIJ؈=[նvB5Ӷ7QY-q撴¢;*z?Usęj}fdO47>#+6])ffӂ41;T|Lr?*H>^?:ӎ"j܆ѾˋZz`a;!ɢE#v;&2'0b=Mt# WË%ZAӶcPxƾ)n ח u#WMMbj3ʳuEr X{]i?EZ) +ӭM͝h;W+)Р*8 9bt4BU@#ɞnm~X0]?ijy+![vdCqϡ*}^)hӵ&q6޿9CF@~  – ?0f谵>k~HDܸEb~ R656Pw|%r/ d^ H.&m8lKwwS!ƟqmT4};QUM6ٲ51!zF|mFεvQЗ3vn~؏m{kR  +A3ScC+an᠎@+཰vlsNꇶFsױZ7,f_'뭀a:M! D3 6hHf_pB`3K29^6^Bv*;Ø"4.?#% Ȥmk0C0<}ؑ?`ҮOUrH`AmO)їJZ[ڿaC8|P-Xo^Z}ODtō`&jI@λxJV\V +1V d-!"Аjv^+&+vcZB8}Gh5Y :1.T5787fF3]\֞0~T̐#&FIH@۴,$Lպd@[msnN}k{UĽjOb fgqkgRExޓ!ea|Sd%/Tq % +eI8Pz-īX:z|j6sIm=OhʓwR-G!n oֱkUߧ8k$zډNNE +S]hkBɛ 3džɿˈFLz<(/TǼC,v_W(V^ jg/oXeCM!/h`c$6|s=)z[MŸc됓g)bv,vyn7y.83~TƎq$&P MKuyJ/qhx(*m @bS7ʫx-Dt~JET~*Fk9DOXɖߺ@4Qvǁ[$oX~ M+6 +"גb7Li/ű ߴ!q4q3 Jd%@Jmis%ӞE0:7]-dK`9+/rDڊBXUyu^hn&+ŏt)6KDg\i ȊEķivRnbow(C+)u«N^x@/I]FφCPϜtlz$h\OߤS8v*345▘(4JދݠWo˻nԽ805bv,㏠)B*Q$5 ૧ڻ+V3;}^1+]_V~{%g`L4@xQJѿ-q^ؤ '_+.ϓWL=XV` ~Jk7lDYvD3!]a𓄊sT@J:|5vl(P9Q%hP§A%_>-cݶ~BZ%b82~6 +n蕘1Ǩ(@˰FD+1sx ~Domjo8uRzqW[AG} yRVo_Bl8Z5|f (xZWuڞʅo+wZPe1#Vqs1h3[6eҔFJ}#0hi]4}%()xK c% 6o2j;CnrfRi!`WC IMt~ܿn!-LH&B5quCFHPmD@96>,Q1퐐4n5fxKflD/ nףּԋedNFN8/w2JAR'>9L=z\w,u$ JTM9?`CE%\>*q&gwie2/wT$>h#3|+sg9=˟_!|[h,ږ NԀiLIXHPNӁxx+FVﮦml(*5.MOKђl"`ɌB(lޔ#;s4`Xԋ(VĘ$: rNR;\/rUmxCKĞί$eR4e1x(oY$^ +[e䛥n$!]>jӘ/*(;Eo^Ex!W#Kfya~No2f.F)=J۷$>cθ$=Sxh_"_d]OΨ)0~ѡvN"N(n/|3UϊV{uz(2&Yz,Zv>] RgNجPf08Jyݧ;I +d1 U֔x~F~|Ʋbvܶ|%/Xiطwf'o2ů~Vddcvu'iFVc--eH +`auR';89}Dxby>vi|~+ +"Z95ۻf.+\ۧ u5%bR= ~}zgT#>vJi( Ŵ3ߍm,v>u NbL9oi + ҈,tHрLf62gdbT휍i }1d^;IS픹yޱ)P!Hɝ)H%]-L;`:5;;hej= erSuJw΋A#օS'MwE}0éܗj+׹'\d2yZc6ԡH?I|zQ ϶2w)E:R9]WMJn)|cGĻmS-Mǵק!ϴ| ?gzbզA@co{Y7W2Z;Vػ:a&!o3]~{ko]}of}&AO `ncsv-ù'N»->ň]ԝWH?PECNY{d{aR~-G@},pA6w9zQ@\}zX /'!y|.'5^7GW&j_"2qo ӛ]8-5SӓiBҪSŽ2Z2?!*q}Ujp6pKEd{y6tP+/v1~s;'nC),~)du%H_G&mvG-!g'ZG{9L[Z *>kD~о .3Prjp(;Eph=zzD`ze9cP(e:#n} k=J^MW[9ėo>MPmtp@O1qWoloFy#eη_VEsP^'ӡY!OLX?Zb~ls2uZlͭp޿o?_ V T=?+qۗBQ$49ץ`Ur%Zɲ<N*me1 6?:L" x\1{rj+A{nxm;+X#ݑ Ot㋏ʺP;@h؁~n1\:6p|U|v]47#DZ=4.}p#tDaReV F"|8wwF`+@FqQ$(%Lw1h#z( 8[N63u:-/r~|'\޸.@?qO7_|wa)/]_~x{/w=_咦9.X{{ye}^~C +.} ?opEH9t1!HAbj &$!IŖ| m% ^к e!X>ݧ +`kd, Ԧ &xg!JQ Bx#1SPn1!gw>=#̋! C3ʥ%;s3#2YyK5R"ubPPvhD +7l=X0 +PwXD]:Lz@4?pgx19O42NR@ 䌦:k\,5P&nhPMG}\4 Hy#l娄 r}h?_uO*G'M*tͥ{>874 l]ӊijT1\F.8vN }qD Ffn+.e+94Jפ H dNǻ^z?Zdr,x#ldRP"aXJ .RW{r^7pJs33yO lhQ ^n 3 +c"IBGSvL@.XAG+x)Y۔vVԐ0G_ 򌎖WYMH?t>:Ids"l:Q>:js$ߞs>`%ivlO߲tYF)3)MnO}6p}IX1qӑ%Jwv&-̓ :áѣjmM*#hIt𠼠Gk}ij4bk/;,r鰢>؍z-#4= &bL񡵷'/D22Ұ/>wK"6;Ch PB'Tʗ + HS&b-0P| 9(Z=%2o֢1v}ch}cg}]E7L֖ÃU[P+~eXrٍ ņK + t7?6=&o80x[JVpA},w>>G,sqk𐂤lD\1zXt^7?xuw':(/b\5"~ɪr7zx zCT$=uDaOz=\Ώ~`+E1tAkˉQ*xbٹѣCqθ] +!d%>:ve9YKjr"oi_ﴵ ~%EDeyyg@VC3*/ gWx ]ދH"%C#5@%C/xۀHD1L38a/,KDP@JJҀM%]J-r{551@QLAI :-te +K=U3i+rDQkH|u ˻60nč.q`rzm{[$`;X}Cov&ǢQxs%d8]$<;y=(^xջWwI^{" Y q)uE$j$3% f( +m)-|1= `azB_Jyfb@u3]v΄etI ]HP8`æIzWM?qYIwzѮiIpq'C4^Qy6Ӟ:MIAx丁kA7oֆM(tJ΁3VOY5 I w0˙ռo*|j"^[XC"Uְ`%R35Er^;'09kg2$=2Ks/nVR=%+ ˧}=>E'rm|d, <:"m b*-9P&jK|J'\wPCq9%>f8R(;̂HQFOUE)SՇk.j~@?lLcPhxEut PlU|YTv](ʡ5voIݺ ~B  z!w÷LZMݓ>S4ATR%3JzƗ@r^ʭ8"HXK:f(T͌qVP瑞!8r@ݗ,1a;Wb.C7@&<"U"3J~p#pRD9[νG<!8t|y-ꎀ'Nj:?_Ew+T5BlynSz A͖%X9,=|`!Qa ;䕏kGuCUZYa~8k7@C2zvR=.,T +bJ0(3,JK͐ + acyŝ/5PXo*Iͮ\"KP"@MHn'A'L)5/AMOJēsB+-֓UN䮮6 ,+-bAiJwt+}A_{Q<"A\ +&<\CBZP*?N%8N7x*0id } r>GLDsJ8iɸ"{vOSܮBEL3z >xs|QoFv`qgPڟzZJ֠-d&IC4Ů[T-]4 QTXwU>|%()&AuޫgS*S2aZ 'm\YT:s#R#djiph+MX$F`ݖa(L+w>jh:},f%j0@=2خC +Q<%?T2 &ZNِi`?~$=mjM!N&sF {U(BzhlDƥbQz鄠H2:,(=@2>qLl}RfKΒژM&60wnjp8禜8,lKz-8a& HK >mfcP֐zCS<iH&faʬ00BNN9s%fCWCRe DJU{:{V: ):uS(Myhvtc(X" bWPA&?16NYoqG`YAɦ4ÈZ|AWvt SRSYBaHQ^U*GW1C}D +҅үLǡ4A`H@N&} |2E>e֣u kZ*_M<e󂷎$o0 biq^AMj޼SIK+*|{v)ZO[84+ /g,I\}jj(ψ>p3IH>Pb˭3L L 10~CbB<$ ]d[4IG*%jYW ux{8N{{oQ?{L;L*/`ap):*6DM `Џ(9,H !V>6fz؁Ss1yD%E"=8Yb}5k:ˢY|,FtdjԽ' GG0tKue3PZEluUpܠBqw^=9nI eҺ!.L',cx o +`= $XEPfF,‡:C=TP I7%Qe5ytr*NHgt[Q֥jۋwz,#9?W7'noYw5ږ!T੖[y}`;Z^k*{ +-F8΋eD2b}zjϠi⺨>%U)cz5 +M#`}26n:аirmŦQn,0%[>F{ρ3 ?lm8=cLm*%`Oq7:4C|r {+}{Wr& Yې|^knLeY Bi6~ThW#(ˑ!!Dph֭rPۣ1Rf!+ U^hz +'tx<' +` f[ڶ̱ٓ 5S QU?TߨtmtrubRK2SU^qކ U'T5麄c吆vru3aZntݦbf}<3T3]\Ql'mNtRvxhFݟ؞zCG}8JnՍWHGSwJ?+0I{~Cݷe"x;z+*Ԝ̱Aj?0DdQMCxT.,ڢlflxtտnCm!Q3m]# ҟi^zx sٰbCau@4`75:W(ai m5EkIH©bS ;I {LWcW5agꘑ(Scb=9~à W-x!ӃX5c*A°᙮Fnkm,Sj0|Vla/OMq/g˟~ny{vmHrFz%YReqiYp MZ- ٜMkR4!U-R4V lQ:>>42`:wήGk>]vkȩ)ꄶԑΖ̖ʖƦrĆ28$b'KC_eE_NMfnWU0ҫ5kWqbpcT د%X-UCx~^1D-$wC~:?Ah1>ArOЩ`T SaD*,`E왫A wS5 Nlݱ6)i*v7pLxV{D5| a}10s5$]yZ!|BfwȓKUdT޲ )YL <ulvq,>'+ŁңDJR1ݤ&"n>g/@ rsEK0:^C"ty"COl"9{GgB5 +;jH?F0/eJ>Iurqn+5ywE e͗ytג)lO޹]}1^zgvzz=;Y qw( W.mt'mx} kGBӪRGy& UN6j]&>$O6c8-rNGMIǗD5%/;M? _͗_[ {yGni=L27?NʧLo007kGgu`/؏~W/)CCg}]Y_,O~-l_&]hxoбDsױܺ-D`?{3=Ю + [nŽm!z>6邇[4VVXU2+&*;V%3U`Ϧ6[&mX_Z s33s{y؃ӹHӹ4-#> +stream +xWێ6}WB#.ICi +ئF ֖mnۯ!evvQ]Ù3g.?-B+NkΪĊVu";|P)a _v ע(Nsڡt6wj!dsz wҦ%% d"@t]O.JOe}?n۵޿"rOجSMlkleۿ4kDr' 18>O[X,֠l92( +XqA $΅m֦.$E$҅-xسPа@|W eSWkTuEarXb>U+ecZ9%y0u)f +69ߪ= ++D?#賺>.߂7o%hC)aDϘL$n 6źozWWq/Z{LB]?B%m} ++i%D,_]DXsoU+!q4}83Mӈ ̎^-&5N#u*;n` \oc3pN}X@6gD٠rAbCv U #j2&Qˉ,,#8.O$TSs:1 Oye|vcc4*iT+m=-W@Ƴqn,B9qFoxphX`:N+K.T%^tW<+zę_y-Fo7Pk} GP+GwbEFUH,?BA[ ̳Si͝yǣMMhrtX|s|ŽxNG_x Ɵ tYsL4Hkyd9#fs3cLA@ +푲鴔zC 2e<l>#6?򘓫;1fYifC*- q%;WDN߈_5p?޾]_Dۓ +endstream +endobj +244 0 obj +<< +/Filter [/FlateDecode] +/Length 4235 +>> +stream +xڭ[[\ ~_1ΩGz-(dQ:bh)K#)ifn P#Q$ŻO?}}9=OzS/>;}obj{ +rڼ{}8?[;o>~9-R=| 8B{cYo>_Z@U6[M&z.)—[g}|ĝ?vC^`Lr m?Ѕ|lJW^b7+VW:2sI KcX/s\Oˎ`[ +xm랋)|nA}9Ve\ ţK22@ϦU=5"&UyMݦhP[뚴ZP}:Yx~`x:vKk:.SHne?:w11iot]9w=y쉈 e$v7dvI %17.Md DOw,j`􇷋r+$*9S@v7#*tK#4G`YYø<{́m:.ēRIޯBXiH^&fOXH>tj UG[ t Aޓ(:vB:ͳ)wLLůGO?oƓᚶH>t(!/K{xϦGu/H&Xz6U`΢g"b"k+(#hZ:]+hyr!CrËR>"3m6ރL)^a5v^W./m3TOJr﫠P+{^6eד߬N"|OɁiGCAI؅D,d}Ҍ+uGe(Y9ouϿzLGxJS"PZԴկsم8dob;!i޿`rH&|8{Suc8Lcս |Q ?!9V4l]246# בO$1RJ(qKiHk W.uLΦӋ⻎ 7C B! ;|/il@֨њ|n|z|%8aJe>!Wuf:1? "lU@|: +b(3EQIe8̙(N +ddu,Njg}ECɡ*{G/.}& {|6l:̡7|WaQ,bf/.9AɹdˣU,ȟBPImͮ(K$W냇eHesv# 0py"X~"LR=OHu4`6PEm@ihA|+YpI +,w/ Lq"e95HW|&fep3IB=B/ʂe3tta{p V%:8Z؀k7ҩXJSm8srE{f0$Smz h>PQڄH}n~H(>+ / ĥ>I$ө7ttOk/QN Y% ק '%AeU>hRְKABVl a/Kq $ +_BaeB8[ńӚ.?N͆Dprեȩ"o +r @ь E)7銵*f + NSs^(WwWS1\!y5D,LҬQ1I Q4}@aM,5}D+#FzhTWO*p\%TTV: ))]7,(ຏ/c"\6\hy9nq!^>kBNezQFWQO3ǎÚZ/ͥ/8LJAFǩ #V@ +(FaZS߀2VY k$Bzw2{[EŰR'eQDu᳓ B, t"%-ιrE:)U+]C Axv6+MNJzrWˬ͵NBm~L\>ʢ?;zxlCpb:ӳŦ3n|;y +__7(CGXYp,~TF>%ATLw!cPk0XdJdxspې,gb`tZ'~]>zxR#Y ZS2WEԸFU#K|t_Ӎq/>]{ɸjsp#GNyM^nE(vr~0/^8{ 0RYr,EQ4FH:~drE߿Yr}Qp(jĉNܨi"g.T(#X3:R!byma588agjR^vd e۵_'*i6KJp !"ݨX Sl>O+rq` Kעf>G4͜BzNDP,,=] !k ^[nqy?|5lz3*0"K@ukh)dYr>.Ua.9o0X 1av!gH?M@:_b[cxQL#KT)#7̵HE뀜1*D.LI?[ 1P VUf$a{3Ac|jơ?I!!ȾR% ;eRn~FgYU xf +[FJ!W%a& 5XDku䛇whq#5N10L\{bp1 Oo(k|ɟf:%[ĥUR mFwTC?ty=&%#5`tjI3HPQ`0uc*jf%eK흴M@$+W];qkֆ},hXNH?ye`JI +cX&z%;5worxyhiJ-QYmM2BlLJڴ (YbmLPsdYtS14'B;6mǭckϒ{XNSwi:k$iS3XmZ$MchN'"=}cYd#bD7ȍ3nSVؼtzJ.Lf@ZYMN*L2ܙ"Y)۹ $H{jAe6-1 K4:89 (αa,#WDT31)~ ZdKfIO,K ܾ-$=CZuj_xq>S*ŐuIM>Su04v$e⬤h4y -|zcC9 +*ӣB*O%_ywo߅˫>ݻ7xDoO;?[!?[Wzzb}xë揇F!> +stream +xڵ[KdG sc% !$4 įgܾ4s\]rmWoqsgHng~L_|vS8{vxϘpp;s2셧&kO7mzDXVTW*Tܣv?N<# +_q5Ҁ/XAWv&3Z?]ˀ2S3(|X)顃l\d"hRqM'R:Ʋ{&R2MeX FdNG"J@36g)+@ԏmT DBI#ֳZy`~APޡh^\3dk ډSrʩAmB]Y1e!֣yfBh/Hf9e,R<)mzE"eF+'&m,Z:S+Hr:>>uy{cՋLJdҪ!W`d^2bVԾёOvNz<퀮T&pWWqshr$G<9#aIR\ECSl@RǪ6Ts;xe#|bV |eu +.Yn} "{> v$H+YNГ +M֫Զq?M29\G6q +~:UҤ\(c4/( c*{> 3'&Th9&˯ˎN[$d︖hI`}(dlIoxB$r.4 K(t8$/ 61#hF{pFxDE uȲn#5YڭS;HǴSp1%Q%KTiAvU%v}X-vXItyd3CuUA tA$c7-1STइ" q>kwu*@K5HjS(_a?eC)1K(r2A2mJxJZWU.,B@^ŻF-WNh]L?S/4lg vJ1IS[`0G^$RD 1I7UEC""[+l='jB53&ĕ@HD 8Nǒ2KslInktߖj(Yw +V 8)l4jVNIIF >Awt3iV&Yiuc +FY4>,AjA)`P2H3+ ?u\5ե6(+^]|v (+Sإi"Ei;x'i] "sN`7d)2)8/+j%욶/YbĝLN(=߂ /"&m1~ͮǢd( m[J|Jmsbm2' >l,T: mLΚ "X)UflR ?isDf: C(k˨3Nj\.J +:S pΨgZ:vn JŦa{ *U)9C^ ȌV$X+gzYsvriq+:gZn9/ +(tzb{UƤ~Rr8!I}f6j5\/Dsy.&zFH`f#/ U9;],e|MaɃVaEҦ( Vzf6[ʏB>HUhk-T4 2gbK(m3ץ jlџK-Tc$ +2 my73ƠeR ;@s,?fx -k(ԮC0OfoцhZ,UPzU`dƄ_HP-@5ᱵ:Q!b18 A}$zf 'n|v+tj]EuWp;- 1/VfS] q7oIkD< 5;vvnEaw1k 70#VQL4ՕSl:٣1Čvmqұ2QP8-j9qi16mI8vvhA 0zŏ v/^q?C~)u{XpjO O}?ot 5<-6guŏgseL_$}zf6xc-n9u[&+\%# \}R1,Y^-KkfuX釶Yma=0:Kng$]j aU*tQ>+DIL,kGiekZi=x",ĎC^65KԨD21J[p8Wo#7vRIv\xqo^{߅Ǘ_//w-m cμmDZ#˗__D2q=}΂y;OqU R]P㓼:n~OLڱ +endstream +endobj +246 0 obj +<< +/Filter [/FlateDecode] +/Length 1068 +>> +stream +xڕVMo6WH"m" lF@Ѓ֖m-l9+H_ߙ!%Kd&Eͼ5SLݜK&%\i)JVov̜A9f*YZ~~ڲZgx=eՂޣBsh +Y9v (YHZ%LI&*i\ʕ>bZEnkg0y3~*/ 1UA7;2ﳟ֙P:&+`a% bQ`Ǽ"8V@)5'U\;^\>4d0dzH M̧fxIe^Q!>~o*@9 +endstream +endobj +247 0 obj +<< +/Filter [/FlateDecode] +/Length 26963 +>> +stream +xս[%9&"Xw)`_jh0CywZafgfȬKcAav餑4?/Ok/_j}=K;k)K/_>kT}[z^^X?[_Szn`l2vJo>5_0:I #cQ`}ǀ,${\nk@{ #Qzň[иscY֯PȺ"+TnF8KVp萔@*N;wv0PWsӦ]EZuSˆ 2Q"B}~C/Rf>er/ <"d\ԁ r*ӻk,PWL0 ؈\1l LB<3g0}@mp!@(!_Q7ՠwINE5gq>tNٲBtͥgqNyT{u~G#FWG-N: + @OXQC{YۛCB1z$YǤhCz\%,1js㣃t/ \ 0C6B:^Sx=Ș-CDmֳpI)jS;m<*FlhBI= rh <[)i*}DN C"#a]KL$]Lj-^H$0` my\B}.߫2r0> +z}d:$+zi9Ky}f|.{Uu6>F|oA]"E:U>5tv.Ϻ\(vLEHi-l8.brox ? L?8bO.z.\Vڿ-nVlD +fC QM[?ypaךY<Cgޙd_Yx_xʼn"W^.rV=+bQIٽ5%s}a_†WD\`ȳCF!Œlzyz^kZp,B`r-P[ȸOժSH>t_eזUV~etʧye_m*$jN= *EBU%Ŀ~K%|1S!>?-~.s)$Ģ60Y9Àk ǹx5cJ(=֗k u$KDB[L[."ޅqC ^˄E_[זwWpH]5f]hJ 2t-X:}dLuίa~Tpɚztrt5TǢ괕(>A.s$ +SЧnCUxYa:E0VuuIpy!NW.@Ƀ}& ن#MzX'1Y/w?t3#s7d+kS/ApM_;GydԔԨ\1Y*Z:̦/]S/W "T%L2W{kAi/yX_8Aƛ*:Ud،W% +²u:JbHׅV;6.uuA* |W=!HSx" a=tQHD k=Rpr+ZѤ @5A?FDlZ.,[N8$b 0d]N EE]Yu*V=C+(gΠ U N$NwRp- ݴU,߹> ,T4hK]L7&JDBZ'/ R3 &iN\#vݽx =aT`/9<4S or 2 zR\AgS, +&$\2,kڡ"8 O(W2l@ʋ'PtY0Х}@iTp*E†}l= 1`yq YJ2ZDG}NvR[L$wygPv9>\:SןvaK^Rlbd8 !+A?LO]@,S4.ALz{zQ M:f.4@#C}p׵XCY +!0+~m4}q8z#0cL00jc$%pÈ;F sT-1g\Og^]턻^uC\հ40vsz /C{KS*dhL~T%8eʲ>1I)S  EU2Uڧ^POg(ʨdȸU>0g(ܬ(eR[?\dqkj̒i5՘ʨ}W|ͯAdy\x $J}r( -Z(lݺus3ASLS #3\+x!j@k7i+Szȴ -BB>H5 nX%,nx#p;Z2%V5sĴC RCEOe =E8qVP nf"M5A:a[$TTtS0zVnQ7v}U >SeT)L ]/^J+^2jFL2wjTBN{Stg # *R=#$zb~)M hyS!H h}֠U,ba/'af"Jb;857Rfobkww(0|sF&<\ kۻVFU_n 󑼬{s2Ϩ C#r6ryOmMXGϴX| "<->buwqiuCӬv N2}yp]ݘ2̯m]L]H̬Pd?^vi\ V[ |Pol-C%hB5q\4 gZ @uGns5컩y#"rӼ@&*cv;F&8`T[&}t#bL⎑m~n==a E &(RDA]gVx! XJ ýr!!bBz~UG,ewILBk/j# {.ۅJ-{o]ĬTYgQKe\ T*Ĺ2R!=/ʭ=z b2=y& `ؔnK +TRƮrT!`Q Hw6ic[h6Tf8[1 ZKT1l X٠aٮᬡpF AC}/LGZݿ5Z69IDBu&$8idv^#C]eY.?Z ř~@5q|:Ra0VP>&Ux:O<(1d~ORVԓAP qw~֔3Щ7iWZv)3nʃVaqae +M춡ך'A;놟9HT-gVgO;/?p㯧0a߬GCIX8DȑkC"Cނ/tYb,?(3C;"8BGB0C /y _$@1$0 /rT@ż=.f"t{"L䤆S^?iۑU4;aA9 (y}|k-bPjZ`05('u9K +}cA 7c~Nt +6}JLӬvPF[ЉN2tʳfruJ>tf,K%QeDAY9tȻe-*] h7oBBȨ#kO4h?"WL[.\5!bzs͈a}۶~Apd%MlnT"nD5|]ľ1TpRMQRƿT[Fn{Y R g\z MXK03q(8P@O!?/D@&Ɂ=As8:p@ Tu~a_&r9!-9 i·T c/1}9 hm%ժ1 g΃2{0}M3 VY&KEd[P91sp 5A"Å88˚4ԡ]z`H9 ǫ]Q‹8f𺥾'.E +01[WKux >~jEI1A +V)UƩt+nm0ڶ(B׺r ^H4\cʹ@Uф, yw5ܕ6'%9+I21JUu9H RG1HĐ:L3ULRg:SCAB-Fp8M|_>:(-HGU+LGيtL)8N@h􉼣AQ +|*e|Hj1V\[rrXiwnvXiI+m%2hF7"x]"XCtyMrD[ ^#}o0iC|c$#1b`ط]`pv9U* oY<gK vqӚnCZ#o^9j@M)+z)!usŅ:OG/_r* +[ +szQHYp\DxT?-5f3)_լ{٦ڰ7oAÛL̸_҆ 7FG3&bxKL;툮3}-կjX;R7Ra'u}4uThxރ04Ȓaa~L¿!9!k=< ?h`>Q6bd9,!α6JwSe|j_ſ&mS" 79Wfϻ-s!v墮)1] ̓-܂r_~vHE,7*Fb &11SŌK=~MP,QyO!EDJzW^Uh{WL +@'e0ud' 辇.m=OLTܔӸ>V@Te9JCn TýضϊpwA0Y8Q+ې3b4qNpBMpA$ALeEP]^AXƎ-=qKg Yd{X?͕TBbm 8c a}Kfʥdivևַ\OMAH'ch~D[=)apBufZ%wX4Dztk-hP┆*hw`ͨo$h19ד)z+͹5 +ÅNDO T(;@b7NnpM } BdZؠV툞1M4nw.]< +40k,`.UsS} N+Ce!PupV_7? b"䱪Vl2؂;[|-ݪ3=A癰sdIg+*8G30sΪQ40m6vZ/;"bPfwV_,"ɤ Hm"~~G\gfBǜ;VY0;0yH2sK!K|F /a(UlsUs0IRpACVAHhM&!,d9Z1uRd׏\Y#9͈crtMeBֱ% .f>i%-Q3z…K\la:p'3zQ&-FlvP᭴ydk9Fg>sybz )iqÃ̔ 2-z B!JarϦ&(hT;,u.*5xac:S~gj,ȁ9Ua6OHS1HL=&ZwP*deH 0b筢wd +iIw pgQr ڧ+n0}IW6𗍣" ss-;6;Uz 2 "fijS0h_.H]Z}%|[ 5k7C0?QM"m A#21ߓ?0Ųs^QI[sw׻tYٙnv\)K!)^`K +10T,pI P-#e'ه#_H=h4:Y9%KW<>"-9m {xEwŋ\Fi3͈/{/p݀E6¥4Cq%rCg]7߽|J\3^C<*µ3߼ur߼X?Y%-4Tk? %+"+Q6M3HBt]j.(FY`x|lo`:? !`yfE0 ܡQ/s60>iZ&Ne3mKI@oK Xy$ ,e'ψ@!ż:Nc~Xx qGvp Q aH{GiS^wMD$ +Zi$&R5m*[ާe!>o + ubNg4;lJ& xL`a`\9s{.> kL)%1y[΂ejD 2J ܔVwi2C"z,<#B$n!GJ@hC9uËHHd ]|c8ZEPiP1|PsD'#2!IO/kD~E2;9 +dUmxL+-Z^ ʇE3Mf +EuP(z9Щ9F=`;xs:N$ѐ~r`G_;O/Ǭ*SxhQLH"bgN-u0&z`Et yUCJkQ0pP6F Jf3'MyzfA{aq`Z9k{1-kG!K@nƁD"6;Z2cWØrjXJ07 { ^'<}ǣ`Y[/ v6SOfo\ RyN;HSa6(1FB'4Ċ 罍a{kt)Z!gɇyɘ:}}dp!mk%PZ_ԭ!,%U,,H,'2<\a|ן!/,s̯xq?3ö ]-֟T1 +=H% Pƈ +\=Q2W +/}䖬a9%'C|GDzoSrNSY4dMjFxiomN+Evݒ;%Nf6g~% Mcظ5Ϳx 0'`#"&1a. #L0f'Q}97;SMGfGf + !0.`MPs{8K8!Edx\0Eڄ+Q, +P¡o:O )LAwJ2 03 4+k=ݧ}SD4׭D+;dxHOxh&b6;,Q Hk™"=TLOsU1x`L7ǡ!0@T9SBJ۾WG"ފX/406"H8_߁ P$# z|='< x>([>%9LΉ_3Ec|'#g>K) ˢX[ mԓMHēO$F _JʜSF䯥}ްe/3zˌ]4t \/>>QA ~?h:LO l}g-w|E$ ٧ww0"= aU]3<6o}=, N'7/o?EAM(va\U!Q2PYFbGi>kk族 UlW}&%F>ANpADdbTaxG[U<3O,ɷ\I Kfxy0BX{"qDaݠ{0| b- -O5+&Vϊb‘V;(ٵ{̘]nZMJ*9x#Ef2G_?{::rvɵ r!)& G ^z#1oR+î$Y!a4N1}ù&zsFSm +aSo*mjjm52~/⌉?59s[P8b P&>_$\6ISS |4FBΏː4Y ЃOcXcIKRrL!9yJ\FJfz)\=SXk[y /?&n120F [gR-0J#3%,\ő-FW-sL:) ?ݮth8zt~(̊揁zʾ/cJ:LVN=T1~B0F2/-pxRBnCZQ|B -Ƭ[>J0y]WGlj0T{g;'HưA1J Ief)hXPB|+:*>-sņB@IT'iP28!P/1Pӟ(c/`'yzd)PWIk/!ұZe"(gڌAN/!s/!1 xKH#`Ѱ =O\MH/U]ڂ3hm+2,2H慸!#4Rh!qVBԓfC^Z N~o[(?ި& (JNjQr>ЄqM=|3643W>d,o1&Gb<&_;2@&R=,aoS;,v2ל̤Jz|5͒4[u+ j^6:jXE*Rqi"{aRR h )Nh |#资780C{t>Vބ:2AnփN&:wN-\ߟH`2?p.>Q_V XK'ԤxU_i*r 2D)fH`/$8o =nE.yQ.|$J ʇ AY˕2iX+^[7I/o2߼y~K~Hk8_]r=xb-qz'K;NT8Ր@+:vUI'W:qC }~5s,C&9 u y:nDC{HpԐOc 7p~5,nED0D|JE-kl w-3+Hc4KlO&r~@=MG=LWTm/H??D#4T-jxzn;xfKwٻ]z/u?y{KG?o}Yኒ޶g0xL.bO˪56kv{e_}+_>/tnȶK:~^^t/\o(hquZ?ͫ i.Q||W_>tA;{yߥ?_~z).|!^ ٗ4~iȂM\:4guRˌLcWAsk N!j3@bHœYN+phGz_*d{fJd` *0BU}L\hOj΁ vZI`{naPP%tQ(Hv$3Wө驌-ĹsrQIm$?(S)͗ʭղK+dmdnoL^J#/Gd%WwXxP.G̰Ðo $eTsY%S|![Ca\0 +8P*& %2.۾Xm%yZ>2OOrIPF\s|*0Ap +mV9# >\Ĵ5?>v:;qwF\ f؞ιw3!8wb˷]a\d =w]1n0-cb9hrhc29@8VFQ1#eB}K:jة{g~6Y7ĭ05 xT6vj=P/ WO`0+c3sQƛMav {|>[8-.t{y0bHaSi l{{;1~7l>Τ+7AXUȸ5Y ̰ی$bEbl<HxAEgeUFW|3C*[QDeb8쯫'E-'5'+xz<24`?)xrIRï?.g _)u2s=p>^%\{Rϵ_U.4i0 `0#SnO<1サ.:|{ _YMP4@恦_5)ZO5#ޔqI/nir5g$Q>bx0IBN l p5m(@ >`UX3-Ļ'ΐn>` '-wu+j\Y!Ikx.&̇7m De !RcQk⻨IӂчpPG~Zs{I7 !rnIy.i&a֙be;Cdžsagת "':NeS Xw  ڞ0tMa 1CGvav0BC|`?lpjxGۨU#-..Rsjwg넮,]2~Zm-me_5s;JQ2|RջĿ|nh"n]x|alV"ruj[+hq5ZףFLYWeD +6,N!^h:h5TkՋ>U +}֧ +kG(b]BpΧ~Xk] mJQa'tDu^0 2PK;u}PN٬Ā9TԀ7F 0R)'Zr~Hw(xo#_E]diW [vv 腆K +bQyOOU2<>zR _-2(16Hb| .9BMP옾.톑meo(me N*4\Oр9ms-vU4u-Τmvh i( pó7HHE^О6 LW-ζObfB1*%#A/F8ya]f.I iHuD u[;w/4Dn*}MGF.{ +J|K|+hHaԋGY=^lS_yo̤rxѲPiYϧ7l$ֶFfή9mC*~4)p>٘QDc EGuDL%\ $aU׹Q*H$=CI=FĔ[N׭320w|i(wʄF3LX-L;c[кk(뎿gLOu2n`M.;j/h/6HK0zcn0 + 38ܤ-"QmMXzggs .$)vg+vVz?l#Qqgߜpyl9s콊ocN}U=&};c;.9֗&3m&m–g$VnGJv-C$eMM>igp 搑ǵ +=α"B%_wǧwĎ;nhP?#𗿾5jzM#KL~?\=^<.o4?lMw04_~w?_Rﮖ~//_~5M_M +g9\ͿY,rnbϮNRޕ#YPٸbl CK(z+U9\%T,'HezѼ~8ł|-t7_ +CӴ3\}xYetj뀄c<Ƌ9tʍIOVa_0u2l]3m߮ ˙lTS@hĆAm-]KڳZBzM{z>?$k;2^Ͽg?gNס?~~^[1]8>ˋ_&Mup6>8թr܆bs߽|_o[V=5ۀ=44~R[Y:&B=z蛦qRYx1B5;c3* c<@Pg`08<Vbrdc뱨upԜθ~ 04w. jcvU1Dr-މ)2_,0:iY*I%z)d% _A"0f(yՏF eC.hczy$Wf7S<=y0f@|'Z#q%G]Ve,*1r͓|`Yh [䕾%$̾Df*ἅT KEdcu +I_l*)/&Paݶj:ngVz{)M6H($(DaM̌6xsa,̼e_t0WsP)Zr_MY.{`i=K,xLԇY"f@#J u 2D#a!5Ogv|^>e~nV{X$1gaN +k!Vr*dU{Tg- >5ٓĆO*[(>ANeIpQGYO6R]ؿ5ud:vϮ! +`ty_,삲BH!VLqWAޡߥB蔶NVGj 5:lH(0 [ ÄjK~}al68}TS$SG:fĵQ\ NEi"4 +9]X_I7qNZ +CiD1X.{7|uu̷,hCg{vyƂ${[z,ŊTjUtoa2,6j#0ƇIE{ASw3J3;xg K X @c(ꗣ_ 85Vļ^HkP03 jNhԡc0@ )5<WğTX8Z~m B(T Qb"e`Y0/rpXB븂fE Y rr Λm_o(33J#ۗ1U 99R>?iLRJ7"YiG~f 0 ןx{$n`-R;pq0meg M+:X-읺.trdy-ExeK6=ͦk")ȶ0m_Pc擧 O4GQFY-u : fc}a#es G.EEKRaGeK2괞aźd0Πbi!>bcgQvb| Z*8=~lsBa{uqSR\n(۾@rS(x`Es e} 49DGokͥW v\]>{:2Ҩ1l`д{:b{;k-6=ְkϸ Y4Ʊlc_Pi;g֭ T2?ǥp'L|#l *ߖ =ְcϸדLoF.3 "%U (̻AP0b_G%40uCO Uu1tL`*4E#¥(諾c8 'a ^׆2EV Wڠխ쪽FtexC1Aǡu긽XVPԅvбo|DB75o^]Di N6nk%=ܓ޴:ren/NߡKPG͛g[XE":l] +9L60 aqJ3/:Vi۷^؄y_+Hx1 +p GyW0BN @W@ɑVH#0LW{%pU$EBO U$J& p eNj-{'Mu#5oGcwZmMց Teꄷ-^/FT1#M +KĺpO5}m{"j޸f"={tp}yiCPD֋? N߿@v'?8Fg.Lү((uNe zj0O4q/зjVe1enAc\aYOWB\[i&Z2EEe +zJマRo\Sk)J h))9R55IŭaRTjهJQt1"6{GA&LIz 9ٺm_a,W'O1J`+L,7.[rIŒb\9[iP!_^.ūOQ-{dhd#"%: <%S}"3*ER[*վ$|%԰%&2 ˁuKf7\SXJ+-lUXJotۉB-EXњG1c5-Ф2O37n ~;n(;b ]VH P癀P0^!בUyUChmPl03?i; ٓkx= \cI,r8DxBA'*ӆ !A)@!+pmXZ ^mW4hϷ8=~+i'3n6a(!R|AZ 悏avJBok RcV!tafp!ŦT| qmkkof9#+{~ccKF]~˨D}m᭡EW^7Bk cF~"o&8؂,+AhCDc:c$bh|-> ;)&)Gȴg ӆ=4AxB{٬ "xGصVO3k;DZߤ+}#nJ﫴#{F [;nٶHLRm)A=xn=o+pLm{X{?1^V,]wIԥe+ +۟痿E?Vm-RC=W>aE uu*+ /qs%bF\Ƨbta+ +e3z >fS,TZ{JbCaK79/)2D0Uc|C%<3V.bS4gry{_C{_gGΈ[`oزsYAY#6{e{j(Mb_a]dP6&?\D?2;z(m‘zLV&!-i"a[=wzb/8U٨Tu1{N}:)b_]R9TN< տWM6i[ ^[ ii`fe!4zm[ +{yg9M;ʞƊ׈>Bm4X:m@j48b>SZx c[C8W<[c=3LCy{6;>< a#x|OsA,*wۀV>NcZ!_!&eDC/"Tf$GZО $]?xhZ1EG MQg<wA}C'tǍSf*\欷Wnb Gy_"h:/2ݺdv_ +oc(`} @!`IZQŅH Ya8ӌe'H! N|ALz_dKFieaF~hĞ9bY +ܼՉVebw|G08o)"eNmC_r3 !ӄNcsmo1BZuzۺKR4cV!c'o!iF?za5|C:?zT':'gCjKE,1n!aޡ8gѾy0""Իx=xMu!KxއmE Ny2jSa0B55̊L;:qBFБ%: +&[4J$"ƈ1˔늯`ɯFT|Capgce¤̆VyBJ5Xi`Z</ e BzfvSSmx+ipʞVTgba MWy=5v|ʩH ˆ&d 5dywEK>9>2&-қGb ooHǭN8T1jrDeҞy@'d AiU|B".#"ozxD4~!DL+_2L֤Yp /ufBH>KoXQNEu!Rrx +s.e `TOxJ OG_e+=< +y\gv[nףL۠ㄴ͗WJj}3.zJJ(n˝#&@<b+ˑh;k|D Nj-:>?Sc8^m_)TieFތX Fi ʺgdx[ +,V*?!9 qVp`qvPLΈחܱֈ򎾓^GlQ;]"bG%OmX:lۇ JIxv(2 q9v''煴=cǽhЇǿ)"w+Z t4MVVG̹嵷J}wPao}C=BptzFCB閌g|GӌB?K_bv>눴bg6 , HfGQ8ym(tvC0+[jESH=KhzFS|V}_"4,F~mيds!I&$LLFsrljDJWeIZd9 +endstream +endobj +248 0 obj +<< +/Filter [/FlateDecode] +/Length 26554 +>> +stream +xݽϯ-6?^X$C%xr'l)8}b}ν<.p.n6Y,}߶?/?/nz_ue/gyϧ{?{;G>k~fn{iocg'Kߏ oo_sUtdž^}?ޫޏ ׾͟ sK~~3lxzVeJO(|N A `{%CGzxZБK/uY@OӀ2~[w_͉sN?GL|/o1p[w۸|D~ͦ 1>8y3`6L613gyt.v'귰/#}~|9ͨ~{?|KC[}yw}uϲ?p3~.0I $'|jO<kـBzlς\ +# 7mkFqa~rrt4cUӲ;ݞL>㲑;wN u3_x,mzNe`xosqOS{Ɂ({0fl-}.uO,}ymK<塮OŬp+[響UO~t6 y}S}cW_/FwO;=7Sa4e fs &S~Jc႟$˵a <݅xҩmm¯_|;wN01I7珧1珗?kӓ7hpƕ\Hec4nģ%ǘs|lk +Ho/gh `coc<o@<_;W?Gۅۻ < >&?&|^WSO?rp5a)qN?rI |UL{>p5p>'6,ӧ!/ž# }#J@6ko^ra@ vƾ-_6<-n:)`(0݉a/.=Bİ@zl՞o<=(&n?hNk5(>$:t槷O|.~}<Iq^F/%'gmmf~?-cBgHF &7mK}L4@뼫\63|8˚2csrd+5v?L|.K}*{@? +h" K_υ,d.]JϾlK~Lp"O<y65X:l ^n'."~|lH:F8~-ߐvZ\w)?B+Cq,4,Aq$4ֻ〄;Td'ʏ ?dvĦ7s=|+$_l=mXl9 ~5dWd9N +h,=.ғt| W#v:oAXGc#u$RI&aS4}"ƹQ9;ױ^el\n#-\7д$AUlP 3ߵx0N~wDSh 3 w6nǭ`q5z%? Wig!թ#-&@iL(/$f{gRs\Dho`[`e`&$$j׏'hKHI\x@#Qeß [M +H߯\@f\WH+ZkYK4&1T'8 {'bqlVj !сh  r݇=ptwT`gBV: oL +ۏQS*?jt+s3}Lx|~LynS/(*ݔyPBVM*))q{n;uRlѿL\pY AR;iESXmaRV:5;%, ۺ9`뮟d]2RuxK|^J## Jnq(Bzk:zqML0C iTo@0?p-I.X6jH&VM^d͂&8"燐+8;_6e k( }M6ӓmHax+Muvs_u\ٻiß|3Y+GSPL Vc헍Onf'hLƉg_-/P_fLoFph#\s +[߭# /w0.OXl6t6wA?N*`jbغY[~g8LCV =u ?3=rUϔ;$ 3dA&u7yk6֠k ? SrpoxuLty*{lbէN]E<'?`Nn4 +4}b.FB 79Y#p:\|\'7l2a7%N*mZ"a;6eNl3V`"1xwͫ_BeWhzI? YV'2S?pż6eKXR:T%iUkw/H]] 3bM>B8I%~Lvl$B ߿U:20n59Q0rCaKs?}NfO >z_l}歾$ul*yyMPk'458f”iMHp5|qYUeD3N仳҈+'V w:g!.(wiF57=o5ɯAu.gGj!pr mwWlw4N~nK,h{O3?$5I@h#埄v:WVQӸ/ϥa1dXL9C}(r@֣c#]'{h> Ý,tWyHuw̟?pQ"3tt_l5{p +I\JkGݤlu]y $`ASm^%A~:xQ-st PЙautH|>Eo::n~XG7ŝ9YN Lo4`C!uTŒ3كt$:(~$ǐxyF +4B, `KۉXX%nj<`)S΃:ǥ3~j8¦AHiHﺐ1bnw宸GW]*[p}=!BM.S^ǜ,3 Y*IJ^jnE9*܅Ql=%3<4\&z6y87nxh;d?]鎈NDq<]Ýl#FԀ $6-دiVK .PǍhS S8brteC#{gOb\ : h.5HҪT熏K ~ ULGь| +<4"o=ڗT)NQt'$7|St~fLD%#}/zWNg؄;edNH[{ෂ^< 2҇FsCc16kt̪wtOuS[.3'mj?QL%B~y@kegu浠H)tF}+Ni6 tMMp+/!G0d~7;T):mn)v,~f)ѿ<'qa3S.`3u/ϑ5 -on.#/Ұg,V~h-;RoPO ׎-؇ѧZGvʿv8(Zvo]ד o&N~y{PrM:m8 Dd/϶syބգ Ƣ3vەޟ[['W;W\],lDyC*;|{ f4 ( 6Jatpjc ;qUvd{{oz%LLJTٖVUIf)J);*۳LUh&(c#i']H4g{`=& ļ-VtR@ \ Nn |NGH 7Jbp7q:jbk僂\. +_Q1{\?CO"Ѳr+wS ;td^.RYoG8}3jԢ> זE7D:dĥC$q1&nu]$ +Fq|7O 2ٮBAOc/ELՐIH+]I3̨ +RA +~#mu`XD"W b(5ΛxE# SpWpnڗslyXR^emAUu4yݒryi ID:+p:*Pπ4HLX7İ<_23!2Ϊ& N6E9@TpxTd:q}]دI] .5*".E; 6SmQ:s0xk#t^AvO>G3eg71S 9.eWJcwf!feh6U#7)Nв~c`:""n~g>uSU؛coRXqXѰ1`bY.aVvm +Gac.kl 76Bn.$*7ygs^zۄ'tґNtAط<*\F^7\HӒ&0IniA&r$ ߁YNJ9udXԥIzci21d l.] )~sƀ< +ANFP1pR:26ޖCz\Af\чwK.a 8JwB*2 h$()]Ŧ7x%WrOvnHsUd9얁 +踿Bp+\LvKk@@f (5@_+s-ype,֖xc6%k؁ #3/&+@ƺUz!l*el+lC6Ժ)ިx2IG>"b!"`;/eUYLH3QpJE"N +CZ5](׵=WB^`\$Cu_#?Aq!TYG\*DCx"4Dۍ(#ؗ>2/`PF+|aD "06Vۯ yH03^q#2  ^,r_؉\+4Zp-#`[x.GUGc6>W/Hǭ*+ĩ3d?U/I>̳P 3f¬jwL:qIJۼ2R`.y=VwAwG{N\J$,JNxY!8>*'US-,WeMlI`",ȝ$8q$0 +c{Hdz'QHf'{ 0UYG(@hvx']l)_'PF5zn3] +}VS\(_epCe +fdzT .f]TMzl0Tf捩AbRrԬuM s|cxSu*W]#5ڏφ:v[[BZlEJ%RSv ZgP B;t7 J'Sy!~BА=X@bweQz jÞABV>$~C>gox:)sᑥTs\tvCp7 t=*+ uON8?AO7&ϻ`fy+0VUQrD\ zœU1 Kvm)1XIU -:GPFX}uVsӣMXtzmrlč`9~KAnXgwe*w@h=|LrʮDq]#Hng*@"qƆ+&BIɯ$2P^~TO8^~8~b{)OrfOJuO:Owd|}WoEpq]c`4D7zWM'XrS o>VI3++=]=:ֆ{waFCoē ܏ N)6G P=ZoM*+w lhS 6q3|ibȟ0IGro/X~% +;\B ӮBuD ^q] f`f{ZoyO4sC*aij&7H{˭͞26<G\,H~lCdsI߯#<[? &߂ÏUFQmfj @ۏ{MaUMGc?xG_9Q>* *B:wrGsOt|@g{:S`^duEfI΋N{Fn_\dZ#aػ5r!m*ZJOjO~k E㮉 GYIٗQuC5 b԰jѰSpRA!F {zk.{fHyCtnZJײEPVw;:kDm[R_:#:sπYZ }e ZYp\flOͿmuNS*[K5Gom_)˟逜/O{7fᛉ9t\娹fopd7kf5cTM-Ɋ}?kƆxyKd@0aGnwK:`]!0VWU9@.spuH4(_pmNUI a {Ԭt,}lnpy:?vڢ8RUWntXT?$";Q+͑u쁞&-fY<X"XNr (C]uO蘡 g8ZBw?hԵKѻ@4f0w8D ӯn=4cQ~CQ-{GDm3[m29{mskL"$ -龨?1I=EGaVXTzH4* ^'[}pw{T\n2V4=| vՍ6U[Plܗ>b6rZoU\oF[ xy볳GcIP$Tz;\9Gbv$2J`%e6D*p2c2LHmfaE?npJ'`Zض!--rrr\0H_ p`>R /ߌEޅ[ۼ} 3x0QYݹI*ZF'9, K̦ڻE^T%fѷĪ*~>Q[a*1h;|LỈ:W%;)(NSE'AE1xp@lb( (g󺭕n.r^Y$uV+v.]UN>3yWe,U K㶜Rd!Ғ =P}gzJ6TX|ަ"weRXymAO@ֆ$,wěM(tFkZd\empE ћwu0~#(Flkz*)am5O˾omH,S693M%pfFnS o٢h+2mguz&"z̴~Pntj6FscwVH?. MUxf:_gg&7x^t >:6Fwu/h1͇DJQB +k/_J]v _+N* !J6yd3>>`nСbgvocHO@-D5om|g~αn/<?PX>[@|pLO +8kםX7=Ein:l. 6V 0b{W+;F0;VCBnmXkA' +`,Xk/9p}D~$W/*=%*}K"C`~#w0.3 H58X-Sb%g< Vyjcms*/ c03t:n%V-~ߖMRi$-ӯS.Ԣe|N/ں +8!4ndN4)m=,j=EmW -neE^(NW]RS=kJnnSJJUmu Wu dΐx*ͷHR82+eW%oi CKo{>wJVc +:J(/cjO@O݀FvZbMV`EdECV$u@ffAGTJФ;EXa +v""U#OcU}t Aй? σ}u|ӏ!gS +fw_8V>L7/D$w>B?h\@ O/^2c^uLQ\_RؤEThڬ,w|Q6ӯRE67@-GnKg2okYKX{~NAlF$F2%#ʞjPݼPɣ)t-?ߋyxBV & 6@BA+'>!޹OE +s CkQHWQZVlu"B ±PFtAf .ߏ=%ae޷;FB'+3#/0@a[|[KOA %d3sX+]mR  <ݱЎm$XH/P%8^`oZ=Yh,L%\mcK)x eX-}kY-?\c!.P{Y^ -`~v#^,` XZD*Fo)y[=5MO}e&Xmv+dj+U"Thq- (un^APrqcaX@:=+/PTe/ VVȰ_\5/tr] +sU +U޶_@.8_@\f+Db0@VUI HJ1p&X= I=d|?+:NDW߳b_*#+ NX v=2UwRHJbv~񲲗}z[ˏ_[O2}oƿeH3~zLb^([ xsxVưҀ21ȺNS ~ikaaڰӆw9 ??7Zܖ{2 ߖ:Aa Rqe9 io>jyjx[k?<u[Tu|l9QwK{6Qԧ>7%dc5Ni15hw7U~t ,4qp 6џo8lǥ!?=Y2¿fـٺ!T;^p`P Ճ}!ђo(+ܦˈ*5M4޽hOv}iZԀ'|2^">pе vh6֌Sq]j5|L #\Nyw20>GȰaf+!tLBCiCiYsRg捭1cWB-.h՞X hF_~bvEGCFlnegn?K)껄+il7+v`HΟ-T$X\I9W=Jo{yVGå'[-'ӏ)ÄOoxl2ZzT?YCȳFI'2cA5qY>{~0o6p|$c13{u}ce+Ӕ= Q2} W>2Yz!t8"05i|^I _O@Ϡ6|9r1y0HZ]<{Nj:sr<>u3CWf!= זi8/5I@dGP+d@cMyUMrw5_:Ձfk% @' +YcꧧCP<#b| 9q!/36ت1a;,\%Җ*F>sxΦ4$0E߉D贪,>,X]<1̆bg%Ns"PdՂKFW4vB ^_3OR{̲4pdx%ƎNcv FU(bNx1 [| o1>b"ÏXSE)c]X^bjbN-ZC/]̂U[ø#sؙ\Huj;Al+c/VaY:4p`c2e)5݄H)g$21X!=J[ǯhRZ:!r0|/01ߋ{g8 + ֲ +n1TH1T~UȐ F&TGS*h)sӽ6VQaX~ŒcgJسጬjjaq3# Xƕ\cTٯH`RJ SDžR ) h+bUS{62}E4v!濉ek~?HJpŪUiKK8S6/%FOufk)5_%rѢ^^tQ7n23W$ ?`{&w_Z$Tkʵ#e 3"On&DSq O/>ݞh7|zk'͏wܚ:(1JـSۺ>q?] dB&̮\yImEi0Ha/_uLX''ܞ, ;~cF7+I}g1U(MDlqd'KhFSL'CWЭ,FMfnnk2N4">[+h ,4 bo2V41!ЙбNUfK{V×\d 鑥|wu\|M9sSuRZ-'-1O +L 5[ N$=g Q:&<6 F n=Pt>hDdl(p P\R(P je5P&SjQ{ ԓ"YjRutˠ=gP%:F ɝ-.W\_Z̕w5KWm~m:ljeFN^|";$~ \gk^@'<ǹc#s旔]_[dP=19^)z術SB-r '$^f!u$˻j||*rQf0>zUyZv/KtN( Bd #7RQv@ +:{LWWD3Hy6uO9宓M剌2ez\vLnC(rKTh|FLJ}6M.א$4 ;jg5;v,4d1k7N$ѐbn_*uY-%,_q6i)pωM%[A|uE@2\)}l-]Z57c4hk{?}ZM%}`i ,SK +CJii@5د\j_LK+`!5vO_׋r)Fb:ʹ-P &i=/ys*j 'RI]K^4q=I8*jotsŋ:*r&-D^^hYfEusfOPS2猭=d5Z[J +3 ";exKx6BV ˳h'#Lgz{f7V$Ռ䘹9c0vQ@xOBJcbI+K`mxJNw_uW4(ylEs(&kҵzлzx.]Uf` ,$ q39nSqWC<y6 +LYu- +rj?RgOmmg]2p忚DP7p,R[;^Z.zA֨,k+5n 9]DOv1hSh\.8N>69Olqxy[m64hBXzl{IްՒxm&N :Mj(ԃH5$ۃI=8^`@MVJ^1hB8lSuY,^%B5zK15'qe +Ӌ*]JṚci1ͳfOG |ޚ0/-h*tYg<&K9ټ1gBqOY,_O1C=ZL(IA^M@&D.3-z6YXϡ"rP*l3K1 vzkQ˿՗Ǔ_}{U/̻tھs~?nt?~~?ⱷ㳥?~g}{ԬNo/{qagO?ܷ'~Cf?}v͟V~?ß~Ol~ݳ=1ѿͳ?f ?;ՙ91;K>{~FsuWәa~}"~_?~wρs3?}"~|sa/fKڞ@`{~,хvݦ"_2`xw"h~Cw,xol|q '\3A^!-OdH#;sG?=c j76;e¦:._fTH_58"$q/x@0쏓3/[GyxJ+\ClEq{x|ozc_+i=kc?l'$džt6gfJT(S Qt'P1ZUWRq#FjwRs:ԴȨʾP^cHߣkMP%7KJ c?s9u#2{ Opw+ΖHjH2J.*:cy-^F}$ t>P HTD|Ed>~G"it9u־ o`&L ƞ$ ǤDDT#ok=zMˢ\UriHU1^Xɝ[ng^{,/@IGK.۝鯟z\I[\HkBjy( >u6>.Z4t]$䢖o_fŲ/y]w'-[ftCvq; BZQ t|M-×4 {nUM5+Ƥ^4uJ,s+"|E.VSzy8V`WE •C돟xU( Uɹuj /S +w~G~[}wo;pMg<֞mT^nsSqW[m&D z.'#jj{NX:eL RJa,{,>sHFOj-(F,"ik&g(g:zXd*eQYyX*+f=UT*tyꭢB?WBFYo^EuĨrG&TBB_Y ]/VmU_U:JzϺN;Y$^Wu@gm`y񽦿A{Cu>d?!|SR:i^Q;;-{ZӣX&yiM{(cc'laSuWf]Y>FV{,Nۙփeo]6; b4 ̣AQЙ Lj.,=\+3xo KnO\4,MEg'"@ldYA1&Bh1s1J Ж= YץEW.IS[R ӻ|Aͳ߭~SNb+xrN FχdNxFw,?wjs:"3 ]ay.OAzV؜]ktw)%R^4*ZM >Ozr,=^H|8MN{#&_ {| +]$b$lC52@~j<o:!9m)#ؙH B}%W= ⱿU E]:kķ}n3z56~}"^E&B("Z2[E {8oձJgi:q כ=r5 x+JZ;:;ҬwZ)Ǟ?r&ǙVs qxmhGLm r9.(N_U]%pW8J!c _*E\n4Mp 8߁ +{}x9Q,mNp8QMtQ[BOP`򶸲ɼ"RxuSћ$XOAU˟byFauI]k3T,gRMO>3Xf1 +g3]&l>]n۪A*:E~S sidzrV@F֛ *EQ`~16g+Kö<`t&j 4(o()lXtʈMfVvgxtQmuct_P:ī2#SIB>=RTH0bM j_oSUT3DMG^d5Hjr.";aV>\P;YI/u7ŀ}JxGIoikmj7RD:볩G݆ߺXrK 1|0rvI1#PqPb ]ZL,3ZRmP_-"YD/{,q^CT/g~t|VYHTqku$huZIuomcTBG\ PѰ|#Y y"92WdxܨyF .A, A_#i8g!udk:YNOXhyM(;ۙ稠~2PNky| ~_9Gƙc 38{rZh2o+W +4CezDY JiƹTu<~TKL gAV/QTs]&)t_|ׄ|7cK-KH"J0[bp|In WxP1_ ++{EõWtV54V6h9&RWL`~u^tJǹ dGY 88"s̓R/3c2'U=W<ﮗcz{QbZ TB-z{/[\Y8fpO8Zd/[̀yu|zAb +( ̟I!ID,C{1Umc(kO3", ] d אFcl5ou'N|Vkn!N]k~둾Gɕ}%g Kĉm*}&5ֆqJrD՛Wj g,/xy [6UT)7BS)5Guse<|)JZukXf kLARN4>(7/0T/D[~TR]jJ+Nf\xAR[s2 Z:CoTO"Giy.^34ni|[\-àܩ[l`OL}XOb Op4}AG؍֑zqgRo ejWG9$&\%׶vʼn穵Ngu鏡E/Jj>WRb#DWY(\Rl)fcpD ;Zk1h>%ޓ f:ZbIPswQ˅e5@vY ⟿<{νB}݃jUx(Ͱ٥I$n?)@g*JוJˁGWʞ3+sZZtzm;~ߺz!'$RF`yᱦnu<aȁ[t(0BxP Ń6)shy4< U|0VW } H|_\\, {|;pq[ %S -ܻ4.JM^IY扸wvNyxvY7=dYf9gj߃-xD}w?K[ڸ5l7,Ϧ|VwfM&i7nkWN>$ctP6 Nx4 CSx5(,)u)t\1c!>U`3viwbGЖ5x=UwScgMgy[|nxD +|\nPX{2>2Z R(A$!ON˘[EZbbn[`hq9ӂ6m%Y1s'nEo?> +stream +xڭ\ے$q}ﯨ[ +@z0M[6C [zgzvFїQ+띙']"vĥ=POa}a5t];?l\SGC(%X8W6E䴪/2 T6)Nf4 :qﲴ>&6*n n74<~9XSl@f8aLcF@p%uOԞ,auOߗws]kc]"=*Њ l$!G[ՅHoPLԍ/#k' nI*ƍ0hwCnЅ'fnZ.">L*in"&Oda.-̣-gt|T,fE9ll2&2X!t:gpϜa`s<]99..9mMӺ\x!tWIfx};lk:bfWz(l_&Ÿ.bymsГWλ2e!q5fhN)O?،)Y<$IwZY5`iRZnÿ iE#l̋ൂjXdI" E 㤬O"yg΀e-ԩ񮜔IFJ4AGH!,}EP}0R!+Z@$p4mʡ&4! 9%eRu$-ؔF2R05qMREE+&%8M6%V +LqRʜ:R@PS KB-&+#bbv㠢Aؑ3W\!qQW~%Q7lj+x5 ̘UE5 -:p()* RW5TF07Z3Đ*LjiF!OWd5b%&.EDANYxC ($㝁g*l(8!)VI-B4:H1 ;ۂV2 oeL*F%8 ၬ8 +FlrˆxƥQAK{nj(<\ K*ЁBTpYT IQM~,sg,cMHMhma)hKSmdL\FQpn|ق(7V2bnI@}Ɖن2D}F6%AsF`[,>U'8)HpH98x`^:dVuWsQ$T` EyRMZs+QpK,=:8Gb,c@ rgV2ԨJMH-̧qA+-UMҔvcusx;078kJQU8 h 7)XloFD zY"D`x(~hhF%Vx_b<SrpэedfScQ#JL?ef\`*ѡFNh %-0rq(>)#HF@pH>" %Dk'0 JtBZ&3gd)fN8?zSUԹmO%7գ*q2E$;)mc.j|)G"$0ʾ5bbpLau]\`&HDs0\rD]2mbr6!~J=A%EB@ZUhƔyKF`E2#Kha}Y%bI44N*gS l(USʩhHA+<\2vp/H`>Y7y|&)-Ir)6u.Nwb4{gc~"3NPَX#%s6Nz9i" t5Lpƞ'eDe=)F(*80lő,$CP{W2S|dS8Lv]+M`KL6 +_J rδL*BLz2bQL CzeHvOBpf2jSF:Ue;nn+ۙUN->%CusB>sxkHEcO!5#9pb!ڢ9xLqo'i# sN,  RAdi-2Is(!r#cD ׍[lF 3#a$zj9RSm"-Bꅎޒ0t G/[ǠSF5L3i^X/ePCQUkϓ6!^_s|!|Q7t.\vw!9@ơ6;z7U\JҘ1|䶉j~Mxl 5ӯwB~1tj=ɞ"x~cE]>{&XM+w}>vv%]])Խދ>7=џnTqC-h+M 0}?w:rEm*A'[}c\kðo;y*KL[r&!)뷫~3{{"(+fV՛pTzq7/n}⿔@;o(\λ4uNJL#UPqx$O,2΢|Xώcd%si}y}f2tnHНo0K c)"ݍStz<>wTD:5&R .>iyA-(#u<46s/?ΝL~{[$D]C,}~p=P{Zn'wC5'2ɼۑô lb z{uu+qz?@CߊL$l<)@k X-k,8w3XJ&Ou+\߀&Ȫ9HϬ[Ye"(]4U |kw{O 8*t@>ē$(J^!ݖGÎ9y&}tw'o9A7487<˘^!7vnx->>fUiqh'Y+B5?2I^%чnл([O XW݅)Bx::DTnw=?K*}x|kIWU6ujhcw+dCgm"O~^Ԟd'm.D,np+@xVBX&TK*5٘4g3C]*5{ZY(O0,xZ?Ib{ޱY7ne )z ah-$Gd + +#s _D<㚗3rA6U\c! ry_RˈgAy[!90<;~FOm' 6)gơ.R6F&oH V:tA7E* +Oa0!ũ'1^_ڮ;, ycYu/7}yM#Z?4ޣerRkO{d-Ɓ:{@o@"ݑA!c3}29QY+_f~UBt<),WyPî~}: ꢨq vPFghΟyt@>ב`2}!cނh6cX_)1O?+տ]eA_ȫv6nu?[@kI8ۛɣy l+@zއIv^O~eݛ~5qMMo/eϩT1f$2&LbK6ؕ-3%js*{ d9Wz= `ԋ'ۖze/Fz2Le 3"-e3ǡD#bч8^?PWς7}OYUe>hLq=TðEZlѷ19ʦ㺗`*oq1;PNx#OL)qBXdE'ްҟ+0댆vtX2y0q+u@v?b»r1vdY#/P޾oy1N^!|jUd1zyaT/)sF,B*Ux$e@{D <ëQWפ5I|n=>ef[ZkR_PIvēL0*1ۭnoO˃kƮIHV+Ա~ތ0uBLBM2S_>rέozۤPz'R{}h7 "MB}T +~qT(ktB0+ +=+IJz|N о([:Bi/^6/ +fOphBjzSFݐT>Q-%kSTr:|zhh59-O,k$Yf`\^0֠fԂJ#ĺ@:3vvh +endstream +endobj +250 0 obj +<< +/Filter [/FlateDecode] +/Length 16988 +>> +stream +x}K$=E1|93=Uiſ?rZrYK_ܻrs}K>-wۃS(_^Ns]u_~o/jv|. m ՝b /9:Ԝ%ɽNnfX_+;b]kuptneg{;幼Ҽ֍0'{u\8Y#m{6W#xGm'_]z }gb\z0Z?f.SI>Z<کi}Ȭmx|\^O5`1_)'rߍX4b^Q|mrٖ#׃KtA"? dWX#~Nhh]FN9^;z]BgbU ?51;ܙ՗V V6 C3?1_!9fNJae@ioԆ-tk'#N^ԫ8`Ye hP96Աtщ[?y~*+d5"%491ryp_:UlRX<z)$13kMvsBwvZ!a`(iS헗{N۷k{ڛ+S,hw}6oPH)Ά)# Zz-k:~@L:y2!H* A&ؼ,Pi(]gӒV㷻cvLc@Ϡr|dWצVAJ׭t ʨ r3dv=)D:RcsX!Uf׳O:MAȩ 2:0DGB݄jŌ&Ak`k<Tޱp{׬d6װ? 73l*7-+lsZS=-0Ջ +:7ܒe^<}n469s._b3s!nXs< ;鱘/R^mN~bVTq|Gy~̖H d{-\_oK56m ܹiDFwņ/.<|q`GFՅBk<E88T;-quhcw%.揯#m^ m>W64n@(ȝfwmi}Zu^ 9V%GC[Z8f\QِK"ъ2u<{%Ƶh`M/O #|*xA .r + +&]'@$z6RE2kes3ZHle FziĆezF7X㘵H7 zQd[;UTk>۵g}@Jn`V0g ^=_`XW#`OxtqrBL2CMzlZ +ND6 {_o-/]aHOьվI77o@sHo`+ux )ޠ+oF:eglA7n8FIv #6 m52ܕPGcOq5Zl%Ns%/,W#/;uR$[yug|q͕_ظ6旐VjٵbZZKRn/d`_UܞbheF |O2Ǻ?5gЦyʄTf7 ࣕ ԭY bA~DOO!uD PLJ= n3aR*y*Jzd0ɾ(D "`=hU&<*sx8_+ҫ:[#D؋b{7L@.!zLb=v +",Һ8g֭Dpm4zv- >2 W҂._n.q( v9s8Nj]3.l 1<,b0#Σ=8cM\VsiHevD*/d V)C$d:{|>hzbe+ZQlk]e9 JVqN)5P5MQ5vN 5]))S:3Nw{a2GEP2ǼD3hPc$m1(0'֑N3B㢋(~3+оaVmVtaDAL1kP + ̈y=Sa~3NyLg< 2!| 俺0*⢡*L,.rX%2SŅp7ɔ($Q B7$\(YP/~Xae^!Ah5CĘ/yȰ(cePbh%JyV$G4A܁/jXdZ<ǘ8]?4,@1%3?,vPnt1J"N7اU +"Fcˬ,ͪ)+f9c6\Vb-Ў&xXSz  +U-H6hn%F1fHI)*^LfaAr#!yPێZ KS!C_4M[J5잾:**z +XHzH9*(";EG_ȦEU/BK`zA +Ղj`*d=)3FYZU +܅9ʄ& 1Tm + o{*Gҟ"(Ò3\3Тq1dj۲=E{h 5a18_VijrK&mrY|yyX?$'iYZ(a6f]y. . +0+*Fzܟ}~$=dv :qlÞd6 @0 2%P%."d5+<!WTo> '*$7r=_xXh(b*$[=.}>)""x>֎qu 5T[~Ob$1ШwkCX +~hR$ 987Bf:5,@ u=wqw4r4 @-$_;Q҇yUB4# 2LA _AZfwk~13s2yzUBK^p>|lK\JZmEm +5\.jCr kd.R5 HMEHx!Arr_G +bEDqV7Ls뗢o@ƍu}&ïCM;dj<}lF){ӭ:Xǐf JD)Q%2+kG>_>MH:XPX<{ʎ`+Iv%#_Nd$IԄ5.hO>MDwyt?Yʗ4m [ZYAm: ̣Zf+D bg5EݴȆ:X<=>z3;]nl &3fϡ3/jA'?. <:&&iC[mD7N:#s!t^1D.`FIX2U]ފ8[}96æ wjkPl0X:HG\]j .&b=Z^r8vq0hzIx3p̼dAVyeG|ʌ&2Єm8u(.sQjB F-wAmYs ?T<=lܷa»w,gl>^| V8&v>_[b ;KoF|o ɸJfjDfyBn+tb| +|ٕ:,po*?y?Ro30.#fvһf#Ь=n;@wm}g`qZJ?GGqooA+_q | &>q:_pߎUU?W7{Dz-9!~ '}/ʾ G`20w }7޾ "B#mk(xX` ooG|"7>6H[8NxC~!##ёq!kD`0ȳȩ#RTߟ)@J ?iDMR'-1Fl3SWeY:"s/VܢSǪgGǍ+.W^^ʒu.r~zx8-i5>T^` ri1w4I;yJh9c׈~ e֔/Z]βqn~8f^݈R>/$ 4'#M9(S! +c/P_gguDQ"G}H%yՂeW2\%s4܆ᖭL(nJbD4Q9rǸaRr&Ӈ :ʜ˗BlJ~r 3&;W-l3=$?cm P Z6jAщY|;PHU1v%8" Af\x^XO!!Y)īԹ4IX~`RIMȋIX/F%姸!Y'jľ`l y8[|a_jp=َNHm!| ek.oP4!odTfțn|oc=r.m iK%KR'ki;I&z֒ 9 Cld/s+B,+KJD$KŖZ-[jG gD ,3 Hօ^ʡi3Ȉw9#I=LBSrTyȂP2ZKr'ѲgxSOԂc /:%QA{u}8k ׫pHC.C|%KbH7" yǕds+͊"WK!C~/RPs +'My苙ȶ7z yh,|Gs*G0Z!-v#+168 (b< XnI!pp,চ%<i C1}O )! +wb

6B9 |b,T!PTQ>.j6;4F6 X9!sa1|@ K̖I܀bCP2-B( -ER=QJ3EqIlQ&D5$@.`V2"5f%#"\;ZR,N*sWɂUңHU`Tp6uD2S`x~h&HT>$ ,ElHDsn* OXB8p*dHRd W~70~c +TK3𔩳I"Ai}2_f]FKZȬR^t6E1pDV0eayIW"$&gh=BG "<%5$Ũ''s Vs4R*͝iȆ7F*51l,AfSw:Aʳ"Zu`J#;pռ+Kl)l섵9-jE_n;2 E, sĹ%:Mu8 E YOfkY3+ KPT=\\0=wQd&M0,xU)eXe@3{pIGwU:`*"aO,oI"HM 9H! D#Bn?d~xlR8. 4d.Gh'C2TfϦ(%6b,f$h`v ̽KET̻(ȝrRC نdr. ?/QYkID ^e/"QԊC +3HB 0H>{ CU['@Z٧#( +SZHP1YЏJGxHUH59THHy!1=sZ mDo{jwՅi?2z8s1є0#6k*K\.l~~bg!h_YKįƈkye*vԙzuߟ +:])R-)`Ā8hkP~0D̈u.*dRO@Š`9_ݺӱ6{ ٮbK@vJ.Jg+C` ^3RSATʰcFaG3$cyX,f{AuBcu,֢Q_:=-7)Ђ==dN8 еrNjrQ?Cg/r,:=Bz@y>@tJOtX{Á;5ڳkGLh!P̖d8'Ns>Z`޻shJAJ^Qē; S-F4HoUœV̝cN*'YӹUr!:jCM5E#w""9;1?Ҝdv%;ƈw[#d^O1G=S|U~WL>OjG +EU4U|_6\õ{[l~4E@oYBs E?<p%ʉj}DdsUSdx_ԝQozU_ Fu_xٹh`32xj<| /7l1uJ_[&ң![HTv۸9gi~n\F(4x!)Fnc< :ݿ]OR<I@=|v_ˀ^E;Kߎ]ٶ^]ү)~f +gTeGQ}~:O28+~ .]νZT䎼Pw+N~MXwSVBݮGpQ) ~J~7 w: +uS2'Hdc>B k4Jc`iYP=gl_ÜqE8y3',g=q۫ !]`ڴ^C~nw7@۳o{X~5uI1"ΫV l*S|ւN.KP" J ,ckOz^T ?[E}sߤr}G6bRw Oq! c5ߺc5?XğDW]tBŀ=ٙP0ԡ=?~YT@,j "~nO@K}A8:K0x +CًlbGld6vekcFYlb\DXցE˩wXjAZz҄HPeaؼhܵË.G0^#(MUjŻo`kzhxKz_x2^C>_o68 Sx3c a +Ka,^2QaISJɤOhξ&Ceyʋ^s_=R(VG*Oz,΍63[efLEUz#n]5[/qͿ"jw^4Opnpf93\N~|&`f3ͺrd{C܄erj}kVz.^,ǩ"\z&U bMu5U2[ [][{a,$Wm]Kd OHvCΒں t"a? ~yؔp>H<}T\|+]e{rb}|a)Х0-L׍B+T?EοO:?/weZ:X;rMm{;۟eom8M݌<]5IK$,"'`ef76w#?[#5MCN^]J T~c-a ٲsA>02 Zb#tG,rLc.vFeحt-gBagI,S{^ 場;a]pBwN8 <7Qr*\1`۰S/R=ny 8eMŊ䉏FHՐ{ 2\3el"p)&6=pj>RmYAH{΅` ;ts,WⷬD(.g~(pd[5%6JTv GGUtd +RLG?Ϩys!tk.]P{>]ndryD=F1'/CD 3%y ( #`J)[.U[D&X +K]uYgw@͒Id&0yҚU$g~MbXcJRݟcLI6EA1SR[=EQC$Ȅe)h8I,:h̅Lq +$USt? I[ Een +'::䓞3v;eb &cEospYθCrqdc Q1f,d}FӀf!Йj{p\AㄛM*]+}=`Z7kiw1Wގʬ>}[ (E= e~gQeedVWFf*(& ř@ehOgY6 xR:{!21FZ*onJ`+z?i +PAQ!r-epYgSR4no_:KEެ^}>V׷#F(THeY,hnHF},IwFY}a7,%EEf~]SZbQe-8)_6l,`lYKp]FcnDψrфوSN Ii4*+5Źh^%@σTsrF<5M%i /M^.^ ˲ܒ Kȓw{m.\|x#DF8mױlmJ8rኲ,KS?4D!U{ö"~dID;C|puRu|:֢Ңӷ&^>!aNvD%\bS:=MY:u(%^BIsݣdW7(Hݙg< !pvfn;_劼dŘLݣi:#F1)R^^c.!Qe0H}9QEd|an\d_24Dr~I%YB\1!h=8(V^!D^>=Na^:*j뇐MU\ bmGU}Si۵ѷK,, BxhmXHv,qE.~+z_\ѵ٭)/)8}uVC˹:F9Z&u ߲g#;^U/Z-3/ +d +* O1Sy6xxh}bjrYlgH3"Y6G`ڏYV}KUE퓀«O#bp ޾Kmյ'grpQN<ǭwoo2~'!DM:սmmۼ6O˧)_~:r{9rYGbk.pNBEZo?շuh27x4~Q 3aj,]F[ڍ"~FEu"r=~έ݉+fqD`@ b|r]pQ#99;+g|# #MW^;!c;a\˟6& X =b rCIsClDDtMDT@^l\KKwq}x c6S1(Ҡ܊/ ݙ2.!- (ZJ +>mҜ(C3p; ";!,Fbe.fSQu2~HLVy$5@V[UZa.6QL އʭW(xk\ }EeT =HYVB4bAp]Fo>aBO+;n҈`}~;%n.)Cr2`#6e݂l_WصzԌ@*Ao>JѢծʊӫIMoCTͨSWft¶ԁ.CjevHkR57A.W/{yXrFZZ$> +stream +x\[d~_я=s|t^C0y{#W%Nwκ ;][sչ>l5|\} _}~t6ZBiZCk]9ڴmRf;.1&1fbMY)Gc=֘ƇՔ/rӞK;O_V1??"Ԗ{M^n8l[Nl%SWWs,%΋>1?~SeNe_`0Ukެ1)r+ui§Eq"CK3c&ح.nkڳ1}ՆmB^Ԃ΃ѯ$NƏjm_-)fk-f߸Sa7Wgu{^pg4Fºi* K\';gMۉaȝnccɜus#BVU/l <9U/š)6Q>E5[]#tC3L4#t_Ҍ i~F'hF):mVSoP3gMg2 EREV6L:P\* (4kh8>JA-jLG8/P?杯"l6LYtkNbwy4 8v9WxqФg4/tֶUPMqc sf3/X֑^Z3-fH45ECiXbP +YuPvG@5yHvؔMc[o͞>COӖ&6PZfC6H)H<6CHR + aB` q4Z"E 2h:X$ Q"U2IHc-z"}yX2V3I]Ij5P<4 E CHgRUMtHUIڲzMd +&6UUc#U]cf=)CU +c%3eU#}&e9R-R,%,}&ySИg1eNKŔz-5eSSP٠_lgT3l@FP"2th T)[hi&Ixb.rrj$"ډX%PW*& jzzAm.2,z6&k'~ZXӴ_Lő2cٸ;%j$s– JNɍ6}&۟< P$nyP}(7e̜"p2eҴ^Oc# 2)VFp!`JKJTsp:7 +c BfD9GamFB%-+Q(C %8LBy׫O8~M'>g Or0ZW+gI 87}%TFvWm|8(X? K|>5ٻ+-\zwLG)]h۱韤Q >> +B>PVs2DI߻֋bm>$;f"0o,†;N+$[kdڝ8ŗf w/ C5 <@[h><7D #>޴xhjQ` To$&d'=C{ U=(٨5܇cbssu=0O&W!Gi/S=s[ 859'#(Uxhd@P߂hZM#poƧXX>…Pal :@$Dk G"@qB$ ZXB 0 @I +N| O/H(A{SDըa%UJK$P4% +\ |[!LH1 +duBh/P &WvHZ6zh)ڄ);Ҁv'd@ND+hЉVJNց<)ɕbO5DKɔӭSń?1F&ȴGNF]+-; bkDD@oU8If[{2Z& ~(akݝ0]s]Uځm:D1 + @ScQ<;=5!LU=8k"_'ijmcwCxLҪe\ mRqY `)OgtB:nh]-N\kwZT)ٛEԆ皲$Onh)ʤ;6G7Ɣ֛[A [D ^h lW@Ȧ)"ۂާL6`Ih] +"晒nĚ7ׄòn_t||hROS-= pR?9?>{zr񳯾}gw߽x-.j&*kQ=hY4u֘2-VD]/$^[ Y`\0;t8a` j(w ?wbKz>n` QUiwC{ʘB"[:@j̵ Fx*tc&KhB +^3 |4x́vS^1&""\D[߻ml!B!-M}` CQi,hZh1DL܋n=fo+7Zҥo|U~LfzJ~Cfv꒲}9tFH42EAؿpxD8$r Jl4JTc K }pcmQ[#(>ؿrOnӱ)ơ%r0- kQ!$|a|"(0F,)͇c$"b.sI+eGPRArQ!Ha Ǐa+a%$撵h)nIRjZGf&lA@w$vil4P ($='ı#oψbu>0ݏc>CmRFA$R_vI=2B7>Js6%MHd&Dl>)o ]IZx!>uT<]"&_B0W-fS=Z [#W^H8l$*8GfG= 3Wg.QNk3{%fSYjTł6@ +n +5Ͻ<@|q_PA +//=ـY{3,.0c4R[`[O P^Xh\ThYe0h3 *)l +ޮϼ*B{WyC +Kmf93O.6^PeUTdVcL^%{[Z,y;'QX 6c*?SK1)ɟ-T]5`VL1?4M3ys㳋J1k1J\%U!{P+˸ +`@gvxra#1\ `Ño烩1扸qnT?x&g&Qf{JZE; Twv2]Ӳc\%Uh@;G23 \5̓E6^[(C*ZFync { +wd=> +stream +x=ێ$uؓ[ky10;HZCkN$_xXVv,6yx;sf7wS)O?C;wnHrm[_m:х<+ᏺΔx4.s 3-އ1licLW?GtPOMB΅o51Agc8S!a`^?>j*j20<{o*ؼ3b`bMu]ҨzR>1ߙ4 _#{s?)8Dvu͈(fxO.qyXtWzDCu gj6Nqw^'z7= ~*veC8 f0@/Sf“zeXc|T/.Cip?qᶇc]W5<(,?Mq8Z_O[z&UƲ0 FUF5 +iqnRU&Oj=: ߮-7czp [2`tVeTgr(l2c,'#ڃA|NDZ#WSŕykw.-aG.4}"\qJџm}.cHcl@cX7AT(|Nw];ȹΗk +Db0-3#Wd{hLFLaeAQќiyX_"t+.l>ԇ(Lyzq{ xvٍ:,<&Ʉ3IĨ A],\ЭkO"2 +_)p)(DB +ӈ^=v}H~G= m\Iʴeض}Ҫ \7#oBg(-]}&,pCn8zAm +"Usӳe+*ϛl=y9);^b)22j4L7F2KZشz +EZ KQx%-"> +RuPF{c$r(<) GXn\ r7brN+.e6.+j5@q@] +%5nG3~V{\c]ieç>k+x˹U󭩜u|S_,zi5fY}6yj66D<S\ܵ0A` עEZĆͩU‹Q7 +a39ŨrYo'#z y)L%G6>ʂV"qփ)G*-M}m#^k-5׈evItI֮Q"ݣoci6j\(yz/gKe:ۦ~ 0/'_- ?".^ ߼CEk4xԋvk4S)Ͷ.V-~GV-N7&nJVtL>6ћLs Ѽfm.Ӓ uz;V[İ_)\΍(UVMjXrxm|Km}-DexP_mR4)0EuҒv}1L_+h>==.!c %+8G vf/ݗ5/6`nmP/Db/3~"]N4qZ$@R뇉Eߏ/"._@Sb^U4#ܡ +߈xϣk{ /qkBȨ~يbzhӕғ{ڮC{#µj2<8vA‹Lx!|x~ |^.9/]!EWZ,7ޔvo~zѦΦݛ{]_`oM?<nZoKM?}_6~oq|E$B`:wAOϵ?||V0ӣ7eqwO$j\r +$93u5h[_eU؈:Pܟ + ,˧\Wb|5I6Q=?<2Ou^oљ3ӎOu-\_,]ڿ^{8@ufo +kOO6p>woVZ?p'gX=-liDzeUi黧OO?,IRp0ee*y_!2 Q='>J;YH8qPSkGX-V u`5\yE1ꍱJxnhWr@yc\ml dӱ' WX wp9Sm94M'۸X+L2sW0{{3Η'/ȟe#!Np2ehmrW]҄V0[.xY蠟z2$B 1mE Qi5Zޜfr]]O|/h ,ҸIٟ +F)Vq<쟁+?+I.O"75Դ>BMLzz Ό9IBec:+ϮFB5g]a!FL_Ri EZ[DݘFF5 KaG-jy"˨ىJQ p7/ YsW(P=_wv+xcaR'PP*"EI0Rj͐3.Ҋu#O$g sPIA]Zu,U7wEEz"NZ.]z!Jc 2:aZ0 (g*ؒ@^nn*]cYXR( jhJ1FbJ*ꖸ4%a~4wsSupJ f,rh+ЎrQ`E4pj2}{[QSbw@0B;U4c0 FNW~/[v$MxW#sHαxVKu959xjxj%Y_ScW58v hphJz"6soޤ\>lE|6JPOWlt:aes`H~Zr J%a\i6b".Âj WAW*YjO%&y NQ{ߗ(S uNQ8lp:9{!Y"%>t,Y["Y"lK#lؑ_8<8E;r>6$+mz@Q %nXUP*̰a#dh\G}@E79 NC *T*nzb%ȩmNQiX> +8^NANe$OpgTӤ +T:.5N|d4MvE,a/y:jO_A}ɋXruh_؄ E NP~"v~ &Fqq0PS96ȶ۱{*^Ll-{m +d8.M}""E +^q`dNL㨊9Q. ْ7dm:?ܐ'.Q]_">^;2* 8|KțJīvre5BeMަbW΂hLQSpgE<W. C!atRBQiDR_ZT)sTj4 .ٚFU8._AV]dNWFXwUmSVZnԢyA[*5])`UߔxN|ax./<%'^ZkA;kB 4y.UE^gr;׃xfXw>0:P!5gjP"}N7ײ0Rg rQd[:2D\*Fu֓5q pR)/)fE~T*p ŻP< P%/MuflJy{-1+P&w#[¦ 3¦/Qi\TdSڽڳ h.k ՘b\Cs0+ +(%̵IsT;͈b4EY HWw~vnR#OOVRE (fѵއ(~p-6ؖǨ[-鸊Bnx?W +԰X Dl^(\؋ձeD`lgtN%dNhZ)DtX#sB̐]dԝCD5 6:tpJ( q֕C!߀JtR1#iz"aֈJ7KEJ!ѷ` p!'^ 4ԩy$ɒRB/yi>MR'HDN#Cpӗ]RsTa/h}%Nפ'W_.;#*G@ P/2mz%읏kѓk)%zhd_ۘp]mnmKYq_Š5Nԯ0:iݔk;.ԮrSgM .u69[yKK.\*]TnMl̳RS!$qTd] {*l +~T0xTY"W]UWINzލ/U#6P\`a#'soԍ?F Mncaj$|}-:ԏT2Dž:9*r5*vI>QWE^44"i5#g@?&BD8 ዢVbзA3V}le)d%m hUӉ 䐉Ձ16ZLb=d[,?!y<6}|)PhN@YRb'ys삌#7*m>X XzZ`ZrTFދ_ SyԴQ *ĢcQA7 "y7(&hm]̟y.P1Qu!<["]F®q^\\@,J"i'dȔ~gt>>8I\kjtLHU uQvUYUԗ=tDڰT axj ؕk*|[;k}.. D/];?ٹr,;UOv0/UGɝ4{ꓟPEm$S xґ'IG+Ǭ-^FO0E2T/1f&Ȯ!+d%Œ7Sb(7QXjG ^ReW6̇sPRi$U= 8m)TzO)˙tO|ZA6R|bW9>9yu*U>ҹLL4k9 F(HEO!bT*H"QۯW+t+(?C% quWcy M=A Yߐ u9ղF;C =ل!ᕁ +SG)]*J: g@v"iIF,Hb9ׁ(wgWgBӨM-%%_[Ӥ8kü#Sl=FӝhK9{q]z鞔r'' cޒCD1ʊHR ZR$pMTtI:\]bD +gEGɰ5L[J7A..+eMQ~TU>&4iH*.s6ֳѴ~L!Zrvf)C$BsDׂBo,©I!bf2f|\xle2S"./z]c:z\-Z·:vTOԺVE nPGRW҉].vy{b87(Xz!"QozP7D!~R "ohY]$rB],%:u4n, N}40ԩ"Wj1o'H  +Z}mr;= NJ5>ږ֣ZN(I^AsJQwʋP<5^[8ye%W2/$fȾܤ_/S]p~ *T|T -S܃]ll'qб<2/5?1Ǥ@F/bt jbದQuZEN0 Le *I(`'&_JTY0 9D7z /-g9eH+ +g=oMYCCL 9hEsD`9Paþ -*2ȝIECbO%5.̐[μnkunwiԢ2#?qxfsǒ2pZ_46Pw2jd_f5m3Gu;t琌IFBqp̶q|YEY⷟9)q.g+-cMEI7BvMeL.+v28AǬ2Ԙ\yS:Ni2Tj"q^(lbx95é5;q !)6$V{`#Igrv I6xƒ\CR EW_1?C[W?b>mmѧ'Lm=\>@p0V}kC3 +MXPd\~8Uqh9#VˏUŎc] x0. f]]Yhӧӷ?>~X|~_ҷž}v}gP:?> +stream +x[KϯLN^6$+ٕcɆԓlLϮv74bc}/;_C_2}'|u>.>)D?llsKu;|+?=dn||pbݔ[%B7؈msw_NGKC\R^I4bJ%fQy` +il*+쭉ۧoa@o[0okX01MojN . +vُq>sek0e?`xM#^$. ®S8!t,ËVKagm?#ȮJ~ڶ!`8{,ZA8B0VΛīŷl!0IO&`AHFʫPD' < JɆ)z Y1FL,#,9]Oy,V>kyWhRA$c, Ri,ȨbV`XR`-pE.bCaθ|^$YWXlg5.QQ*_ f/ٍԣDHv9t3#7j928oK׶Ob9C.r6iKlxMNkBy؜l.OM:00u@Iu/1mOTr#F6up#5 )JatFt:AS‹ 灒5Aݝx(1m'ԣ4k#RLFz2'w1_{$%JkFӳ("|(tl(o"Cq*/XBhø͌XPN,s]vM/FK G wd@GliŁhۚZnq3Z?It&y :emʞe ۥ?4= +d9`d,ׇ9ГHPL#raCȀb?sc %}d't&hu?͏ZW'j{.>1,ZKC_8/neWSӡbN7 KS|y_,~8~qxɦOߟ;9{ZoÛ ?'݇dwO_OY9x[lĹc@ѳ(L7%y{ͰQFp[z`Ԥѹ:؏ۼI[o!ԱzO)+ԃ>jJjzpH4V,HzUzCؚSk q˯py4GMnRM~sƓ~HPs)]g6Eieܰ\T J Wʡ}g[c.Ojs.j!Hfq.F7.s@?,BҋӚ|1MJڰ:4ز5K;3]>Yzfkr .9wn^k+u%V]r^}3Xhbl֡p1.h6nrYZsy*?s./9F1Y[|-qJ5[j;H(!VEe,Zg>WAِ KEb)tl`{KX Ա )ǟ&9yp~Q$&΍ԏ ^?>l h!8eRSk_zgqʡikZ?e fKc6_jiI9ឞh|icHE)# +sFq|9tk_( @)?6|)ު +SǹRqOyi3PښU>Ò᥶|VIzʂnM|+ߊl#.D2֛͆b-uG|muc HS>!i޵kpM ֛Yy'UCyv]j'jG΃ ܣ9<5u$S/.e$pܟU|OX-~5m0/F -֡Voٕtm>8OsG Gci>{?O7S\'s8F{nX'9+:}/X +endstream +endobj +254 0 obj +<< +/Filter [/FlateDecode] +/Length 1034 +>> +stream +x}Vێ6}WB+lE] AiR[v$-\3CRZdx͙9s8L9Kƙq{u:bf9 |Ba˜ q4J {i8| Xy~ [ZÄv8yzR2L+!VV)k g8zZ@DYfrfVM"FDl9-eTK$19`ZD㸰W.r7NS8愛Y/*wq7vd}UEgd` +l e?$/DEO;2<{r_LÎt>fvt~;n< }?dK `\XB\"^w^^K× OjQR3 +@B*}D2VqxWoO)!tvhE %&&1)D*rYsOC_rKMO/h80PC zy`i}l\:;rz܍QWY12c 3?кC'5!b%sK y@Q\V]a$rU֡B:yhahditL`b7]sSv94Qt$}C d8MsOM;LA&P6{H>uBFRЋr- ܼ oBY"d-¨58hXR%dz! ) +' b? \DvqL7ՠ.}mpQu1 +ޅޯmWC*ff2AQ&"$FWOKEJr"Ҝs(.'pj#%*J˔uU0[G /aU㄁8̟Vq*tҪՊ 6 +M^kbvW:54}+;SQ'{H8ue+NRr~gJӂrvYe᪾Jej H8#o +endstream +endobj +255 0 obj +<< +/Filter [/FlateDecode] +/Length 2820 +>> +stream +xڭZK7cUT 9x;0_$?R;tDII}|9BnN0܎s4Ë/38SIs ˡ#.~9rgwJp7̞'Yo8З]hR0ƾXlK + ilfaC%[bֱ82 ^25 \p +#üQetce+;5qs""9H^d210i7zH0sdn>.1ݒ2g:-*\FMGYO:&V?d~'zo\ُ8 yG7[ކh&].Ts0 J'w!λȵ'1RRNE\E@~Dg|>Ĺ%\p4%χ h+[3;S%hU/ ; #V"P)}>'^P~B_L&;TޔH"5d# Hbf .QA4Lv*y!#hq(h9rJ;((cG&:= ́=Y5BXƐV" +D֑į2yupPXDh{vft;z<%K;\1׮NlƛN3>`2hT&7Bj3-[mjEffnD!AW|Ǻf]^뛋TvfH6 ,.IB cϮ ݣ㐱oLynSr8`{ill#`ͤ<X;d=] /j^3lVt<@1j4 yQ(h%r@/YSOQA{t#('dWC`As,ՓDO\) 2PўyKxu:uXq:7:7"sĈ!w;vD "H 7Ae&* +‘B$P!/ H56B^CC^ !kAC^qh 9k(Uå.&Cv"/]1D(QUJ[PeO:ו1$D籂<t[ 'Oi%Y p g\+'X ` +[dw(ș&M? <\;2jɳ"SsUӦ065V`Sߤ.Б\so-׾ MI7֝{)}jJ&*zb`){o39>☔VSVڪ)CI Iʑ|h`k3arKVۮo*m wMLtGPI\d%xy9>ҴQp鏏&Yx$ǥeQo?^y)N._O>|LBGOq^9WﵺLC +SBA2G\rߢ,s6KFUF>ɚmI=FZ%ۃ.K*M)腓)\lԠ n 2hPU5rh$4 XtS!) dӅ0ilG 2eIp֨eVDWC~ۯZ- Q?cޑ9$joeo)Y)mwߤ+E6FFᓡeM#lq V"i?o0݃@ +q`5 +v;_E?)IȘۻ|q00ؾ i |:' bvL#tJ&Қ.EaKr0^jWDn= r +"%>| G;Z_dT`9PU-Lhݼ(;3VBo ҢdAܿmvޔ,= + +÷1!́;O*V@e5Jh<Y icIuG;Htڙh B!>Gj̪4 %;Nn|uH{UJb"N6u!fi1)YڇG|A"qH1NPfk3Yk}aWcv_.ZV}uѦ *Ps$Lя{Ϥ&-gg؞Y\ CCV`[' r7}Us+fF36>zm[72 fsEլ×Y]ТeF (@OM@| u -MqP*mֆ/W͍|zpy/ߠ}eiymqynty0v0z/mL|N擛 vf ,ڦ# +iN|B}/ ps +endstream +endobj +256 0 obj +<< +/Filter [/FlateDecode] +/Length 834 +>> +stream +x}UMo8WHbAOڦŢPSYEwHJ 5|yf8Y[]+)LM^*IWN q +kplQm|Bxo:H+tyTG|ʾD-5~t1wlaʕ^O>N +e<:oOnX%"U ,&˞{YPX>G"+ +~!ڸ4U\i^*j[),#"8U߁zw S>#aZmdhcPaO&7iLѐUm^VbcqiщqsB-ڕOZ!X<ChBbJNh"W`aO\Ih8HŤ0%䯒j>֓['!=S_ۦmߑ)OǔcaJҏL״gIGڇ'Y1&1N2t"R )q t_R+L-=&=V_U}HuK/$U;|#&% 7mtQ|#+i{"9^%?9X(@WtQ( )\@R % C$d6FAsc=@v5\~7g8Vsy4+c ~P}{JR}C˅4|?;_€FTk-3ɃRKOu8q8_r*&!ʗ~t58P! +endstream +endobj +257 0 obj +<< +/Filter [/FlateDecode] +/Length 16458 +>> +stream +xڽ}Y,7{|2a_zZ0 4AVkTA;$#3^Cnr~ //cy-^^o/1RoZ5{>Qrx=-ls_S7fZ{ͷ ߿ |ȯmA:^{!0d[%1:+9Z=+-tlT)=O2ӉJķZ[5'dJr?&[~XwIY^nnQ^SJ-߶/]|__{^;!ךux;bc`ak=O! "{Uzu`?-2>>t€N. !@~;`߰.3Oc-| lRgtЀngp}~N(Z>ͱY15l Evm|͓l=X[vuBT̻7-Z ANPOᘕTt[v#bwݾ-t` 'hSUivN:]HѶ.GBvk[:?'p/*uh0Pe#'E#ه(t |Cfe?-iBwFA([e6N'fWrmlGO(<=W7# sj1`!9ט>"(mvl^lIt_R ?Nu^FsF / ~؜gF 2dlr>;~U`]Nzd)ai]s26?0ŭs +O$5kпfcBʨmCwٌl)7&ڿ[j >y|gs]쒮[?\ /bR',猪B[w;9~Bu;V)A]w $K&_smAl?-R'!&@s - +"Ff04])2(G Pm +a8E=2V2nm ʷxTThAڐ$\lÅG 9HC x*g'a lb` y]Y҂ 09.$l:CnPwSU06ʕBɉ0\Lk4*]=$y0N&/4 ,9Q.$ndTF aEz>1DAq$@ن@Ńc]A5aTat,!{ +q͠5Eþ~0T2^G5P1/N4{W)7a,ۇ'+ؗxkdg5!=!uқUdaFE +VxB(h7, #P#"o/JbEdN)x/?3ZpqخLr7S;㱩` ,QWeCW W"#td)j6j@eɐߵKdhl2VgzQè81iIq}՘& 5 +Gc`EGotpҝ9d u]~$ }[ kLxK?h&sb[zGV21ӥCFX2~d(4zjj9 :Y rdITI QduN:=xH\ʪ:ͤfZ$A?FNCuEm"]+{p]U(OQ4NQ>Eh"&`nWu"ĕGu"/v7.T;0xM&`AZ3?~e(UUS[.lBxkƽaQ%s0Pj\w4(ƃ!E]|_w9+#7qZSkٰ1vpBeII&eVէO ջEH㲼@4A3}MS%¶ZlUvj𴒷u6b!Y /rJt#n9D>֐ /*SLpl8q@&k`օ8!H8Bj5f46WGTaT3~nS(|5{Jc'=2% +JE8~ӫR>~QU8NK5r-;1g0R;-v\aD)϶B2ɷˈc<<2;,O6@:  asXzR*2 Vgуrޖ/Xd| 8_Z2܊z. SJ0|I8ݜ.w3U>EQlBj{fQ UAw>Ӹj#LS) %YiWtc4 2f-CLm]FE& +r 3k2ԃi&tai@moN3iW9̮C !`Iӄ.# Pe>/"1 >)YU7n&eIo{Bsaeˤʹ.fIܐ,}WfRRx9B1Q߮ fQIdm_G-`|G9=r7껹a?fo;/_F\LnJp Kmь910u'(c1LE8I'ȤEu%%M3z.-)PS ACؖq#nھgͤvmWd|c`B>C#ՕTiSG"bi!^ГIa^Ϳa^F|[WkI Po6FTOL0P#wp REcңyU%/LgPFHtmy#>nIL./3 '!:^]Wby2;`pu^0SjsRz?fuN\mÄb}BӑF.kx0bea(zo`/,oo\חu J9;D4(: L}:fj dYy; S%^#tz2S!כ NK]&lQˣnQ533Ũ SnlihMl-~JL#̡6LFd=(wA\zu)Fd抮u¾ +)Lڴ El vdܻPv`S=?o=쓗m㕴k|M+]¢H}6ֳޅJ>!|_{9Z˄?vl%"mb#!w c}nKmI뺕MG ۲#Ǣ2j8HIÈ6陛+9|8Tr, J 0et06Hi$a(n>DoWBWڃs7|5ƦxjahP I6PƂPeة!$ƈD/'f_Ce"J'4&5S>J2;U܂-k:/! ~ +CМcHĒUtv!A i"G57)A☌йv > !f<]LR_yFGFDG-e B;p=zE g3V8CeRȋ2QzHQehL$*d|`nJcI5ӈ 9ӜxiIƼ\kb^M&D;b[1R +iD'i*fn "$[ʋ!2u}p "b=Q +! 4|R 6,#0 `+xC;5h (y4d6t%L2(0*E1Evz"jl?DIwv5A24X-XR1d#'RrӹL')a/Y 3D1.a 94 40N0e!gPL]M݌F_Zdh +us=M,g2UEgL m-i̛ NƏDrk1}fnVJs"SoH:3THlL96Icd1#,6rdaOYvFFI.'"W#hb$je$D 3VW ; @hW +̠ix-3BƸtļDw0=rJ6΅4ôUkNj暽m+gaydb(a-qUq"it&L~1Eq0"Hq0"{#ؑw7Iaن{FCU6+m6XIWiFZeFPPr0 򘰓ѠAe*Q~7Uv̈́:ϣZmi>Nsco)vn4O]sv07 Sb:ih< +|HHց]63#oe +8M3;{GI3wmF,}PD]ie0m +} +h2T;̡l:=ְ.:'S1*9!cU7\Ýe}u&Kvjk&V)RF6\TM9"uN3) "Lm'w8"A`+/L`yCa8vtMuP[1$jF-S庅b"7ɹ!VUk$c\`ƜRuw}Z2Z,X16H6iw}='?lX$2". Y~t6u@!e'>֑M#䍩~4 h$WODXM槁G 7\jȧ9(k(olL&-y{+SiF͞<G6br9GN`AFʁZ.3<_Tw,0#8~ 5rFb`ѝ=ANu2L$0jYfՄJPTZa5LC!)y*'za8`ו )TD+kX= duwxK'V#G`SLq.  q@A'qÔB۰B$];PsW2 & @ULPo^E 4{.{5#`hͨP$(AåL 0ZC ֛(AuGiMe@ 0LʄP`{I@ 4TI@Ԋz +.Y v!甐>V,LB]nB5m$@hU( jvꪎȸ&$T%5s3ǨU %IPoSѽ/;a:':AD5yֆ \}Go@5!N2`S\<̶VVVpXf +e+u!h&q5s XW "d7K Ȳ$ KT`{DTqXF KPSH yE hAx&1&]drsMecd>yLz%J4ROrgHаQ3J<8Wy۝AvG5Cގr
=x&1AJYm<`i;[cd&#x #wU0`19E/fa!+yRtg8!|O 4ӡQ\6Xc +c jiHF4qpYn5Ã${u`G#o7.AmDX,ȍe.^'-@J#:L=EiZ"$$p\2GDpQ(jKu\!U~/'cY$8Ef +92uXzA MM)(}5k|8J":V3 pHn-3 +TO4 dg bd"N}C{l+$aOxQe4G#pӌzԼ 1Uf;2x|U4@A6R KX`$`Ђ֊ſx2'3q\ 1xU OXkAV4d>ۥgPʋ+\0`Py31Dg2&)Y2;zf &o^>r2+QPX ²WB5/[krCe\8EfPhޢմL +k!TK6cj9i0ys D"8v)yI$$VR(A9&5I ѱ +&N{ 6`+{lib]R i\\gAl$!ff`Ƣ J6Ac̦⛤FMvXt0eK=P*y"qk2I2Lf*(LW83MBse̕m2vm5P?_Yr9}-L@#pڋ{'bJu]ܭ&5w[M vX̹UPZo/yW[f$] f,dpN"+,8nc} yNE%Lu; Qy~ʛm4gC<WmeeDPcxĔV +ӡ`,8cԓ-؀SlZ%v^tJSE=ֽq +BK䵣^8< 7SBMؑ)x's4˝(qj <=z<D]΃h~"];9&X$b(Wc ҕd$($||gYstwN8M0Êupx -&&Y {60 +`o Zfy@D!TvcQ( v*2IOC&- H2`uL^IR=YfbAes0-OЬs8_bTA؉2ec{d{y)֤ݘ$s$>8QaZBGU@ xe~$ًe)1ymG1EVIͣ :kWX^cV<áƲK|u&h:hn/bYגuŤ +we)x :6ur2H `;?<+̋˸kn= +߭^J{-Qj +Hg`{ 9VȚFp>r;d.#ʂbIAs{t !s G.lt4oj!Cpl4 Ȼ;BW_=>_(o}n-++((]*Qջ'QyW]etIF ;5\e]xޕ$>ur݅ʂ&$'ޕ.NG崩7,]M ׫zc3 YTSg.<]n]Έ aܻ +YU)::wuv݆'\X6ag얮|Y`%"KW,usQlse\u̮: Pƻ@qmVCzE +YAO.D>P\x5] ԹS#yHWv<P>0B8\GP{h99TTH *͓ΫaK.dR/'A9(=ԜH' Q ZBMwX󌸁{aAqgt1q#jDTh_q?ȠǢNy:9ȾE5Â{-:0QsV/Hz1.>'^;ZJE9 S&_u[4@ag-^L59SrLa!Pb\c:I`Gb;Qj4z`yM8)!eT.:55Fܚ榉elIm9`67 x<" 4FZN.v7±:"F # #ͅƈyshao1ߴ+5p~S1(k6 / "\[.rnéb7$ѵ JRKCp\/2pWS{.=sD51r>2wV;^[$Wad!A=n=ܗSa{i:=(>wԢ_ם'FU)vɀ>we;ʲ88Mu1NyxWKvv~IL`ۣq=ݫ5v(6\3K`u<[%'I~PʻNG9rdbLn}K1(Vz_k0 GGJy37 +.^PldE=veT"F}AU.G*@e|hcuj@"ikfจb̺913ӄ<ϸ.2.yǭUHbҊ%WYpޞd15v~-m>EB46~(aX"8Ehˌٲ(%,1u=bLf㽊̦EpaBTh_c'LuzwJu36~eO12ȵ\ GQURD?q3p rk؎[ 4qb #y,h1^^XΉMglY4JEe.6Q *vnY^~pZgV  lV(>8 _qrLða@sm\Hc+#4 tuAgkޡs=fZW66_*Gva@E>Kzu%p]C\wwdH1cw6Q3/ II3 ݔxe"w~*qkH#sG񋫼*nEڎ/sQ{FO$:lxr'9Y>"f "eO4NF̈́!dzc +e~.c:5=9I|XW;YƞdK> M5i#k"%Yu#Zw*YaS Hs>[!$>Qzo;kc_5@/ӥ~V)Lo2MxF6KŋY:[ɂлFi@yN۠ͷ]vr#%T,n_6 К&]^~"#9*,E/0y#Jw +$ur_̖ݷBsvG)gl9ok:PZOV +62J=⣔MLk4e<8--_BS+NީkvN+d~y{}v u;ciCoC(OmBƜP wo<3?&^ Vu@w2P%n,8AE#WlI :@Xˠ} {nF+@T/t_!/4 x ͟Zomoe\kV ޠZt#@Ҭ e,cի!7'@Wec v#`^o .zgF&ݷ9uE\ +ȫwKo=d%JW./3^D1ȧIcތ݌@BK+;LiMo.LsƌIN]r}:c>=M/M r}. S +5-ϧ+Au_{ŀmuXxdt~ة SzN;_j\'Ou=RŪPj"8DžZW3M]8Ƈ{;Sb[+Kc!>Xey܈%c`!c/cy/TK^Wmy cZġ1yby>ϓǀ]߷jt~$*ڌ+ei "Oicp+遏g=cMVoLfcz3Ǽłb" jVZ>̞$-]G+̔= +1#~ql8<83WoE'BY}ᥞdrQK>e!CUT-<.5ѳPy w,sٛA#& v;Tp R= :Z1la6;\ϛ/ +$cQ0)@i?kȸ#ϧE8{պYQ,ևHeWT{&ҭ!*`9[pE@"B)5mޝcM.(#dz>y{VQʃ;a_)]3Ա^=D` >[ +,6yy!}iltM#B dlڏhん1 ` -^'!j +2MNNo519Y+2zIlۑoga=˩A\~gCrDCɿo#<2mA0sw"7j=w- o&aFE3-OP0Gz&o]1 rOL:سՌK53n.L"=`ݩO;nu Td(X$M3EB/['O=AW}MWm`]7#&9ǜ"FʈVBkKʿsiɩ3hf,/s+yi98mp5Ov YyM ]%>k+2*`0=hC:u-0AeE +uFC.\5fr!JXCǏ٨e7e n(29o4 24K~02Z5Yfދ>+.+~w.%?yG1H9O +e4!ʍ6aW5D玸s:<.#dbEVI'Yq;Ri#s`T>OsDsħܦϰψި͉ᗑ?=ϙ;}e45|&~&gl/2qe2u1%L&E14An51S1ɑtN}/ho}8.f:keNz\w)"ol Jog?T׏919mLc2?@J'ҿxߑcS¸P{χ+vo&Oz>tw +d0?鏰@d|b ۏuHUpdR#T{ErE. Tt쟩Nد5_V,Dи:g_W)mxd1LZ6|Lش X{|4]4(\h +R\RaiY:gF}YsPEL.gI\^GvF|a!Y4ݭP]NģB{g Zs+g9Ň8o>>3ك5XAFnҏNJbexؗ=)QGΔGs k; Y%JXrfi>4W1qj^|LOPݱ,H!E5v)xxW9ޯ)<9`8:^/[_]ݝ]Mɋëu2MU@iѥnN,ţxoıN1F~·'7+E);\6PW|Ov\UУ~W釟7U~;p~xNf>_m}MJkRMjZE>~qRdSS)_ݾ7Vd5|X(q7KҜ7lڹ=ꤴK7e}('_çԪw?ov}﷟zZV?*d?NIwG? |řhQf_Y5/7 +endstream +endobj +258 0 obj +<< +/Filter [/FlateDecode] +/Length 957 +>> +stream +x}VQ6 ~У$[շ Vv5=.q۩8w,Q#)k8n{X~ɤpf}+-EyQu}-o݅r)4n, z!UkQm +endstream +endobj +259 0 obj +<< +/Filter [/FlateDecode] +/Length 4836 +>> +stream +x\KcOu7y@nA#zw`{ ׇKRgֱlDEbGJqK}6:տ}q1}<:e0)>;G=SRR>_ )]@AP/ٻx<[7vBiuN ~*kq~ٞug I7g ѤX@˲ghxY~Sf.)Z5չRgѺ\,_;#4j>\ɅIͥlĢS_ +Lųy9ڒ֮)9$w6h2ftt_ioBѠڢ +Uԧ&tf1C6ð Ȗ%IAv)ssYTˢS,Zc)ŌQgVbKPV MHh{3[fZۉyT,f54 PiY7AIQtS=,&/' !_HZ+Rb,Å&7R"v ylXGK#P~xILW +uA׈ ;!\;JeAJhUp"X ntiY)u*]j' й4_;yY4,0T99̋4sR#kO)läQJznF$qk#$w}Mk#4exqx-DREMbP5bŔ4lZĊ++{^j'mGjSy"qhk 2s'֥zXnAȤTDʕTK4KPBNrK}9\w*y`f06| Žu7" +ūIo..]a]`օE4KC|>wd;{ݢWؖٗc.!weQyH5[,n=]9[IQ( o3K+MG}ˮ6-7 + +.'Rl*44%WN[RF~%l_IVI.k TX,6xH^FRm-XXN˳6,eYK 6IW8z5"Y8辛fge!z6Ǣcѹ*iUE@H+xk܀JT{kWKm&bJLZP%%Sf]BX4WW LLMväYc]Jx]DEz\vKP]Whb_6 @‚Xy)#qWUg2qBSpm;~Cf)jGA^=~{6P4\"u3oV}MjX]9Qo*A[/7{ꛣaw/'ASV&7J3/D-fG}i=a}1-_Z}k4 S@8ـ< +)V烇aot_g\,?|}o.=i}x4O*79>i\{y>|PsvGg\ĵ%Q?;lji5YNTDNzz1: 9H(M{.L Qa!H tBdC$hey +0p$WD (R 0%BQZ Jo>e?C0-jrρC2=(gmd$6T*!bCxԊFA)peU :@Cf~FHK9&p%1.]ZXQnb/F_yMOI$nJr\ŵNT +[Ĺ֘+zx-ۑ%JLlzgW*c -QN> MF,᜛8 B tUΛNP, sf#d/L[#v%A= giz4mHVl @3ۖ/)ǠBt.Y,n"芔7+&h3j!g"3b_oa rTҤl!F<&w*<`C ۼIgMGZ#ݦ_ 8!T֔{eMtDxd +=߆uڷ+]%GhdQkܵ[v4r2TrMYK^u.+C'=n[8~/nW6q5 ROV1Iَ4.h`֭xǾnpƇe~5{cϲvk IobrMHltlhtљΚ# {<ٚuozDVWԊ3L)G/1XT<K '''w-iزI +E/KjrLpږf40TEk +C7qW,/Kx'eyo BEtW^^&KѸEV\^GOΘvh IJނ9[vĮS9a +)\E{|%]ClUpw\Gڷ&UE&j|Ї71 4sR3QTʫsT@5C.7y2w)^c*K ST!;5vJIeIN<)&AĆrz Qt/G7d Nz 4kq:" '((W)U30Bd+ u1Pў*707PGv\OhgGоbś 7 [`r` ˼aݥ]`W95]pWhMjoRxv!~!eY?Ӯe|qYB}3ϯ6`߭5DK[; ܫjWA>Kא?Ӊ%c{żZmwVNŻ@{}p-핥z:Er^"mkz=s/( +5-YliK:6IMlr6r>:laұ~k4q}4L4ښHsn̏>F4چg>nAE?! ,8F*`'wb $JF#M.E^16ٽ2[;&c-껨EnvPG0pRMp# wzzKE+4GI1 ]%s>\&#r&9#V3i(\iXwIӒ4f_l=0q7DD6QME䐞[Gt% t~x+VESh࿘BӼBަLvoed!̰W& :eF2@-~9{}ܯ$[{L{yqW?ϰRנFw*Z37iW~H;Ņ4r a Ɨ{z|x$3T}mvgqwxvƉ7p 47#F kjw,Yq_y 'EK,-;9 |{]HM=(QBБoß7|L +E[Hμ>}R?)Xmb-F(/\KJ: oԏB=P%WfTL>Rtj{r&:Z3 2E'~=8F,Pd@%Iw}XCĆ?C_kC: +VsyDßhN>,h5}u ~jed;ͦس2!4ib})w89M~n݁O.b) ³HQ6-żdI?`o~e&4J_~\ +emk#Twҙ1FP<DcE_÷ +Xܼ׽̒G-y!{OZ~xw?>݇OOʟ^ZY)~I+xI>ty4xߧIӛǧIӿxHƝO*u Wjq: +0g7$?K޺?qx +endstream +endobj +260 0 obj +<< +/Filter [/FlateDecode] +/Length 1175 +>> +stream +x}VYo8~ׯG +%6Ƣ@M*,ɑ&_3CɖlAxE=% <y/~8!ёҜD^yQ0 QL}#0F#Nͬ8Ix=a=za0`ha9C$hJgZF27LvK"]"Of*/WQHH!u#>Q8P\&@ldh MsivsT :~g\# Hv=|i1 ?='ͯrăuGIГ:M*(4ǃ20[jP^AEۢz"-F%T4o.ʄ!i, $[/Q+)zP 9Yzʆ дH7Hs$D8GcJQAԻZ01a7:g)Q0e]:΢Yۣ!9 4!KQ:bga匷h{ͨԙ!s(pS-tfu`+ Kaim^s}+gg45F`t,\sP=YRv/ZYNM̜l]Gߖ:%a.>>b_g?D~H]H9&4k-Imו  +mʦّT< +gsuEZMu, +]v5C]֒)Xb;|6A X4+i%O ZlC#ӶĹ ݮmvDŽU=ljʲr 4Wz",ӄ›o4~PE# Վ\-xޥ1Υrx1#MI ꐍkJLiXMܸ:7s*a8Y٬0*!+*-_*%DHM8iWv\ .hh䬆T>B^jՓ&=&i[9zAd1߯SoTbӸ`֚ÕU<]gDE7&W%pJ}oZK}dr? + o|,gy$BR9>) +}M +endstream +endobj +261 0 obj +<< +/Filter [/FlateDecode] +/Length 18304 +>> +stream +x}[-;n{~'@uJR^$6 a2;ݎc#Z3٧ɪҒ(x=ۗ=(쥼קu?[ݞR7燲?|N`)ZcjƳ|? _y;-==SWsOmL=}yS5?e-=ض2ړTSiy}j?tlOvKi?:KTilɇqfR}cy@O!4H?m1<3=xԧ~>8kFk/)Py wgTi?G5&dX;<ʧzcT'z9p/8:0}lm-{Kٸ}Ofހ}a^?6 G]I*T|~8t-YGބRf>WL}5[Hv]d."b4$*fl/ʚ*m)oN؞P!9(p4*Y2 t! ,I̕L(yy~?MXSeU UXO:X<<!~uh',rDЭcx27kA M60׹gqf].S H*N2^N+)U"U)Rؔ& +Tnb B;+􅮪nRr1.oiJ;lߒm` DP 7d YdUD>P~\bY\-Su^Lj-E.VRA݉rނ[m܅ZK.FBrIl|-r qw|Nulo̍έP kQ);MC3vfeМ&M24%a6ƛr̙(wQܙc3g9AY39j2f"o3TʕHr ƼXidkЯ K U^}#O?tRRWo{s0 gEDzƖ|fSaDb t* **TW>QT i/6 h( 'Ńh鯲cLjƭATlͪƇ x(ԫ֛^-Ɣ V/N&S©D6d jl +. p_8@ѡЫlT[h}]aP[75ꀫn"DXK O놊M@ ED!aPU Ês'6*8ީ1^N,oZ3ѣs%NSh3"7DBM\C Jnj-*_EUZpN1`0CoP#ɪ6ȸ㡚=dhT!TF*\XpU*&ꎢP< NU@az.]iP l̲jnљa4HǫP 5hz+u>Ww^JN +Bo+5:%I@4ංB%D> " -n9<QAxf6ʘ4)}t00~'y4N*sA)O4 !|lӐp ͹VwoO]ǂxxxb`AIA; +*}ӏ +Y` kMPO(<#v50}־CVY@"-ZlcLoQG.\S7(ȥV)gg +ei d:_E9 +ЍE]p:T7im7xS2J:E `kqt[޶F v}XvuPx@6"C`"&e09+N_@7iv%¬BYTo0ج@ph+m6IkMeAjy"mprmؤ`Mk͛m` \<ƒFey^?u iYP3a5LbM!(p498q85>-H6cqm@pt@ &~ 8[_;h$miPséxn:,FSy +->F7Un CUOSqcNCE^qXm#@W!\>LQyxvj.w|SXMR[2b4u KbnY58U@v52w?ci rz؁0Ʌ{rt%;.jX,"`ǀq+۽[3*Z%ϟꅻvt_bnJ 4\{(! U^ ݠNFH)xc; u77[F"7|=rJFEѫ8؍8FoJE1Qވho=ĴD5s9HRp') +5T9cb=hٱĸ!qc,>X젉EQagd eTrP׀|OZjC Y-p^>)izjbɰŠ}lt]Y_`qHD}Wj蛄O,Bj1zLR ; ;U F FATǥrLfkEóթ苃ݢDSA<?a: ϐk ,3jucYWуC8"eX-Ct ghՁ O$B# aI**b]jP05Ld!.㧃A.1W4vC kB(5ncHakt W$Iv\hZYCnv B[$ EI-5XVZ w^֕vY V=3ٲ ^nr~t[i]􄿚Uc.ov^jVv[ڧ.cORYv?ËFr;9Ɍ|"2!#t6uCUNǒ7~P܃1DqV6Ei? Ju#x@MvSՆtK|`V ~@jm/-sd8r0b+@7 tq߾nwɼ0MD+S(rEnP4E@45vF`48:, Gxc<SG pJGC8fV!M]GhKY(I;hʦ&C,_F^ FcA&!MEm,^0rlnHR6$gԂIѤ%MѤSHRͪC$4+"IJb$n $)JLDRX,΃Œ":KXRN?IcDҜp2NO5>%1s;1P)Yt[ŧ#=f|JeǜːM3f!Ѡmh*O9  /zx1zD%BUXx9 [#WjHMzx%˼=q Iq$A8^bx?Z3q]95k 66&cb<æ}99 w2l: =ν_d(a3&MDb-31,]0-juCtڬhAcF-`#FlGո2=1Z:rsHX[D'+|6z4Ibi<,'KaF[SKc8T}й7,i\,1|C?m,sr,*UWwz8ʮ L:BY +9UT +½kc$cmWauAX ˈMY5 +XC.Øͼ++z/7Ѽ9N[aHXߌ eES gVԫwO=ʦB;Lںα zl]V)m=ECb)g cTŪnHk#WZg+ʽS,/ټ~NS"v;‘NW +"X0MTájи/!ARx̕%\ M,Jbԭ`u-A1XLn(oS\&д"++8Xhe <*Fa \, flDCZHS k<,i%&JETVW΄3`I#f"*=zwͧC)j2Q0mլV*HUA̢C0dDhbSxB|{#LI3rɽY5 +?gPZ1_ﹰvfDir3YZ9^GHE&Z]mIIMeUDV/8a Ř@bKVyzY +)=mUyjk嵩LfZYBb:dž*Yj[Ud&=st {@^@R( 9d%iJ9ZP(mGH9t[= +&hl/Mo' / 6 Y@ي1y񠕪vH$P209@6-e0s+#C1 +Q A9p9k<0@6R_b"]`I(rJZ) iN6C}sbn@F +_0SiBQ6'JqB͈[Pv)Ny65>a: +@!?|% +(T05މ`en޾Y6FݖF02G07@$AI1{W +Q:ۤPY*H+:}s]vI=Rp +?⇙\\8_N7&煇Qe(j便_.U3e/fNگq&`{f"/jG?IU= p;^v~Mt3G\`vl6|SgCUBCagӣj.4VTtcȸ-\-Z˖-rGi6=n);HNR/Ɏ"+ROo$dCj==B :Ѭ*gJ WEvMGF.9K,uiMOohG +> _n+,j,puBJ/r"R&eߑ|_jk ߡ2`~w'ݛY&~)tY_'E7H2bz6K;UԦ~vLSӵp1`;Lʇ+&y||6WZ8#WY4$V{˭rޮȿohJZu,9ᢙ,U c>OMlk  3!o!I}|Bө<OK?|p>>|X˾/rvPe2Vy!2%ʋzK`K-E1.X]W=qRPRԨٓd Lo25썔HcT$C )2[_^-bPlRLO@d; hNgMOFoaAV\q:fdTG3 bϾw/gTt`@w/#6Q~ZWVS%8ia>.R욒q0Y;Ji\jLGU4LV&fu^Q<.Y%,`?XV":`ڴRr3zDhm(q e3*KdId_H '9I +ϱ1+Xy@[4VQztUQn%TJJ\M};!ރB(ů?=>A4:5z.LR# vkVFَS +S^((:,cPf4%@w9f?Lr"T+(-*ծ`$¼Xad_VY-2*?$MDU+4Z*\b[np]=6hm{l;>D ø I:?z@=#ĎbnxN]CFc3@Ma#M׎60;C]7 +H?plmWa`Й7cu*ޡb ev#2vLîejٷum!z +i|YjxpmR ݋fQ2]`ZkS +=ۅq_1V@F;8϶75 Wi}zWSY +Q&ZQW=nm4Ym75( [\UC O 0nrèbܪ3_^]t*x"W"*B㿸E j5U +JízOj F=VV_V]hO}V)74T2` $~YXi5<.wt>k5EG=}3q%J3YhQK!QbOQ16bgR} +@p.^|O{@}a<@4~Py4kQDvYUOo%;f?Sz4z_a#epSjP*ePYp +]]%* +{} +8ژ&wGCxڲGCa1HĿ$fk,2+)9&*{Cv_kXY JkւXaOZ1NtU +Du{ _isQsk@()&LQ+jK}?]8Zq׌)R^hihcF40bU!nC&C.s,#HF.3Nx{hB1 +byi4Cלc:ȻTx4`B\ 2ZBUSV`2u\B2Z49/1!v&x$\"M=i-ReB#\6HV0F.(@+rq:$cIJ.Xd\E&_l1`e-?! Ҧxb9snO1Gt.)-l-}F [cR3v0Z8\:SnHE'X0㶝qďyFQ id0 * Hq b9Y6Xt#z̮e%,3 /]sPfOt +LqI0qRpX݃бen]JXge_2y tQo ,ƧS7{sa=̮',Qּ>rC)78<48*c0d } Tne ?SYr#e|`>M KBuhJy`('0:vu*RX8GUS4`L@ E٦h}Bx i?AHeAXQb]+2btp5UZl50 LSO70oMUe,6ƫ{7^Ggjc~SBa*ôEue庪˙]WFc+W8=q 8 UPߗצmK\o\_Q~wxsnmZbWݜD?_fוm^Jk:k#%܎ŧ͇p+ np8/jPP 7sE|y5 +B3v=]mӚ°,lK;s݄c{Kj֖\[1&Ls caq̼U#*qsrq՝دvFA7RJ _ 2ߠgSCH_ll@2y_>clI#nwq F`DqL+!2[G;爰Ep>[罐vӡk@Ô¸탌toTo]kt;On+f1AzGu5y:9Hk(e?]Fʯ30bP:j-_1*8JI;"y!O""@Q~ԔPj ҹy`*9Jc8M|qg_q|0zmݟS]Fώϐ΂u^NR#hPsPM4CRiwF0DfKGjW Y[W%P)7^HZuWX+?5GLi:_u&7>\Y7fKκEHh߬ +m-H"lQ AQßc|Q dUeCX#??,gO@8  Bl̻NeGXN4;`vӼqr݃{-`o&.rnjpsձ|s zaxT4TEx7Xm +--Mhhगs&(KػD~t0OX˞ʃ쇺mMҺN^4RBzYY6$['@@geI9-2ă7I,hކ{1Sjo>;tZr%5g[U +Z`yvuk2ι; ao(%C/ +N#ݯ/F:o~TKȘKYjS5 ЄM}t<<] %pҹF@ε`BuJZ*gCRyBCC0V/Y5ڪu|zߌab> Kt% \b\[KBe\iH-da2G>㻣Zc)Ba Z;A^qV\:a^I*Nv1ZPDPЬ`͝;Kahfg(ǦY_p~ڷ [,Xc'S8~Qb;y`aUDA Mh}ud$N_9Z>:ό .X 73oA_, +^6@lė^A*gz!T7xHsGc8qIfT5XMp%4B®6H+alPJ>`Drv@$D&V(ᱴY/]|\fl2UaGF5?O+ +X1Rg)n9=N2EK9fbp>v UBYF؍x )/0iũbz9EAP< k"BcU@m8!b4fyq|8 Zô~,fzhtNkk)M倏yB~=//  SOӦ+us: lf JL#2Qj!(` mL4u*}AGᘒ̖rxʌa'Q)eԬbC&MϯȄ{#i]ش#BM2aENB;ҺRǹ +{ImdʻUWЎpOMy01Z4|Сiwt1)S +!lp~@QE&0S6`LBBK C2 ΊzqVU1Xy=JNhj spcgZ&侥|É:hCjɫ^1%1>b`ql|A3Ǝ4(mv9$0'=xAc1nɕZӂ*2j1v"2cWj k|Hq`B[U4X>cܷ(9nx<~oXP\u GpHd?öE@yjn gG^h7`Tp>IvVe_Wc-Nt`s N9=p"B[90Q6`jV@vR crz蟀j}6No\Z|]W^3ie5N5݂TyCE@ 7Ͳ#WVp =Xlj!7= cU'5Znnf_,3z.WlMU#6a}FŲ-8E +mYq :j5ғFyT"b2sF4ҊZ&weJ+T-Xn 8#ȌrLsWaId a XP +omMBv}‘y3-b_[.\V!JtTrJn1%]'ױbTU0qm>$!%"&ړ'@8C?haAV %kએiu3P(V#2UfL.WyjU9;0~XFTVapRשǎ9OڷJ5Xǩd;$Q$h5G 4=88Ɩ ^o1mJ5/nZcR5wGU5cXNN{SDv!n #x }-~G-)ƞڇ껾*յ'5xɎ47wqbEEzL81+b_H3Y^''ȳas:Ꟁ(z?KmF|leԉ?|K*~1U1G,"ZWeuP[- xrpNϛ#TS!fEBfK:i]T +g +h+V Y!MUjN8ޣV̚jXm0;<. ǣ8p+9(2(mC#1T=ՖCVoAM6Uca`yhYwLa~I';%dR3x*uDՉW9Qq!pV-'KeBWF1 \=HFcf?(r. ޸<3Uf0oZ߭VLYUƋoճ{ub#Z%fX,wsq'r6R ek83fD^?. +ǟHNw@ ']yo۽~ yT +:cFA]Gc +Ӄ= cóZ{3MBOX_n;c [#nV$LZq߰ThLqfG YtH0WdPe,``_jHkdy]xU5~[FO +'Fqs_X١VMOu%D»F;V#$ N([63MfSZѢɛ-1X0"F/Y +ߠa}7ay&:\6vB+L1|N3Jd85xlebogāW,2]ٜCJe]33ɰ +ƿPxBA׭5m~VKuHLCҡAwldGL x DSmk}M]l)2~3yg (e'!ɨ & +MQyG}rq %!ݼi!T@VOmi3rw>9V>#spفCbOzxP:=$V~pwf?}? +endstream +endobj +262 0 obj +<< +/Filter [/FlateDecode] +/Length 8110 +>> +stream +x}Kd7r\^>g9=~[oYr-È ɼU*$$f/(Km[-r2zk~oK>_Rrݴo[or(o^ZG[\SR'|wi1Vv:>|N$tb_Ǻh4i6{(mN$sѯ)$][R5u܂ĤC ț%y([iOܒ Q.02ۮc@,ܴ>~%ݲM,j},͊D_|/F惖cە Zߥsە]Ri_@5muZT2Z,ϊrrl3ܶ]YisFnѵ$YGn[TdVSlkMLt#(5qlJ]ǾRpFV)*ra&̩7L8[geI't7&c%;FX7,]& ފ""1^7֍1#[q,8 +豩v./Eg2۵LȾe#[G'`ڪ|tA$ /cխ&kE E%q֨B0m칀0Ȟ ؅Av!iMStJ^ZJׁ! +w-J@^FQ:C(!w%lmsIVb6E,'1:Ĵ E i@!Wc["!(ijM )*t!WrıFC6 '"ST4aJP.c(IŢYű6 wW 11 ,'.3`QjlM4^I+nͺ&RXLd_&T_{mgĄNBKm+vЩNYQ9a-$ 5R.3@+ꢀxO;2 K:n0T}XM _E_r1lr_'p25fQjT ++3]-ؠ7S @1e.i٘ez[ +Ff)>NLLlDjdH.6FP17015Gԟ6qܙ׻?ν@3%Gۮ`;1о63 0' f"*Dz*E VM)0Wݣ˧ h\x_w+ޒ3D%ك +kuDX4AwfȶwO[赓 PwuTbx)AkËݏ*$d2vO:`vG\[cmYڛIn +o٤4/v٦ w]prԍ!nxPF6<%Bh&QkR(ї4":bPFbk#oDM<Rٴ``: mD*F+JlΚxJ* W٬նC6IfI{c% u%m6۬ I$j;x$bUzI#EhM2z, lKuiu펕bBΈ. F{4{lKqnf,42,t[3&mC7WxQ:nܟ[CJ^BXa,@{;ңWXo7u̶z6DǙDa؞[3ˤg3hU`bP̾ao-2&QlR"G3em"S-PV:*nmBv$7q0) +"Eoc +C2 mSVv 9͝|ͫaURŌ H95 &L8,3йsmEe̾c!ss|G̒A%DX!FOS'jD阝>v)bZL&KkF)"jCQ mIb\WNm2Zٶ3;MWV y `Ē Ab+b Y sHf-MRr~ g9!pXGlu,#Z=-kk9"jv/SV7J*v{apdixYz¬Ig!R`.5ֽfC\id3Zg&(V +ͧ(T; +ZžNl儾G|BQ}?- lUfN ]-ĊJnp}Ǟ_b:@rBXSׁ4 [BJ8{T%u0@0m`< +OzрKmPCZWPAуH'njW1O e(1#G0KɘXeߔ 5ʹIlq `&eDlq߰..t-a dgqՎ,6$ oweXX=M̀FK@tbPC"`7[ ~9wa8H6#47Gm0b.`!*BCa 1̇[w[󎀫FUrKOPr5man=mdw0ULzu |pȉ>bhPC4h'c d25ΙDN*D:b)VR ĔdD qOCq!rg!&b@Qh+q7L[jpad\VWpj1& "x'k'Ø1.gZldO6o2ˌgU.3T$laGM<E*2⼂8|a<LhxrCtXp|`҃؎B3#f kf!I&“N&[lG8P +Q(.F\EWeHwE{ +Ne*ba~zEs@;0hŇl#Phl)q/:*aZ4QX(byOCZ#MʡYj} GQ-mblbR32ʻBHs0[kJAZݨM!fFF#5!;dr4 &걜!靑Lp4I%OQCDnPd(.؞,q$kD04O +W# +BƫB3-}l^n6$O h-^Liλv"CaPɎv:]2 fh ;3&$lޥT53قpFOrN[ea#tG 9pde<=sCػ)|js3Dh>MdnG=)|Bx08ذt +,A6!S`9tr^N(O3Lq +Z%oī2}F03q*L&oLKKr^MVM@^kEd5zhyJc31jDf[kC{r1npNf;D"&Kv/Y߇Q./Ŵ[al.nqN[*5oN(N̩e:Ƕo+k˷#1iO桷Xtn躬b;R6<>ozII#8GN%NICG*; e+cs ḵ;>[(NZ{ +aM<7} aCPv~lZ{,{ +vn?b +CIV LcIցi|D}iv܉i'i>iƑ 'K_/HZi~zk),1xrtKMG_ͩL|d 4_~14hlU6R a\ڭ9$yDb[qE?h?NUPi|=a=TޡPFI匰^;%Åj…gDxAQݫZb m0G^`uCƺ=z=ێ”)C]8Ybġ,7bbb #3;~&7^kyA~bX +V{喟WPW7ޑۓ3|,-v7\*4;@)^~⼿7ob{ 98->~3 I^ȫ5c`?BD+Tٛ5- ᭪jnr%2%h*.~_[f$$̂&oICܦ.SVf_&c͠ Nڃ aګ/pbu ~[ iGue1N0HڼO>;y [hɧO}ѫY ݄ctʔ{[=>tUmç̂5#&i bT +x@@n&t KdBBAE><_dH'̞;a$z ⊼%Ȥ=K8S~Fq|x}x@ +nCd҅m+fޚjU>eb7Q6IΣ(%F>щFסBQґ$^;JzK_]JX x㯥Mس*Rbd%˦]0!j&v4p#*!jQߋD%.F4,6mAt_H8T ԯ +TLEK߆G E:Q +TS|Oz*#ydK)rN}) M0eөz ",I'~I(.apyi1À[׈?gru3qaѪ6V!_xU_G 7OU);732'1T}D FXV!,x솰ԲpëC=~#Z6Gq6>$KUMٱr?3g1Һ +%q/ |Zi['ϝY̺g 6i? w%y:RVnݓ |\+`"+Δ)|ȏ'ik+颶DؙsG,wLqڒa+jWǗ[Y1MTK<?3!Z; +`2BS{KK^vɼA9h@#RSi}>9^l&g!&?A[ft=-yheoꍢ|zELE_ YD\0e> +ZQV,<*Vre;P"ͨ.E/:f̲Tص[3/f܄ xr°|W0O;1[=>NI䱛IDgPMkrN^-LS̜O~_v9Â*E0+, X)3# 1-PZ}6J0j, :s+<{{[%5,O-"V>Z{go[=lIt77վ VUy"e)K<ٰƉt9σ-7^^|~O5 6ubLK޼)4%mw뮸??2Ty+ # x+vz+#kሐ`5 <.w龘|%f've_im.njy*ӾE4W8mkr**u`S&?eLxt%Ds42==jD>i'emiIny\>gtQqaÞ?jc{GDGAAYh%)aMiu]{f$&)ƶH-t+/F]d>g,,lK CEܹKvگ̒NʧI a:w^na0ۇ_v9ZLoAx uJpU4Orx~N~wˇau"w_ ?wCݼ_,\^?RzoyNx(ID!ˑ#<-Ekd~Ayx +bkY֐oák6V@m8A[]nȽeA3XqǏ%_˿fth/M}Q[:/6j?~nן/w-)e|# ن Z8N =&7 nIG__m3_N)vaE^H >[KZgsO`]W->&=V_VYX-(C0,6 u CgӅl9n F]Q++kóƿ t+|nR75Kao!c +j;iמ'uc& ˩SeL<[X,TA?R2 +endstream +endobj +263 0 obj +<< +/Filter [/FlateDecode] +/Length 1730 +>> +stream +xXߏ6 ~_G}a}Xw[k hKtwN9v_?90k&)IW$^?D"J)yפ7:ͫeZ(+L* +[$H+tJ uN@,OL"t^:CΔ$9uH 꼠Fo"Q\ġBl$ au<#FWx#h4JVTQ}P)35+(1b^R/p%JbEQɕLsBЕ~|dVh@EQ*KH + ٔl%|JHT淸.~J%jowu XǍX 篚X|{+_źlKPH +!0-Z04ۻҠk0Wvtۘ->D$*gOU|J>ۥe}a7퇺бa'*Mw]\[jD(DiE(J x|V%ۻ`o:6;Lp[_UTCVD +U4QRJ:1T)K=XV[ɐ/bixw+ bBu-{YZݡG3Iy|$ +"aCIx@KOVaF;-#em~f|7];'p[/׬ֶa2| @֑-r?N2G\ $`}+ s + x!݀"<6 s퓇H 4[vďn uVe%z,%t IJkѝٕ$v`M10fzgX@l\ۅ,-bq9Dc" /7H]]?n[S.y/oV+I+Ε߹.Ngs^C:'l (׎[ðg`6iْjR{oepp55;%2y5".pA]weAF}zO%R9:ЎgS:ng+ t_Fh.#5Ƹo!3ߩokJÕHDZ = {vسisgv+>M%gV ty WW\~ma׺_> 'dѺnr^VnnڌUQ$q3^؂k:xAoڤ)uma{E> +stream +xڭ}ێ$9r{~EA]8hk}?m籏k6Zɷ#ݾK<ӣs{$#I.Jgj,.C8-Q:R-dWO VmѼ\v!wSσ! lbl>VN{=ixoKmCo*Q(3pbq|m q1>4@Bdޠ⌾X-*Hc3l}`r2:`FyE/=Vzymu>q݋o4+o^H!/ql7ƾWκft7@B65ld&}/ Tݬa5Y9l"c{g&sЁ6dTpڳlGI4%ˬX|G ܲ>8dcVzy|>-GuR%̳=/>Vr`-bQ[(kɢ"e`ώ}$m$ $sȋ}&}6rY1dߝB$weHX-Pjݯ)`2w81 $OA\g6H\$g“vU!=H}vEWlP:C4Ju +CkM~ϧWze[1Aic38Wcm!iUSF_@ l1p^"*$[+@ +NT(;DpYv'Uڵ,,NԨYw?6F벃Xq\[b ve5kGW¾dVfp+ raT: 8w9k}(1sPasq'&;ŮNm X}/ǫmlBC߀ $UHN-P 0D+>]i}L+Ym%i `d+IB5%%kR=J(i7*8^+Sd(2bݽMt?Ԝrۏ'XN\I?) .]t{-a{@M7md.J{#s%wɭ-\Q| Ղd_߻hNn +hK{#@$>Rk Kw8Z]UR|h@v`7RRkNPq$ 5 *a_jrB<E +x\QYƲb]&"dgL/jI\kU!DRRoւXXkeQ/*,(rP/Kjz1) +0kJ)(Bif+U@jJA@gޘ"բNSDmƦ+,Y׀aOHA%ktWև)AY4&j$*̅Qh[)Z(ιFspUl(Abg&jr^y!x֠n.k,$b XSKPhܙ|yEuhuq2&[`II`g`E)Xi{wDZ%$w$S7ϕQʴuILS鰆:1\͹^.Ŏֵ 8RXHu,E #aa}o]8M]-%wGe/IF%L&cJ$,$Tva$䑨a,kTر)CilܹCQ:h xЊ2υ}u`x;i٥}YII;gm쇰3t64ef9lgܤ7:wjaeР2 9.H8ΰ "< ER3㬡46C?cy'yOz@|MJU lƩj :k +qTl ޢ̭H}+qG)T=2I7=e)SF! F:'Ov\Jzh ,O]]Lf}Ipդ =Bk׼G;hy]hqJ0dЀVE>9HFP+|~M'Vvyoh;[mbKa$ok{oFpђ ~iMUDwl h L؝uS.䎉XЁ=&<فxčuzxm/t;7f8>ݧzt*@]&M'{@yZE1OUG-;{ +Dc$W:{brarLVm7XvU$h6]Uߑ=;.woU+M](ySH? ~#" +t]m1lF+~ +bD O9GE11N>a1ű}ů:~VĸUمOgz`{>4v@ʎ_e}ŏZJf?[_=9Rs`2G dcv`D`ŞސQk2649ľOc#([ Ldb??`705?P( &#vtЖ:RÞm{TR<9Nw}ȥÐrR63@X03a1fow"p D mғj[87w3YO]q +uɥo7IdXn3:d3iĔ4't"6Mp,N |3s6C:}qJ*^&& 7\ޟsntrSna5h0r{Q3 rkKP}<_/W:_9F H^sR}gw~3,O7_7 /o`x3ĝeCtQ~`}~U_fX{t|2BN)W̕#w~_g̐KgA592[vJ?Gb~Od1=W:̷&͋[ $Tii +@[-M#w6S\kwjGa&37#Y0PM@agca11Qᩦt@XZI*ht77)81SV򨲇#+8Ɠ +r\2=SN W0m6 +DKcHrJ iG: m' wK$_,ݳcS,G'!bZf#|#*e<ӂi5#[}>ᇂK<]Y`dZ ՅD$̦u}%L`fJA%H#$*AwvHqA%fDL h[](Y,&TrA9cX˷H`9^2@kV ry+L6dEe |,nmHo=BcHuf11-2PSTrY7=jS4_*): \͊rS7C +_ᅐ\o&GLI)fG9]МVՔSvh״o״vLpM;HAXIT^Q&nr2 +l/ڞegg3..ݑ>Twx~HWW\p7F31T +vxS:/uA|Hĭ˜?2Ba :1GCWV93OjZ8騏|\| +%Er 0/yƞ_4z2"WQ>XZlF:ԃP5Q!Ci *Y z6(/C8ݘkwwOPII/;q}cj^+_kz2Ux@S +O{Rgm+"W?0] $_gwy\!TP{;+d*o>KBVJJǤz:֦axzn5[I]ξ3-Ä z 1L29"p!8 *)KFɚџܹOzp<$:R7G4.])>a'{.K/QX`543޸˅.-<@]M^VE•[hBK㺣 gr I"=& +SBh>̫mI^Maf4,H!iAOyî6l\;ߕuUY܁㽹NzVV} Od7i^!:eUd u*DR hOLDPA(- ~Jyҷ EWʦqYx7GJyH+퍖bTrqEGgv>ڟ^槳] +=|5la7IF>i&c*"diWGGth?g3wP֜x + SAG׮+*cto EӋJO+N 1SѠx_M`(QiGM.#qo:& -f-#A2m ms[@l&Ҏs(:'dM0͒ɉm f"J'Qٟ82(B.]ژkpi4Pƒ(ȼb1!uʂH/7բ$Y&\#.<'mZ%CD8X)n˜t[jbm!%9N.#@=ǫ'*FS/GʦkJH̶dth>f.+Ըr uc@;*>Q8T:ݜt~d)ɶBz[LkI3:pK:򩆼@/Qĥ +aܛ+筌٩'"f 1{4.S^.8noex1ݼbI|o!:h9Z\O$T;>UTa#|F>"QBf>x Wy(yHEhi]oo/=Y߶O=l{|TU+lw.N4Wj^5@ceI; 5D #0 ë䁑l88I}=3@tu])X(DkY(֢0V,XxO3qk+ZѬ`zG|a;/\ ym`~,ǃ,/8vG]ܷӀ¶p6ߐq:@7Q&ExwV=:{@`uOBf3U@3oDK?`5c)U<5Ox;NI']Fp4)FtCDR#,6̟x'M2<%- . *OPY/ PCbrS\Jyb@͆A=#0zL4'(Y#=/⑞Qcz^Ԥ\vjq{a^ -:2BUȑ&/;bz߳+a51TآLj]Dnd1%V@O.mQ/;j7HRB'BfqяIz @Oo)LU4PY'b}caiF,¹Ƶ|[k"~  +=ܢȱt, ~yޮӔ!ͮ`g+2+%J˴u4CZf<ʹoP#ҪڳS=51s@1(H,-:T +,>| ٷp;b#~mWY<4EW╽3{IBʳY+=u=ZQ'laѷwRWsW> .D"SsJ!ƉեrS㝮IaQti3@MP@eih} EM[T>ٚznRi b,&{_2Chޞe]W]$WKee%-CT",,TTO8GBt|g{{,{Wsz,gѮ孮գ7O&. *LY{T.Gs,cnnt!>c9^ɋWDe_xl^?,| +9v@xjhdxJh @V-/cݟkB|^0Gt'RyUo+>;gYsą2pl8/fH96u&f| 9 1whſrK~ [&4vkB? l+T+'KSf?ȔC%5_TTl3Iљ4Raz;ąi@W@Ҷ{  Bۄ>FtS k3c\|plgۅ͵GV^0"9f͐SW | 4}z~]AxBtdOaҙd n7ydhFw.H +y=GmٽyZ2 Q"]"D* Pk/R7ϟ# K&ZapKS_q `KΧУ< yޯ-E/Vݚ+ /3!`GzA{DY|b@τ(hU.o, p\џqY213x18!Mh֚Lrn0* DzجMƮ+p"HvZh:s,phy͎QO%w^\@3Zx-d01@PrUMF +q(ztG\~'EWI(ubjd{Ε5vxsA0 lWm^z^PRW{9=GԼľoݤiQu<-!^67]!tmkهxt. L!A700# KQQNEߣK^B$ `$yRDClQqFJ؞)%`WÏ[0../D*l;$R 預d9Db(1C`vdiY +nO9ŽUT|+"*)go"K:L'h~ +UZho :mU{,dIت-@A\K g`q۫JݭAZ)ˌkȈs)rlDw +/~Tglw*e&%WCِ `kẑ+9Дmꘃ+A%V :32U+YY&w\k B[7{'yCkv>֛=^MGwHMu07[./J GN;}zC7\ox[ (Kz&x4'Wwu +endstream +endobj +266 0 obj +<< +/Filter [/FlateDecode] +/Length 7214 +>> +stream +xڽ]K$qׯc,̫a{,0 dw!͈"HfVUtvL2$&O'v?k+]R=rwe9pqvBjۯKܶ#5'o҇iIz^%m -R+RN?鷿]\l%_Bm}] +#>T=.\HT֡]YVɴ֕۵e&ڑ>^jjKXaZ +z[ K#F;1.v)^|8/xmmir sV$XvҧQqZgyB D=ӄTڧrԴN^6+1>,hR+i,7J[} \B[}[)4@BC-Kۄ,e(sZڔCLT.CQp-8= +ϭ5h֊+pLґ*Ǵ2I,mT7Fۀ_WB 9 Y +A0V*8PѨÁ<"t +!Kao-U.LΥ`ĠT1[kLB*Z@D^O+, [68= + 5[t;hMTgPe`ڧ1l|gA;j @HLW* (s c:.}:^n {qu&Vg;p܊st]JE_H&"qQLmFͩ3-K\|\ءVNT ~``qjᡜ VqkNv +8Y^[L*-*ږf6P͌ȇF`:ebm3oG!E]"Pc,_XŒ&d&vhZ1r&L;BC|L9*o6_!?F>! (4>s+svG;%1KTZMk\UZϠC6SiⲴH_LoXH%ҹ7L +K5⯵툇\ ^9Ej͕0mr*7N "dMX7X^$1ȝTK|IY}9x̔ZNc~3](9i5u0jT?>$e-hߵ5㕉k1+ S>>*Qy+!Q_=l>i9ESRE'}ØRzI!Pٍ@3l6@kq&a1bE-򁹑_7(4PD>+7& iӚ3rDYU*\]7jN,N/Og؍XX93#i __A e愤)6y\UU|r<19EUIցgΗD B;j$}WM/$S˲,r}i_E8&_DE#7 ēE +P큵_#K^bT!hJI'*QC]jE2Ge/Cb웂T!bAEȗ(Ԥ =h>)zQa(9 +1UA9Ng:ms%b"5HM8TDh F\ +Nf W +TJ_>V0ө!뇷_V/IX}Q* 4{5UAFm&|IB{^;O_c&ϓԖ{P 7l^PTĜDa8FhƘ0_CXDN;VCQ h9wgHz(,L(\J x'DWQUnYI_}UHt24iɉo*H3mO +J􅵍M|D•ߢwbY*U"KLorgM84iئ3L]6)`XR-6؉(wADȮNmzk:nrdѓh6"=5/xoH@]DrpnV :`(0c$/4y+q=e=*J2+MaAPP t<H3I*ɉc!C%WL#p=5+lؙ\ ߽ŽT4vn@rD ZVN/b"ݗqؙg},i뼢:D:%@P"<ַ߉=`ʪUaJ ~EgC~@}=4 wb`"hWcOV^L;ٶ3;kI5q',>wg/%Fj7RBa{k#2Eoy ˨$1*AU7D~4ɌROibGv0К(¦+'T%V `XUBČqڅi"0sDjpX#rfiUR W1rހ^衪IU1!TgN  (k5mG>u_.9YTJc`עd>wqLPz0rB{^2}+䘱2dawu'`M̅IHZ%\墪:B@םй\/𪷟ASQAkI|QfYEYPA I=R;%1On`/ߒ$Ro~ETEjȜE5m6:uazLKޮឝ)`s[؋`i! fK4qM֜ѥQodZ.y +%HX&*ug6>$[lk+W\3e`7%Xȉ|)V+|7z,mSx3!̽(]oe铔\eIIF>p 84LVxGZťμ[^w]Tg+wFFՙ< 9ˎCCǝ[LXLbx7RΜg@-ȣ F4Q$e=*SQ/oNw|'$1:u>4 +tUSY- hp wx#K:9:亣r)w |_r$8l@%էH5zVEv V +ƩU[:ъKċcAZe'oEϲUii 4p^g8ׯEh>G$:a;ic0kYB!M3/CdFQ l+ IfLC]% ==:!YP=2hZF4.jJX7䴢mۃ??c4a%M(`mw^ʞjn@%[ғ0<Ƽ0z~w"K[3ã+/O[X檠6!:Vs(Ǔgbq)U~\GluZz 5z3{΃Tԭ;4$ч3;:O) m?[Ȏڏe?Nw܄qf襲;:U t[łۭ1IFon<Pj32?ߒ3xTb *(X!F HM-6$$IJʚ)#bcy$:Ki2R*՜nTEv@.lBs̔qFy\*ls[z/nHkXq0tBS/Fzv:MCs4.TxZ$·'?q]~K_M{I ߙuCC~ӌ/W_dY bwـǛaN6myw^Of- +P;.nz"}wrQeFk=~nR_4!=`הBualj:)D5 d;oVqȴu%6o۽ͥ¥H|>+3ZV{􏧿gJGhO//?,a}/s/˿}'R~:ӧSSgJ0*>#kmx7߶͔UM:qNJlwp!čf;]QY U01.:%0"( +kq7U Iƍ  D?E_5wߑq[9LX" ]$HAgi(/-\s瀡a ttIFb^G`5MՊ=B!Daђٵ IC{Q&mEBΚ2Bg0W]NhP,.FԒcMU3c|wHwWr+`e,%w vK"#,̘4)* Ur/ cKX#c6mŷC^@>ʪB5NvoR PnrlEdQ8।`.闓. W@:2W0YޮT?pkgLJRtڙ[b?R`'$-y&cƷBWNRײqB 0N7j rsPZ⬺T"A-,9\VpU+@7J( +-[Olu0a ?_Q!$T*> +#cҋ^}(*(|!&8DGȉ)Xtk6"1x + +q0 M#!=5"RPT.hQؐ KIHr%Kق< "4Yf&e~IɄ=+pF$ƬWs4Ba桿xDQrLg!\7q." z&Jq`nЉ,69cs>##h)RR HMbm,rKRn/ݗp5u/c2[Y+aMFB?2n0ܑɦǬD m[iܰc D +޴¸s8JG@0ooL\w) &Imh0VНM'emNѷX=OVB;ѹn&-w=x̢F%7LU_ij8kG)o?UŊ{/N^摜[G-)oSb?sG+wOk/n-:(V)vÑBV4p}GvvƗ-<N~҇1]%='QwSzK2䡇3^Z֤b-+lԽ- ՑG~(7K%ӳ/!a] %7ښxz@A 3W{ZrX16)n||#zq}bB!^# t1Tp2(P5 i..Cgqg)S/*(l}z^{ RCXYKL/wHR>KK9ng1_iRd2&5#/o1(h]CspV7[lE#"]|ګ>Qg5c{<SJ.xƑQU=&|G ( +ɍȎH-iDž"ٛ蕰"CCC`5'=q7ڰ48|aG$b~KN[mVV7WUӘMէjϸE<@,uۃdx^h#=(BpkEIAW o6-AEUx8=JAx'M|Џ2@p-CHe$KUsqb@_hU*e7[mX=%2+S+ +JKXH;ȶ`EjבruD zh*]/kիsT=d:$1V:Rae ƪ]GRl":(қ^rZm滷V +JRLz-Wq:z{G%huxUs;%cծ#ĚXxA{5[u'VlVPrrz;ד»06 ,+:KSoJ +"qNC+#ͭw UT {#,cccu63+?+hh j}"6ZŤt=$y_>Dǟ~?//ItNK32<_&{~CSz^?_r#_,dU&)S< 2OUfR҇'\ 7wQNoO|1 +endstream +endobj +267 0 obj +<< +/Filter [/FlateDecode] +/Length 10856 +>> +stream +x}ْ$7r{}E>fiI(ֺcdTaJG[j!ģO*YG;< +xV' GPnS:DIe !cqP#1xF?C>;fw)8m +Ȁc_|S2G:aZ˘\ k5ѻ4BNt-˿S m -B5o#61}8 m +%Ls4zS̻cnܠ1@n +Z:L Fiɪm_C`3^cD{|z +ƈOp;yx +h(lJ] ꥭI#zڹ oRnPW4T,װʁPCxzlO(NՉ)JaJUC0O遤B#UȠ2kjE:H xv@>`'o5сBӨV#'ژbT34;y=&\ OYJw`"3 +{{Lƽg&>BS 7X$!L%B^FYX"p@\g^e,mW@",O 3SР) ӵ>q&*`[*#3|5팣 J@jqvl{S +I+AO\^ѢؿkF*X_8z\U[AX|Εԭ- zxI@/c}QA8?7YuTxuzNWKzR6+#x g:YV Ccb^V7V+Ԗ8 `•qDb}V: ׃u~W:gd}ΕuL 0/W@b`M׵*zib)*t(lUmB-)Rp[r;QPCa֪6!IZ/VQ-jԠ(4}\: ^!H +";iYZaEAOl ZyƻeVc[*@/t_XaR6Ba߂N0F] lYcw74LWb}ݙ2 /Rpf,doS:cb'-]ONW^zFc^;W3,T0^ E퓻[x͚uӷQ" [rɅZp_9`Ohy]l3$ȗW+56`P1m]\Db q!GlA/dLHc1RB t0y#G.sCi=QY{uu 5ϚCeL s8 + +tRCxaYq\^qf&'5<[5(p4K^em&gmW;7xbmtnr ]\7xddݢF7|xb[iz.AN GHyOL%'fܦ@Q{t @ ۂ[C1TzEy3`^#](bg`T pnjRz H/ؑ~_9Sk[t ߆P йҁ dIKw9FA ́`b=3rPEV9]4L3$=Z9}$h4$\'7Źuq Z +K@0UrU{ݦ]H=GyfIrmcL m9Wa}vs}[#u[8pk}v1Oqp?~^s +qzm4g5lC 㿃p N7J g6hbp58C s[HA͂bWPvo|5RwöH{_xa7_j}?vI?T۴?]?_7k_?CU}fN|IRm(-M=a}EvO/ӗ矞~|iW1hO Қ: M~qjG_z?~!χOg'b@g:xOsVW +# u??{ "?=^|Z&OOf]!c V&0HAeŠ#V@ ]#p'<(^1 ~H_1)<*;l݁n>@L?D |ov#G(`|:'3.Q]v}xxx%DsCr a=Wr勶+̱qo$naB~apvo\>>?[֔j侾FLw0 +{o`ݕk幱Cxx5 - WY鋀8L? |Xl:0崊;R%f&w:@of;좩Et&!Uy|NT_WNzpѣ'}]:sem +;GJ-,^钄;3!#Yҋfb֟Ŝ/+Yiy +d/;R +oNY069:Om׬UTaݷ+=lGyJS~ 'cDi1?<~?$Q;v8ZQ&|Ӟge"?ATROȂ[aQ!qPRr~HSwȚS {wL4E݇:6y;ͲFd>_W yRgb[/Rdr8zoV߂g|_ O:&!njBqHM@Be"vv @l 0[c_rf=َXVYը{zd\>t( IyJjE6tT1ŎG%^hHwp5"pǡ`IHLBFyaˇD/1g Oj$پq4s&k-o;D 6t@KSf0X]PO{0沏0s跫uH|ԶJϚ wW%jF<&TJP MmQ @3aLcjqZwژ3hNB2b7/<MzoHS1-(j(znGnD]ا)BR0O)MI0MT Հ0DcCB At#yLMZ"M`&}*IڳpkWJ]B%N7 ]]hGਛEp}ϻs]iIjUsv1ފxRXpNԦvU;:4-FVm)@3ٸY|Aڍn-cpv[U +U_^ֹ:&,O(ex融~Q VIMjemuXFn&::%ˮsZl*I-`HP5%i,2.*zx x#ҡIUD kVSתߝDooBnFN>;ÚVT;QmD6bX݆1qh{aEEh4E`ty/\x"SKo/_clåFpJ:0ž8ꘊ6;:v6p݆Tǀ%vϪE +&P;! ث>9ÊEkfQyfЋ6-ByFx#jLLC1̠;[. +GcnHY}|e*a+߽ S)Ѝ"عbF EYfeF"fǬ'|;8=5Ja HH=H}KڕrZ#Q*=0A0$J8UtKvKҹ +HoGCbqE^0Qqm[]#A8k5TA*CcLZRI7(7$kH[EޠD4>2eX$Wlw]7^(\IwR =;&Fٳħ"`14DȲNDkXEw|#EΪo$V_F&47oKB]L6שN Zy ]RZ*]D/7݂4FiAy5NSQ9DQ Ɇ͒!T%r`x?Gv7LP\-KXz; (L|^nRbM0(t[K2g)!o4,BE-Ь~{D[̗ FT-͌-t4dTQQ 16fE5^X 1m- Ȱ0y4`,3a*kૼ* S6NwBL荿b:pq8dN1>anc3%}cۈ{g'E?Υ}—.bjnB!U̔O[ #gQ-$mVU֭:+MG(X"ĺnXLi_TH(V-("OYCМ.cΚI@$HAR@6Mah\O<4@AafW 5i3BMC'7A MG.SO Бߥ"5q>C<3.!-w{'K#}i`. HVg MyB_la9sWncZksy[ΰ(>R:3XGt NaJVù#S" +&U_s0~ ι~(AN-E1M^\^:5guU7EO* No+bJ zu9 +qZ B)7?>e2!2j2"W:=qwki%6EXm2Ax#?WgB9t&} +Tڛ j:](ln91çYI°7]8ER*:! uxHrԷ.a;l=˖<Ksϕren,)h.V]?T. f7}EH!)Duw,FȈ%Y:bR'R +=$i9^E?$63R41r`&Yq}ХX5"aߖ9qE I X~\Y X̃W e_~}D~۽G`+R }O^苿֑tϚ]r:Ov承{ةhF14Tex@ߊn8vOqGqEc]@ko?+maݷ{ٵXn:vc,X^s~-oyɹwěhEڥ8+Ötiub(Me}X)-5G2-*Jy "֖S 7ڝ./2]h*:c+zPBB[8b7( ҇9X +͈8NnCqJӃ/tKF9tʌ)]'ʌQ sqAB&k38lDl(Ӓ%-!ǝUlhPlMpdǼ ,^6i|Wۇ)];4flM0ng³8y}5^H~VoM`ܰǃnw&"&~MgH #;87{7+D!, $x`x\YåE;PM{Ħ I1B yz=->qq媾Lw<]Owen=Ӆ$g;8'_N /LtWwC: U'v%u3f_|][+>v's}[ +ϰm;WRj5Y멛pEn~ٙ tE3gnu3Ƣ9v9|{Wb+( `v0ۊMĉ!\>i&I3TE6.Pvc0mEދHw0z[n2W)9JZN3zu{V\"/r]ʹ|fUJF~2_uK.v%]st3ߌ< ww;/ևgl4juX<Ɖosh_0avX*ӑqz:M֦ɷP͠ox$!hEoWNL1ɖy :S4@sa0Q"3NеLi8X:%`߼耷TΧv*l|E2uxE*/rQtAr3(.V1IȒ/J̘!6=fΑzT_T|6o(;MK`CO%P]@Y4cҞǬ +gnG2:&tEM7o{x"~ė_3!5 ot`n5oscX{~#0ݪ;ǒJyARZ9\$M@,i +>sW NC,h$ 2-4?-$8&kQ֕5Y%6a'䆯R&l~`aҟIfdFg9D}Q, <pf GTjbbxI[vvS0TA0y&#gi8 0QiH UK9"@\0^LRż$+4z-Ni3T6A*na +7 + ^0q Jjh,Xj&6tŢMܾN2-^x!{Yjcd~h +@*pjE#V# +#S)`ed s]bQD](|!xso>\Yu+pR W8I.Y'\h@BL^"l T+_}/<]/4~d:>$~e/0>"Zh1",~lOVtoK2jȇ FAt6}:’X[L`'O\]*Eߴ6`6p`T˴0_'Խ//JM=^zqR>^Ɯf2σ58kFyr"7/,VF^//@„-ªyu.wvyݴKaɴ_mo񎌓-YXlӧk |*7P>]UUL+Ac`̤APtraP H*D%Dҁ¬ܪ{GSEZ˷[#hBaۿ|o;atQ.b"uhX?!Krٔs +endstream +endobj +268 0 obj +<< +/C [0 0 1] +/F 4 +/M (D:20220402142220+02'00') +/P 71 0 R +/T (Utente) +/AP << +/N 411 0 R +>> +/BS << +/W 0.5 +>> +/NM (031ed1cd-b659-4870-a55a62777955e344) +/RD [0.25 0.25 0.25 0.25] +/Rect [68.022858 703.432324 111.537479 713.931314] +/Subj (Rettangolo) +/Subtype /Square +/CreationDate (D:20220402142219+02'00') +>> +endobj +269 0 obj +<< +/C [0 0 1] +/F 4 +/M (D:20220402142223+02'00') +/P 71 0 R +/T (Utente) +/AP << +/N 412 0 R +>> +/BS << +/W 0.5 +>> +/NM (c8a0e098-e4c5-45c3-9f872c7735e845b4) +/RD [0.25 0.25 0.25 0.25] +/Rect [315.105883 701.932468 362.621849 715.931122] +/Subj (Rettangolo) +/Subtype /Square +/CreationDate (D:20220402142222+02'00') +>> +endobj +270 0 obj +<< +/C [0 0 1] +/F 4 +/M (D:20220402142229+02'00') +/P 71 0 R +/T (Utente) +/AP << +/N 413 0 R +>> +/BS << +/W 0.5 +>> +/NM (4c15153a-83fd-45e4-b906c01c64d73129) +/RD [0.25 0.25 0.25 0.25] +/Rect [66.022185 283.97268 126.042353 295.971525] +/Subj (Rettangolo) +/Subtype /Square +/CreationDate (D:20220402142227+02'00') +>> +endobj +271 0 obj +<< +/C [0 0 1] +/F 4 +/M (D:20220402142232+02'00') +/P 71 0 R +/T (Utente) +/AP << +/N 414 0 R +>> +/BS << +/W 0.5 +>> +/NM (bc7bf834-e04e-4e5a-80b08f614379dada) +/RD [0.25 0.25 0.25 0.25] +/Rect [305.102521 283.472728 371.124706 296.471477] +/Subj (Rettangolo) +/Subtype /Square +/CreationDate (D:20220402142230+02'00') +>> +endobj +272 0 obj +<< +/Filter [/FlateDecode] +/Length 12853 +>> +stream +x}].}<T&|g X` k{6vקD>ɪ~gUzUE/5鿿y?{I6_O?_{>^G\Ve+܏W}:؏-=M^6}ǘahr:^^qbP^1+~k}>zT֫:mY6b갥Ӆso/_Gw4^{9wvi;_HU>^њ[S՚|לgDZ'<ȩI؋AN b<ӕ>&M4)>L <>nзAsENrLNB9IkVaeG|r9vU'l,jtyjӣ m$Z !~r̚f%>!!|X/Nt OM{tFC`ٵGZ󤬺qL۶Y9o/νe2MQ%d-8*zǝK%3[7WL 5.Ӂ9jS``ymٔo?Gw@5: g}2瓯mzQ>W]'ݠ49Mh,s$Ku + &/}$Qv(CPj٥;s:Ҫ."k~? P[w!ミS[}B;y~xW.O~#[([y7H쎲8ɻN.uԯdP!늁k`2( 3M=D+wGU! e:lښY^{{✐n٬+ +7(`t;\Tz6ɒai[K<(ckiZ6([ߌ.ἑMF=@趮"%a.59qBޮͩNyɱ1E,oP޲v%Dwmے +7m]N|S?{`;$Vq 6 +%s{"u:-Xc!'pJmOfdUun[>O][ + `!VȪ{]+mg?FkTɃqV%'ksVCkkX.dTʹ֓Ew8Eea֏S0t<_hTS׵  f*C +pJaw%ҷ%8}'4*N' zTp6~VlP٠oufB9ejakk0/x-P;C[C[RM:5i}(1x(Qn⁍r m tr(&9*{4"#\N[% lR4 +@I5Rgguo*kbB?2CwTe@Ii +kJ/ΗJ8kԄ#Rb$u(|.}5׆oPrg1 ǺŽPZJ +TUV@F%x^i!g˔[@!BD[/ϷJ YwWbȍB%췓ċ*k7 ^|ߵE{:=`6:P3x/'}v`:tJ ׉OE ȌwyǗBYKeN[77k疀ziY΢0|é!8Ϯ ^K_e׃2~t*kx#%ӱ+U,l*S6D-|LҾ@׃sk~T7 l&uHW%0 jp]9n(Q4IǠ"tx#5=YI+LXRi>IuQJ%CL5TaW2Oe5~Tvq*-C u2 0V^B;Hx[Jre@GA{[MNOƁ rҰ"h7tA͂2tB$h :mϾDG>R>-v:/moM7_扵L1qn](oKZLCW +j˜"v.ƪF`Qŋ]GE|9V9;q#u-h|9 +;pa+E d7֛Aݞ BHz~veWA/Zѝay?Mz=aȹB#=pm jNTz2חsKR)[aY6%Ϡ "T5n)ϓJIl{(JQ7vzMu;3IS6Bs:GI]\OGm՜E|@'RI1iOrI܀ڪ.?-(E۸EF[AOw篠*ᖏ /~ۅ ɥ`9p/$w_.-9]\iC@0S +mNg`n#{mtWغ71 `Q <;7Nkm3`%jQ5g;b6&H% + U[j2HLU4 ` Jl)]~{m آlkĖe4b˨[Eш-pNl14[)[o(t+ց-0EI `k$cL.5IY)فlAm;Eilӫtwy"37%}xSʻPب`[NvV*5ͬ6-m[բGT[G2!ELiPM5b*lVN$mE+^LDX͘d1evL}ݢ6w} hP_4\ҦJ)8c;2U㛙8uonq3.;p+CA?\03m3֬͌- <^"q9_`q)%2c +v w1(TP%6C zs,DZh%P;-SP8/0D"]lNn>͍ՕrȣEJ.i sUMED@$Z jXNG#nOȺD\.ApM推 WxGFB-kؤSQMTQJRM@COF#ܲ^.)ԩ-VΰrU[K4\A&;ERU$qLw҉X$?4@RA4)znќ}L1*EA^i*:Dd;Jcrݜf|,g(t/!ӛF!@bCq3HRP@bj6%mSܣ q[(~paW4Pr b}a%"B vwq a?1zPh6$?Sa}26_)E5@OM4a^2]Wk۽򨪾cΪVTp;+`Hl(8$ь-dT 0Q "g䫛Nvn=iȣqEO?s(L/ 3:-ih5㉸!bm)5„Y h"<0^թCw+a +y4N6NG@•V:j߹~3SÐKG 3 +V m̖3A S62@NS}p>XL`w58pF<4*$SjJA`$HA֦ GSpEW +\b$.x2>RplHg|4x7e#Ѝ*yC?7F1P֏ *<^a{!HeGSD .Ax_".J! +R4>>)hFYvK@gMtWT=4OdmOi^cܓ00U`:RUu +dEG)$!A +@؞c0=Bԭ8LLj$uO1N9T[rPs"4,Į .Hg>PuPЮa1n0`FN9<`,[+fb,JSXabD/-aO ++%%a3l9ii;Mx><1m[Ǖd&>#/33U:E= sưw&m8W&ʖ&/fle,:ơ0T0^G'^]SB lH0^+e|Mלؙ&\a`rӘhټ#;yg%@}]@`87 h "0wSHMpj^eRk ՝!CƲ&[C#7zoMz؆ B"+=#X 2abv0Ew#Ę&6XK-f02%c; fGnyrB|v'?O'Jj(]5r I zТ:wgn?Iۭ @Pǩg/,7dZLҽL׈VBbǯ+1BLjPWYu/1(MnɃrO< si[D8N˱rUjStsc~I3 NGzKJځ*IhhXUma?q~_g‡]4<!4 ME$ Ѿ#q>`T׺)3!{k~hc q Jwv +})«ВHTд}<ۈ+"[SOT0i2x2iںeydhd+Vv bƽؔF +m&S罱en`b^pilM% `=F0-3pZ i̔6NC4 WVy vyK>lE.v +vW,wVvMy,M-ٺ`?# -iM^ zoLC.52]62 VgzYurhe@Yr[Ta:_ȇ63e 1Lt.YIX@]Kb + EVϦÒn訢PA] ڏٹ\7Zcp:dRy +lrWב.$$3X; tB ~0K2JB +#݄eC&c=lA uMxxśJæBgߤP[r+%Q~jzU؞!%5c02\4\|Bb;I?T܃E}_K HxtY zK(/MYƫZhtPkjcb;TrXhrXe]ڪR])b#ƙ\~ (rGƫzt"ԹwK݉͵D%耰8#i1֞dNhi lK{ ,qm*T <4V q#C_CV fiAq'mFPzH5i̒UI^ *eڂh@ª]ކDiސeX,t%zG[ +А,ivo0v|5Zj|EGilwfD9q=f٥# ;oz: >ucR-2%6s_:W˯]eEF{p{x>"Cښ4[)c͇\IYZ +]IjJVVEPD3Vj,<~-;zҖύw[/G-|]-vDɓ;Qck פ~W_Ƒb$r^nC*&B9?ɠ^OH֝51e~\$o8Ũf"~Lu +~go6GY+{E6WiJuT\|~&bB|r)! he֠xv$!)=Oyqz\0P )g(31I<+^}MɣⲪ\8K1Z +%_VorlDy-3*m8U@ xv>~}kʸUK'yj7J姲 13z(eA֩(P竢zjGTS~+r5(Qo(YrAdW2 "IdEhٗ_BP-f8~x+'Y߾_J~jpI.PIhj,~g%kNH}50La; !/mхvqOv6|1v+}z6'nZKgAauFs|?wb^\fmq@_=`+t|.wSN 2btgFC2"̸ +}BpkHW<݄c~|yS9ˋ;sӏ׽˧~?6-'y?n_^ /i돿G:-ۥOKFi8SQFRX#V׋K,oҖ/i1 g!8Q=*}1 UCh#DGHzF(KWoC-2-ooy xkU  +(DB|2}#X!䩕Dޭج.lȵh@ҩN-Ga ֽ=PZ{,<#YT*lQMUs#dakgwŽDB"rWNvu5qoED|RWqC_-W/())5@9\ 6H7+q4q{qv\nTQȮG9 L1!J~|Qv+nxNa g| ,&⮸2DCR!<ِh]^?V1j. <,> vzg{9C iM8;Mh+A+~qS歰Q&\g +C +K5a3=u;hK-Ie8êuЉ O1eUjjجZ0bK8f<ۏ#m OE''pze/;ĆBb 3)ʼ*7B_B&pW") 7ceMUV`19k!7z9nt.gě6-I"y߻yǁݿC$b,eG >sdvO1~aaQub~`>53pgDS5n5&SV%[ E16/U-)cR$UB#e +BC; &ŮIvړ,4د腮s .r)9bq:U\B¯Ơ/#1%Z3 lTN}LՆvMUyxy"S g@յE/zPf3 <+H uu|Ah6 +ִ:SB6b?!֟abxRQ 7fȶ.raV lY/MH>|a75paԡ;Z2ꮬHKR+?q];a"{yWwiy" +h >Dy䯔3VS9Qj|Sn~pT g~Zueihdfj*6sO؏k]#9% +(ʸx\O#ЬA Zr3JgfuM1Ya!Cy*HtG[Ѕ`#%2Aw˝\`jwƀm;}7x/3n,OyO潭 zG+$+P-fm9z!㷿GP/ l8ו7ҍZvv5Τ-l61:LmaW|+h6Fr8;`Ս#JmX@J<oE(踻DdA7;фj;1ݏs{ԍ~^gXe]+-SvΩNFÇӂ|焴nWHZz!i5KV̈́+nJȗY+Jhx=@iˠńدTmZZi+21/UX]u#Q-?`'PHAIp+ ~").4a+ߵťF@dJJQsVNd]V~ӛ_㐵jV>JG? ,g++c&vٯ&p7HE؏æ77d鼠N]j|nޱURAv!IJ՘/BTqr89 O)(!;GyUh'bojv B<>ý:A'~2y.֝qR5kRK|B"x:43Bf!;xV*lTs«yC,īK{Ұ7z t\+ߠOJ!_1=i*!''TvY->lmD&v'"`=pX:>8bbL[vdZcN!ڡ+7Qǣ 5zl>9mͯ_­sGPLSj7 +]eTMe`Sk:Jy{E4FqIWdcϑ9ŤڭڧD/|Z:!<2YZ݋<%'@L~{u|@$.3ZB [M`-w (qڤ +REzǣ5u|8Kj~ZW\؞#ؙN{=zeQ)t츝׃.]F-;.Vf/{vrk(c? ^}Ca~?e^"5*?_V?[_~Ö/w~ ?J푲aIǓ.oSYd|m₿s|k* +endstream +endobj +273 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220402142425+02'00') +/P 72 0 R +/T (Utente) +/AP << +/N 415 0 R +>> +/NM (bb72e99e-b069-480b-a2dcd005678dec1a) +/Rect [265.41329 613.231507 305.924724 624.249024] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [267.6 624.249001 303.738002 624.249001 267.6 613.231504 303.738002 613.231504] +/CreationDate (D:20220402142425+02'00') +>> +endobj +274 0 obj +<< +/C [1 1 0] +/F 4 +/M (D:20220402142450+02'00') +/P 72 0 R +/T (Utente) +/AP << +/N 416 0 R +>> +/NM (3425eac7-4be9-454b-9836a7aedf37ff93) +/Rect [265.41329 601.712525 312.645998 612.729981] +/Subj (Evidenzia) +/Subtype /Highlight +/QuadPoints [267.6 612.730001 310.459273 612.730001 267.6 601.712504 310.459273 601.712504] +/CreationDate (D:20220402142450+02'00') +>> +endobj +275 0 obj +<< +/C [1 0 0] +/F 4 +/M (D:20220402142535+02'00') +/P 72 0 R +/T (Utente) +/AP << +/N 417 0 R +>> +/NM (7698165b-46f6-4f70-91eb2d919be0cfcd) +/Rect [298.059723 500.776001 469.460114 501.776001] +/Subj (Sottolinea) +/Subtype /Underline +/QuadPoints [298.059736 510.729001 469.460101 510.729001 298.059736 499.711504 469.460101 499.711504] +/CreationDate (D:20220402142535+02'00') +>> +endobj +276 0 obj +<< +/Filter [/FlateDecode] +/Length 1375 +>> +stream +xڕWێ6}WB+Q6@m&F ֖mUlЯ̐\Sw4̙!e>NDždo_֕p5s +[ר kS kEDI쟒%e +Z şඨmi~YJ P> P7Z D'J8QT)JRK; T9CK(\)lhr"1ŀdsmeVD9k]x9W gVy9w4/gU*U:wW !kVE.2l+@[տX9+E]b+R m5cf,ofݍyw8tVePޅ%PRAy75tq7--t1U& +X QwBmfu|ro!ҊLK63oƠ WbxcvszD؋zn3*VȄA]|j,7[8k>T|W[6t4Zރ_ M~>֎mO"0w:Ťt(!^%~}@m3dض=`"`fAQD6OD< +!!4! Gvqb#g,%!1'K|{ +>tDHi"V* K?15p5~|!k7 ·Y VnX(~M]]_/ɐmWՖgyg3 -40TB$^\X=ٍ .-׶kyv¤ƕe|r0P3__2oyyىzn{p6-,If4 sZ%wuj!CݮfǣȺĢաK.'pZsy/17hp*, +*o5> +stream +x]K$qׯc,'ɼ& V2֐Ɔ z_̬`,0۬b2x?XZ?/_.|Ow~~V?_-Un㉯ok Mi^>^~U_Sm.7-~nkد{9GҌ-Vhot9voX[o9-e0_4I;aia[uqߐz 3K} ,Ņra?;v~lѶ-Kݖ+-#ѽ~v:oh"a|Tpt ӏlCҗir]imIr;j`I5[GR?-Mhw**|y weZlࢭuž<y뺮`@Y%^E|P"]^s^DԶFd)? a%T +BAWEh$i@*ŻZ+ <+ OR +ƅ@I@=9r}Z糯>y`'!d +9Bdyb06NtoȒ`ɥDkgI֥dz Xh1xXj(~B4b-(&pO`F"3i%G(n4pZhJن1 @ela 8ii}ɌQ vI]%_BU}Ϸ9MYwzNil +]͚J˴Of,;jn;6p|'VmJd ]Bh<%&qjW;Y29.QQ4RPb*&*~?Ig|8&~| M|..B`5<. ېs,Xm33-,w %"gX=CDd\2,jCUO?iK' Ҿf {:63)[ȡ^'Q7>sbɤ1ф-YIYr W˘^!ZUUBe%zSV)r ~tO;hU&~pU&$ +[! +o'*lvALy)E@ +D#mOY`Y\eL,__TݍFDR*: xb,!Y|8'W&vDYGkQ**{6cL,UfC di"~NxuWd,옊_hhekYFU.jXIwFwQEz^>|b(DÑ W6ڨ. yb)'kpY.4%*o=K=9Iq7U@Ix=0;&z"L mKD5Ng嫠j'YE3'6ΜH(92;o7bS5x +26h?[=۔[p_`CO2o(eTAG$nGR'yloKC *.P;ZM?ӲHzo[**ْ) +Q.?Vc3ƮI֠#nPULWX,2O+;c 86B3x*-CX 7RxyϺ: Z|L.MMfG2E`,R ]0}r\lJY+9k djMo_WQu!{g}sz +7,D=m MbQ#/"Z y7s9#yݱYъqcC0ƺBQDWzgqz =Qw,uvOtyԅ?Mֶ?W6;&@3,Ḧ +;:sUzo_i:^c"[½OXyy8+UKfҩ:*U |;Ov4ig={Ef7l!wyY(>Hj2c#0C=QE8k '5DבE"#G-”FF.ff1 0+獽ɁL3;!^WrgZ:Ȟ`0GDBҰ#U 8%$[53bπ8l&)J*j`eC]aevK5{4x +~6˓ա{WtE[]ZiYgx-·+q5m= r=0Q}LyC&,R\NHiFSW5 =[@}Z0Z6sc7q'8EARWPpMk5CW~`7z +9r8}@"'#6eıSHH@+)YK;Gt8s*P((N8(d 䉈M(<YY,,tYb_!@THE.va0d);dIE ܧJpW躹=$$߲c9ƇrjG2V:lY|>vv@-|e#`63MtcQ?0 +L\`dZ&ɍϔm[F66N&>G~0jȚicec?* Xf|Ine*w[MKBq݇uRnGdM8Hs*sir 7ɠ"B8SzK]h}O e^ b$>UF,<n"zVwl+dѐ1"}4@rS:7!$D!{ζ4L It ]0褥)Z[vYsq7$3EK TU + +RGYE'y:Xˇj ּA .xDnA\ PS3ZJrjVW'ԁMҏ, D)1xS HVі=B8%S!GVuVg6N:o)|R_M2D4[ROր%H$n! *JiEQbm)|I]/`;Hk$xp9xWݭYme5TUڍMuC6 (*" iD9sK:T,-Y:θEU*)sGqqr +qiu8vduXrK(f,g8Ak#I%4TZs-Z]%4fˠݲϾ;"PurQN4cRXI-%7ʿ +jym++iD@L(NR82,x;,EeLUۍoK *_^|+(V E Ue@d,~{uPy^B(K^hX`@RYTxc$$첏s!Prg1QXjQ`@G\ +hƾwLRG"[h)lVˤJwnBZg9^9nN#xdy9i"xAV[ՠB6%iPjZ_F$Q=SkT5alŲ܂Wd +R8(X焚#a!B\gZcfwtE,*N^h||:cC#hꆆG:xAod#*aGr*ZAjq ^XFܑ_É5-}Dl,9ZdwCflxǩCS23?T~= ؖi-Xjf{]B/؟Db7eZ%`N9U~, >Qt_jҼo+A.'6jCXj +"OCЀd_C6o&J6is:lxԣ}?hx5 BWg*c{p_m:`{\^iVtTDf:Kjbk7{Vgwa2'7O(D+2hcGz G ؁!)d(VPe2B) l6rwISn bٿ -P8XЊz+khO.5]?*맿‡맿*/R꾎~˧?|eM\zY\wn{+/o>S+/.%6YDb{Ӭ| nTNo>Ԉ ^9(Hc b@BHhVOoEcra3wF(Pu‘.x̳Q#ɓ0&v7-dD E4HkbvEQ ϓT_wFdTZ1hNj2uHka.qdn"YWJH]˨^ߠp*+?aP}ayF-Y\FHnCisI1A{<  ߵuYJ؋*+Y!EB;Ge :gB̒'X.icw#aޜ\ PFE48_: ꍆ=\0KC`)XѢ$u!ݺb[U[Ր*1a~:qZ 0+_-'N4}]>-NuuB= ZMF=%D4TcLGLdz*G$D ֖E +*ܽQ}HmXa- )4J=HXhB·FX_2ϒ=8"N<#[Rͪ;gDMzB7Aa'D;:Rx Y9mf0_izB2s` g|@ I{-? b෉jsأW@tӃiu m8ac|3BCYSg(1'h'cAd 嫩t.V4e״>׋ }۬;BW2-]< +~/ixèǓgOJ9mm-Ű&Cl=&A-ޮA&cnmmj9#F4 e 9H X*yѭ8wk:Cm=.B-sbp|ںyuD]51䋪c/}^Mҁ (Fɡ$Qx5W1IrQtHE`.\kU ./?×DrXzU+[>q۠l,*}$-!=sl7o7 NDr޶]СkWQF^ lBV6k1V^;_' +,fV [*1kAo8c՛'rƁ޵P+|gA6ļ/ƅ%O:gl_NkFxz,sn 'S!MxHmSzY7N3b ۾hGJl18^j(&Ұi`~c 6PD .,؂IVZ&&SJ| +areXF0lP ̵-,'f@šgx )w[X(*]O J9duu)=w"{h\:LE^ |E +u՞킉g!.1}PzȤKhT{oh^MU "hBmU V6B0Y|Jn2@I" +Ç+ +lPP7sF>7cmaCR ,[@#$fu8nF:P9[h–De^R;t^Li*)h⍌͟{7#g69i_U\Ult:2_qG)cQ/Cyt7x+Bɝj,m[zLS$mٙe:ð)!>?fc\g#?>(:bKOu Z~DbbL`GtV2D3A8AoHD3nڕz:K0L1UY³VtѾpscc cUOmX>68G&DP?AQ/@,xnpW)tB\2:9FLtږWY1[FN=}XOXDRz!tvͭo06\760 ߬iIlmp_ b51}a3;S!55$Fb_깕2A LxYcXqTVҲ4ln" ܙ3j4ڛM_ܸlLhPvc@Rj7}0NJyk8]!tlA"Mh^wF}]>xٝT[Is4fbM=9=SӚ@@~I`s'f>{ghO!e|< ӔM +sb@zW!=.Ώ̥1ֽpCͣԣpn r;`"Fˆ&t ^+|14tj#'K$ 0٧md%AÝN{'{ܑ:ȉ%uFlЉnjljCa0@p&gTx4W2`Ҟ&]|Dn"^a?SnnXt +RSӹ0RzSCku!"F*l +4WQDurGGX3ܤ@sJ;wB?9h1UC'&Qa%uLx`GLj 놐ɳS +cˬvoRKί#~M,#^Hؽ(=aE|ċ'06m.,e>|qUg.? ն堰\3L7v/VЖ|֣ǟe:5<=}a ⶗n^?qR߸VG{XoLtV\>\?ߍkϿ6_P +endstream +endobj +278 0 obj +<< +/Filter [/FlateDecode] +/Length 10077 +>> +stream +xڵ}ۏ9{籜N~y& dAA_I"UҙN7OEREQϿӿn;w˝jTYw>w^{Xd^-wx4/FfK\s"7C}&}8=@[.WhO~E}&M +=C9HС dr9{tK qB)ObC[D &(zu0]<2F'|to*SSU*xm/_K>KL}quӽFS*bC\NVMiHF )4XsL52:aSz.&-4LvrhƱ6OU/@ w +-aS +=5f__CsI6U, _L4GͯF2klS_j':Sm c>]~9q̇aUNLL5֌JgԥV;t%!)Mm%b÷Қ&6NZt>Y#Lz>&!։=G7J,iWDT$CqSԆ/+1w|\/?njK͋~w24! ǻ?Ń/?Ӌ?|~S߽?Vƒn47&>[~u~4]r>laa}fk??^<LѬOCo/߽|Ԥ?<[^=^FQL<mW+IbL!N?dhz?Z7?>=S_0*Na$yh?f i ȏxE`f ׏늾1%l/Ƿ:jqf5_/> M'?twoƇ<^{o?^xYHFSr/W+^.^.:@ ^ |grV|PSaӄG7!fxbPuxӫj?}z;4kYCܣ?/޾ÿaPwwoW|\#!ZJ1K䔡˒n}f/F?1S>3$Rw~^D:45v_à ]~\ܽ|g2>O%[/EzP~Eגҟ_.~o^~t/3DFo}f?L=3jK^j.tiI$k+>m#++߿1w@#*L=myOj>ɨt֥%P@e TԩOSFЕ ZEh_JnCBN.a +RT+A @ʌ@%&[Z OM!C,1Vv ШǀZ  4(Z/%&U1GDN둬 qVSMN4uc1c ++;r{HKӃ\0w 1[Ye2^߄'f +YjCx*VhNZhU# vz0PP8DPFDZv;Tӈf@ݘj{#s3Lh#i77zV;`·6$HXұ|$I#)킢oa-G&VPMll:izָXM(R0d<%[=n/7ހa*idtL=(GSjBfg逹3Fz$DN+ oMIAF|BȊb,+dYH.:+& 9Nu"ˆS-dfS/7VpeҔPIR<AZ.}2q +Od7zGޗL +} k+%s +elT3 J𶳼RjH:yReGR :9 iP \2(Q<~~`% 2)$.l +U=X/H', cpЖ܃S-$kA@QX-p̦*sB3nv3:&=2JKSdh8)?yb.1,6V!5Xq,1*$oe = a3McvlQ9\gp9ۙH:'1,1jFĄ1lA7Ҙlx%تu=c= *ُd-/uBVw+ +ڔ1MKJIÖEu|xi)!Q7*~A)̔KtO ip*'>@u 57-xzhr9Q:x lf?;dL)t_@(";VoZ`͵:s9 !aff %l.wKRpU9= K](UApi7 +N6-%;mnu3qYR˙)}8ͱ|2c]Gu]KtbU=g+i\7uRεmaD DEgKh~EE,(Q}1ӡ\`<[6)xZ%kSk<UvԺQgl)Qū*w55lT9 +z[,6uB叛T0U$m_wZf53[pgY# eSY t/"A"s:1K$"{$p8hF΄l=Al}E4VS7,kfljWw0#\iW-ё:V5` pl␵A% +\,&A:]d0[LǷ3YQz٩=INA7Ktⵚ,1m-ov:mj +o96gv72 @`1'g T[QťalF0VڝfҔ,ءVjm] d2!`|5&0jsl=3cy]VBB9mf QZ}1+&]̬|!Z/O+p7TnX1ї=@E^o +CFLka?d%: ahrH\0cM@ʾ +Ug=Lc>OZfnL"s(hC\& <"Yh{L4mܤ@HHjcK,Z+a7t`0ˊ$J!ʮԴv8O )LB0okCrjCH*d`&|b ̅'\sBSV>LEv\lVFKd3W 6/YZȇzzpywr^_(u>ÿr貹qeܟ\<|<}wt> ͝(YR9y _nqr 'KQy +ٍvv&z'bVzĢ׾<h]xݎTW¹ f/вmXxEr`O~7}: z^-6r¬ig }Ϡ~:>^wڜ>O V߅vXy3oST$bE@ɇǻ-e>1%־'(݂ yoOɉ|Lɷ(!ָJ*׉5[kCSeH;}}o +)@Ec]/xLl\V KD(b(ƥ*8^|*E4'32>Ra)$+u۳.|w5z3ޱar}V-"9˒rK&% +`>.=p-%0jhJ?X]f 7ߜ~ CdfEWv]f^A^]Vwba OkCd>ۣfLJ `_ӧt*b\DŽHXuJ;>ojs YQ|М8L)E&3IUӋ+/"!Die;`ұI3ݗ2Wjj=,|0yUwK[EuhN95D{{5RU$ el +MzdLg5HJg\tNstTeĐ"Bu _=^r@+xEK`N!lUS/6;L9f\IP3yF&JlUu ecg?W+(5 r80Y[!r + W=HU0 `^as܎2 @U +`bmEOh۔Ije9\L IUړh JFLB [ %l.A TQRBJUYiRxT(j$}FHhM@ҜHQZquqPE(UIt$I*<⛄ _6JUᒵ)*@ J-$4LHl 0m0Ҥ#mO*B>h@ =۱pb f2nd%&f4SAH3g)IfNb3&"hUMHJ9E@n4mmW~Jy$ +NКP[\S&SxߚRFhdOA2f c|t$=sbG؍z-{9d!ҁY%}RQw$qx?pª.K^˽V\#P>&`\OqeƏ{9PW.jGjR\YTZSUTUkj$TbVmo謣HK m"D[W@dC5|9$2iKi A?s|TK,Q!n6JGp}:rOzЗE +BPI[DNA,iu֓MGh;dBd;ۅN=۞$LU%֫\<1ͿO`Zck߷t9ibΙitx{[sCn.jM{S1my%|?Z o$rM9hQ 0ln@fAUYqkujZYu>(ψR`} 32D⏠iWdk +u~ÅE!i? ғK}U*rj7 scX0c :cRqRMf6IƖ*.%XP]M.HX-;>U STlYTi2:8&nbB%,pr'GO;\uR؀S`;k2<$ DfQ+B}#FĮ5 ܙB.1p^xhvmˎPJK5?i7zϯFFp֚# 񝀦?Yglʺ X +zU1Ϧ/QHTQa|뗚o i7d ק)-1Hlh꺰]eqHkBȎG 6q!K`Paafo1;"*{*` A?('-n9̱*0]pf4NM 5 |ݩ O=RLlP]qpo!Ki ܝOۜ腧%ܙ7M˞ɀ8&6Qx*'F'R'T#adu[ tnbo?|ܮ۵gI@E/hMHvg,-qwKܽo,awEj7}n#f=ÖۉI k!z6bl$ӳ^ڌ_vUۇ-f0Ban9I#FN:2Xn۝vMXq昕=﹆k6JPݨHfy( %]nVv;*>bzUK;7)`$ZÄ!Mc«H^WF{hcĭ1XW\XARQma7`x0W"Y]ίV`x.@Z$+|"+ x3bC` N^9N dqs|Se#']?H ]_+w9lIGayU!4H\cv/ *+ #FU r4%}Ƒ( dۂo~6v ޏ9*j8)q;:O@Vz[5dei5Ԇ3.S;#}&(1 Yw Dw)In 1{Y\@eZatri"M <#t-]oӺ + HսU= +̬ dUs-L%/uZ'X Uٞ/UDN@v-Fez,7g&F}޴~$FDE>5Xsv߻hq?}/ez_H(@:)jC9XaZY^B=7#hX>_24VѺK1L"@m _[O'ZXliαJk}qp*m +'zkb> +stream +xM%6_qf}I2A{` ]Z[-iCdO+G~e;~/;_5W+ɯXI}ݓ +uiVr*k)(+++zXY:?de珆/o +kG/4ouzieE]ɽoqeaOvX?Btnnme?6~Y?~z[{y-xj9xL(n: -LZrhv"|tK3on|vn'lNxK/,=x|"DX `mMͺr{ɉ=.̹|7W֡s5eV٭^ʁNuG[gHHV_v;jx{۹o gk:{_~XQ@qn5}S 9 vV(_,5ׄe6B67 +k}GnMO| c`8;On^[O$.dq:8]νuVX1*n%:YIJVg [}0THyµ4H| +-y&;_z61Pv q8D\l N9έs' u?' d>&HS;`;|M9hVY[WO|$E&++ hny!!zfR i:[e˲O1Y@g2pSĭ9{C8i\c;_~ c,7'smyůk/'ƪ߸6ίt@`8 ^Χ .h޿i} `N`t qϺV'R#,]*fSWPUzN! Cvp5gw'hӤd t9e~GI3As⾐H,~ZtV_B(崙XNHUS.JEVy*gu rݲN‰E,V]-[F Y.o:+6;Yshk㱫ka.1coB(4 sé`4Y6/w=K`. v;ײ6tA75^) j9Z޸<ZQ5paP:2ngDOH2n̈́WӍ,9 .QY8qWlc8!#3.*t2HrB'7Hᐥ޲ICYUÓ0Xo&A\p V|mѓ%ꀋHsU1]z(ܳ4gBYJ +]dS8Li? ?9Y +Ĥd.@g. r'}uf%tCY|^p1M IJ +H\q aXq}aёyU,y0`I &a@']Bq3Œ.8J1 PS/זޮJqhe 5OU&XܽDž N} ~$F.UJsSдԿ# D\t+x)y&o\87g{[g}]29/ *Upᬳ^T S+= +,]tknȬ&[^'I߶ l(m\/whS;n`H4Çfd\\29>+L8un/+\رS3[i]1A ɤ]&6!]/lgQZz~Ɣoֆ]OP+oth ++ +T(TApXÄJ磲a4(Gp?׺T Y6=M$A&]%71 +f#ņmTN;xQ3z2o ޺{'N t _RgXZLPw'=R l);aL9Z1\W%BLr ЀͮE W!ͩP&ȇm'FְaEM^!Vư&xC@֞t5ENPfAejb Xs3d`!SD'ۥP9ԛ ۠l/zgl`0'x7ȶBZ*o5fp3 Z_U#VЈmE$ωHw=;e̓f4b}E׌f+{1 + G?O"~7'qNX SD tT*_)<)3e a(͋o[0uN"v|PNm ,<.o&V%mA8۰٥Üʆ9ѕYZJX.o ,(NxS  +UШR1 s=iPM aaawVhpy8R.G68ov{50)?`?->_&&WNR eM[yYjs^X72n5MfP֖˘N!ILt5zƭH[ezmmR=poA`g})Gv#]-kzNaw*\᝟gH#C*Jxny;p{v?Br_:ߥ]Nlyި0c6$_յnd,)K4CS&{5lص +aiDeqiI$fӸ| r;d\dN?΂Yi%yciz'L7s}7Ov8O&NM((e>j~('-V>&F_!w.Rc)Ub W*Ɋ}\}rX5`d"{JV@w]BI+nrw- _ F?"`J*! IY@H^ֽ^2/HKZ0.i E-%SB#qKj[`:R_Bޮ6kn2ӆʨg;"e-xLӅjʴn|Ujwak̚;ρ|gcxsot⚖6xyU<4-ϚSF#ߡz()̓iM\e/QpQayߥu5Rcfޒ9 +JC(\QOu< ѱ(mr| >e2nγ8WW8 C)Ne,)j>rbo2=&w~HR\Gop&Aqc`n Vwx|.-Xp$Vh\ h^%VG0nVUt5Q#\[`Ĥo~"9\&>76on +ܥIı5C)36<7H҉lvY9h_ͬp2ҍ;ND%^aո|A[dd *Ia4whŎ\̌;\Swp~6Ȼ =Rþ +n^f ;*OWk&Z=P7~0_l;[aRZr|%gKGR%eP}]ҍQ 7)/l:Y2K<J\b o Xez]BO%n ZFїĵ2q5Uݟ¹T{顮4u=,+VUK[xA2ּ r8՘ Aa0=!ݏ4u3{spkw?qLг)U j7Aʯ3!wDqˌ\{q52}Fӌe^ k/Hy{UQCIZ2ZPS9ߪ@fe$X[/C\Cg(n73;5V9("0H.t+~SSs7NSaÅy_[ Cdyذ%S4q9(zԘuÄI;hЎ8*=o(fon5@b@67Xԥ5C零%Wjx.:1pUY+ ĺE> KFt̒$7|EmbLKjb' _;gÌ-BJOb= +HF^o9of5AH!PȢwq^{11g c|\Q oH}]T& .W *cCֱ$niMFe "\ˤT:ۣ!+oΦ X(#> gsr;=3:&3eADcFRec%Ō t-"4*ޮe+zsc}(ص*GGP0t[؃ȸFry|a =C<~_eA;?ofV+Z@dlY>PJ[sh/[¸W#LFh]ŗ +f]eHEc +◟eٗwoyeH- En&j!>=q&n1Hy qQ) +dk +$= Gy%aI^]5Rvp *qV/ Q./yA4Up\LTH">[ RV̙ i]/ؖC^*UV\*X! ,U@/X] S|{T`$B =xQĮhpI0{v-F<Kp`h&-SBW ]=yLq"/~A^\Cv?к GhsyN_m~k]yXj;c8:m} 6 >@D`blB~.FuJ7we$WvC{6v:8:+by+>8c%Dkݒ3mj z/u#qB@l ^@ (W: +<1.OA3\Z"S 4F TeH ~w@ ^W,#UI0\4~d:% TLsG`rTSLEC +F-v~pXS8`O^ .MQ54WHdg-H}o,zPѬO`ER~ ǰrA}`Piv't"]_}V,M +e`SaQ`CF( +,UǔjLtw/~wҢp*8TCTV'6HivusŸ1/("Һ#U0 F9^160]I.C1-_6 uDt[H4ȫ7# K+?쎠4DO~m,УµV@?(F*ː~|H7 +'v뚜'LGW11GzST!'vY]< $`nɗ:)l\Q+0 "si碀aCkSòisC>Q#oA\LEom07<+htpU0]F=dKl./e\8i,15ىh*}Ø^[pK#FT (F];`A$zTl.lR=]ÉR6{J?~VoYˬ4BGͪ1f{i?HGaiD1bU|9r}{'I/̉ L-4x4GO?09zJUqϴSB42u+T`w}Ȁl!wmmTMԤCKƓ +T(WY)$+079);yXߑ/I龅{Ci~܋eySs]"6GokGe:5I +vм~6 Nqto 33i׻pxML~ G?4{]^/p@{=<حFw&>ԕ1weMV1Brr-HSdG.v3_ۥY =ç[b6(?xz +x߬ux]z n<  *p) +dOb<@3۝3<0N!]ÐO jfj^#@nX(2; f_\J/ cvOdI-LakqVߐ=ը`<'%\8"τn +ES=ў-aοKk7V0Em| =Njq+$z]V]NX2nՓ> }}@45G>AF*ʻyj*WJb[`C[]Z_ᮘy[~lgw/Eݑ{0 `?KcÀv.a1Yod+7]ga4|D:$f/pDͲQd;:x+%J'fđcOA2hOwXT<|dV*0qzt5pvF m_lpЃa26%~EQ~/#p_]S|-s(V.TJxO!RSN0 Ӣa;\BemVIw.rA $O1wd0p[?~ܕAЖ5j "^ZfE.>}V,H߃)Wn!VK,V|14k){wЋ4oEüΩvŏ|%C +x +Ey+iǮuNxc(  󊊎!85-82[C@KQ-S˖| F*z z÷w9ֽ){E}sya?yI2k4H3,_~VrQG%/E쯷]z[AEen8Q()Ĕy*_~V'aK;E꯷]+_CFa({ WNnog҃^iж/1Sex ebkWkFc~1ܻV])d[)W$N#ݏuZ6N7OIqIAuyRoUqucՏ7 6`0\ڌxa\~' x6ꋣ1̨!EŻsAo nq˥P[Xi^@;,T9 VvnmtTqGUIJqGLaOSM >*QN˷l!Ut4LW7 aÁWSC_e<u))P^s~6' ?VgߘKDP"Zl;r5Vі3!{GV/# ,8ト"W}AF3Ş^ڈ!`HM 'Q?0YP㮫C ~YP@4ѰŪ yj-)?=LoY"2(%9F2Au*6D/Y5l6(({hId +!0Xg }b=kĪ郔M$-*/w͒9ݳe@rr+k-Hf֑٠ҹH=6f[|Ǫd/L;سwn_RG{6'p1ztsf.w\[uĵs8rA>qm4cjLM1m7nAЪ0lv}ɪ%7;fjsi"Jr4W85GԐ7ybok@ ;YO`<ٿg|g l~t"x}b<=N#ֳ%8QƓyw<;Nq7;|󝚶e;G<5rǘR>s鬑笑9K,''F'-WYnh?mݬ۬?mKf fVShs<%ICN qyb5k4kd47p3>3Of|f lfiC\n&Se?d2Kjo޶9re8v$%EHۤÞڜht o8hES\'ZqIA爯7wOյfleReQ6SQ`X]YrCw2Y)Jk.QDlc XuX4ҥ&sЦfw|˶7c\L,ilB&ʴ׷90 (c'&hvŃ\8Yo~qhZcJJtVAMT +ge8,^؂y {~6]F{UE*^ H4'! 84w`FjA{?q[z5ޡy=\bՓArnit.l]|*n!*ȲJ >(#-:!jJ%Y}hAeD!}:BFf#1*To }ڨ(oaPMSؐ +kxqkHh)IRxS0 EwtxKH[efd( sdj9)8^,pvWbS-yq; +G/ +}̚I±mizl5qkf6یcQDo``ƛè\G#`Kq'kA|A6-7JGCѾ]^L긥g<("1!AiLcXu3>&vHB cS)@D;ʡ@%B?fMqd wL (R/ٱwX".Fr1X zg-Ыh@ITG*}FWw0{`j."M%aF=ǿwLQ^"Ԗ=n2y>u>uoP 1pd+qÓqxÞz]KQ +Zdԛ`҈1 ȖońA#^{SBBD3i\\k!o/z /{PRV_viL*|1]~\xۤHA<_-C؊=?IQ |lhr{cHs0>xtFV$œ` 5Kؗ >艘PTsw" g"3x*5PE_hCN 8֥ct67ɝMb=MJ4J,Q3HL|Y#`؞"a[-ӟ _~ +{_dXbg8\Sև#>Hvmw>O㇍_髼Н{o;*o͝'?$s0v?])]{m#Ovy[s?l, +߀v8َzJgeˬ."C#z6241˰|ƛC|,cbk0.pht36&E,Zpq.i*Ȩ~zJŭmr < ~-z*XS` +-`xd_g{TD8>賿[ގɅy;> AUZH>%s~`{ÞHCfnim} (}CaeOxNdϣy&9_i㺓1dlI (lĪYyPl-y0kŬ .0 @ieLw%,QR%`${`􎈎$HzҊ} rE<\evcoIfdVI)Y( |k kPV(Jڕ{ 5dhܻT7ݷ9 s/hez=4~lDz`J CZF+u,GQ +yAZ/ fRXaASd\ +&=蝞F\ѭmgLOt{6x١f8 6w 7;6}#w[&oJZ +v;|6̮bvl`ZSU) 6%#iۆ4+FMm`A\ Vp^4'Ѹ5xZT롤[70YQKS+oE4b1+՚"ҩ# +CzL/_`ߵ+})O@xt\aEiVٓ>5+՜`dž7%Q8\|]jĩ6R:HQ(05ѤIBj_jofOLupzsu\E{- t忊 Cx-DS92,Dqu8xn"!nZ~T{ltoP'Q>7͒ Qxeh(<]Λj: l8zߘ +&)Z}G%| Y rfYe=u? p IАd>}9WW@ZbRB"wWrB@J+w@j74'd3s6=Rz^lL(Q*S**J GLkUR49h{*kb(^AT{`+#*UyGb(^t`.S!(–ܥ?:Gb^DrB-gg}pF +d=Żfy`!x?MȐd&vg )C!,EX@1 ] B Z|Bzx}U +ě)["G%{/N E6֋W]~P5 `ك08ۆ% +ⴏ0CN +0 !Tvl) VZ9 r/ɠe6NI +_7 ~5X~`|Ziyh_!m~6e~v~.?Z|L 3}VXh65h?ڽyXo)X >ǯ|DDc1[㋭lFa[!~ f-(6 `to~^}_5w7о{o}uo$(FDhp_M[v)ۇh${k3[ =޷> 4 ky4d#q [#n=EJ>fZ_ӲNFfzm?>HR\ k/}O)o#- =fr Wc:;~ +=Qv +ąT:7]=Ygɺ祢 |/e/9 ?Ł_(svs|ջ_O)"fRHxa_5;v2T#7S@#vjg0y*NW_ŋxUg|;{Pɥh&?RywXܦuXbG,KѹT}$_` t㪆N ~V=I ;lUtcLUig͟W323WY2<#/_RA|iK 9[f074- nʁ٘)gK-#x\*#9`rTyr@H4צ-5a'qyo5rWSZL-.%`{gi"Ѵ>Ӵ)K6S~(GKZ'hi%|Рe,ضFƢ%.-Xu -e:|{}pA3T_^?Xk`de"oxX8}4oΫȪ(k [dͪsf5J+^A<I3:U"U~U^5r^4u?5:8/*>efcN-fc}39zVHWc0;Uq6xm~X)U#U"U{U3WV%VepV5U%U%rU5T厥* #T[4rl=*>T,Ǝ~;qIm~-"p[N,kʒN2MbbY+yuk %=5BedjQu(ghB͢.&&F3z=X[ )XcG밻X\ؐ!4< +堗~`K k6gtclRqJBBFW7WWQ/I.xHfZʭ$]+cۿ$v.D'?e+ E*z]VHx3[vL,ƕJ w`5g5G$MֹqY19geN7vz\e1%y2نR%s)xYjL]4[rp1fScP,*Mh(XY{PY{:,$H]RmXe|'Ĩ8@ m.nK.E*B[/|݅757wq45y8XvwP3{'۲Fn]HGn 9xV~gnsdo~n QۇږjW\_~`5սFv$]*Dok^>czk,'kr;7?p~lOSz?_R7_^~=9_:ϷRZzp|bs2NIZ}do|\!ai7fYs FCA4(GBT&kw)Xij/^1,k]Ҕ_~q'1-&.Og[R'Œ{ |ל>}y=?lk]$|Oğԡ#l77܏([MxZ]D- m+"y$¹v{A aքfXx䆵340W+t#ˏ8o/wV k.ڏ+^῿N␙bj_lsmjL}BSth1rƞ0/;'jHo2޻! ecFu ϫX@UuZ+yk*H7>ԷFzr{(> +stream +x}]9}sYNP_}KH0f`v,0ȅǮn{cHPԩ*wO ݀+IQEQ:~NG_}sO_n?;cirsjm]enr97?_˓)r!kex4rϽX{9SnZNKZo6r(\,e[(͟ %nA,WG\[gI)ÛYںV78N}{ާ@JP4S>`7qv(kqS>'ʍS^CoKM$o&9}ס# +s!z@ RaHW\ 4l`ڵg]nS?;åar:^B ;Z*s$.NS r PmP^xi@tApIj+X'7|Cuf7o{ӱw"ޡI4EP I$<Ĉ޼ѝ땨[DzwH724j#psiWO^)ʅ/CYt+xs,+tp|R8;g^o"}XVk𹫢_WE߭(f'Qm`?|oG*n bsZw7NoSS.1])N)p;mj_eԃ1 Л~ˣ B*'9X6a%X"QiNer[Ƹ餽WhЯ +,Р"D{Un׍Wũ/Mݴ:o鋟̳JŸ~Rk~QUiXWۗ /ѶM&_.BO/F8w}6+ۃ=wۥz:t=~Jl7ƿ‚[GG8u]zI1s OާFzWeyGhO^&9w[װ.`>GE7*# +g+s-Ll*{7בs>ߕ ~\0vnӞ .47bDOߡ`wNpk:< +BBF +$ڀiݔ R45 zۿ=١ۊQ/"{ſlYdp +nmAO)BظA)~]` A߾9nOo̕;}]ɧ:oӺw7W޾ܿr˷O4><Wmc6׭OchKK@+ݏh?;ܾ~|ww>ܟ>ӗ>|>=~wL ~lXG}梴7ګxӫp?!p?zjDifTf;O.Sn[(Ⱥk.o߽:}omGH@,㶷߻ c v&u=>L˲ow D>Q~4+E=*A;)!].> ?>}~?{@;%DeOgl쪟rMš?yީ|=|a5?vy{SCbT%j;u+f 7ʋV +燎>w~^7:] }p=}{K'Zy}ՍzhtP17sɠz؇lÏctM$NEt6PtIfPpw.}LJ{gݔǽ?|z 5NR;_wIA ?:US&iN_/:Pm'Vwɔn~9Kzjk"L>a/"f.]/eE( `T>?'p/X UQN;AĕUX~٪hߝ`R'@(&M`5ȫxZ :4}_T8\v'liJzY!s#[Paݧ[٪/V/:T"b@+TBIA38Ĕ#%$.pƣ`@B{5 *#z3PӜ +nX!>Jj8#@z<4AUni: ԋEF @xd A de{J3+:Z* +Κ+eBc3Nl1=ڼ$w"%HLc`>|QXd5uϞA8h xiZl +)'AU.'|Omr Lz쥘bLl]2I-.8r^1$*~|VfH~;kX0ȁUݧ$,D,Et 0zVERZ,x͋[u-" ZFC4Fsi%j^ɮ줽#>vHy/3!' 7W c Ćcע@KLegG[{ybEN ˢ0t*\ RF[WF1=+F ![Ī3y $jE1\!lO{ cknUER rvs0(B#$9ԒmsY8-ci (B'] +( 3X$.iP!HC; ~thzhY z]վEp믭eRH뼂@S(kTŽ@JU:ŭfBP?kX .+[J0@ &u 2kXѪFQyR +#ymoaCkH; +}~SDDN~[eZж:0]Yh:xqьqЪ.tE%0f'jLAmkR, GrLpۄXfޅ_gRk[ +jf. I,‭/Sr3[IBmF!o{}= 2.2_dSyMAs\0}X"k +f@ӓFzoM(KdKҚIvAV'k\"$S`y4WNl̎\'DAL >nh֔Tm`km֏Oƻ$3y__^uixW:л \n*\-Q'+0/Y/Ц‘mv"RB B}%tL/d'5@Upku-VWq +.Ww]\-%Kf{WB0.B*Gzf6æP6ˮN]טUզXe-\lF)+Z+._ۤfsE/>W#$eK.UJ'踛I3dqN(*-yi6.|!V:ĶY^;[گϪ[0wM{^C}^dzUݚ\u4 T D9y/7Z2Iuҥ%AAxX8ɱʳ:<- yE"}sW< 5Mfw4*^An>eIJ;cF ;BayfQ063H̬4jr5bH~*QUE:ĕga5IN+qX™MΫHՊ^W~qXNcIL Yf%χt4d"ImV ͮl4GW7;noiIypuyYҬOG.ΫqݶQݶTtDЬ:}K`QiO鴬M~Ze) ZODjh}ھ϶ԨD.)s2!K3g?'Wo9 V}Ubٹ֛ 4.</#Ze 1Qi7[Cm!cfI*X 9zl*ˌjnmkv¸6nf[j?Ӻն_dˆ YӖa_k;uQ{;iDMEwεķ{Yuۥs [\w_uU?CQ/S֯JӖ}nBR-ϥ +t'rkO,+4|4@4ߴs Q y3 q5g\gˊɥ` WW3ۖ jbvP q˨Vp*mK(kZ"V\堻ߎ^vfin GM'F;Geva~҃&.[Rh3Y} ԟg rVl1󱔃#LA{X+dvˢg[&b3b@,';lEW%S~) ^*qla7߸~^|!k1\xM^+d}8Fh`Bևt9D v~˹&X5r&XzLO4rSvUg1{Y~i> 7rf_?pgЩ͞o[9!8"[8hMx#nT{YpevQzqP l٦ /帍Bꞵ~W 𿮁9h^m¼r*}oy<#eMG<3$D=-n7ƯkrX3{GHEɤmyETv^]plHZs=Ɋ9PUn^. Oz@.q]:Vʉs|!$(s;~'0Ej^cYEwr/v$:Ce:uC^̭NSu2/l6BY/znC㺶$k#(+\І–UZtŎԻYȃ>g(!s|8K\:Qo +S 1102 +M4mOeno2k'^obLkKsI+zBe&X;#д.ȞbtٝG0$cPԦV +V[̛s!GCjqS!)y?̘NJBY52Wet $g/ 8Y^Z(uKIDq2v\)#!X?شsUub8NN, nS}1n +0 RԧLVA|IdwU4 4! K)¶8iGU/(+5nj0eAnA$FfI]JիVUb̚`vMXv3I\\\̜+mg&ӋtqDzOUvHLmPfֺUbnvZ$˸؜ ΆӤ!xi랛W_-v;$591[ўkeVk\]Vkm_eȮ6W\wvO~EW@uK3[Cxl e;uQX7ݏdVH߻c݈l*sǾ6=j|]cwl-s1SsnE<@Y`>x,àvn`r/w,q~7P{]oG$XxSpyizUD9]g'jWׇj]2hK3pYSASQHC>uQa{vG~B8蝽NDC+Ԓ$`Kd܈Lj`98Z%PzIdQBKR-|Qvwl/dTq2ct,P$: +GcQKCyd9ˑ0mšGz ^.KQ, e֒5&C3H~xIf o"dh>!q3Am d,5A_\ ncH.8:m+EqHbwץ#+;\*,r\.44A b˫DE#EEWiraYbB L+FW1crP<3lEPG1,yӻhtbcF.4+Bұ_PW(kr + 'P(Pҕ9M0awr@;!\K,,raMEcd-5Xzq֛Y+ &Hl_&Qԅ^w,3[0\oD۝F+oQ8,d&7..ZG~s(AW4C5m nx%K&7Pmō+/ +(y%@rzo]B0u +]h궖@K$t,LH=wȀqEH,W%lmTcs[&3 $&Їv@|B 1z\˭ uUvAXK&%ۑWq-zQE-8{R;rPS\.;Hm`3`Ԫy8b6UOr&vM"X™-9\_BwG ~"N7w6`LS梑jɥVrHGTc+m +&h'$t!/Y +&P{;4^\aQH<" r1[R6@^~? b8'X%.1#" :ɦG *hXӛWfҸo䕖tE/sTUS^GŅVvg: -ʝe"o +: ~Uv="L .dB H?&D USTb0SΙhe{Diyz(AnJmermwTV֚/Fj7 e ygȅiacO7Q]. ˾וk`\pFks)t~ Tx!W;-pUٰ7] -Ќ~0"Xp6nocGѬ(:.UZyw*-QЖ3 bMCd/rBC +d7hL%[ә=IG`8[lgڸL ^.j*{BȻXd7a [sⲤN~H+fN^6{)@"K'ZQ\*v1\16;0!%?/"*f焓Hn[8ձb`d6g "jےF_Զ7Yfv AWk,# օEwr]Ffp"?AH je,7<,՝Ց%UE=(Fɰv!CʪZ@nz[ /e-VTWV!|h5X'Tð l.Cٞ` F=Pǖ,Fsq*U-83< +M:5_qLFWJT m > +stream +xڭ]]$q}bIIkX@5h sX,|j|YQO[qF]%zͲKeyhV\уJ7FZSAӟ4ݜҮ?`eג^bg'}k:'jn~݅՗0yRy߾BTbĬЭ-M;v22[tww]%''&Ikлxjl.Eܧ; +dL [jC咏6#\ՕZ";fTݖ0%2Q;R|AJb.(6na3Uj[V@i$WqeJ-&~deR [R%R'Vf8+/7cg,ׯUa!&I+8tN92!}G. XeBgxOX#-)p!h$#]&JTF{uH_ܐ u%oF3G<-}囷@-Q^q@7!"Y/;|]]u? hBH6@eg=\~U[U1Q6&$ҥ/G3`_77B;tx4BcFMA'7Y"LczY +"L+J-|ldoǦ] Qekd$1id +^|BH.oBL#60I$*CvhmC?1OC-|RrXn'ZYښ%!&:Xt` 7>aBm> ^::2]7Kn,`n%ߙ2.14[lU `V6߫_wkVceS,J9x +\1LLoK„űo`Mg /K݅D 4 FXA +$ruW__vA\ ~sF=1"]mW=1Ѯ J@}bŰD|2OSMZ X΄' B7siSi9ܠfHfLWɏ"ggeD_WadfZV#.F 9Ev]-FJ&Fz1۞ʩwӏ2BEHJɱSI8<.1^%5EMF NC2|Fp_ jIDեNwA_9 +uΚ5$8R$гN#HȨK;'z+,2;i)C훮Zo dVlc6qY +Me!Y`$T9܇KE6KJ゚S244 y!GVFL_!*rsV猈=yRFC^hBgPJy!)BxJ[7vpʼn =[ԍ # P냥҉~H=W&0C tj(8I>~f7inTjӏk=[#v6_GAsiwCYTS>+o;FdEWoX@_VMռJ |yqRXYiJ0Ti3G>М<5O5e'lqo>cawޚfCORwaϝP^ƹ^mMnk;\[7rOx?wq5´VocGM}!a.B2QN +T$HOzW{\iU<ͳ묎gkJj#QNXp(Ţ#t>016Œ*"c[`dpoS 'ւ!0@&O92k>ҹN^(u|Js|^avZ"Br}1 :S{ˢ`\޽YuQV4ZRb@1&>1 6H4j+^{ ?L|# z4pv0ݛفتd|fDY(3y$bݱedH:oY^c1@lZ~oӈud˨AIC )7SVosH'6ɱB,WJD[wInQRmxB=& [{qpo~$3q!"^](9 27Sٲvtt͘c(K}9jOD`ҀW(0EQr.gKmZ4_@`42,1 +No 5ps=tb U"8 GWs$T0crD&2i +<7z 6  k`%T*ZOtf"3)RdAj&J]rͽ1v#;jgLȼB + N(9L<6s`ʺŶN4J]B3_7/tz<=2hH[S8uպPpp2 <_ǀ]))g>4YXD [70>lILL*Vnky;*hUmǤAsz+8;{ +9U^{HНlVjFMDˤM($ -A{E+8XlChgR~=r*!ޡNh`\32x ŨǂJ儔R^拤 b6F)xBAuޯgy3ulkm"*nu1#ߛ(\~v<9K5ʰtĪ1 SEbۇ4ڑ+ZѰiFޘ!K-:7Hntކ{P`<ӪB"3K, {RU{#038M-3T7>s1n.y/`5܎&q9NºR88)o^7cN2v,BgH[X.x-WeW1x~V2_ g윥NFYYpXpr̞3m7nQ% _SlNqA*nY~lܓXl +C#Kl>6&wN[~bR3,)p %6*w7kp凸@ưaS-g%8h9@\+М;puX#[煌c^QazYwf"w5 +kHJaLDWRִ^o#c}ubJ\+;&P`yXIeGL2U|c֜I7 N){D<eK=c U%n{C2 w;niOb; +սIaXG]g$IOq@SVuG 0<#E}vϯ+_t<3UOIW 5Wˮ8DVbS9MN^ݦPLA5eƍ`pau-l&da}.dC2"l +JD@ mЈxpn!'~[M`!4] >Z +`[kإl&]].DZNN8mqŃ4fg@Gii"'pOazy^'lt1oqamA}eje~EyV^ES1&yqt+W1ћ+xUvʑ5K<7Jv,6a}DV*X>8?z#uܦ 6ܸ#uLL,bHˀuMᛱg8& L&;i}gh*[<e/TXR\XF|esIcҰmY#AXUW/{sl6:E5 4 g&]صy 4;0:qmS;_d^H`H.pROk(ؽmɡ!@RAdB.3ӎضqhU9e?PX \.A1[E8xiXAOUqPްm;mxWwyrǤ%/L#w~"ZKm979KV?Z.YquVHt¬$~)yxXvOQ ZZÅFD:W cya@axPۋ +*y>'QF?#a d޺51FN9KFlkLAؙb '~扂kZa+waF6tXooz{y:i|E88wkcgo1 #D.$} }΋&6DRcoHixƣTks{yi:avmOir};]/p#SZ!x%C-piM\$#S+Dnȹ}D1NڿE" c v܀usp8d 5/p>p.};Slx=%"/f~:~@?bch 8&O6\kGdZhӄC/\#`Gcǀҁ +:Ak(P;-?f&;O&Qj5Dp٣>[>-~+L>rqnN]NmefSu sԣ֟->]llb:AʼnWYM 0oO/q{ ntO<Ń*+b :vWsVIE@Te׻eJzYɲ|lsʁ0xl̯#0N)i!sb3 KGG_ve~bpx퀳̴rG-X>S-ir'`IqRlۨШ-"`*oH?=rl0O4e(%v(ym '<3c;iG0qi$pv"~V\6'2;'`&aufвgkT=K\>qZ9Z200`]o?D9d_>7Jc9{Ls,i-9 ή<UvvuVЩ4'޿ܜߥ?_Or?3姧 9:7wԞwKl}[B}=MJi{^.v\נsֺSlOSd&5Ŋ2#y +endstream +endobj +282 0 obj +<< +/Filter [/FlateDecode] +/Length 10352 +>> +stream +xڵ}[n{>Z֭TyH `_sl^d#HV .To(Jx +uv.{:rNx>p){?alϺR]/=Q1?W1oV<Ԟ.q{)}TSw6(P5\R/NOfIWzz(eIJʓ@;KwxKB*m=]rP+~JR2+лB*+=wuR@v;.`K8k/u^J7)؊Lmϱ9gKlu;"*TKf3LV 㩊0HwҪF3=z[g0l1gY(}Ge@0J;y(ԉ۲PbCG%J9ʁnqSg*7CRo* c?Tmh \OΗK%U4 CGߤO{C26hR.0Sp'?NUtx\|b#Cf 4!K B`-6VWxH!r8M4>#  d@aV8 ` hO*5@*]4&-%IlV/Fl ֛.&ʩApD:xuOst;hۜ`5{qNޭ +zx봩$sj5Zhq\ +2 UA?u>NyߣSYd;l;uо Vdv7;SOy9[v+(Oq0q L K6 _gv(`;aRUgjL4b]n ș Uc*o[JJDS*#fyܢ-5ҼUӗ1nvXׯ!og7+S.z~$icYyR7k8/\ fu#m*B^]pi^C:e.O/si1B47wOry}xLJOb|㳴z|,xp_N/~? +{^s:y؄ieD;N>xvOγwO}Oy{VhcB^,9q|˻׏?>;Y1jߗގNNAOoOR >M^{W&8[Tfr?ȅ?~4]Op7 6pN/%?vSg2^!H~ѹ0?<xLAȍ}x5묊@d>wC/&ETi{?{y_Nzׇ ǗOOCݳTsF՟>xt`;f?,1vtH.==iû_%x",wOIqZWG.xÇk Iu,@:70F}BDj{XP}q:@06/_ySK/pHJvނA/І$9"s &l*ǐ?}0U\Sc\#XŜw-a+mH#Va/aZ\ r -+pw +lE4 4XQ,t2ӺoV'np Kdrf""d4 +oi*CIvbM4K5U:.` +YAJp$V$§@PVlΈ\ZM1 ef +~QצLUvjY+6Q !ڛ$SBIq&$9@IrH W> +9y%aT7etO{4@Cxh$| e.~@WveH$H>Uެ`b !BG-}Er?Qe`pʞ(li(R] $U,#аn&FȐw&wLցdʀ*bn=EAbQU)J#B``#joki>Jhc5\>o{zcbPY V "CW>maa> TQ,* }D=*qպ @<`tb"*VP^uvJ|?PZv~“We-U~)HK}4<G?Y͒q;OYhIZ>J>Pw䰊Te*ͯnf&Ә /~"K衦"p\^ +ȲǩTU!QڨJ1Q@A}A}~!*͠M蝭ͱ"D/DT3*E &/ќ$`0P]Ok dp(bU d @9!'Ӆaǁr^/,ɬ\ iW#[p  bXK ]Bz8oz] Ue "4C4. .. YhO~`%3 Z.lulەmnKg5sHOSM5:l:WT#_widgk,HW77u4@Qk:hDǼ; _!/`_i˜΋˜YRd +fv?0kImsA atJ+6b^90I(m#V0bbWDY-mBңUXU#cCjQ):Xhfdn iE`V7W+u’-y\-)j bp,(|D6y0k_.#ꪞZ +7 1!=٣ɚs«mqUqNZ\0o񉒁6 TN+cOʇ}a4gsjA +<@_:`nxu9I ds% iqCtDONcaFG~Ym,A_-.6.5>c u95 RA(PFJ 6 +t6^emuWSksHZwꪐ }if-Sϴv%qAho:| fK}iNiC)\|eڐ)*3>y Zy}vMZ]køu!>Ics֮eF6'Dw/ӶDȬ>׫`oBe8.-Aˁ[\+4E+ͳ4G.GoX6b$24U@oH/v[jEZ5CNWhߖ=@yU_ۺ.vs֧󥼂NhT fǣ-$4 )QۼkJB^݈ahiXDkL@*hpC +ЧPxK>Vxݻ%B; VjeV0K XnVP|8$* B[$is/ uXED +r̳wQyA<;-dW"b8l9]º& 5CqA +tpðm-{ bCFJZCMϲȉz`bٍ1'h*$⚛ڂ` +V.!1ȳZ;UvWYNE*e`\Ej<)F |"QdfvA +iMVI-[r8qkH M#W`m!}UIn +ghm.C5@Z'L{u lJ˼`LZvƵDڛoY$ $G$n9sO`?VpZ%DݷZ?Vd*=k; +7PW"&WW#mסS'ȯNBɖ #󖥒*>öCdg`&Z?P<(F +p)PxKbYSF\&bUXXO(hrQ\`PJ'50sţ&DKT !Ŭ,g5'pE@%\ +i\]ljSK[R  hHuೃPx-*x kQ([As󊢇fّ߽O,i6:̇T`xttoJt%F剔?̃!qyN:?W࿡Cϧ>[n#nggEq|nЌFGf\=-AӍ w_`'tb*:!˗Z!6j̏+:ηZ鎙_ +.'Ą3> +ܨ:oarϔz^'*.M2eI/y+L*S×!<ߞ4.D+L9AAOwo,YqK k(4h΀*甁tg?Q&QI#zUW|#-ͷ2ݭ dzFT)nHSs +D@`\̗o%}K +xg|q55J> g@G2:~{W<4Q FՓ3cg`y*dt790~w"QS_"^o1彽j졩NS4f&ҦsHUuKr7v\(n,߯%穝rp_7LikYl<|I e2CLcQyJ[꤯K߰jQMєT^쿭m[(^7&F2SdESIhhAU9AzAp, &6Gs%U5c +^%J+vKN|Ti[%ᒋbɧMzMW~!60r4`g ~beTX3VŌiz3Vb +R"RQ*GpȞ7Ӣ^Gl=G;su3INqכl{g_К?S)^eט8}Ҿ-{tuE)^OƬd𥉉ܝՒ22*n0F> +EHhFL0*&? +嘊Ao,MWdw>2v n}u;ofY +s8L]oڐOMӇḣt5HJE 9K+E/c]'/]58YU + NE阤,KJ_ x^b4,Mr joqAjpX8/5mu&[lD;eۘ+Ȫalۡ[{UN8Xr@s]^#-mr^sx! @^ 5lS5j~fAt,1b:^-E9568qIԜ9aI/WZPn튊&0%424a4#`~n 0[ ӡN#`|@PiYg$TrJlsmǜq'8VBa菓8//ذ jsȗ+HLժn5ґw8\fEҺFT;yʣf-_3 w@t)KLS0u\ |uYIMv0PS\:,;4GVY M='mssz)B5hZe +b2%hÝ޲AMu%Ko^܀ 9#z=BK6\P|M&Dŵβ/AtͩU{7%`5q%vQ,pCoj\L6Y dbf޿TBU.ذjV%嶌+Q\`@Qy7͟K.EYr.yYek7ŨFt).,DC.xԯ H(t^t)#۠J,<,YDc;f6lcnH]W8V̼QLLi1|rw,lF8[WFij;V(::N>EM(] a}SuK]OngZYt٨WoL@qyj :+.>ƶI`n1uH]gڃx=dgO`oG.i}57nhH\T/O`vn|Ax!&ռռռż6Gbs2&_mp/w4=pN7]P=`Gu%;DŸawce"R_U0Xvw:*dHNzs{ 5sĦN@Np}z[ +"kyHӼBta" ; G_"b!KE[`C%#m)!  +A-ӣ2~C#-aI Vu`||'QU1g''nSQ@m%ϚCw2c, #GӚViUR榌j`Em=u$W?WlGNaEw>w +Ej? am鑀;v ҔݥŮL{cCI"Cp[t7m(8v歎+@ڃїs8?\p iL?T$tKi'ɽJIDQLu)ָJhjr]Ny ֆ6iQMIo'=wO>ėhE M*ֿY2ػCr^`g5ŨC]..+1ãÁ7/XwI5+rjL*wJnے{il UO+r-ievP@CR"jɔ.uRv!cF1=8+w/9 h2z-ݍOگ3$w4HU3 zg./\Um ()'K IL@Um.do߸o"'1 @}-+̿9&*`Oc'QHV=y5y5Ԭ&dKrCU//d$ T H /#E~ +!_f%ld5šaB*la. vgN3A' 3r~!Eb(n>": cyNEn'.3W@R0 mOǑGC[\ٲACstYoS>H + vWHQRk _@^ +SURe%c2lB87& ZߒiOl!A!kWՔ6 쫓QTV/Mr@p[4TMh#avJ@jaqjYz05/Z͋VffTkZ6grd jۀt@Fށ-3$[GULmPL2xӖ4wm`+B4sHړݔLL'W +{p{X%0 5duC\F#Q&i zWI(b봫ĎG"^uMozUXpqF?Sx3Ѯ?*Q \Uf4ЍVgQM}u^3F˫li1V0:p:x`[Bf mU/V$+nM}]vvyÄbe I6IVA:أZ &XFܓA 4` ڲ0w ]wk`w#5G"QoUTQADIiǷ> +ט2&>!1rA5U} !xj^V/F NA`ko-0/sa 9i/< p-*]$=J~/ z b畵~%<@3qZ%m )ySTw"Ɲ3iF: "sg4ZTXJO\ǯ%Ju ;-bO\TW#X)BK* FMy* ۢ.ubd:(Vڊ'b .+8p ?wՂ+r\C;~w9bpn,Ab_R632 V[*^"Ĭmj 4oUұM[}/mW/D7S0@M@V徸}тgyLu:c5H ҏ ~"@4*E,~`YweT!$CRvߛЦ rjwYV|E|jDudUg~I ԝ ~L0Vh(Eb+ġ{t+u5y!UNhV] Ab\\sk6j'm/~(_v7[h[֙~brlu20?4w\ш0;C[%jn.۲7+UY S:ōMҾm_½l[[g .1jbPV눓2JK\k99kXpqpmzPʕRܡRe}־Qa[T߁ڞ|ً]5_Ur&V>``& X{E5WuӺ9"ؽn& i]XE2/Z49Mij-,U-k4YAq.;%dy^hЕY.[Ťhh+UKFU--N}ۼXXTl+Њjv- J"8Ou +Ic:ZS>bIͮ!h]^M8^%JA+@m]lՇ!D*ȣ7l\-1̌Z%qצ^d1J=ӥ|v^yx ~7n:K)*K{qg9ܿ{!]_qj#j_ǿr?L(|W |'Z1/7pàXQr a~t]@;O8N۹B +endstream +endobj +283 0 obj +<< +/Filter [/FlateDecode] +/Length 2773 +>> +stream +xZKoLf$r#a[ +4rVԓyH0 MX,V}ҹ?qwĩ~L}ٸTp>~wCL{3b +vS69s\u;sA=h"Lȣ3ɵhl(" Ť`ǔh +q31з7gΜ)%%MdK4wO})K+yp>h'b vOS`߀$}a4rK0'o uJ&71)<#h&EڣS9)nV9uI^2R'c'&x0D?d${Ʋ-vs8 \%r{sn8Ӡ38S)6 [r|4#4 yҞ(TaZ6 уv(.LwCCY{_h 4q  Ǽ¼@¸BY\qPWWKN+K ը/d?x=4?QS  b:h՜eǗqlxq@xbLrV -L{WTq;4B :M?x_$(m֬ 8YА+1ԊkHF^-<ᆢJr6=*8pUtVB\1[iё;\A2 M 5/J` + eHm)߭k$ +a +B<pR_V +59ᒞaI_,%VM)@sVlph@*N]",~=Uܡh_BT--s #ϫ17VV#.3&TL<w6aai?7}q3Ww*:|e]F Tm( d'EMͶhn7qCcwCț `>;Q>H6y=7X 7nm!QY1LX!&r^`euiw[7mn}Os*\<2[Vh,̃2Qj|Km}y[8î8]\C=,L_A3Sc/m:6`v5kņ X_}Fu׉2 +CTc +TZϞ{T#J}Gwij]RkrR_!,mTk1Y 1c}rVvxn3'V%Xv빜Hd Q٠+*=4k,M+wO8~i@yA-5tG_f/'JgH"$ſ+AsRTg: %c‡e*p^YQˈlqAXg]NxB*B M<=/q uD 11`O/TY.UIbQ.vcLP-Iu_Wcp!P7KJcA}6*9Hij5Ί2 )\ IMTk:xPӁ&}[D4RbpR =rl#㾄%(Kypbh$XR)jCUoЛcm$eD}}bX! 1{ȂL+v˛E)VOJ]D)&7kt۴7`ܸj)XcXP_a:`%̧Ԫs5|.U/e\t \݀Bg\PV%(`$A&0ްp)>?.,O9P/6mv#K׈C'O>ܸy$tA kCp l\ =fG6.oYVcɑ:gQH;NbQ7`[, (Zt +-E^:!ɫh]T9G( AFˢ|$ r_.lWZFEu4DҦ,F1 EA{Y.Q-% `?RaVW+ ?d&uԏ)$șH)=LrP|xu2 I2k2) 36sRKʞl2ʲٝbB9d7 /9JI~?zʛ1nkIE!{}u +endstream +endobj +284 0 obj +<< +/Filter [/FlateDecode] +/Length 795 +>> +stream +xڅUn0 }WQfUWz t6cPKCm%"yt'I㶁D +c"هdWZ + # v^Ml(Da4M۷ 4yf/w$4fZ V/l1yNjP$ݲ'N Ahi%O D*8s_퓷e -NL$Z9N=hְI&͔UWoΛ8.xz?h1O}ƔBZTD)v M Ph|%DفZUz_5mL$*#jwLgA`߰w0w|`XEGm#/ U 03+@#/t)&F1՞wȈ N"`43ǛqWt\ź>e| է})&Q®mAD=ᬪBܠ2W*qI#`&Eԙt˘č~yLQU` 4B~ip _اFzRоnWVa *<_u@UE48G"?鮞27NK]$n,|lSC/ +w( +endstream +endobj +285 0 obj +<< +/Filter [/FlateDecode] +/Length 1195 +>> +stream +xڭWKo6W(ДoRעm=YƻwN wHS7y|ɟ43|V࿽>F6xnQHa9hiQ} h||?:H_Yaͫ`0 +, `Q@"Z!rYHhE#+H-l XS=:7(QDIs 9#c̲t+Wg} {%!9$οr NfU_"mR1 *P%CΝfĦVX,bl&M@wqBͻjr;`b:.yrojUi,?TiTC +YPjHC +k 5r!A%!)T61QiWy"OVj LX̢Υ˖g^e6,{Gyǽ'c`rK/2=9AKd< =ja]Hb6(Q BFΡYʞ79^N3(-JDa M堨nҋB73sg(k.9fZSN]KZ@8[ y=!@E⽶ZXlmS,: }Y`efcxXlo%gÚX:.,8 1 9BLjp/GPY_e6JIXIuPu$\I Ʉ~bzC?=~y>Ʉǧ>ɺ:qQ˝#aQ~O(x31hLd*?eeDꈑ'F19q^y>֝/J,\GBmq?+4u1<ހxD+rr3- #ӗ'uez 䰥Q!?$+AG5w$ؘ+i S4G^'Şt9q|o#)ivy|aB?\g܅0nY1kuJYiLqR;gq~ / +endstream +endobj +286 0 obj +<< +/Filter [/FlateDecode] +/Length 725 +>> +stream +x}j0Vu-B mM(^^e!>}Gz h%x7#dǺc&/').Ǽ\=y7H+e7ݛg_S "ߎ_K/7n@GΡ8X9#m k9_U6eR[QYz?r8r?1eƅ󤬳(HͼJR!V )X!pj`JѪ S`0@nabI/(F !U vJhB& H۳\j:L w6HƪE(\ &FO %-)򴁟}G[>y%2.#DX\j4a`(BPNq"!&> +stream +xڵ\K$qc,'I^ f0 VAZ כ|dU$xyr/嗧kNro{V ^=TH|ݏzK"O68w=RlzTӿs6zIU l˩W_]-]0GO?S3c[jKkkINS]W6ib6WesPP?n*ך(7duFͧkV}W+x#.5)OrQ#m=_sHKtGPpڐ\ˡ5h}&:֥y]?o}bM@txzA$}{T'^ӂOꮟ'w\c)԰\9Do`Zȶ|HWBvm7lrJm)YW]qhʁ)pWAP[ II((;I̦G gy;6/>L|$ҡ d uf I.M/)$bK_Bf@!TC6\5ET76wt~;L8EofOɹ_9_F9f6XIw)P4z(_*J?]!jO#6Tg +ߜ id*;et϶;ԙbd|wҬ~" .WR>Mf?.|A+HRڑ$ճy {CoL +gKk&뎕6AscjZf |y5л_Ʊ64H{`[(G#|L }7bF|i9-C7HwK}¾_ڴ]e48`4Prֻ +U^ ؕ;¦@/]sRYFјEv/p,\}tosŃ,j:Fݵt,`$@ +ik~%9Z'"^n I̸hlMu1{P6q&WGl>FħG0̎q%(RכUz>sd%pB/)E4Bu1lqyid ӺxBT$Fy&=fi01C#ލ `8~QH2O_KkiТl~>?(ǚ v-]Ali>+?Aǐ0[NySbmbB};`>JRm{}lO5&&{OEݎ>=vd<*Xw<B +F a\%nOdQ,@}ՇA$ê"B"hw> m sCΑh9{؂1F]tl7ްYeϛؓn&5v#W9r2Mn1MD4V%,A8$~!Nđ-^ +W +mTY(<Ƒ׌6 r +!`{m#8W 0.kR$Go%R/+zx_܃".i,\ڡ#vx4$`eVJM=@ީGdCI`+pMS3=ϫ w>OeBD]|iB7@zDh£(Rf)=_A^g9M lo̒w𴶣@w2QgFsgPg4{CDgeCAt Qu'ONV@ҒiK q +5,e! ,_fzk,*$v@8cmqΥ^Vt&k*X2Ŗ~%I#E~#Of͔JG8%IǏwG_hoΊ̓lPz/,9eP{ܴzJ*lC(9`$v?(InUak{]֒^ٚ~ل̞p9 lݜ7iL,qO2Ŏ:h XrUucjlkl_M`[,X,{b6e<+5XU9n j.앸9ZTlMs ,PKc3)Q>UY ?8 Nƹ nQ%q` 7 + B{+*S#>#AfT?8SbO ~h& ch@ńXr_ xF9 kJLc9k֢|T ytXgt +׫<(L6]+P+$CF[KX˵L*F4AÏ ()Ԅ2N$l*{ѳ4fmCfP\)Nɣ\UX['VUэ;\c,Hy@JSNms.À<(yժS_*vqZ%,҂qX}~ʱ6`!= g2a1ִE60vA֮tqRʯQd@*îâMFaEQH %HI> <)]~ɗO{+ }Fz≮p`ˡ/8+͎f7j ++Q`UnJr4Jڧ8W8f%Rta~pv9%NdJo}m,:D8Dw|r6KRy #TH]-Q5\0Wiw(T/!:hHr}]YК>vv8L,zLkXh}25k}sIy> +stream +xڭY[~ׯ㨍fymZ Z /A쮂ȑfA}υpt5؀Mr;P?/l;-^R||WZu1"-~WFV(keUqm- @ n@Ll;7 u"^V4i"q>n'|mCW$@j-yo$RLsҐ Ԁ[|DeT.5ɗ7يFv,&!Cm%5x3h|b(SxB*`\kB:֑s;D[ ۥ i #@Aqq;<J];l?[qSRHgL=LՎ@۲Kz]8(Ҏi_JzA>qk5=0X-Hjn{$%, ԯڝ8(z2%8>C1R>gSc`{&5e\ȯJgRu`er|rbڏ~G- (x{i(:)OS~tne{$+.`@RE=i>8ނۡrb{ & !XSR\rhXxʩtT{Fs aQZ}t)vbs= x,yʛt/ԍ~Ѝ.˘FRm13̛*z!pmNֹjvS@ Fuc'yJuՓ`kU1'ta3)O)J5]V mB$^w/5N|9cC:5^!Do}Uaۅ6\wԬ)I[O/ΛT/flmaEo8pmNzNOLS ʬUj2e0b[0,@ +M +nA9N3-6-u@8_ie3fiN z Z4MS)Bl?vnp+4"ɫuqt:OKN|gqe2&u~;}u:\"yN'P{ALPM[&N/u&=ig"Mb_&x 9$Ƕ= 틑ز̗.%M[;5GGV/JH: 1S&5+le'$œY3@$ERUb]yM29FYZ@HTzFSJW _8ʷ | F43Ǭ1LBWI%~Lb]BEI6C! Lߓ2io3YQ&3 `j_VI7K4rNt߽ZS%/vi4z2[]*sWZՌC;ݖdR߳s*[IYE?/Cdo'+y:vș'uzf=RVRuG)2īSzO A}WYoKv{+OO5{,B3<;O̸f%# DQ? A:ǦSJ+ڤF\ + +7y\ +endstream +endobj +289 0 obj +<< +/Filter [/FlateDecode] +/Length 7780 +>> +stream +xڭ]ߏem~>8}t^؎ɦ5"Ν;3]G(")!^~xſBFIC{F֨_]vBA!h.PHs I$`ZЏ'^QGхr"6eVfH:!cQ#amGim2%($ VocJk,(GA((cԉ*"݅쏺,ee6h+bL"ֺe5쐓]# r̝Qa̝%5E2iHJN3D@:#_xǠ8EwFidKÆH@ }JN=25jfmz `'sqPF㢢S1"ۤq&LŐN &H(0v,AIX=izPèj ǡ˩A<D0NDC`(hrEVbB^s6\Q P! T#cF"r c%5rV:!1CJr aMS,LAPMKBE? ڼ(bQNs Դv5,l 8wFtt1A.hn%@ QIw:#MޤV.B;rLS>5hgs,˄~Oꅽƌ8Vj +A?%qͤ7'փC2C- I 0rF3QOhR8$bXK1iPHԉ u: $,C aBjX ya!,L$S)|j Sț!ƣP ɧb;S,UdEH^[iX9Q)v;ʤ \utKzݒ`?X*ILqU0ܿm p'2p6$çvkq7n΀3]zϴ׻ο}Upu_/E36%QmU.<5`$( oݽ@W2rtKr9:''`nrm!;X\mQzö me9۲n&d3QhCd wjsn7ΦuӯFڮVe7"\[id(ӁF{9Gn&Qj6˼lX;.:v7sUN\:QlϧW~'bCXѝd3۹Hd=蛞yt(rT46yolom/z6A6|Y֩=lLAIbooȿ D?zr7tnWd,kYvXdW.c]}{;i}nOT/s\ O.nXtlXv +FohQj;">$ h)%Ս{}qCԾcP:bV48mGv8]ܨrUB*9:ж΍Ѷa5He7{љdmWw썂*A;X Yc*Oi [-CJh5rγ!Ve +ߛǯpFzk B0 AlH%y%] `QlkQl!T'jC( +mqlQ4x,{[٨R1i0+-= hc )!S$EY{P B v3nqfekBTIۛ/kK; 6 +U3/m 5uK`;q5[`[T} l+82C:gBv)mm/%ݩ]UJ;$$2526 CC}6| +m.0w~?pw +o'`?m#EEuƓ-E52G? Ԝt ÅY/ųݺ;4 pt1wѽ^b<^r]=Y(Ԕ{&.ѾSVaSMTUf=?k9ٯ=ur/n5;3y-c/!-bRףal[/mu;k'+B /FNV8LK3~9.N9$/ a-ZEIѠFY7(F;1;@f<`HW~'wȐ?;Ku:d0ݓsvt5,rg# ):-NZhk l#H]dVHtCCqFTd[*&S*& kBHԾF YGrXG88d@ ΃c|uԋǀywn<3:8\65Vfvp uDҡ\bG OpsȣNLM|v18:(@ꄕh<.cIƆsw6/YdUh֝hcO8;yZOC,?po@(h*7+O;Ʋ~p'ۘL2(qNU9Ipkb*0sRENν0pCRV$Y"dž0r6Y +pŷQTe[nzS2x+c3a ecAaH &ꈷۊ -vUXK0e0 0QFb]M-һp-aG[. FMr-]~"I-`)y2^`): 7I*{ϒǿ`o'?rY g#PI9S T31DSaEPmO,=!de!:ݧYMDwUTv'%ngNP (Kop93KRKC 7v{R*$H+0k̙JDLۛYϗ Ҟ:vh0-շ µ,_?la ?丽]?[T5|?^ |<%-Ժo.hӟ.e@Ry U^~x5phd_$a|1K >Βؒԓ5 +lRFLm[f +mn34 =b!V:ZF@k"XֵT1VҞId>pSR$["'vlFJ]*Īr\u=5l7s6's Ƅ]OQR9iVެf:1^5 l\P'6;|>AW8FiX ^Tm5Dtqm%(h5AY0k88`Mā ɈAmܭN4Gވ!ăzϲ:H2%2B98,p-&y"#/h4ڪ3Dr=(Hsm4A[ +C/Lg&eud:#Ei7ξߋ*c?VQV1Q7JtƊE[O0%2VţE=ѲQ9XN +{ЂGV$*[c-h s +ho;E!kA^n$]n˒$jC-4\E M;qO=b[$:RАŐҊ y>U2b0G-L,'FG[W~RA;0%J*7&%Z^ޗޖޗ޾pv/r 5~_ &kwwY7Dt_̻?j5 lSmg\ZdČNY}w>#UHL?Z JL^MC7V-} :3 X❶^%9{d9gSdxݰk]O}5R2ӨŦ+*ASp23.AO5UVɞP5;X zYyY+5m5s_kwG{ns;nxoO0H-xgcm޽jWnVxxHDQZ"dKE(mxd|%ˡc;LT\g=KEj'c$^,M|Zd7h!0P6p"CGKЏ#bqJ j*b/9QlhښcP$\KVߚmnZrYi_u8 +F=PJ |< xqӃ&"U2#}.+8!M*=kP^vڲ8eΏ;Z~=7畡Xi\eV!&{܎ai0X,ӝK mŀ%ntFq]@BgI*8nGG@ O)8Wd ͊+!^aQV4>Rc''կ7FHVnêaj O`)-Y^4& G^'ɡ0Tqvzg#gu;jw+tՖ +eƶSW^ZeYWXmYEרN~%>{,˳4ˢTtӚs- $[S]Hnƒ?xQJB~Lf,îŭXwv/ ɾ5@tR-Dq@G(Q+O)[?fU]k;(ffhiKɢlDž!`{:=̡wPVP;5ixbS$W$2+^gaZy59zgDL + D+p3'M=o݀Ι?9s@:ImEVjlS77[AHh΄MrO hu&2gvEw,4:CwvOh V<JȮw= +HSVx.(Kl?WYzaHTF]K.Uʽ[9 ;ә~E&Nis6c6`?6K )LFwR'n(f@+bO)bk+v"]ݻ^yg.MNt7}s`&'g>]MϤ:'rHv>sDR@p\$4 ]O + ;5p1lM6z9f2$hIWiC&[Ir{HMi\ uyŽ" $ZgHs5È| AG1c.6sh&47&=o#7V!G5w9Wgzw]6!"}bQygc" v+6N6瓲=}c9V+p|v9g*}b(!'$:r6)+kZ/st4Yd]v<_L@ kvjPzlc"'|^zeeVksVNoGqM2nStAT`+<6X >H$Rܖ7YV,w{u󴔵y{̫RcÞ&<'?/Znrf >d2:o)qڀ![UۚQ!}*E1Y@tTVjxK.]!O"1:ϧ؍% f)𭗥rS +;]egԌG3=4MGV/)$< +%HO}/qPt9;PSV59GLg[w^ SݍoF +9nZA)OOLb&`ǗJA%E>f$*(aE[2f{OiN)SL8bo]9\`DL{j/4y߾[ +K;nۣu@AiHXkOsRd2d2[dm:ĥud*!|wh}5f !na>2qnCnRJzoM=V1ۘ +y̤׼&L`v'(^ll_lCDeRm|83g>}n}76ߥvOa>m|JՃ̛]FûؽaM4#gnIkyeAߺ沛eC3"Ti3 W:53;җ2xXhAbSAY#\2%C}St {ضɟ1ld~w%%sGa%b?z'% V=,I@*rlgEsEuf%{e^^}Ϝ-*m-s +'sTnj~?7 +endstream +endobj +290 0 obj +<< +/Filter [/FlateDecode] +/Length 2459 +>> +stream +xڵY[~FZ^DJDM[`dXǖJmickA}BJoI`W\?,@~EB/?Jˢ-'gnU4_ɔ2K 7@lYXgh̖[ʎ6,q*4#"BtQI9_X5[Fp䄸\K Zu24( ]sagAF Q_yl/XI}kgƑ$N H-'1X<,)+ #i.-H*${Vq<s$3Arb$/ư78 +/"7EĤ q\~DzT]4cp_R<Jxz_xDOsAXJ>,Dijlv\2[I|a lXK岽x<-NiT,^A{2 YGX>jn6FlQ~̆nM] /@f5k0~+}6uT\\>(efhF` qd"}dR2 Aa'hsﻗ@3mIy^,WIZ*(fr$lꏴ0 3mWcla"3%m`uaՑ@=R} KOv( sɎK[Òמ>M j)~g#jPf-}%^%Ն`mczߒ(P@)a.ďKnPq{7zb;l.uuK꧈w'f S3 m7BX_'0Мu,,{d.?'0^+7%%yGëݵ,u׉صkӭmB9>plxoމp|Ċ`mV 5A Te2=a[ >5,VG0ޑ;H(chx{Ӿx<&UTbI?PzGNg`h8v$Oo^h{Ah =%WBS6`/N@l} "E i]fэZpUf9i ߱ @-"Ђ!?h5Gv=퟉SOߺ q3"NesmGYP]:>6INxMP6Ͷ획 ɜ*aq8M1@*j~:xz9؍:btJVD0"}UJ +yd LiK:*ESh_OŽzӜx4]҅7›=<`{[joO@ +^۹,j^c7Rg̔|.lot + 8dZ& +endstream +endobj +291 0 obj +<< +/Filter [/FlateDecode] +/Length 9015 +>> +stream +x}KrZ kdn`ÀEܷ} 6} כAfVZ@N#2%z}Y~n\7/-raúso_ZBjIE\۽BHUĒX=rX{귗K}8n? VrnGiޏyI^mv`ʖ*/y^ +}>%ev{\rZhTyhJo!.6p/2R }~6`iiIT},V{8Xo{nc'>~Ǔ ;&h7vN] + -=J9{̷X8boM}G"ީAeS .Ŭwl25gץq=-8/QJDY) +r7&hRMp9%6يK**&OB6Kv[̲^NVjNV\1[zco + sB5u8Ċvi#BsIOI!P «D/2NhUkk0x=q{17,Pc? K`K4`Tw tᅎUs{bmm-}1?gi/M`KiA_pԥ& RF$Cd6^%a)A +MxEL"o&Ԛb$*HS*m&-Bbte[V +d:_dߎ-6c-)C†O(؋”?65n y80ʊĵx vHAIrbʰ!j"6TrrR)]*_Y2x(I#oӻܥjgETU4$2QtfR. ZV0eǨK`Q$&ʠ^QHHֽA^ jDli`7Unog^QXz06r $_!B950 W:mMaUa5)_X 5]PݙkL:<ܵij''5fpĉWńT{1qjol4&m,{L_]R5 t'(VdKשZK+9;j¢?즢(Ū*;^ D Q ǒ( ˊ]Aj +&D *n5Q{Q^q,H6v**yխLߨSZCխ_k3lt3ED4Z*6hf4M4yCTE(ZSu{"r."'*Rz=1nl#JذqRWR@+P6"y!&OdrUQ B98L@C9Yןg{lt2ZK//o}ۉ(]}gHon3u-0H趧(6Y88O&T蘆>ΩM'Ƽi"@72,A=II1gb >|OWz2o/ Y13*ѓz79h'2oa8Dg~;tĐF]:I}GWԑ`f𥁍ID:U94X2Vڴop`l3}Wg ~xpjNCҗg-=4xLk&ʲQΚ~8EtAEV q:>H5S.\I5MҜl^e6Q˚968sЌQ k,Mnx'O.D %Uog!gʨa.`<]Xnx0uum-n˖LXG=JCkP15W,C~U_l0\ʻE)ƭ>"/Fj9,]}FV{aLG%C%m5mޱ =Z9Z٨6fv6?)E/wDCJ9F +oGiJYJ=L&PaRBւgDw{{ˀ3 9F*"7oR!1 eӇ"M*6ƾ`gƏ*\Go*%c%] Tm8瞃#|dn|4چ^R/};8!ްK C{Kic/#̊D^BCs\lv3@7_C"m|V^Z#Mj%r cO|}Tw{}G<_< f!mC3^Ĕq7Rǐ 私ı[\ƿ`_ЧSƂ%-cgȞCb41)>|-̍,-ri;SL&͢WGѵH=h}a&k(\#I]\%YC\eHrV%}7fm,T]az,YEd<@d(/iJP(aATdI-'5 ,QS g6Mm+pG"]$;Nfuՠa]Ŀ}1Oj0V'(ˡvBay8ltgt`nIhLΓQN4 ߉T:YDnY1q52i;$zثJ|+m5[*72fKF5+"&ֽ$)&)У#-I,[y8nҩv`Yɖ~JoS::6[vdv!C>G|]5S 5Ouï??d7/Z2g&Uǻy,Jq+3_s_;_^_Q)tp> 1yy>BLDd1/Tӊ̢pŽ ך}5PAm_ TE)I5Lpok?>,O/5_T5)L&._ꊓfz׿^㧿|ӇCyU?S/^kZRSx]/o^Ek}w/Vʌap,$Y 8$Fl39kV)tĝ7!;9o40fȣ]ƓhH="q˘T$VuI Ϊ> P;'Sg?g). P0l}N+cG K*i&ՋtKh`5ףOn҉ƒX(uVش5'nmgPF Kԕoƚ,E,­a<|~C}1.68+PX6yU>40Gˊ 8౩W#;OrR8 ̟_T>Yl~Lٚ K]0SP;Fן^tHTTrB1Q+)+ֶ> Ϻ#hf[=8\"~X'ƦcG/Y + +I@i8 b1.fgmD' +ɹTղϥKjM@a*rOC̋W{HU1'I46}&AG)n3ţ| NJ',:f18!i)?(=Y2Zo +|t)LfԕH wez"}+G&_z)љ=3.Ȣ#Ifku.^x/: UąmoXW лaW N79x9֔:TB}<}(ϱLk@)[K[HNZ<\eS#ςaƉC||v0&+QL`4)yRF2,Zl(s& 72`MB/H9\BjIg`%)s \=c_@Ȗ'Lu`YB#|TggTc$3Jaz"N~Qyb1VvCˤ49ӹ0a|KQ^lUNX hiCӪ1\5i\*ㅚ)-;D艖9k-3QiLp*qD]H:7u%5 eTaz3YsX+]{]JD?9['4 |& +J*>"Mf ]ɰSKVt" fdkͥ0kףfw1ƣ'}Ʃz'y )m"[of&GJxy!|ym;q rRd=|y^neao~}+^℞i2OT'LQdg^USrҝ1uB.p\xg ۬~%A ROpxeY>AcZ@tuC6Eޑ*؋n(VUg?[q՚˓d54jPL2=kl_ųLe{7؟aYGF>z|WC wWFr8Ϲ`NiWǶa vvt`x7 *?a?C{ݬ?/sx9q֛&ݲg&ytOlo˓k[69f7 =ǼZimr2rI%\@5F|(0,wytVlL oA1!6b M&Ϯ~*;;N#KtTqu$aҝ+l^ ~a5۞C}s[Ȩ2`R1sۭVHiY+êY'0F#X𸌠@VN1sɵPTZfcʔJa;ÕjtYm=ka89RU6l\Wf?o]Y +iS!-e'%[1|2zt#lMi~S 0UZx4};m +mkh?=K~!!?N_QxO8Nۏ?,hҏr)lGO5EJ.O5k_ݓsKv>0~-ca@^\ +Wp/L3kRc=ŇDGT8W/Veze'n a9o(G <JH-WM?P08G0.>l8z^#NLN Eb~ '^H1'5^h81JuӈN9[F7!y@$C|)w+>*p RrB ع]Ylv Z¿*6oE^CPzqgQ1-*\cnʫuKrMijvRz.W>%ݼI 70f3 +d&[E<Cn?x$~UPo)mE7-W^Cu.GV( MݎkͰ4h `Y`K:0}PZwR|`ޏ"UE`XTtJ1A^к{؜DF8Dڝ^;jB/լP#xg5ZyUՀS"6`T9G'j7~n+r +W3lаɭ%7(4w QQ63uj52HF6ͧF,F F?gJL1kF^o'LKb79hmM˳B o66 <5BθS8֘u4Cv5?g(&|8#~u43?fXԠ 8tqݲlUa4q̻!jd52̥>A|C}%m޻]jCLALuǶģqRyƴl-IRO)m#"2kuq̓h6r[dz7(( +/^>v8bz@F?%=ݪvc\\CEwv?Fg2m#=EW&;dULǜxyw lyFhVb 3>"wg)66 A:8ŭQ;p L)V`?>dlb+\{frcڶ1g'pyGoz| Y +endstream +endobj +292 0 obj +<< +/Filter [/FlateDecode] +/Length 3800 +>> +stream +xڵn]_GqHCmX`5>h-VjI$I:Ғ]@˙sΜ- ߫ tq3Uh1uUw.UcwTaneSUhNdBkKON&?ξv=h*]ia^MQ{< M, =1ddgw,G H2 +]ֱje|P.0<@2ɀB+s A'" Wg"oyCelXhƐV89PW~4',>k*?d{6TmH*d̆_ͦ#ùGlCZokasv LFogP cA6H1iĵ$J@1Z&e@BzJ@m$'?9Yv_`wbcVź-POSZpwH$-meB1! +T@&ׁm"̳҈lc>&mNboCv[p*O +/쩍@N&wlw M b Z>@P!&b5ZO2- +u=q9-|4ʕcvm'H"ZsX)G|yw<6Bv˻򯊇خ(Du?+N9` [ Xp*TWzۯ{ȞkbenCz5,f\f~ajM[r' "h9N|-_#+It3c(8d!y 9 Ϩݗs6dn,ce.any!_ZT>xs(:7֎ #c tcDަ#I;#<3vF*Le/xm2eg9lמAk<$ { ]P?d*iD?b%w&ܜ3ጟMd1Gן:=@Ʃ>syŘ{ْ-nfXů|SW|Agא> V@Nv[v[jTU]Sէ6FIO#ꡄ1r+񞨟6s53>m<ާ3XFx&#w]W3z3Q{ =tjI +[t%uuZ| =RufmZ>gSVFa&"uI;='M5xrˬ4m{LH`AU$NP–t' :=Ef0z%x_M#"K}vӴ[A+a.p`1 LC In7oXQhJq(7-|Z +?$ 0?iu? Wh (8U5dbIQLl:MkL˩K$(2 +/{Jk-]&"`;JvDA:4#ϦĹq>>-h81~A.09ʧ:!:)@H7H_" BLȬ P7RSZH9{\gP^vwt#ƥCFw"tvyˏo~:|p׾XhCz{,>zm!/_czgqPKs=^Su "8E|7/GI +endstream +endobj +293 0 obj +<< +/Filter [/FlateDecode] +/Length 6417 +>> +stream +x][$q~_1gy'_$!ރZ#R!v\d"Y,~uaN<ϯ_OϧK |>7I.ƔsV~&\l*6.^[m6OyMΗ*.)[*p\Z,r >]hn3k6;ժp5)Ӫ||9l +(M㔺aكLouxnĴ:WvVZ|.dcS7w6]\kAZ9]Be͹ъtV~ʔpgɁ` +޶ځZ<ΦZnU:):wNa:AmZPOCQLh[G}+KgW׽~ +U\leᔼKEB<ԑ"%J1}T:P*gM\Jxy]lKoaw Fr􉫍Դɸ\n+QuAۥbk(xx59x )Wشh[z1м ?5OJ*mքYmAgqG- |% No*Ci- Pˇ;0 jyھUAo`QjƠ4]AM’. +EC@ Oђuc_+Hx!5@y i뙌3{+*ت8'f9$5#0(8nբCwg#v׌'gw̦t|hЭ>'ORm`o3cnAcΣY7OJZ8'(ɬ F4t<5祴 oQnP%aO .,|9ˑ}n2,%vT=+=;m̨J; s {iT}8//ΞS*K'Xl)D?N!nzU&Az̊}$МGCV6ܹ A[wv!Tctr.4RlANo0(oJrqpaFUϼ+u5 }7WOaoXKT1|=kp+b8@珒}УqlۺPނ'ʺرj6|; }b +( +oǰ!Zj7,=0 a~z _EƯ?@ +HG_!d +S#PhhϓEJ38ʛX>M\XƺOtŐ8wpHMu` Ka +xzb GlGBS&zƘhgA:O2mF"i3ԩ}[aiɀIPΝ+&<*4s\iB6&Tac٨oO4פdm1f +< ,yU 吟6&؂Yu SNr wDTO2=;ǹ׽A D\:4i\ ]`;.3IyK)J6bs=sJ/һ&ހ!:eNLVJ̽NC,9!&[./pVa1nɿ%G;l(rh,gH6L_,`i,%F4$NH-P %9 +G61ˣyk!0 YKB"jx慔WQ@^)1牔XE1bKprjKN~ԌK`֮c7ksSOIa^Y~&=nY{ۉ>F~RЄ: vm~eW)HH= =2}ғz.Qjj$F F`0g ͂)W?J^m(sT4 4FPFGg7fXTE<أ )PPwk .jaETUi@NFѝaĆsD%5 9t~Bͯԧ3L%!C$#*,kѷy~q6 ^\.޵Q74͔Fގ֒uhw1"k ͯ{G^ jlzL]]ݘ; "ȼfR4vweiD&H+#)Ch5D@~P| ZCl"'i. (St|"PvE,0JWj˒œ0hff{`^>)uD#@g0WTOek/葕:h%x Hv+rRwǘ豟]/NGVDז]H!{3>BQE TÙVػ!7en4cҥŎ %Bkl]:ÆNk.R\g8כDaG։bYB1v*c +,[䦹͝%|W<-+C*c PY'O:: x>h!*L9t̷f0ʪj.]GmDZqy-*Ҋ"L '"NY:O2^}FN |2# ڜNq Mɘ#:񩓹wOqv`4 Q [Dx^s!l ϳ+ҧH? -k"cGa6(my]'v"%^v,nL(:oVbQ')徹H0o& $2..fb-Õ{ݔf ѼS7sgB(N-$dgFU)3Fm=ƷW{8$D֐ O=HH%Pj>QK!Y61>J +-9 +@ݽ"\VDΝd$=ۻtZC^lUor<CmPaQ\OEE˗3)Ъ m({` ǟ!kcSYk)Q!2%Je +n9 6a{l8e_Ђ [W1TT;_ގC(Ć#oP'BGsrL8ڰ>'Vxbcj1~6)y~u;O. ~׿-^8ߝ1t1vQ1˧d˗ɤ?? /k_L3T {.1NՁ)\ Iqn#y|I7xtQv7x:[eaoь'v~:W^ƌGVC?Sfs*sH7bVP|[g'(ߨ{ |V}.jVҪ$B6:屄ŧ8c>ȧf*٧'# <嗢RzHǑ/+앒uZfn$ʢgnesAfo!=GFMzw+#)E$^8f%yNH]2q1Pb=/4a neFbSsIr<]j*>@8- +bۭHv1BȾBsg%quG!?d*{}p$ o!|}{(4ZtG]EA Q9,8;^oP٩kvcDJ,b)=Nl^J3tJ(ߘLf*KڷpIݕhی{G'\$}K8pb6_N o%,/rܷpO0X&khje0f)ѹd$74_Ҭ&t_1a4f"`,XŨ$0̘%t|0JS`ՋGd#`N#^ԬA, *2Z*,MzV΄\ +:ig-.$gQ,C*b'@ R(30TMapc =L1N3)/Hau4 +YJ+o|?NrCєG&YPQ?(bxԇMFtQ%GrʥLIqWص7b؛ҝ(K:L9 bCib*`L"ݫ 6Z2ZB;q$# ̥/eO]MH_WlSE^;*k G{r5{EɤI$)W?gӈBzX`gᄅU +endstream +endobj +294 0 obj +<< +/Filter [/FlateDecode] +/Length 13692 +>> +stream +xڽ}ݏ$7cH&d^xa[/ ?h4wSҞ4{ۿIFY5{`"#aGszι=w"rlk./%Cʧ??{߽y9q.2R2 [>=P<3`y{~x)b(zPk?붍<4qED{1-]jJ@_uҭ3객 4⽍k/Aq8m a5a:AC+ڝ^m'Sw'2]2M^m'y'"mk&b225?JukjJEZ׬M+gZIeZ2)zޒb]E.`EYF1#b;%zTF. ? +XsLy݃(gT5NG '*YO(?ΰ\YȴrÜE2d4hZV |KK[۹j  75yײnC.H.PLX6Gub=CiC:viO-47g=Nr+^/J|sY9QRyC"+ʠ$؟AF)#Yv[M$U2y&Ev,|k~@p.O.%=ߗ֣^B<λ"?oso'tr>e&ѢMy~˰MKu)alm&aĵ$S}c\ss#I&")w7HQE솗?ہvr[-=~NqQ4pw$S49!A0-se;=Tqlk*}Go\-ӷXyٶk>C;%p3~tSpwEL"MRkʶ޶n2È+sS{,7H?[;9GƋoTIu("^QQ{]OqZ1PܾI5IؘCtx/VQ{pM֮,nK;ɽ>7k4GxO%J<"M:| 0nNvWzk}o`vBOLַ݇d?"qx/ԕ1$>vPUL#&zە3jo8L6Lų{H][ }`,4*=^X yX.=kQ{q@{`8_`wR{%RCx!Pfz{-6`,so}p<+(>VOyI{.؀OgwTBFܬ@k{'5؝\;0h Bmx,:tת~lXPɂV/4&b/Õh#VGHͿcA H-G5k;^,ߍ?ų7P݂3{C0:Di3+P!/o2 [վwaU-|^ϬJ).:EPFD \!a2 %\.3f[s}Y$;7}ɇ/ike>7 +@0- җ}+~kҼa ٽ^UmR%KwtW\(J-uƔѻr{{ڡ_7,&=Fr _dQ{݋}k|w-n2]\6uM;Jv/]K-~z.٫Yiv`Dn§>mRQ $XG} +F<&9y`o"L1J ]47Dh2s1@d4Cu3SU!vs{\d8]wga閴)gf=rޖX8zcs22/*MHV&r"$ßJ8Tܐ; =rɯtƓ+\[M兢OGJ~w琷~˸m᫿%}ދ߿wSS_z)ǧ?O??oi)OW|w|C|fLDÏ~xzoH{DċӟӎYIHևO?c{Etb3bs6O>=df~^ ,3Ϗ?Q/vR;)"w]*qlI߁XRBՠ/O_reER ] +Z|_tvJ{W?(􍔹Sx|VWƧ_uS||"-,Px^y?wM7ORH%tQwITs' ?ti}nkcΔ%۠vǟ}Ś1Tv㲗fs!"4cax 6k7<~wҟ> ;;`{ՌE Cؓ~?TOϿ?C'COwjg~VJdT<8?>=|? ,闧aO_Tq,g~ǟ__izõ[aw]mmC{#ԝ +%EѾ<&ϖ8=$ zPx+ȯ]6mt¦l( H! rTwLt=qcU`VXh'ˡ)d<Ơ~& Pin:~s1JG9\E2{4]#Ez54^!k$0 9cn+0cIGќ`Gq̹hۡ8o6}tJdvѡ#ˎ Mʯ(J Ynj` ^~F:&TW(Kfj݀™ .X_.QXmvTݏb:՘Gj]SToS&mpq{  d>FAtH\I+!U6PsX邒/@Ujpk +A 7p_KVH +UG7 kn˜) &P'dH^DG%d87%]vn8 VKݸxw9e0p;\m/r9ߊO'8!j+D$-UP"'q${`k\U34SpQ) [L9_ny +8䓴Vɔ2[%dJ;p +61 'y:cwYHtܠFf*,q +j+=%j+F}Y=#c\'8*D&ĘZ\(Ct(YS+?JL 5;(hX&UU66+ ":[$zUK)T:QB&4 E% H0m cO ulS%m\hi8 B.:%EAuY3Ӡ"j@Րx@HQ nHb:F {C5"!VOENr )@de+A8E<ҽ ~U<@ڣMkJ7yLG-6\l{.kJilHCM K`*FI %_/H+Lݥ=:Xa5XLEH' +tr-С /+(] r{Fn(q2'I|s%Fhm*`&`jVǶRDƾNuCHT摄Y1r ccы:Czфz +6 +-y@膜 <4'E&f}f=kc)4rwF]fll^{cQ )|:Ecj ثq%O[%7Ygf|3-H|{~&zo.xO'ۑ{vq{a{vQ{A{r1{!{{~q>u7v"v2kA;!ffUܬJj֋ ӫ#ls1z!4k;r E:H$,ɦ/iӱ6-BoD!\oA2ocyJԮu$#n>@m +A qFHM R7 B"qB BA! 1f7 2劏;11&[c̸df3 0_/uf3fƗ /[e^0yuv2io^({"sHhҊfoI306a0$ ejtɑ+{IV? Rb_K ?J,bɒg1 ˵ XxZBuXXRnE=b3<[Xj{zstNMmb}WʇLo]p,c췾(^~ZK_M3;h>uhYOalcU8(31 +kalڹ*E}hq0ykE0阈$X}{* l}-E +#rQk* +%G=ͭRB|D)SdeN-$ҍ&${}to^V'"-$Tl{C#_)(dbwS.;@F50—K0}g0g0ڂ`rƨT lB]t8G}AGcA`RJARF}cNTnGҌ +!Ƹb2QøE{3m!˅v/ͧ3:8t E"˒q&9? D#+*@7AoO J`ި̀[ҴTVP28ɪ @4u_ /FK9)hHj bhl ;Bx&,ܞnd č'g*XGpm_^YRݴ!o9y)"ȸ)OLrO\CI>Uv49۸jѡhѨ+N<; EcMTQ iQAKz]48C㦆ItґN&jY-D71$`+n1.9+6ڏͨqrw#ϫu(9vc),])"l9{^L>.3NLV[w15%РIF`HLE$ +I{R<^aeUM&Ujj*@1-&3OiD;] +Gu젳7e1zaJZфv3j5)y.6 8ٵ*`QgWP%aNgvjJ\xB[LiXi*fj ɔ<`% ~+)8lkYP 5.$spiޢqT0v|C*ڇ@زH>ʬ|Sȳ- +=T!Zp +! ڑx |^O[Edo  h4QvN(%J~ظ d"Bub/I9#0TЭ! ¼ȖeV iTj%Y5An($E PhYi &1|Cٕ=[6DDKD2 +iׄbcb D@(@PFۛĵ2Mz g!su[E,#XKQnh柨Q@]DA4ƈ4cEu6eaӋm''!?K'{|q`.IJڒܓ 0 +! #`M|Ǘ@ٍ]U\, s0*} pAR" @خABQ6 W‰TI,^cTوl₍CyL]3iq I|KmaBrTq*[NS@wӯiZK\uTE" H= PEEPЖ: +_a(]ʄo5G˪Mm=W<\ҬiuELjȓT""@JV"yɀzNͮ, c,y -#-֏2MQj`E.dQ@eF�{hcqG2cx,P7;D3$pax$Xx1\MӹǨK9Iӱ 01E!5X0Ku-$%nDf'UvBۑQv%prc\$7*Q "nfX%U;!"KJ8:MyX p5*qNIΎFU@Y DRC]›;74R6)e' _<78's AywT↩7,0Uj GڕADZ +dpbk62jp$/:Rd I"d77FSC ƶ&8CZ 'ZȨEqP̭aa*ZC1Ɔ 6JWq[ϛ6lcVЎǶFiǯ5ģkvуdՖؠ?7xr&b(l ~sF & j]g) na\A2+v~v~p2maQ!iZRA+]%Q{Q M[5`q6ɀLƴgC˱3u +Y}Nն:0SM.~KY0CuCpL!'<< z5.azUYqF飄E$5qb\Dh85iP`pPEg܄ŢS"I宯3%}!}!}偾9Kv +6,G]n$ks`"l,Lq˜WU6]:aUbSI4ŵC~ʡx#s"ŵAKΓo?k) (%':ͤ9l8/jt JʼV4 i6c:|mG>x=>p~<43kiQU&Lp9:flH`Kst|cn#ұ: k94`luLTJZBgC[BlKg;t'ۼ,,0PT^ӈ""y\s6o U .DC{C#A%B۬qaajBC1*)BR*:dԽ̗[0vйv4oo,vT%iQlq^=QKsN[Yu;?ZJr1겢x謹 L2oX\%9}[˔FF +F;fuq8YX7 ؘ恁p(.Ef% βXMX0.|]*øc5 vSؕT zqPrU6s0Tv!'"'뤁[:f@tTLeO1j>a);pqz󓆙4a[(F׎QV痎"jc1/PC1՟իy>[̶x"Oup)`挻Xx$"o)ÉDl5stҎܦJpL@0e6( +g_ĉ@|XH3e`lO +T'||T)?+`X0.A1쐏^aLƷbn5vc65scPѝr7nɭc7< 85`!pDh-[ntɭjK=B5cRBjw,Ea~C>C " 7+ xCoT:Ё{`Q_Qi[mRh/DnZ5ӁgsWDs 1LіKMS;-uACBnp6V23( uS6R>_Lv{ 6xrU6foP2RSRt󘐢D2gPwߠ$e-%+7 v`\zѻ"R8RdH\JA21})BlF/BMv!f.,TjA0tgnE|=(Os?: +j^Fcu +0>_4_f}C&hQg]9mzu j~PQ 0Bd}(gX00W1U۔ +0 @\GߵR7s f7ԸOP3֣ƅ+.<ث?Iǟ|#RdX)Aw6m +kwĢTLA@).H^f5{͓aӴӢ$*qYGޫyԥ ,).fireDtѻ"p? >FʆXb"F4 |\W!`%-f\aLsa2B5-)b7SLP RNJ Dl܇+B`Uc8uH +\PdP q஑VG4dF%$ {nU59D&qz+eWs:i BGu@O +X-YX8kF+E,a)b=W ]x[tA6 + +?a0҆ˊH*"|o`mkȋ :2yL!@604mх +'%yͳi䝛MM.DkA/u1>zx,Sc*ĩ-]Ĩ]6lj߃XJV07Ěj9a0ٌ %UY jw6MP&lO'nJϻ70oTNzxTfɎM ?n}H?.dv林 ) §0oބu +)YxSvO۩.X|)ܐao&޿x#[UtT&"GzBo8}rV*idH2X]ia[X#սoVGj&Ź*EY\ ԒEHV߃Ԫ]Iue" "縧jcH6t_1\li$GqQ Ajﵻ7ᣨ׉FqwZ?nG +endstream +endobj +295 0 obj +<< +/Filter [/FlateDecode] +/Length 1893 +>> +stream +xڝXm_A' +$%R|HpirE$FZ:33$-mPJ|yq9o+)f+ɾ[}+-EZmq-N೬j)$W։Vpx˦TeDS\|&ZjڊEsZ2"[9a,J#٢5µ4-2͵\$VY`ćM6]D#+w/9əC@0ɆH79iufyj\D3{ i\+1Z ^:p`m@CT+ZRȖeqfJUlYBZ֏@Rl ^]] koZޝ|>qbjВNwva_6PAJ*AZB2&U +{}Q503w.;xLJRGKiP1~$r_ ,u((FSwL6n6'/E:0Q0.>W-߂;F}.U0/ -@$x<FEFnиHNwI;(vrxNV [?m~CֿZ4VhC|d pzWM$X>H~"ݰl7ONlqfPbgs?W)[oR{6fea]9d$BT7;á0)&FkOt}>چ6 +kuM$_S + `s&=z?O#Ç-xc!)f5ך%62טEϝÆu ;䇘H#…`*92g +Nh;"fnEALJ8OiM=p<Ѿnsi 3O ԊԡCp‚,UWEt/ؑ;$]Rcn w lT=>ӌ̘ yóSEvPD9;۫i.ehbqNHwYBT)돿`R5X 6}duHƬW`t\i3Ow0 +} > t82l' Xz]cȍ]XY,cSNRBB1KA-"& 3q+Q<8t5sK\ +*~C4P /.) 0x{RQ͓?/D U,G5E8NՁt:Ȏ1.@ _@uϮn,0S@Qp44c c@@ ~ayUb9yUҒ:Y5ɇ)Y?GkM.̚\5eu-BF 5V:H)EeXfW/Yuw¤yy)p;Q&ВZGpIC $Ugؽ$mljSԎLbB1tS=5YMƪ!PFbZwϽiZBk mHWiWP HE \eOc_J@z*iY~BC/ƄEoT@m>A td{.RYp[][U^2*,ZM)lҸ\yI-_pFFn5"oT4apxle:\pv]Zݴ`6uH ?N'=¬ +KЗ]XxL1~PSŷk_d +endstream +endobj +296 0 obj +<< +/Filter [/FlateDecode] +/Length 5559 +>> +stream +x][$q~_1l4M-&z#e#6ׁucsΑav=b?_u,K.C>{ +1|rk`\?ȵqqJ}]|{悃wM8L97}SטSwcC_2PG/3/?n{OϚ.?S},ԆxbrڛP>on3l0CNg|L +g+m̖0!Dxt2 3"U _שV}Bk`|}K_;IC⮋;H(R:7Laeʏ>uC*Z4CYyW$ڢ@d46DHUVpqC(Žֽ< 2VI(".yHVFOCL8"50#]}=Iu MV +[8.K v5KJa& +/tSJrj:/BVO ǼWi}sc^G*-f{k/%'\,j_~ALڵ;ܼ}+6әiU.Km5M.֙`pg{}c`kB=E4fM~ QhLlmΕ 0.$8:=E-7k +2lHCkm^Eۣ!kynT4yK]YKHAKG #$i<.+wܑܐwg@}dh[R3i5>4jr^^ eZp)CS_ëjJNk4eh"7dݜ4y)n ُW1+ˍqhώ\cu7%,o52 N5x['١[Bm wF-oι&e5/QGME=-yn3zyc ^!Z^./0oN ](m \,[JmnenY5G.s~~JO澤Z5[sw|tz {ۇk+%w\ۀZ6u͵8^m6[ƐFWCO.a2b~TVK,u +B<}~/ `B~;{ wwoxSMI~|TrD\H6zW\uWPrNӇzpGjG\ M+1_M' 1,~m1A@/ff&OculI&\`Qx9 +T3Tzs&rmbxj&cۥ+/U88xj:%t#O _|>Lc8Up?w˟s=W|iōwfg3Z[.ߔ ko׆8Dxg3}uIMnI>w} ]o(qU<:k0쬝ֱ9t)o]ONz:oMڻ!pؠM;2e" H:‹(AN +'lqj<-Z_'C[g7jl;zBb1I28{R̶HB F4IT b=#& 'CtRbpt +*jyWQ肒Yq$-cJv0j*`/MQg +cuŪUAaN~ ItU_*3EF#4˴}%(Зz*UX$"i #z؂ -\ѬO,Sj6gT`=X4yDGt AGY+GMx*3"Y "vMVQ0vC$QhDZYHzNb'GdyZQQWYW!I߫˝BUT{>'*e@BA +2ɲ-wơ\$J6}D9b|*pX'*Jl-Eی%/sa0繯i\N\#?u4``p1zg[bUԒTbx"dl^ᅨ&XI*V-T*RIǁWaJ0H:F!WJTW=$$ĊN*.Y D_%^$QE$Q$~+t4`i~"P0൨}Oɽ[ݓv~P;vЯ:ݺ=}ԣGOC*Y)o/ʕ=9 {rxr9?SmmIKM&e/{n ǎBK=HX% +=Nm:vn 92V#T8GƮG߄pN!Q[q|_8#;[VqOوGd a;TSARLLtaȖGᐟ]K-!@bcN-,JaԢ_x_eQEpP4C\L;%, <,XFXgCy*S!$V}-a1W7II֑cBgtV9Is Ua;) zʁAb.%;QRe}Լ/#vE>/FB7,>\#6li> w]ZCˠ<) /`>|޸ _NY!0CO@*g<bIP5Vޠѝ: v%g +YNǕFh;p3 $إ/0YDxqD3ciHʴLmg̴c&8`F:45wLj{WBB+bCA)+Th{mPKv +4$%l/Ѡ!aLCl/E^-sy!-MeVP;MO!Tj!iFС4 +xy%N'[ ^ؙ'n+/ ci܏g糬Y+8VZ/|N1!w6^2jr3~cCYq{BC̄ 1XHv4bҡ!LM 5YKjVaGj-Qg/@PD-@(!lBCܷe}gg=:-Z?c6ͧ7yMޱbՕ.d^X4v:ZLK:R]>6r4յ!aMn%"vQ%IIނ4X(Hu&y8P @lL2^Az-u-Ԇᗠ6sz>jfB~ q -nAFC<}?;h+YӴS&\7' <쯣I\r%e~X@Fս-0 G<[[ʮ|\$fEF@vH+rVL׫-߽U}V[DOՒx:+Xب٪~9g8+X]ڛN"(kNo t  +J8CΧ3'.s3Vq Ѡ3@VCIlY@>'e+8r,9=Y'=+g7I]l{gK\Mܟr^8TM-2V myz~> +H^η/ +P7vsё{E"NwN6!Bѫ ߛ +h&&M$V<ñ%~]rz^WFΈ_0V:H[=IU!Z|N-HAM"s!.A/iifG}u)$RuAKn%w4{,SVOnԒی2$7*bvGܕ @J2H{2aH;B8α1 L4SŽowjG]U;_.n'_;4\Ie9u#o-K/ә !W~^c5^=j%}wt"M9@" +m0cNnx۽3'Q̀.|bR 57+& 䜋z^?nT\׆T\{p#BzK2s.nDZwA-3/ +7|C +endstream +endobj +297 0 obj +<< +/Type /Font +/Widths [278 0 355 0 0 0 0 0 0 0 0 0 278 0 278 278 +556 556 556 556 556 556 556 0 0 556 278 0 0 584 0 0 +0 667 667 722 722 667 611 778 722 278 0 0 0 0 0 0 +667 0 722 667 611 0 0 0 0 0 0 0 278 0 0 0 +0 556 556 500 556 556 278 556 556 222 0 0 222 833 556 556 +556 0 333 500 278 556 500 722 0 500 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +400] +/Subtype /TrueType +/BaseFont /ArialMT +/Encoding /WinAnsiEncoding +/LastChar 176 +/FirstChar 32 +/FontDescriptor 418 0 R +>> +endobj +298 0 obj +<< +/Filter [/FlateDecode] +/Length 1541 +>> +stream +xڝWo6~_AB+$J*Ї +0كjӶ +INe HʴZ w>/]i!EB7ReJYQ7oI#tVnaJQkZvOі +Q?l^Y~rQ~Qd( +JTȯDBEձPXA^<䅊K# BɰVV|xGtajxV wI0B@qDPn+յ!z;Luvvt^4iQ%C*nm)&.M $x8cDJTҫ-J4ԛY@jlv?$l dwXP +=S3,ی} yܳԌll;Z߷(VƅT`CAkgLj߰ 9)@ɝqzp0.5 S39Y{ mHIK^o9:NyJ:>.y}E:l; |bAh`}XdFD$sذ[1+;ov?-W;,tYZ,[#N۷=@Э 09 - ׏'}g_ջm.Yg7L OUd/q?Mt> +stream +xڭ\ێ$7r}2{2_ MRcYI+cJJ6د_2Ή 3gFc Нa0nd/?|k_ܚe-^הۋᄍ$c ke~_k7[~,!D5.my%J y[Kkawhp*}˷̠ ӗr +ki=.56˧69F人: ,mSoSa"QdPY&cY:˵\ 5Ta!B7( !U|վ96P8u#0MJY.KطߗI8ib)եFo_R\~F9::hgڞXgWweo;Kp/Wts_aP0G\*&vI;3>ؤ.֜%oj#n{ĨG qϳfYmG~;pt "e 1>dIfL2qL[2>M2pLdef]$Ӽ?΋nɢ&L8Gjcn 1]L:waL2T-GCd +$c̮2S|py"cLSZdy{VO23,s@vW9 &é&v@i1t~{u T;XMsY#ޘ8^1\){5+ōҝUTcC}T%[Oi[g0-{H,bdܓ5 x|тKsǴA$b%%X\{!!j`86!iB8Hn4Ndv sWT`m1%a7V/)n,, }w޳a0LE*!+Ik FF o.=\sw CfSןIl*EoІRv=35.E&ܗ~OvI{s_טEZQc:kBZ ]x&u!5m557wxKkp4qow63+mq ˽&<3|McJ,XHyuiGsHD~bE- aM{6^>K-~œ~;VZse羺~==׻b;8 ы'bN:oN`5jTq{*|U[=hat g[ +%8W~;%X~&w:.aa*Ob\W1 om4㑟ؽ?k<֟CՌ.iV-bO4p٩1i{CkudDt7u0MrӲLo' +`@xC;Z}|,28mTZDT ͜$u0503zKEEqqtZ'-"K Nkz)0Ez,zr[CCufluoܠT>6Bskcޒ>/[ܸn[JE8 +>b(x 2AQaBNP416EEQw]H~0{PQ a8@D[%(yv?ZW +6OpbJ}k4Gz Tljj/WY)MFΧ͝~Mܒ1D^rr#~4?[ hwyg4::2 GD%.~,lb"ڞI + m]l87йIs:5=13U1OKԌ+F͓m^hԛAO,xˆs|E͔-˻ڸHqd E Rjg F݃ >fZzAI!=vkY7+x<^P#u2[\YA|pV{)E:4NH:Vd#bVdXRSKRRX4AԦpOȮeeZX*[wbZ6[{Z6Geш{0i\ZnWNVISnR Nn?V8>'5vȏsV:}3نw,cx2; fy'/p';RTZ X/JEoW\!PN'Yh< *RoE(K@a"M2݃fܴUP<f5SjyTpŦ_ERNTɂY:4j"64;PL6W:[ {^ +(a>M%^Tg$^geG&[yQnGO%f^<>@鼩FCU3ܓͬI77Gu.,@U rMIՄ$^zR(iǽ1b1j< f>b1YXY-FQ<`zëvz'}*F}Nr$w1_W-:-P#˦y/TC@W 0"N9F]f'DbQ/Fl>s7WEV1ܯ^0a{ﯘ q߄4m:Y]=X[)qP _9%޽۳/O?j.쨟!}<4âSy{^b}݇ⷧj?v*$3?=.E%{/'YNNSjSݟ/eƏ> +stream +xڝV[6~УL%YlPpco$^$k=3'٥9o.s&`)㬬K(#p&KeZ9f,8e`m%X:TTo!dV88h,s2jJ \(_"]M\ ÚBJ, S,3"GI'&#Qjm$ # ̔XMQi3K(,+$:&"1Z +E |ZXsbަ D8N0_U?d?YiH/%_2WA`LX1M H0)a>Ч%m&/]^CI} 'z[1gMx9%tUHLr=.'V T 7>@^# 8I9n=@WvkEt,4:Cۓz/4Rt!9zaA\_1]A_SsHP@Bۦˑu،PJ)SLT28n-3*<@{LJcpM6B7ٻ\A^eIȒY!-?p4h:M/0: ۾圓TUH|Xv3k_:7Hvd +~бziD9*H]n 9d2 Pxz;)d;5IXBKy0FxP0\QIx֊DnBO,P`BUWh*GhQBI>Vo<l‰UFpp -j=0CN¼-n;"AAh~bJ! bը +1p16bt+^G.xJ}1'FcR7nc^oO4{Aʥ(!\+5aI|^MAКKT[$tDxnd&]|T:> +stream +xڽ}M$9r=Ex ~]IXthfZ#TB3Я_3#UZdth/u֊nVr}~߿x{|^[뗗m?n=nkrW>_^~x߿ĸn5xɨ?\z+d-%Arb^!8P,ޣs?[EЀ_R.~ Vj_I:^Gwvt7&|47GkU@A3~ V nOT]Zَ'ێtv[oô׷ܛ4x= [>me!zoel C5xY{o՚dl-I1F{Pwo#c$)"e}{̬}@>:,"B[*V,y+PG?AjXvw?5{%29#M4vBز.y%k6PH hcgL}w!$ܹWg*L!@++w\4m Y}_F[2 8,iT/[GvCM)VcP:<("q:Y8"E25/UXC6fbw@7;K>`rwcsP6KC[E&TC%D1(}CyC@GlT+mw |A]Yv"0+0VC>C13'6(Fq?13SZv=$ 61;0r P0Hn +0rr܁$ˢ)cj_-fEO)/;FLѝg#+>4!5td_I]yS1P^:oJUH*nQhc*9k{a{?mQ!с ݨ/ԣ0v6}ɤ$PI9oRMl2cvPKoMn-1&=w9v>@]ilGNP_AZP]xtڞ;^Rnq›HmD&?5х>keET&nr*E|] 6&+%ethP]{kR;5obSNY;7oMnڄ ߶@Vߣ(?m\J8IqAT6hk\BT7PxLD)tK^U%P_hNMQVDRUʢax1|0aT2 HK:ZH?CeLE%b!ґf`~3d<{t j :u~/}dj4"2rJAM2 wI%𠈉̅yTE,r@Ex u62&By?xuS&?T&f{S? 0} wɒ}{\2AyXcm;N}l0kUmDgJ=+ ;>2p0QAH"#1(I}AIv JFCwEKޞ1|xuD >xL9_nHB@[O64DU4zm̈́"c.qò GDw#|%@8 +{0WEUDB9޵&&un\0箏a0`;: Js# N 3ze 0(i xCvn5Z1xf4n(|J3(uPSPfm +O ө!x#C;@Ct"BJp˂r@a1q"FP`:誨=Np9"lyAtA)Rmdh-D4ݿȔԾ}73[J N6hm':b,i0^ljko5tԛ/j]?_;)AQk9{?KXUpzt npp3 c%uk="Ex/,Rhq:Wfmt?rn;4vgw}@()^O"#tO|DGNE wPa/p"K*T%D!l[xuA+Le`jd`j9A]*b{!uNØ^!U[@YgFgŪQ|<DWTJo|RZN CU;U0X#8j,WBpc!*4v2*9'bC2|j#&4' Ʉ͊izΊ\YF7 Ḯ1&ɴq+bQؒbN#@Qk-#UFɖu{dwA3Y» `c'YHAW}Wܼ8J~a6MCL&킯I$k%1,q)1H2OѪaEۜbIJh]H9d!aIAp;=0qlʼnI@ D OF8B; 35J\͢{L?^IFo_G1]k1A3hD}8l sENDw̆7lꗲ(u2yz =[5 +06~ B ! f,qDpɸbh uD EL + M(+V}v@-KH:1L +WxOufcxR$v9tXq G:6 C5~ 5&m5 _/&nq%{ q^rN<5.Eg ʷw.rtyud7L+#B5,۔ߵoT=U"| ᡫ.;pK/]JIWѥsqd׹Ũ\$V"f Ty@drQ&3.Q"!Ǔ*u)GBO!CEkq{;J]=Nւq]|CcZ 0VAaG, p;L=M3ڈJMɖ6OHi':~"IP`Cke9dȰBwS_2H|A$yMM<):vXfٞBIl:6p_xޅrsQ{ΨN /t5rO('3۰3ǘ*hɝBl1ST.PP~p}oz֬p߇ۮ]㣄ΌRB7f?$ǜ9?%o$lҐ9s?co去z ӺYwPut=tVk#>Sݼ{V]\?rsG/=}oOk?ϗƶo +Ǘ?}|?^_C7MdOKkϛ?>zoy_?hq+W/d),b-HQb; vZiQa +G\tQfa $ͭ-Sðīhl © jPެ1OX;q9<0֢N^ٔxW& }[Nd& `C$B7d6MW,|e[ީ?r.VJ \!Q=_(18#;X@GHVPAoK;iMAO4nhb +ŠLB͡z$^i5\SMJjٖ1N'{mAsXemNiM;t_nLq̑q(z5 :n5:sz9_Iد|):g\>ƶo1owZ XJtJÌ5/j9Pu5Y Cl2=B#%˺v,P_q6g{PE4|,n k08:nR:aڟ.YMNN#.d:e%\#%]4 h1@ t8]rҢҏu +?M:¾Vo9@0fWŅcT!@T{ +Sd$|d$xҾ״.θ>~T ~{=9dx1e86 n29û$1ݨ ۙ3ci[6%|mŪU<(QR=Oz^AQ *3wn^..񇻿b'Ձ;w!L`6 +!82;A8nX}ImSoMc(2|ŕh!\?;]Tv؏+ ̛__m ү}:{xQvcDik>r,QC3flV DVPǠ&.0`MN$2JliEc#% '8s7:4Ċ#,z +H={//ЗW##;e4t,>kO̊6vڼ8jK{I}-vtjG6z[ʃºRV )J̦yNd:EF{KBfqB]Y +xjM$qCq$(JKir_YNm-fg8qcb9S 0oH[x5} `Zi~PSo1>r/)ڴ^֚ј]0]^Kz(Oi͏}5q |NoQk.̲3\ko%Iޒlܙ"klF/.s{|?5Hdg\E+2=,"iɾYaҞh0pd`JGBf`,h*\**%-љ2K*`>.eЬ"J˂ +R6;Ǒ +.bGGQ8(S6TtFsM< O0cV`uI-lуfz1 Vjzmw"1B1picPX&n +%1v1AZ#+dj<z|l\5dQ,Q+Fnˉqh|xNXg-EV,RbS[> W&C1(4gjaS15ձGj^2Kd`6 V:(fi!b3gY;|7_4 [6;|C(BgC3gݔCtx=/#qf:k6Zg3cD& +̳ 2ƯSvj'[ގ)yu_jAۏ(S3UD4\(j%c~pH&ŰKa`H^\WiziClCSdHrS z0"ʇ1 6ipR qR Zm,۔͙CڒfPۺE/"(FrZZ(پؙ%NJ.aed20g})o/^t1UySD>QL-V)k=S@*`m` + S]zUʇQ#|}4ak91~kHN7Ltxh=-}i8tZ&Y3oS>n-m]()sJV#JN  +Z)Y8CDV-;EƟ4M;u@ dl cɌqXK; frZXhZzVZ^&d]˲iq%.1Ei- >.SvD9*U_W2HyDJy,^˴:B[m8EƋc.SSӎyG:zKNx. g x>FՃ9$| ])8(}\ +CC!_uO#,_1=nnov s%I7!G#t CfL<_S ?>ُ) h|Ro<ݼPh=:L]HCcp(7csLL8f/N#,_hrmT!ǧ<=Xy*h:Mu'ra#gFO؆I?3#cR4\}DGWb'LY|5x&IHXN +3$=\N $rh}s\UH^+ rb@R3XKA^mU^6@Y 75'm8uZaA1_pf]mSIr"W֚$ɇ'6"4C G8Ryr -6&oצשjf? +cRC 8&Q8}˜舶xc5;gn}a/ˌy7+H؆>.Œ~->ؗD"bklZV,[ +.Ә +Tb.̆D䠟-+HkEi #|¤w$ VaZ<#7g^ U9FJ:&xRa=rI[ZAiЏ]q {{ƴ*Qa>FAua'XP= W怬gEPq +&Ġ;gI!%$g ЅtšnA?O5jn,}ʌ~i#[h^)Ӓ 5vIo92Npڠ0֛cv#_R<)+^&-,i + Aby 낼} +C/oqӽh~U +%W`M)uc3.-ZWZGx2_wJ^DqcHnc䟦KՔky?MğMC\ }zӻF 2ܓ~(Q#P_Vu?gqK`FTOCHbBG??+-qT8{$Ge`Wr!'R<HU^YFF󏼇lB'f҄]x >VRꄓ(I9F89~vi$Nqrrc:Gt_F;h~81_u2DP>k 4+\!+ZsnW`*O^\E$ +]~|upIgzsmn= $3͏owLݧ?kx˧?(ul73I:Oo?}b~nϧ~?z)Oa7r7n7'Y}bcy?HE=-#|:gr=y6Z_o}nBe,ca`0CFnwI+ſE0I>0~^RhpWoéL/y^]V"y]LYQ }`^+R{RS.tA1aX9W|RG +endstream +endobj +302 0 obj +<< +/Filter [/FlateDecode] +/Length 1476 +>> +stream +xڝWێ6}WB+Q@v"@, +lّlѯ̐]mx%r8gΙRL[JBǕdV_y + +iumqS2Q(ǎNӰM)cE\xMޯ~جܐ 2Ż1ђ7VmͶXmpe7h֞!ӽERRZ +taqp::?5d' -) eEqQ}`s}G G2Wb(PŃʆzڵ آt|NIVuDt /DHoXG^#PcCԫӆ6TP",֫u_ e3|[>_\@ H1iW_x,l +{ɷoG̥BqB8elX!WWW2K>H_eoN%V,"^g.GU +U#Sk I7Stpz\ UjRO9MGN8;3Vz&VqR̸['JeAJ?cLè"ӒA^s[OoO,)Le +\ Pɨ_cm>h2ErQM=qZU@YfnPP)+IG +{J> +d;%mQO<Z/eYRy%IDSD_*M%K@輘}.ӳmӧ>$tI{,M=q~OбwPߌ)5BQ"ҧfM ~ |<2uOi¯_6}mnx +endstream +endobj +303 0 obj +<< +/Filter [/FlateDecode] +/Length 12540 +>> +stream +x}].9n}<ޔ>KuÉ;،ݛd)CJo3g&7gZ|%$")ֿ*Oo_Rkh#x׷ ؏c\Ei߆7I\U~>R;^o""m ~^K~$-k&۱@ln bCr|9CY|㮝tbxu8fY`ӺTj&|4P%_vfKpA{]'C`]u>xR=5="y[$M:L`&%/,^[8TFnGV:a'p]N᥷6C8$ڬd4mJfp_SE!8΄#uƲ"VȜjfzlEĵl}.IOrQnW7]t꡸JA"an$ZTRSf[sP~Mi֋Q+8-ƷOFiWrM1G1>u ¤ L vTmS>h咹2ХV.o3 ?GBkr~zRy"K Ym:oP%uݼ2'Gn +Q@X[q")kR2d +0FU&*Ծ +F1Ւm&Ӧ"BVzTW+ +uJoX [6*WTVsFX}NO3iM;4 )w8=EYMĻ,3;zu/8r2ˉNܼ*RL1q`P6li"*Ub"MVN +p- ;4 ZIj7dt;. |[7N/ kﺬŗfVKg׆ y"K%glIU^G,ڸNHq#\ ;((M$v$+V)&enH~BoUQcZ`=S&TeЫ=q =V3l +a& 6KUUOV`;~ ZژΖɋZjƟ + kEohkw'}rW3>^J0 k ߸W [Nð_38p~ڸ^Pn8z!Mv\?5VnQzޥ&fh:bTt8?}:Ҙms(ٵgkt>թ: |,f4u-T*2^75j4TBtQ0:k+S! +̩`tIor9jszv$Zz%\?#RLx6h߯Å &"[6_0N߸u 0-N~y~Dj!pML:$*N:uhRӽO/Z'|N/ƣi̔Gk^v$en42SM,Lfh&_]en3׹}}1]}n +G6Mw\<ݰ6L8Qd10/];&wpD³uӎsn7q EhGf_\:>gmNaegfe} E[Zс"ր_u7grvepF2bgmTWWrk;1hMͷSULJ)}ulTz_;Һ͈OJSGu{̇l5f4KW^g{#]k<]%AB\qydֳ\ 9lsz]!@Ox LǴLpk;Siuw]J0l.fpVJڧy椬M0Ee:tށMUHvdV UFo'-4Jl>OH+4\CQK`6] f'}eR'U! ح8"\@őL6l!ʔ!-}׆X(ővZ=:(h-A zJ t` x2j+fO&.K;~r\6(ZL)"c<0 M]h;,X11actNƍ}@ aVa2l9U'LC"Ÿ|;)![ϖ4 CvDX,)Xa: b&~ܐxal󶪖Pto* .o T*]g[ouXGV^a酿j\˜+컭+!PtӢ80Y>zlku891a|PosU7RŒ_r;Z ӦRdJ*R=$0@~Ne_0<}c7#uÞcCGO`tf+iwO<%CG h`e+,x)XQ1MOwbߡd*mvu>cKT &\h86 VR0No֓xt~ $׽vGL_f3|u}dSReDdڻŸ92&\p+>-6Fw9BC{@Fmo*>%b1@fIeF->L2Klno,7 tf#}z'DžYC2,\so昮]˾?H=;COcs; '_{f'w>1g?U#.|m5]dQV]_k}š%]tt[.W횮Q{E`[ȩ_7ZWtǺ,[?P7k(Ĥ:n;v)^tV4߃m# n?DIze%7;_Ẅc=(%U~q#߬EKL!Pn{p4]>uox̞`F&pfĻna|XvtP7eꜨO$A-6sJ]?ݾ&rڱޥH.BAFʈ-S|rʶX{r:<g#qQ1/#{^;o]3O᫸mשׂgG?{%Mb}벥}].'(lʹ8Mg3npܨBeϡnCyQ|MƺoMW%RT6N+$Zq<`Ã0E,ڵkx2Szn/ +sK6D#2x"e 'HFI'E<_E 3#KWFA˯T՘bd[}kHL;վa.Gb]e9+ )tN(E}CӳcSzRE.ïI#tݶ7SuBk}6m7;f#+ ?ݜkGČ*'_+[q[m/mFԯA9{* gE_t ~w砺5$ԣ< 3l=afհ-X4Xfv-LfA;ln=W._eHHA%5T ='TjV-R-Mwx:"˜DM1a~Q{GqNwsw=ֆ5n3k熓<3 5CeR)lxE^Kt;oӰ|{ o铩|S|(ۍݢqHWY9^i*E`'n8zH5o#1Ԝo~?>ћVw׊<.Oqڝ0/]4UE%iU>)ǻX*І!GF7=zbN Ƒ&%qWL-p{ts\xie:ڂR零OHӳZ8hOHSmuQsnڕ솏Seգ~9+T>[TRhzu9|LZ\Ndq:e+>#Ken3n~7= +.# wT]e ғ^+fsUtg>찝V)qԒs6yF4$p:53] }z)x0i˹AӞ6?|ۿ(͐ݎxsSL۳x^&o'eB6Fڡ?5,k*!-We_}1Hxm^E8\趸+_'cE屷?H#^4h:{?/Iz9_|/׿!/״c?k__ӋKon*-i/%e R_B|#eE,Y4!ɞf"N>HyA R60|yZPF6$ &Ѩ$B( ?=LD9= 5 OƈEn&;OucR1A>-ǁ0qE}eS3yf Y2GJpo1,m\DK## ۸+2t<@9@msxX1s75߹+2? "{-iF70wRL rRX<Ω"DDE9 x S\ +|c3 ?#H2@H}c:ǁXNkJַ8Y£l#&l&({֯Ӯ*Q0K$zژGS#X+ma6Kᶍ26qH=e 5#ԷXYms4kIdͷЭ'~sromX{7&9Hٛȉ7n|c7dĭ(ybÞx:I,XX@lctLM4I2ڧQM!X!|7GygX31cº +f'IH;A@rc}8vٺu 9Q֌pE_VT<݌uϖ\-'$Ae __Yd2P`)H.SSĻchDȟU u&ӮV|fA +8AG|aM[ K;4 Gu͟{-MSvѼKɦ%(9r59}$'R!/bh٧tYh(uzVBNJZbʉl6J4SE i TXJCVC@ēA44f)RC6T4|mSEO%/:Wotr%f趆b WÝ6h;ps>2ҝvzSSb'̉$jc.Z9BV"%ׄvd| q1Ywā#$96VKӸa/l#_tBneAhZ֖3ĀQH +H +G1Ƞ}4BO@ JiKS{~o -4ȟ1| >Z}nȒT MH\ qXb҂N4G_i$i\ĥء55.|QvڼEO~r^`.')%O\-8`}`~@ +#E`DS0EAw4vmjV(,o]R̐\Vf{9ބH1Wi&䝳gWz@9o ڞnPj& )l4xh8󑗎8i'F(x4Ky xҗL Kzt| N[ňٹOnAxc%)cސLs:=WL@{:ICqਦOn=G0x6~:cd&f?״M/@?=.lnx> unJ;rSد1&2S 16"Q8&լy·_QC3[U\?(1KZ÷2'S##&Ğ:;oH&3(5\`Y'ye^=vGN7Q9bwr*2y1uN&>G\y#R4~N\l*<1S}*tv)Zb8hFHE=oJsL.:@"e8!l##`;}!EFD}wn%raGp&h'ߍ/DmֱdOa- 5t_578d8Dp?5B AmJz_9/>U{0'pakn8m:V v|&J1d8U\s9a{9U{"!|e} A( Ʌ< 砳u<q<xί{a4~A<ܐygVA o%p7\iV>W x-tⴱUп߬whdk +3y bNܥp|W"qT?0OjPsFKGdZPUqv J7!X.Niq4}g@AS + ĥt8YҌJMN2 @hsm_%s!]*g +`ȯ@BjxNit7vxg^S)}l3r㠴/X   d`|S+_4N<:|S?Os[K&zJ !0}*?=x }po0BM{}Lu B3]ews0l3 m{onj0 $$#AdwOpH:f >HiUq/eibpi}?Q܍>E}Tg*ǹLB8Z~+I.,\4ս2R.LҤ1bhF6j.z'{ IayVF<&cf0M#%ʛ["- + ^E\jMqL64}RG*hw07F@OI<$şڹmpPhf>GH<y}ANPo27 H ~1;bJβq[ & ˠ_8j)P_NH})+³x:HvpP/ ^w.80 `D,; $F'B=ന9/@|Rx秇;b4(pkߴl]]#;J[Vmhqmdac!Zu:H @;d/9U(H P_= pO=#'8B~e +M8Q%5?6Im<;Ī|&AHw,և'UER(Η@|I(n{js„fkND\md +Ĥ-vr^+ӑgIaV CEG:6&A҉:>%u &JsBY}QX oD Dz*0sbZW95!N\43x.[3+z:/|raOO].vÎ? *^W +bog|ti(?`.X@ +e37Jms+hTǢ̚ e,+T*&EwMfM]S@MɬOf*bk߱"7%uFRn2KW%AfU +$VE>iFjI]nK75HNLfo^WX/E& +  +>•/o U^+& +y%E^-[3d{.+tW5V3&j\ *C^UFM>bܺ˫M^-ce»oG5՛*jj7%Ef F5U̚dtʬyʬ^-#iuhʚ I@HG٨::COx L: s  q[!ėJݥ D +YbnV.h8Ɋf =PGmu>C~ݠ| 3& yaI^:4 4~a qz) &D+90 f^A'~a–GY9W>'r۾ V8})dFoxiM}9+n.FTm#I1zۈE+'0υ2yKq݅]8A}݅lYGop-syO$xa-vT32@v5&2%Zȍҧ`TuJ\O*&/ƒtP6F ̀!+/.^(BP_(A`o<1_[walȪ;Y9g%EPj0/^v~~/41` ^ <;F}*y 9|f4M ;:|{/J]XbFo1bX>B <. \:k5S@NfkV'ds@0!LJQ /;{e^ +V1$"FQfrF h3VԱU%r"P|rX=R@eiEdV:L ));Е;r8n# [bs &Hv)g)9q@E&637$'|S+ǒ% Kڳފa:J|lk`w)Q8ƃb/ܩ8䰌~nT@ +U:5x [^toT->b*c)bҀ곗Xf" 3nk@ұ:59d$DNI )(Mbqi2!κ&RoAP8ޜbw@278[ li(b截a(Ą*<Փ9~J,#\gq %'ssh֜'`<|:#暩/~|%(oR?.>]$G +|`F/noå~[:ߥTڗ^%]/Ǟsԃg ΢(0>Gdn7>/ +:owQ鏷/']%_? CU +endstream +endobj +304 0 obj +<< +/Filter [/FlateDecode] +/Length 1105 +>> +stream +xڝVn6}WB!C" [mh8}PviKJ*pۯ )i6-99s>d$}&S!rJy{ҥzp>Nxi:mDUƳi:|f +Z-B{]fΜ%=+Y)TIA8d&za.& )-I&*ٯk&sW:+QI\Y(%HV4RfǑr$Hn#]+W s^((pH>2oGfGztzm^nBH4B[y|)<\gWcmP +w 9/z.y*Åop%G܂P~`WJq\Td,G–Y/NUehNiم\ir@ִr%\WsIU +fC SǶ[4-έ:C{C=F. UCQ1wW?{`[7T|Yȑq#׳aPSN{:džEO#|hFStx4ͩft NlwG4#z Dxb MiDϊXvX%Ɖ0T+@NA46б8;`!2mWK~svO}M4CN98P=#49~0tF41Gtp7s($b*p#Mlv۰,?Cl.c;ew9kO#K,ۅc1øbb6[Mۇ5 )Uu9 +%KR&)dwLTXģRB\ƪ.f᪖ӥ304q Ud`B6eoB)Ցr Ť܂+p>L~$qi.yhOJ[/П }|IbKTˆ?ɅnQtaN9ۻ^a54&.8R=\S7[1y}iLN^}1\ +{Iɺ7',}8ӗgw|\ +endstream +endobj +305 0 obj +<< +/Filter [/FlateDecode] +/Length 22258 +>> +stream +xͽ[e;r^"1ҋw> AӖZ2*cIg}wfUe4F$c/[0_yOU|_0:x u0fۗqZx%p|^ߡp76V%Q}(|]^[u 87j鵾\kLG2|^pk&4_K}9Lm5s?XknkPj{ٺ_^sޖkpl|,<; +xŚ#5cR?Ll>z|k|]k/1F$4A6~ľoL[І=9q=B[-Y'6^4{ ,|^T]zcVB6^5ЪTF@<4Վ=g(=pMuC}Ms'PC\N9$쯽5^{vx;asśuroToJ&cpKr¸Ӝ rٰFtdAAtКTwPFj06sɈ#T9|GrfIi<0k)?s?λDgT'ɞg$皥(Жk[v?o9PHsL?_Y +4Ӽҏ6*.g~Hm}Sr*g\ ͎G轶e!g Ur0x"y|:V~y?N}GGbR?n3p(;7Q'rҌC|@zF{IHMP֩19;p`66 $h+?ܙO??,YޅOq??}ʋb6cuJ9h9'5˲Ώ3]?gy!@ 3[/?arl3u؍k8oC>iT~Sm<; }nE3ƒY'N-F|e "V$q]׏F]?ٔ?Qh҂0G磊vr +@}u$L&ghC;(OB\n/LNYC袷 {6m0Oe,*P>Ow\"qKuu_֝67qU0.neo.cׯkG$f_dR|6ܯk8Wi̙sfpD1 jEܨ4 M}*&/:Ug>ʁ8e#TF븽͒2O274K=ap䰽E°Cۡz-r2H_|T*$L`]{^w;5!/hj HB5B`޷s.h\v)R[H/%שaE~wY^fڒŸ~ N88u]5Wi6Ŋ3N)a,荛e49\c#8"#H2BUѺ6ٽJm jS9ї#Yʒ.|!uRu +q}u{"ũȒ4~s:"ԳIY^3߯ϣ܄ ]E!2Q(U#e#?GYa8 .(%iB.a@pMcly*-)(Mƾ٧rT? 9Omsnz5@hGYN¢-oY໮H B/¯YSr& GXI䠯K-^_@i;QS]&4PôjDYߪga,L>pS`@g -`[ pMehMy,`pGOi %:4PjoS>I?ؼg#u|rޢEx3ݞj" 覗*娱̹o_ ~`Ĩ\p`/noX%2,B)D뢂0N*wVvd^x'vf 8:%i"g\fέs![rKZȺK V{22a\1.x:BrKfC~л#TO9G_*BB ~p3c;hRa][wDH|6.? ɔ\(^N9 +S&ZC0p].e(f*^Ϫ :F[-{D\ֵ8. Y6ĭ/fS"H"[Cѩ/֣}A)N5#$,y,&ST4+fP c8>&eǬ,> 7=ܷ\z?~?@ۉX(yAjDsBt l іP{L'Q!&{PQ ף#k :Tiu襀h/Cz$K'~WVpY\,h? +tJ1 %p~9 CU௏ءi"&LO,HЄ%CEL|&L!%(.ca+U]@}D.ӭvFZ, s#:7hnk+7K=6}T.3=ͱ0ώ5{lM%fjVdPxгb Id V` N[jO^ڴW't}k~a(AD:\!ӿOF47;l6F0ĵ[z]+=mTѦ"W.wn$DkΒrBi.Qr)˺{Z +d@nfjFL̓R!/4&OtȞ/wU .\h uJnh"UW-iu=W TZk+}v;$hK{ +ҁ L1YIWꞃ yO%Jq0M)-WaL+AztQeam%";vT{8W$_`\fs1M#8_oH`CUWIcO}07SA5b t:4Nԓ32*~弐CNgⳣr&tK7EkB{KOj/toƟYR̦a! ZO;Y8Iѩhb4BM|`?֌x"@ C/:/ շ<I3?y~άkTHZzUu FɛU[u@g#O1`OȦX|F3dC.^"Lv^r_I9%2kTIUgI%ayD`%mcIv~;w:YTOX%- "a1$ JHT\$; AB$wϙ &yS + 7O;I;{nIAe +U +ϝ #x? 4̯ b3(+,J< +2)jX17`lZcSZߙ [6utwe:hç:\_/ՁwSLgӼ}"f:Иh1h +y}>1@N>/8gnj߿]&ٺZ(NfXQÛG _aBܤna]RD +rB$*%]Fw Aѣ +>[[FeA +c*?.f'h{n@@C|qhZfEl .aJMF([R3O[ft'RΌ8'aчWZ> U^M|TRװ---{Tc.E<7l@%y i{ןh['[ƌlzzн}f`#2B5^UۢonO5}e ns;fvqbF=Rnq90$RiDe{hV[,p%}8UK1P>T:d)ܠ=)grpx_;-̜mi՚dl$II %ˊBݗ~gqqd&8uף^8Yi',6uZj[2 ճ2̱DoV?jD׍ +5 +e 5{Ql/hԆ4-F|oQFQ⌖Œh<;i 4[Q?fudwAQ#h}`]|E/h"$ެ;u97Euo!16tWO} 0,KE|dB59XzwO9HH^Ug|m郬|dF吾9N#D5ϴ?8Y>@]XF"/IUQ25)5߿zʙMBgEL'AʔQhzȽ˚Pps鏬~eRAVU'\e:9ӄ)qRWCvu|}1q_="Ϗ#'Vj[ U46*5W&sj.PlȟDdδѥzR>Y\ =])ЗO'"C\'zzti8tPxڷ\T8,m{3\RH[U/lHf7߇{j/n/WnmpY{{/;զ @c=<ٴBv۱i|jǮ@׉Gi`'x$TE6FH#rV/ ?&"[s gT?"bu;d+K;b=&}6M{33f6y _ (Ϗ,3M,/]^ ۟)ԇ|1,7^׿yݯ1O߿_C8y_/kL5Lد]//+qb-/~;y" oy/ZɂNR^X%(,[SQ{G=ͿzIK[򓦜%'>hږ=hȷEQD FtN .{5D9+|&:wI}z&TgƷM+ҧ/,  \ zЗTM2SNV5_{XPbK88RAO+P>`l~k*nZRdG\Up'of9Rj*;iWӂʳxڇˣ"'ǯU^QuD?jHO (NŪwn +*#&2pRh,ҦJUK=aX: m_'#H3eR@ES)*u"D'h$ +TPv +iạtZϴiuXhjYt(rc֬va6{?5En[mz/paK b,j:p;4@CKO߱ZA;NyWZ4x2UfJbyn#J֏ "TNhkۻ,zI L" 0 f[]Mp Y[N(4   nIL$nTџ6zsn>:`)8oj uD0UKO7Yu:L z}``'dy@išX-~j1;V +vPޑalyt>~4i.eDPJ2mn ӎsOG!םtƭJ۶UV lĊQ*vY[Q((z vzF8#u5XOlT2.\ԴyKP ܕZwObL +58v#3gb&{-8k]vq&z(k: c`Vu#oܬ{Wsyd mv#rtbjU70VOaM4$%͹˕yebH8ս`D/58é09@Ꞝlj(,XzMn~ӓޏaۡ͡ҫCgm?>^=v1d4go *]7aپs >kPx#:L-9ꍌIf7%"&::'J=D6?pz %VZa.끡2f4G1v(U Vl\ +lol ڷkMwIY_SXԐ6n5*OkIa.Hp5D3A8q.2a<¸KK]_3|*{DLtc];ˣ,TM~Knnso1bo1b~yo-6aV*[|$%V,XQ[[l@x]`XﴑiS +kvWQ>Wφn~U*_TPnUnV*PA/|MV<:x2^Rg[-`Oޛ]#D< хmF1S;zE?6yzdSRʾ)s}!o螶F9pwU]ATKqoD +MO)^RCfCgܣAh‹8XdVT$yQ6^7)q qH8kWWv'h+B4 ijTy%shȦl L]$9TRK~_eʁO+#n3&D⛜S25;yt܋JimROrs2De.Ia-Sk ]ƹl T! uDJ Ѧt}Yeo5 48bє8ަ!Uǀ{Hܧ XY48HJkSV:e9ڧn mZmVE'徢BiS) +0 IMAXS=~kxez%ObjqxU:>Xc՜,EcKab&s$4Hu:ǗKY2GgEBckg'@1iJ,N%'WV(~TMc0^ȏkjxm gQ+kQ9V; mwM`ɧ%'wޕzj5Jw. `*r>Em4fU+4ۆc b)Oc[h;=IhcY&]H50qͼd &ZvUʡm ,tZǵv !PS`lVwf:]|V).i+~dz‘dp/"-y+k K"ߩp=G2JtIEu?`~Q+-I5 +[eL"\/B-i=]nG5q.`MgWQfH u6I5Fe-`F+k 2iNR:d2C>3SuORL?P9@L72LA_|7A{SI=L#*W!|;UFў+v,})|5n$6OzQvɦA|O+OJ9'Ac_m6`(q# KtiF+qv +23JCiϮtX5A$Do]9ILJAGЮ&j5ZiHJ{3_Ht|UƲ38= +@>I"2LRRL[L]P&PW+ +'յǙ`K[x>t"=MbUQ1>%Wr;A4e+$S!nϟQQ O0V^n"3AVgǾPvL[@`*]@DA櫉x &bӭw7JFlEEC9peZ3Zxh[^&4,@™l 8sj]7N爸$n{\p.&؇- o Jo8W]LjoȔ`==<&=ʉNP1 V56={GSIpiFg +<04XpF8}w\hsR6 z0 * +soc@ڦ*a 6 + ZID² paԙd'L +ą"k,H/Wx+1,C ~KR +dЍKaEd +WoX=qa^,B)T^XMm3涓מ@3EL,ܣ<o$r”iL"fjf&9dI.YXcfNvu8Xw=*OX9}F@_Kp=aq}94S&X \ƒ2lRKCj̞1k)VثuZA˷2ϚWDmz^:5۽}Gw(iUuEwpj.͎_T-;]ݿLƵjFCU^:~Fǁt;`lnŎǝ)w/YDd02e +,oJ43=gs6,ˈo~Mَ̻i8Cct YXw(Mp0Dv|5XVluQJׇpq=9^7/:6˴bs=-Lㆳ,> QM0ޱTL,ѦDp0lM= 7oIp.̨t,S}为7e_B\p'fqmCq0u.l۬-IR({yl^!h]XoWϩah8~_hV5ˠv]Ӈ rȸ== sR e + !1}$ +w4Hs3y]urϗxbh'bKsR<#V~=cDb[(NU}$BQQLY/D4FS]p a(D@ɬ]J7gLj tBPnafIA?Z59'E@3˲{čaS97 bpVָnS!xg]G‡UKȌِaezw`6c@f]ij]PIGL"cfe:?>(m|&e.9G-B9R|MH;2r9ji0"(&H]9H$<^όr׹Y1{ڲj"H.7QI7u/+st.>N0P`vŲ@hۭ"uuPKU';ַҰaI57 +^Ob NR2 +Q7+=MD5M" 7M yX }BLBޚI:*bIBJW +u/;z[NviܜrMQ&A8K_L]( \9 UI $deYGo"N;’(/(51W?(}kn#] YU;ibi->5Mtf"M9ANE5t4c$dY3w|fF&^(0,am,tH::m P;A>z +Jz7؃4L|@*9 y&$+jRΘq{fxNW[1+5X-@5 ]-ЫMc6i:r(e6Z _SrC +}sRhJοx 0X$ӝ=A|3BP/C:)i34PJ=$B E.rcB<>gJ {`ѭ<2eY}oĬ +3#f# p n蒂uyXlwX=Ox!E+z5늦~HU6GVl&_;rbo7$s]i3ً͑TAX[񬝦tֈFђVs-D6n8c ~܍]:HT棊Ԟ(țOxZ@BxR#3r ͡7ZlB;szb)^8P\>nk]T 0dRz+W>p(L U&q$[G.|QfAm "T/QWxJj%TSA>]% +Qડ!ˆ0e>E]{iͤ#a.OXR{ͣq4gҟBdSlk;k, ])EjD+K3^S% MkcM6BN7#&EtG}>5)Ҷ)r G<~$RZ8lvmCPk +@TXC1E2/s23SzG >L}hp ɚge* d +PAzE3ORkÊ/wq.eyUԢ"C= D/._d}+5WWHkR% ԊO`ku<I9byvu'N~p9&U!z4VSsXkφL,

YHJ0S IYm(H T$}G'ZRfRur5;uYVBDE*y*BJiC$+$:HH6&( #K K:lEE + J%|I96 ʶN9<9VN*'^M<6l\(r\ qv'K +Ao]`:@ogd<}^.@T.׌.$P| L*/|}~i6r:r.t1 +6}q$Q~g8ͷS2_8zY&{$PE }Z0p8 +endstream +endobj +338 0 obj +<< +/Filter [/FlateDecode] +/Length 12897 +>> +stream +x}ߓ$7n{X}$dĝ^;>ygbϊ{Z8zޕH|@2Guq 3II M1N߿ލw?9a/wf1Ҝvn\OeyqCבcaZkJ(S9t>a?ACʦqMi:42Q}&#r)]RЕ6TýsE?p[^7B"_2>زÜC\Q>| aӅWNR&EJϯAi[`|RU,^J~XSzO:`"gȞʅq&omTleG|N}UP/X9x!_ E`6 'EѦSmb8Q]CceY !vNTɰfi +qn +egCJS%BbtrBn:HVrñuҚʃ{*;mѿ͉ 9 b g-" I}v\l6xʩ3#)[EaS||kAj],*\}徶!vWEIclIK.qXRǝI_o!F[m®oYԷ '-+VӮA,j(V* 4Ho֕R6D9t) JZLnDBht⪛"n>oX2fdJ&#+BIKZ$|~&}ȼ,_ +;oP<1TB\?%I|/(hB_mx`se92M`Y^\H'{wElف>ґpNVN guƇyT# ٝ@^4Lv^mi՝S7>@I9}6f3 ;` C̗,Kڥ>@c}P>t(x^ NvP=r,H yMnmgjuWuZpkF73HڪbA["@MB +I.q?ijCSA9݉g֍rj]uXJnsθN fEt6bKņ56,?W;EݗYt%[bb lHIEE8 ȷQ/$ƏJ=c@u;%ޱ_lhCRO +Gp$pSjK7ƢnAiTV~yfJ`nUKۼ+;mª' =G;̦Ji#S6+ltP{ 8@}N3g|b,#Fo'*3FBZԱSlhz5~#ZّlhZʼճƷdU}nNN7m68e&oy /Ge K͍h,z qg?v k,=ֽRoy-Re#-xT&J7t/~+i,sbpz.+E: DߘE6 uZTtC@8foշ8o︭D/!p+ry +yF븖"<]bTm-F(67D\Y1':8֩-՝qEzr|-]n"]5M퇚Ȫe,oWu~~>BŴ/9]|['֩~MK{gl-P<]wj𔫛gWtGǚ%ϣgHʹ ނGbo>nen3ņD4uc_ĂBousKvS#6p_hZw}fAg5\fVyzIXM6 sNE78d@KqӠQ +4깵D(afw]Mܚc+'@bYt+u-Lrj،W0 ^W°H:nꞺ~BCx`WY_r{1CuÃuWiرɊVr6 |h@ " ?@c2B (7iD=Id2[2xبLVf%7=NXDqy\syՋ{#Fyd5( ϠsHxda*w =TfkbEWπEp^@g^VޱOsE6lV+VuWaW. 4BD42#qѹ0y8|D䢔5#4 +KcplZ]ȘN<ˢIBG#}ndabi|+G +1ӣT#x%*r 9+Ÿ wԅekЗ kHquw{eNDSH܁32bXɻyG3kЕr[*k<,>b.;8P(#ќ|li +} )LA:E#G,'lι<n,U< S&7o'ҙ:qHV[sEL5 j,0" bF3;bj0\E, *VLm^I/ ʻ7^e-=u^n_i?U-0ntk:`| +~C0'fI\VlNWU@OR U7] _F _\|ԺK1F3;'W</*}mJO>δ>Jx +pUp'.ނ-TDDRknmf:^T/)}Wv':PҩK%2cEiyzƀ%:'2Z\O{ZϧF:n@(3-:OΣ룪X,Q>Pq .wƻ//| +€t3`*p]r7xڙCQuS3͕ Xkyz{$ců +oAc+ `vvX2m\L%K_[NvVoA6RBP :|WZ) +$Bq-L,s-ddS2isS d&'dQ#gm#I:`aiVC0Fՙ'([Z׃c ѹmڵlQV43c|U|=nqoX3`. +B=GlTBG8|l9orJya ؗM$R[!aKDۍzXvצEs:#aQo&یkxMPfx Qբ2J-UQ~%rG1<Ӎ@m^68 M[@ИSx-13b`B dAAhrcZO mˍ򕐾n>`'5zw5) Pl., "KdqO Bʖ|KF[ȟEj*~]7ygG=^z g$zU4կDjٵ!#\iY9Z6X㵰!hV`> ARBUKڻk ]:|MlyO,#C3S{vt.9rV `p _ +Ѥ75hA;z[}kC+gϝ1ƒj\Jۇr]mF4rIRi;xr"\޵%̅f %?Y.1(<Gi;q"N*a dȰad~-}0?=;H~EPLN~N ej7TxmH>mikY p'1TꖸJE-ӭM:2Ԛ:VnΕ40Εױfhg7uj|Yqߊi_ZNkXG{bƆ_aш;m~զ[q|׷|{ӹ 6l/lq77̙t 4EJj`?i 3NYצiÙ*]n2‘ Y"X+e KJ*3:P#1:g{1dnۥ=x[ТtpgeMsz|.𠠩XaIg}, ,L?Ҹ2'* M}I-tXX-OXS!Fa/Wć v\[uFWfS-?]/6p6#)t)h6_d96E~M#~#ΦZjd<.h3_+Vlc]h 8SW@oZȉ]RS;\t~M\q>2z\-Zʘ`ʢcmHNvc\Z<<:Eг> >+,]JzTS``-]SZ#>Ӣ4#ݐ \W&ңXt`%+b6_l\Eg +pzX'{` a\F^"h%~DZ5(8(^S[Ut E,`Dd5|!9LG/8oh!Vj=a! U 8,ɐiU^& | zΚ 8 Fi6q9V22hD% JiL9VX* ؒ.ߥ-p(r 2WRk=?S?~Mǧ-,qwQpUxbzzoѩ5]*A! :$tu):r7Mĺzssjh6# W k(|&`zg8^*BsOQ_y?E~&;b"4.RդThP_MnJe֌'<{׎2&~wTJ mhH^-R=9C־A/왺;<1 oWf=,ݠNT=-ΪNmX~2ZX을s;%b +P*7kc6bn+Jb-,NCZ#~oDg{9ZlKKKkU /xԬm˓0qCMbfigB,lbEW&++;b]eH +LYvF2DkuI?sWbiM[?vs_ĞQx,VǢ>L闳;NT :"p`dRۉ}Eݥx:x0R&i&|+N|BV`Vn*$BbYɀ3 Dfrb<{jRu6oFuLi1"f$vkUP-y>V5D8[7Zt gt_^F'+5c*V~l7#6bs6"A))7 )/]5W_;:6AMvNN"~LLSQK tmkXSSsߥr%OGq]͘*zd`nU}dkGM-riy\u ]3 2kq .'^3W p:bHZT2 +bEׄɔVFoY)gU'W1Uv,GN?fmw?.w?>ߧ3ZHՑ|޹Ku097ŸO?}xq'0V[QMfp✅`iwGGXl?>}{qW:_e <{hfTUsAcyN&G㗲/b.eҏO8}1Kv~/?:Ɉ~/2y|8v,awB{)6yM0}p+6RikNmKa Wf$p[*%ƁMZ i+-ٵיڵDm&ݢٷpp5%DA/k \oO W`6~W-mb.#ZhYЛBo +*捝+tf.ٵ9jZKq{LY4 X4sbjH%WKmfr.f/=͵vN]yӚB65Zg5uƮ2bCRfjj ^ j]nk +jZ +}aFH@ۘbojRpU1&Ro$*s)m[ՊgLJ[ԼUo@ijيfȊ]+T!^7-^h]ٶI-^حbT(jRQ-UKjךzqR7MުԨ j +A ]#B |섦@85֬rhMY!kM%knӲŢ=.ʸ`ClMY3d50|`fXXPofTUmW\pn/\nzW. +ݢQÕ6)]VJ`Dp{Ve8ZEW, gUOXF_\7Ltp{Nk'NsƂ6i W֏W– Y05NM3\'pd k^4ah[Gl魍Bi(kQhO4tM1j#ZmYIJb7ѽ~blXYv3}&o0:fruސlO*H*QoNp]7,jBZ-. D0S%pb{gy`al L7ͮH{k3F3ENc{8jT}kI`17DES5쿙FÄ5KyWJX, eSUCK0 5sz?Dm|i2%PY*.|ؿ,Fn̷?jv|y BApnR3>R2Z +o7&TZ錜8G re[5+'InƝэ?pF73T*Ӗ~[L& ܹdkVݟ.g_Y_U oӅ *7Lw7=C i(RD z?)*b: ˦W`Rp +’ga(*-9HJm1(ڤ$F]3 mh{ jފL8@2~/4s0^wڏ(4܃ 24B(s7V9RDh,G ëstP%ygD<$C _kjkFԟRSǶ*FqfE α׻!hBT3jº!f%?5G'FJ5E 滐k?*E20fwP6c +h]7f)S;WsTQ{lqdG0G5 +-ł:T#5Q*rU)Es[jT'&:ӱ +G[jN`9隤>uq?VcIRW V2G-(fe +j)97&0Rjw{ "ՓpNͅTC UgtϵB`N~l8j"ߣ1xv2\ ̃{*a RF''BԼ D!#e8qq^u"r'g_HBun0G pUdǞyu0k1 72~5Ɛr$[ 9\nm*_#9cZSz5)̩.tN:3+Q׊4*/R>Ţ15nj#g[y$ ^o!ΰ4<Za"Ϛ6Mg][8̢wܫEo˿̧R96KJ>cIrki'٭>1sJ>r;^QpZ C;TmxxjxUBm`P@B$߸OV6Vnn)\)u=ˡU^ECj,^5U~m&Rk6B.I>bO:,KԉkeynA0hsؙ?…?V'kuX֌l~ƅMAEx2peB{Frx%o9Ƣ P=A{gF;KdV;nTC̀z7Yq͈^^2ܹpĀbe^ҫ>8@_1@yڈ *&v02D\L&"&LG".KM5H/UGli/^nR36GMsyݜfy/A2(\Y(%;[hJrWpЄגM>v$w:s]k7yYl]m$ '%-AHlZ^|]uS~Kyw+ЬR KYDgbMaX;㗪/2v/V5m#T=BJ6oO*ʻܨb X)*vR%XnMeX ,s$RiKxK[͵uk%!{bDA-oq̱}]P .~^(3vǧǧ?=_OO_?<=>~(^Y1+xs#;=~ϏX3Oxuo|}ɇ?8~p쭸?49dnYX-*hMA'wc||zl>y*˄4-o?KpD<źq.%?*n?e1:kͷ~rkwX憒k@lS ]L*gxۓ1qzROHv׿cHӧLhϻ<v_d<(.'x,i2Oa4Sg!_d??fav3nDu9 m$FTES xa ^ΒE0u}Eۚ)ۍ]98tzc\ e8K1IErM 65?'8ox]ayP (Q\b5tVᔸ89M[ƏѲ`Y؊QbδfR))BL]Ry̓wj.Ȥ{C$njjz [M YMuAJε;ЩGx3v> +stream +x]m=_/<|)\r^ScoUtc^IIEIQ~ϯ78_~_s|YϗQu!w? +R~_廷}'=i~?򟬰.J7)ÍMlעwp=_/}~JV:XU2'Xyj#1.w$Bv=DO ?M\Y}RߒK*mU{nw42!+Oݬ??s<ٯu2A eo,NM:_&[_ rx {skGFdmwňN9W~Uo܏V=jEWV]Á|[(raHEA#KO. V+LF #,rI*˴N <˸5JCÎYPr/Vuhy}]ǹ^{@b4S/G_bWun zWR`V f.~abQ!KXs)ĵS*/Se^#I@9IГ4B[awp D, 0KQOt n}=˹}6)ay +՛fmyΕLW/?q, wzN3c|~*e=d)`.iy{"R+|[iN8kYxﯫ:C^rcDHndSЂoi&*\|,&>̘~:xzIGe[ hg Dz~U\ %Zm5aR d kA+&_XKX_/kY*  S˅/ɿbAܵWZ*<7H='IwSh +K ^i#z[7-aSbґhdF] 绔$ZRa_*MFiY ]gmSUo[sMz!!q +` U :W_Ų #25tgS]!ߵDDp><~5<^9\ƿfI,-%BHJh%.7x^ @Ҁ$Ex9VX!٤+]y\x֏AE% V: Y(%4c@g-!{=d3|̥4|(>,Dڝzj @ɨpFnPv{Hs*0QR[k%HSW1mI$= Fԫ'2φⰄ98M~C&o[0m&i\Li8A!WCE5*aP6W+JEmښ_//BjsaE|idI:;mA-p)}$Zտ@rHly\+vמg燖'g爞爞爞^i)cLFjşVXBά{V=>ЄpYz~Jx.ԩdW*90nv܃=cW'% l)/$f$2:8Tά8NTdȈ +PE!pF1d6^Ⱏơ?$Fۚ8uѦ\py&g#@zw{1k:.@)ArE^ E逗,Hjԏ:@ە螶Bi,+,4'$a(d_Mg |/s%/Fn,|V"n# 173O|W 6" W"fWc(U6j^ۍu Z\V, r`U%= R:XEi&elQB)PXy}HD_ +Va0s>/_4 v1Վ4ZmCa}TX[K̫"Wi^zSDZ2 ,#wca~׸BBcJ( U"H8@ıu71lTu˶Oe+ܭ:)@sZD3郂8 ş*yW*6Mw`gmi+g5uO]S +y"dB Ug{ޛN).JZ"1 DQtqjaeFӴdܶ;$ZPiuiuseRGtܷ!;|Ls%wȽXXX3刪ΐސ@(G}hw+l77cUN+ |wH.a ڄTpi "`}S>- EV{3cqdz}уti|8L`gY"X^Pf|(pvLN*PD=R0(7@X.P;H>a}|͆~{v{TO7MewڥiK~^ ŸcCªˤ]Ւ&)X'LF aggT;aEbh`ES9@5[uqG``cezهQ3{+Fm@J+:]k-;!PډZѴYM)4wӕNzV Zm +jډpx``^Nh/OܜP|zv˽ߴ8-cFk brF2SR@a"Kkmq!&Ԑ [[=\kg dZ|"s[ͥz~zڣ@9UYQ$cp9kDZYɵF0lUCZ ev:oqL,1dId.k^ @"ahg4 lo뻓85YE&OyvcNNr Ei +@SK5@=4$;X# ֐Xӊ +7eNo-ٷ̵IquT9\ J0ҩP@3UlI6J)8'6O_X/9⒳ehA!F@PO͒"GUeJ^koU֧O kBmY a'x:Jul$=C 2Jը8#myjWX?$ŶJA}ē34\LXHf́SmXߞ0ZDX8qmLZOY³|dr؜"Hu8tWE2Dڸ6R^ltz)uf 8qH\cf䏕wmhX/!#rK i+~j +і¦hc[`K?Ӛ`X*Peas燖2:V`KS-az4+p:kDǴG\1,fq"܌7r?T8 492WiÉ +/6nDW\d$Ϡ:{\.:1;[a}Bه>GZ=4'EȚT;}q@A +ܼ%|o@B\45㺒…pK@í:u=iƥ950 (aM :y\g:KS@_[?ް&ȫDxQr(ˋa])< +.zF$1o/A'-3(uQ OF-IA$٭މ>k/דg6^9vb{laŘkvW3;|ІX̊=f:6ia3I36!mL+&Ǵtakf ja`;G"|ؒqk ^ cG=ȗ3!U~AhحPp.݅Y +('"|!?ia'^ޭS!n0=aG*O%l}]q~ȼѽ73C +gtefm}fnDxd89k WlIL\KIT@,J7j]_"Ӗ a7[6d, >~D旁x㊴N"2@)9'+_ViءD+Etr +w߸4F[zL&*s?H2K$KnZT'z+GǙ+3MJ]a>z;Ž@).a>#JW8c t; `1D=iD jpO1pgg>DTEΙڢoԉي~ІC.^Y[}~3Ե:ϒK~%fԆyNygqϭ5l0[bd.r6 MFp̛_KGڝUJ8 wj;L +o<T>⿓#,h + +\d @m@(Cxdap{'i.M'zJ+匱V sdU1/?yA Ox˵@ G pc$kdp.L/fe6?h⾅sӐ\MvIHv՝;U5vWȌ/ٶWvŶD p@[7&wDŽ@I8ox{f}6QvQ@I)W1H/K~t=IfvϜB!3OI6167}67}!5SJ|멜y2W[kI ά#x7#Yub@2b+¯<-胱CiH/mB,c=3 66,P +iU[/l Dv blՅ2tIQU!L↥^9vu܋ RZciSXv#V_Aw38΁Ti|PN̢ *V-ʚdyȢ=a`Q1 N(Uu~6ϡHzDIr\'ɫp=4GDFzk9'pQUC*% KTS 4k ݡx%c&rX3KXNjs{}[=X Ppz'π +n7tMl_5'YkJ  KF+H/azҰ + 2bXk#A?u,|>| uUD+"?5bs㻺UaNaGx5')7:Ӟ ; a +c#iC g 1?:G(rvF +(Txll\|lƛfar.Fim5'- EyG҅eXfG ?NԑaQm8& J$͞##sCȑ$-5B{O@~AiNfα{^ > v8ůS%f Ho +Rdr^wzMMKb'?(q^kڃ|"DM.^_Wu4Vfgߎ-("]ㅹiG/[e/>lp83 4𰫰܋E\V%SsHBfA7U ~`z"Dv'ֶ63<~;W hu.3yؕ_+Uu\G'Db+֒K3bZ墥߳yG{R"E\fzihC;v+ͼeԩTݐS۝1 Ega|ll|o*S5h ea!NqOWMDa wM8R0*{ް%|,GvuccȇV=8 #1p}Lӧ!ATqϚ ׇG 1$כkn26@LC ^Zx)L + +;zJjIx#DcH/;&h +WU{W ~;>ه^pZ{tj-F|bZ -p1bW?֔¡'9t^E5-! ؠ~(:y +)'!\=:jgy4pK=F<2T]c7p +/t[j"JwW3F|@bYwi~݋bmkb +&e󻆣\=Th­NhQF5b2WK0 ɀb%$LBoc]+ +K&κu Uࠇ +h>Uβq q܈ .}sFSy[ƣDg5\.)~kٲ[]! :@n/dj.ٓ |C q`GvKOw/*g +|aLZeKac +Pt>*/R͖=`Énc˕/.u 4wfrl^;k`$MKPh@!B͵!&6PVjm.5[iK=e/gDz =F(ڍ] T0$>/#EUa,Yg_{}r7Brsbd,I'B~v~I= <H0q*.wU9]p:/ {#%XR̰Q{'8AGcZ\*ݘr!LXzőL.S.,5Sø#% + {S+2ȓ^x͡r%MB"+ч"-czژΕg9\Su͜DleH?Je%V_;rEo5EHYZPi8%k_ PkA2w ",pUMBb=!X{v8-Bs.`;\_ +zT5gp>um@`r2# ٺV|x)f8 3fa-X"+AZC)3Eh8pcM|wt}PA\,H8a_T* (|I'? |jchDs2٨^!9@}Ph3E@P~ 4Ǯ+ Z]#ELX=ˈ!}`#ǺXJ1'8n#g 3îdvbcF!xm(\"7TD??BegA`^:)2<)\)pd|@dp2#qx^WLǗ у/@:E5&f> N̘Ձu}$c0/4Pw<)8_3t}xY.M㩯6w nC!ncebw4C")eM; b緔H|Éݶo\wpe( F^k;j4-azxdWXqa^N=q^%3!xPC-;Z9+:A+:6w0uX([;m8 A @tīRVD#XXZXC}H:sF +\UfX@RiS/ ѭWƷv+#aψ]*1.jdn#|in+zh1J9WňsIlO)!ANnTq@n-SaG =DL}iu~U+-_."GU!ڽ8fE`a- 1" @-Π(e)k@z^9PQ8"Yp^H2QjvS!(*G&b4N{ ƙ`Դ{QBGyc$xz!Nh_1GQc ]+S#R;x\~^Qk#- 챢^hd;p a >O׌H$dZBo,EH$Gx;M)->ٕ{0$7lmWc8S):ɟٓqUԓA=by(/`eQT`lFȹc!|19uRGW-Nb_~`lw( +xtESATRxjz[uKV>x]zםŒD4gW;I3}mǟB)%E![|8$2uҕZLȤ_9֡غbxrysE0}n&[D7+C`qw#D`O+p+hۊ'r}m{'_52I3WFml-``<$+VGՓ N]s[\y)Orŧۙf5/"[kK>3=6 +>)QP6W>Q8-Iptq +]NJkBGHۖ~(%;! @p@fGDIKi{vF}_/px0aӀ@, W|ie,"b &eX9xs^إ`~4tVɁ6ĝzSq5˟$IS-0<ZvzabSjG2_PN/oTE0γx!wy7!{X, u+<|9r}i>8&O3}+m01_H !xhg*֎Če;8\ܑu5 &*Ixdcl O Oޘc|F3h By*T{Yl=l+y "t&e>Rϭsq}L0%h'UoFA_m׺0,w u{s`aN3s֯Fsۊ˪ʶNrE_o/wIzU!U.s*@,D(܏Am.$Xgc]Ӝv "qj9GOmoK#ڼ^;Q&p%Pԙa :YhbBHmn./#Cw"őZWt#t?i8l7re[x7@(-<#rA6@5tZ % #WQ@Tv~ +M%!掁Ia0},dAR( +H7*[SJb{V, +0fa;ẅ́#:ub5|$ RPmRc5&ޚ:x 7,9wy Q4x;CǁlWZ<-XqĢ"on$Ich/qE&D=3S7%X=&OđH?wn"3,engu}V=eȜOaQYӠ@X#}̱mEur)55yl +6^7 +OП"im'k3f̮D)툚bMcWڰOʮjşK)} Gf)Sq8RQc!~ +17D;lyύ~b5vG` "*L, >7#6FTiHsFrrX宺."FÔȻa[ V9,[I-ٯ/4$v> #<.rf$BLjd/5fT&GfUiw} +V,삇WBx*![I#4nOh=bɄz3 eDK`7#Qwz-tAf4hx1=2ۖACUwlKFwYbo*fzozYb@X|"=s~}֙x+,TBU(GU)==*^J꼏-7TL!UC C&V& ”@gzTHVxYAKi͞0s,Tum@m-ٴ'o!D-A!6Ȓh Uᶪչ3g ,䉓N qjC2Ȼm*4Ԙn5'k^9Bj1dq'rh>Z1込z7\.ڷ#S{vˆ6s:=eP+;3[*W9 uWwQ %+p7f-M`d*#R_"KvKhh# 6BMJHR]c 2l19B|',6A = )}qۋy/<^ R|[o>y6dz.۞Hd" Ӳu = +{FzށπDs3Єd~D&˂Wz2uxtݑJ{ +@}†R8Fꦀșc%AIʧz$a#[-7=Ky4F{4Tb&iU%Mp!=WFة'}vڢa [IqggyX e<$ԝ;|'y` + ? DDbKV +j'vpM[b3v=Yɠ-f9J +deq'ogPxg5> uR5lb3D;XoFPA|Դut8ި"bb- ^gVV7^ j`t]J`iq=TNfTb̠ }+hRz)Gxl'i3ժgK|5NGJ.[ӃYxx0v ΂ My=$ys}n4hg4@g"iG5jwǰoӳEثO/F;y*$<&3ēS`=yQq]-h6ݠo +ͧdB!L{Ξ[`*ll7tݪC- PЦF8Y8{P ]3]}^tTWl+VJ:. zT#.E*GTG֢Z?ٜ LB|{./oyvm;ӹ4-1ЂVq% liA;!zE.%N *\IOYwA& '~ʞx.a5: +vPqD)z:/KP_= /Sp #la[: /{RCy[cP9={xpІԚV_2F7px?Ew5E}[98wK;a |:N }y-5++3(۳C#&L~XGa»6Ywr8oZ?apX_x*WP~ |l$SC|^`_)%0Fx,SGl+=ՒiWe~y5!]ϸ÷n{d n/"CߕtYQ6O:V1w UD &HM(ےV8ֽT#hkP䮩ĩ8'cIz4Y8BUx#t5R`7v=2AT3T:֋.wz9hxvC1%G +*l®+^bb1eahg<0{#糱*#GUc"9Ę~n`:mdoh>)jedL[d >e*$qJ rDD$F p~aI + Jl>9\ Qc_\Xv$ CdI |2 b(HPJc8X< +0d "B j&zr!0;Vz8豞ZcȘw;[ 2e+Bxd݋(@Y.Z3uqQ4i"ɩ,DU@$2fhJF6/9 +9>2C~s[{>(&GiO: :o\vs~9ӛo99{9}%=]MM'|Cj_>.V)'' l/e/Ӡ#iŎt&񴳜JM㝚p\Kp.\HA[_.b]4}7ݯ t[͕+ݱie`x&Rk`is:M| Wݶ/~7;7/ijM _zsf8ܼ)ޔh7QU|\h0^-O>>Nqj ƯN8Nq_|-l9t%'>J[9 ~-H~3'_iݿjX%ka b%ayjqxOVGN䕗OTbVZ++bԘ&Pjc6.> +l%Y,r?3ysƵo +p%F"@$u_ksj"$D^.Q`*B,7,daaawuȳ .ŭćE |TqF XPiM$y>r|2GK,b@Vק,V1D )n Fb.3<)m "S Q|z`a{!GDǕ1^ s"~ XKcS.?Z(q1qoi .>+2z$5cr)xn0auB%_KXX@lRC,&!ܲ&zx&"l]갉$(s0}L"U+tT̽qAKK"qzlqrFk&|z_OGvӇĂ4b cܪaꑥyw.gTh)b> L,ZC,O {IN*_-ՀayJz4<3gϷĞW0˼`1:{} ׼@M\+ۥDҺDm.XsJ9,ug8 .1B˱[vv[dwAC|1}HVKgodKRqޚ&M,M# +E+7'=dweE"b*gix1l3Ĝ k$ k+Dhz :*yծ=J * #0b(YVNPT/<쫨_k&bXkF,CQ }C2F)0'0E@~"q8*/1C<#GGu1vAr21p$#B!:˕Q"#2bHB#a5GeB,L#c"c)RJbTmW 1 'jgR +P.DCeic=7dn"A>m]PV1RJ1 KPgTS51 <64ٵܝsv!+ǧ45]됞g.m{, hIaW$Y"dw\*? OJ &JfܵL[K}:8SPZ̽TSqhauX%4r#Ζ^>SsB'(0ړ9'/qdF(#d),qu4sKv0@sS^ X͋޾L qږ $Y|A/`GwQl}+nxD;rÞu}aBi9J+aa°c;@$8u.ݵDRHgLEdXSix魾@6 !a +%o `~~cmՓUc7ZH||֩PN ւv B5(ƕ=%5>!≐=1o +ҧUǯs~ ܚYKgiQRD̵qSa$s-&S:ApGm=J`@E%V; "l< wtmz\LM_x(YbAHJfZx0σX5 #ڔKԳ`e3 +H B<7^k.mn|*ϲzgÐX&Y)wtqb#AVjH:@]d3ĤB )2Nubwl\ȊB1D_!b+$- jOY}[ +$bDF٣^ja9&s|疰B{Du,:/ۚ +,X>7q:BX$X%nxШr00 ^rFދ@ibU87ShP(ڤCSvQr!b#X qn tUk!LwX%x[Э˞X4*,ђa?[N"5d(&I$BeNqZXfq!Ōx͈L}M%o ɞ%xE%5`+hoqR)ڴ<"z$NZ*}9r!<T3X #L*'1Ä*W u +Nc0N{9e,Mp∪c`Z)H}ϸl\۽%`eU:nCή3! a-:TNGG` )\mE&h|r<$Byuoۢ"ۙl8I0FT;sD16%h昮$[lz3#\]'G͉bJ!(MY<oLXr~S W>=PD/ 1M:Վ)"A s3}K9t!DL.B46м!gPBUőڞk$iN=KsF)H!ғۚGx BmM)?GB GjC*#isjUznkgé@6=ql=ɦQ<\\/)zM9{0CGt!N,KP=5:%xW8fq8dJZP`[!GhF H8q9L.^$ u1Qf +Vk9ED3=D0fr Dl&umV[ٳpmKY^!>/Lns R<4fгYNvY* uwuH!MPCP֯a ~Y{`Z"\"+|TZX[ȝB0Y ɯG^9QУF>B )b"}^'?K_ +Ĥ_! ( j ߊI]5@Ӄ{+ͨfET8hDNg _^kiF(Y}xA,Μ|WtR>SS<( \حH'ZM# 9W>e0jvus7N|GLQqnWm ƹl}U̅P;>"}h,HqUaAR΍`t;9] g "l]sbLECZC4KŀF)K;RCD&.}"X:*f_}M+ LL+1:7A\̃y<<`y|AR'+OzmÓf,<@4@4@m^y^.4Mb`WO_{v?><}4$]=J+UT{cb PͰM K +fD(Hxi#y'P!e،8WZ&ng_<ߒ5)ƽ(uʃK:LvjrOT(b0u$[gAN %psNᣇ$EU;ieHX{GkTP`¼FqT<{˛3ct3M6ff8ؽ/=^ W5glJ:WLV 9J0^sE\b #GͫEN! ^+`_ c[&3783kSJs](rț ,jx䥦z-#)rJXH1BgzJ +їêI WK}5LD'rb*"]21I#̗+2B5;*5B* +0O;^Hv[3Ou"uIc<DJ>ێ<=)I9if{#)/P,y;cC!5Pޝz3v#F.VÎ0ߗVp_Zq 9qB + mY5R5`0~pI8)yP1v9<9?ۈkdz4w :*s% AxXRmŪtYZ}#Ű:U>T}e*Z%.Y,=碒c\$R/ G|T .洵Wi>9 +0H0T}F BpN Q¬,˧BgWoA)qXOuE}g:8# [N8nDF2ǾL hao p{.,G4JŊ 0y+"8Fx!{͌!-Nhi-UοP@;FLm(nƺOϤܹ=&'(N<9^)Z:k*eo=P,O0$mU÷v F+v<ȮMQ\>U:7~fO=ړ:b)%q\RܛyPq#˿2mf`P yktа:8 r }EϽmejAp—CgMFFYrȨվۙ#;W6+jP-G ~YO$Nyv%B$hpfq3~equp$mғD5 +*BlcjEO*^a +VAIYjͯuka- (yN:C+ii伱;.аь/j M FK >GE@Y 6;y(h-YRPbd+u-cY5\hs#HY(#Nu:T+$Z{/GxL&ݶY!,_" m$aڄԻՈZ61p]_۵15&1i ?}C^&7ƪ j^ؒ[Fao$[Cp] 2 7CaLdAV,bhsڲFk! 3;a>eí`~5by֠ր&7[ζ֑` +9Ma/9#rqgOOxg1%'^Vm̳1ie!.1Dr=x_~԰b9UEڑW1z=4'ҬҴ\hN+G^IgNp0Ve< ׶=4DԔDHHr }[y2]vd"%=B7H̞x)>L qlzf`yɟHVz(0ɪIѼu dX9Wp 2+(w4i.rM/#븳8g۽jcڑj tF#Yw3,mrryi- +J^mfP=C]vbUN%~_a[h(;S/ƖW垻979ƌTMQ $NuCrgjNKH|V[(ϊ婻bsovT[{3̯`inIdmLOyK6 1[hQ^F#Ov &ێlPro>|t^d{IݸXT(5ŗ.E!C@:OȝMŁK|Oa첬ۈjORd?v ƴxS7I'nE%M0frrT%x.5{#,kJ7}>HT*ut6x/-'>m?GlF<fA6`k%(QY5P GWl(Wƶm;QB=O+6l gX<=Vs>¨(~kd0;WyN0gG\GF̴N&'*1cN9qXb:[4g, ly ¤ +ùb0 RZblʎUo`#\ n!ij3axfMI7ȞxeQt_Y' nt&@ɝuqJ}5c%˩z@* 's?kFI\!(yL?(̒k#e&̤<܏*j]y73GBvɆ+1~kBPp&d8J]5l-fRP];-U墱E +;$#=&Ef`f}xR7ӎ7&o}^kvg[K) ޹7%R3Yý: +6 +\sq)o$ rln6:0:j^Ex\he9x.}*s'/-)3gXnD<:`IȘvJq%7dh*#l.{ɢtY|dO;HUztT<|ٮZaEqTD"7t"-|l/ 3ߌo+̼♹Dg:;;/_qBdqprA djup0Aruq|eQ% ĿfA:ytfU3 UxQ(|D%^V* B"PCaױw3}!40`5 p~ +.x}D!1zbZ,NǨժ4' v HyOTyAT;v%SKTosB͟Ґ)҇9NxRbIA> YP蒥|rz#7ґbA" nlMItǵc| c샜S7zwVчFJZeÍC cM-xU + +a~{,v Ts:aq= S`Q)׼ԡ;FaܙEb:_ ~ ,\Kn$޷Rl#yHEq"yیBzV!W\12ˇ,p {&umL %TyE#.\Qe`᳸ytH'U7a@_! e-3G[H|=` +YB(5'Zh~"HXy|4qw(qߝ&92C3өV&lQ(7:\ ԕH/,kD.+rR)})-6C0/BA2?ok+j%!A&ojrb&L҅W.bĈS$'>t`̜wPa %>M[-[H %wu >Re܇A'9̉ tbWM%0zIǡtdw#i۾z=hX#p52j4n`/ FbBPhM*^{[%tũ_u. 1fex&"ޕmZ.g[WI7j Sq? !\NƈGtS3qN~퓎Jv.+pJ +ȼaFkTl^4:u`h+8f2سĉIanP*֢raɆ$q>s@h 6ED3_c!+dBc2=R*xPjֳZa*p9Nr=WFE9Kz}e4/đJGcC,°3Ѷ!Sz_r幆I1`X@PEj0Mθ{A{Yw_ЧKe=nsLϏ}oP3G3Ѽ8?Ll/xfXv҄o// +ih[҆>nuiC[IQQC*mnǤ8憺"pˢGX~tċ2a^11s} UabpUډUGwf5 IfpQ6E;53@"KgnQ19ª *!=c-CZ![氌$! z =< >t qqn&yΠ5wG30KJ%;[G[9f~k@1-⎮.tWCԭ湰1P,>doEϚ2WĸeO̘"B蜹X:v9"%uUČ_ѧZ1.QbvčmPraf jl3[>Ѭ{u{ʅAǧ8G*Z$zA +#Я}F:2B)xn۟S: qA5C]3y4Cf蛾^&=~0@# +p㇑0bb*}3`,*4~cG \nxC1N*axo\A,1:lUBVrco@hzPiɂ1Iv 2d0UHK +LWH#">ȸsL7qFLmZS c[DHYZ+C$a2gz)ӥ{D9bH=dMj v&=JTݻMx鈪36Yڿ\}6Ǖr(=$&sCFHzVmZC +MF9j BGވhS0_5UӛxcbTID"=u +zW,ƭA _scN|FZMFвVmZ>^gݼI[hJO=qƦ"icM;YDI5'WBL\NsO:'Hq'^ƽ%Yix m^>yى`0'1*[WzҳY#$@;#Uʩn#zEc9D5M^ [tĺI}e9c[vsӯc_{NW*0TjB@\G4^kƶcB0{]RZVWWzշ9O׹>\sܦNDx6}fOEWI>gnk !i뒘کR+ 6^xZ[%mټW5\ nV'ᖴD(Lz;J5Ƽ6f^n96[} ~|D{{MJbļhAOӑt+:ﲙ2wt]-"z#HؙO\ۯlKKmz6=q\z7Vq7ٮ^$s@ 4JgdM"\bʀ(ӳX|=ӭP0SCgٱxw39 TW}jv.{3*n`&^=B/bU>`x-*,u>"ʂ $0(C}CsX庫rs}Z9 Kz|v7G?#O}y ߽ro.'@sY5~dGU[?4^4QVe4%*7tN7bj`Q&F.tU|3$T2@H^j|a8`so鹹]}G;I-:ai 'M/iΌM7 z#8ڹo8^O\C 6.o=M?;ctlIHȌ=֫dYc{y-ν&(iPk߷Ч }:߻6I-n7}XBb O2~w!w> ^3(kGrҰާdFxʁڇ0S}Q,S,Nq#f0H{ڪ0Ϸ9uفt8w +ZdT%!AL '5^$M`]b*hIڼJ99e*ID9rI\8%]Oh"E;Bt6]_ڶܥpmb\=[gu=ENN]g* E`xW{ 7N6VD;Bhtn!V^b4EKkn( A!k V(%mgJ#J`m6rU";i+'v$^XڮćL;?oZ|*AXWX׮)+i7?p4ikWW6@&:s׵46#:cR̕NMSAyeBqT™esz +X% J'i ō$jyS7)Ǿν)h^fjP%WCde :mZb_+F{;+] I(o9A4U n]!k;?:gMw'a+qכJ783Vp" +<n[e1tmξNq]@hG%5T(Kc֛}\=s$67]( kgOP`tĹ /V/|73iN7o1[&JW,ކNO%mv +x\Je̎,H_!kas;Uz0S}`6`- $'jDlY(Z/vWbio߄2}8FbBL;|ap?pPmBj/Vuv"Vw\eA5Fi[8˄ܪڕ;i^ʹym`Α|IJ$bz%sSE-;ۇ2,IasNJ['s?Ċ\vjS S!+P@K}'X0nM=)@=#> mHsC20i9nhN.R%`HF +aV1w"z\~۟M|itV}kk{+2 ?YևD-xa*i :8 #Չ5ˀe+T~S왲Gjii`{t"TgS} +?Q&_C#T70Fb|a±}8kKrm#${Q+[^/7ACKgJ])D B΁cJoΉ8&s5sF&1co|[q0{\WA>4zL:H W^'F*4C]؎s=XOՠRfof:Z^뚗_V\ $bXߗ]{>>69v!ш_ b!dJ U;%]S0# *aځZ=h52|$*rd fv~;uJ5N? .+IX%nNʔGgC(=-螨R{4dc5 '0ABbE +>ԂUi<2Opxv+wDJoOr +0A LkrP8GhYCw`sbРk%2"5 +G](G->Y4"W7e@O T(aF懅'9ۈۈئ7ʟ +HVQݺ^$8d(Ut[+g +TLcW\P묗c_m\m6ʅR]݇S^'FA#8V`\ta6O X +(&j&Gah17D3*yJQ|)jr=Rg lzi(y\A߾,0|rE ]+?dHKu>=T?粗Ôwcvl2s#qZr"I9 7~zQa;a+-+'~΃"L#MwT:%Ĩw၂Dx}d\)_^w իj:Xa:Uc"l%l^{#`{#4e"t/z(qMd@o_s(hu娥.:V~8J]+uߠЏ24E;yYbx_G|Xm/~y +aA x Fl%>@#+YFƳࢮ36Al"KlD ܜ9b0׷~"By7oiWiT] gAD߰tZ|5QaS-׿% dv⯧8g\֎6ϻOXV".)>®ۈ#JQsOPk=ݫ]M kZtNQ9OUJ%rN{'sN}QG=ï %Ջ>vNPɾܨ<Iǯ+q}{'k4HWhR +O#q&5`Ī}U Zï%q_zG(;%pP\3~SMX&`:M5KlQ> +hZH1(;V>j&xaR/$Y5 (@ZRwEGHh![{l//d<{翊JNqt:YRw%mXEm\ϨmN:팬2g:] ("50wD]S8Gc|g,.8C¨хQ0iڽPG]֤DM]oрĊ cA"2 ڦŭkQ\9m㣟0;3Ů( 8"c +r3.>pgƳ:KAQD \ ԝ(a1IF]C3Jo[)( f>Ěf9f +V3,K+ݎ̿l_(0ɉ :}̏aYT3Oza`%F^LX-ٛlMf-7|(XGytaf5MYy$נ@a{@@彴}~_vF6Bx +2!Lvql/TȰ\^ NƮq[9h.[fϬy`]:6ӑ7NXgZV ]Rݧa^Fn M r6$.)?&fhƝw2v磨C'o4@ D2;TG P.3gCBLHTc׆x{6rhX*>Xn2vD)Xb_<YTtf).Drt,2v`&<, d]ݔʱ7xI(Jxe2e.feM5HuuLA}9B;1-Wj-@v]d3m>sϙ]]IշBs; ƍ2{]OSoBeMpzU[RՁd{~1O*ܙ<AY_޻+-dilb0>۶Pwq'•t^YYD8,\~#x殨;/1EwjlLX >c [gt[g.Y!tLgĻoqꀰ*wg#(_JNzP; a=Uԧf cQ;2B0W086k{4<:Ք17:`[> /M<46鎙b s1|)ֻ=tq&go&ǹfDkڡ/>خ+w\;wm{+{Ԟ6f_*>U=[r|'Ú%`N-D +ڟ]bQxmKiԖ}/ /w]ܨp +s'ym'$M't*.q*۹ 2PNNz ƍ 7n@$/uArӑ1W8por% )ʀ1FI?pb 8["J}Q6%%Qȱ+rp.38\ʖ(C.`K{` gPw|C8aL!S6r 2`&{&D ЭjiOPF: ta3vq +-m{ՎLvi(bS>>hW{/4kh)0V=>Z[i U#(./АEq㒂9Y/T{ Xp8\x& + + k*/":Q! t@}' +]9]2wxo捎nP]ijkȖ:xm%\;;FG;-b*? [N +Q@:;pe)ʹ\>ݕ0Zi3O!QM5;k#5O$`˒p[حS68Bfoj}&w]$%I2 '.ȶ Ԁ[>r>?8<{0;5еM*ߺuIK9F.x(>&|i4T_JAǺ|.PZ)Ԣڪq!{ҏF4%$+r콷z -ӽ)ӗ&ҹw#uݽr +өh?VS-YsRih.\;}hL53>|3jh3Fdʎd%nj-.tk!Nḻf4jiŷ mKS͍;l{SNsz-}ʌ;#0-OhTS AU Ѕnao$έ.wpssٍ؞)6ZƜz2"Tz/6.ƀ8N3gD-RZř}11IZpj4v<7c ~=2]6&P ?2 ċ8ioꄍXO˒1Tu;nۜt甁-ukpX'{nݮ +Vkrxw2QsO+ Fkq۞;ʀ/Rѩa +T!t,j$%(fr}Ή ^+CKnuvԸ%\Κ00fnm(UO6KhhT\%Hِ%S,90'E}s_'`ͻE&H3liN-0 D)}9|ԄU~f SS}d^`;BH5 +};HtQw(N+(FD4_onW %^DiJZyFzG^Bk(OKDx~6ȖS.%nk$1 E@ ۈl={~#[[Fնe[W'4P[x(B߂ݐ+>;'9{Ah*yi32XYω9Qg~1gxl)W]J g~cj³nxո3e{Qڔ 9WKGe#wǦ%OWg`ꌭcxi?0N@P5A]RdTP˨} 1._ҹoRr :#fJPmzHCCwD230ViuHO(ABT!b_F.ܞ+A lõ}houd*c,f[JA՟duh:"Ij1IBOzR2e{ok$ҫ5vn}5b}|O5 0MQ::(c0v p$h4UK^~ˣg0d3'* 1$v{.كe/g խ;k^˷jͶ;Z4-Flv4Jjn;v)mHھ[*GJrDxs]Anaiz.]~éz 8PZ(Khq Tސ;;0Ț W@2oYnGMy_CD),GAM m TOn~G=Wޛw0( ec͝Cm/ޛi㗘&e xgO߳xF<$9$qS g"ā(|WgIfӕ{I.]tDq[#١-a(Eo6sY +#c˹Y3Tavf7f3qFՌZ_Vʑz }|wT~ XHqgQ +\m#5$@T"h8g~ힹNOxoc59w]H"쵏4MC&0\iD_x[3kn&Nx]_CDd&#$8&[ndbZ_`Nڝ'S=NUqY۳dY3&uF6Y>b˹vKʵ +aH|"B+[Z؂NhAqXo >iiry)xT;ǫX,_8,*g>+TGF1𶐾bO6ms" Z_IB +!8Lkiγ~TAmq!3((lYJhP*I8* _Xf.:t^\liE2`{UmT]- Kօ &ƂZ-.`>Ð7Aﳾbkr9X|8xzK!0EU"En3cnôձ85&6\0-'2t#V_Z=D=!p5 y:i;\8Z`>:>eV~ K~Wkkٛㇹ2Gׯg->2=Q_gd \/ U>򃴽L<1mҞZ (opjAFҼf޸׸Iuҥ*f6PDKP35}J744 k^cʞP`[Xm.+25<'"eoʫ R^ $sN$ahi7-K(~G<=O8Dp!%R:Vȝɞ!L|ӞYE2o7i 8,%w7^ XĊhUN0 ͬ5^5+776D`}E E$*wO 4xJwܻyZyb#rh#1y|(˵G%)gpN@)BNih5Ej{Z#-ݵw t7Vz(+qƞܔ'v,+iQ4!gvSxVG\RMQv:3S`X| !!V/!> [ʸ5eX[ 1*]31'L.T氩%Ū{DǙI=zA԰.8a' v.( CG5szmK6 S-]Bn{Ƿ`zz"dzW120Hw<4 +n:3F3(CNwO>'MN@H6rHwm xwVU5;{ @Ir}Hbhpid+IэZNw` x‚NC $DݼfM~*좲4ZZ\]!ʱ7NLҲ e\] ƞ< 5:$*aZ2[3*œ,Vrs,̰C7w>3V×i+ѡRCjn\3x884`)Rc5rF>v`jhܬC;x7 + +xwFA9mqO{rR2tmApG>5" 9XS Gudߨi r */1[`>_$;OZ+}Y@!Ⱦn=jw>weRX,~NO2jnpog ׺]Xm(i KkNpN 4*!1wbo?suKbAq4{~l<~VAk!f>ktw:qw:.KWw>ABuC5uXLKn?`.O-03v1,gٜ娵y,EI*9(q"QO4@G@GkuI{"e@ވgY<3Q\*PqvJ n`HGD^kq|'M`z:RZ Cd kp?kga)I2&Gɏw +l<< +Lq9+,P4tH 8=F/1^!YQs2ȜDN3','Sr]`ZX^&bx(8 đT~DKSE +D6j5b|CW0cm 7{9{96<˽aI[ɦ_ikV X!wj&Wzh=dpmYa/FEH; !<,+ P 'Ž(:"S -(i-1n\LԵ$w=ђTʱ34QP!#˸Fb^4j/I&F3801ǃᘈ԰_:9ɄP`d#^5z` ´}dȇ$'ZzӊYEçf Zͣ{By Һ YgZUo ؄CT.À))IbY иIcBQev:~T0Lz-TBIP'ؘ9%ڌ +Ct8y37#>|慎rO+#ʭ7Hzmu`Fn T{ 5 H~ mF 4x7'ڈ@ڦkONte$s]L|K\TE$2)1,>zj)$YDA W Խw8h'#|}+w[O9@]kQ+ļ iˮ]ؔ1bkkuh=YЎybe^wNtGӞc353ټtlk<6`.BEQuȥy0Ρ0fEmoLUF%m_F1&&+gٞK{h$r/_[{_D;dSFsߡtu*"BLrkI GӐQX&yƪJkf^g>~omF+,` EdahfT|1trqqqRr Ilf %`Xך?դN/&ݛA/oE񁅃ypiM |W%T=R{d`"^[XM! QT3$5$ǰ[1d;gZLΤvh%4#U6E!bmXl$$ $-eNqPm~@Y"-/Zڙۢj0#(Z]&-E˂K˂VH> +K +P <"|)`WYjRA=uoS5w4:?RM-krQP3դ*&5s8)2B(J R]V45{C˘qCO&[)Go6:{#޺3QˡKf+QR_ +ڤ`AJ}XK9Q)WԱ9=6ѿ{yi7PP@HQ=~8(\:8a6ł0Pb`0IGa\\'>';,%GH0ZWM( %2b< nH0 symtb{^ +Y > {YQŵmzrw%$LAkui7uGM 1lJpj Sg凅yuDÊuMf;t鸉au{+PUӉ:<9r^d;L9+nEϬV@!),ys[?āZMPQR"`|F[H hs %(ҦL\"F q!d5\9{&{I ›dpI1CŞ7nK׼;؏*Mh`=v\6ݤe֓c$lQ xWYlvP5 :٠Dٵռw*#eb'f}Iy:gI۹R<Y@,'ׇ..Dc{g7Dv.xr͋!5kn ԑ+$GQ7=ӳQ8q `gJ0mgdN\Vh)D0LI\ +iNVqqmnRBFB>)D +%qK "1a@&Ѫ'S̭.fL>ubk.`b.Y(uH5KM 麸mn/[ӔMO0LN/p@r.S7 _fzY>+5(ZEX+(GP0I\`z\ | #ٌmt\c}#ds}X[kQٽ'&]>sf~_FO[2r. +j&Mj,a;{1f:v(^|ۘc3LL\g(zZɺy"!gy{Y +w#w%Zf_q7 ,spb]ѩrW}&J0sp{N7xbp:΄i*O j.ڦ"jXй3מhuE">E9nbJt0܀v7ꞏ4,4Cr.9kN׶n|C|#h3GjSieqBO[r&b,x2)~x:7O aYbOh6N^sQ6̒uIba/Gp,$9X|O\iFōԆ/]fv"K;F$EUəUD$'JƼ0 +̓$͇Q |{z=דo qq\R,bUIFѶlugy ~>Fr=]/2 `eG15OoOogK(2J*e/ +@r{i{9o2*  +6rݾ0RRh.%a$(MEH˜хco߀m\߰e>ö(t0y53e ,46kFcx+d3S/ِC voYF̀0hU%ch4:&nu2 z~3Ţ2p?G!\P&,G+z/r{A-s!K^Qћ~7~ 褐f7G!+aYss>{0IT 涾p&9hIǰ/z.I;*uDIT5LKJ՞6 i'2Cekg>UPc;s-ڼqLK؄sA|J]MkX{}3 XTT.!$ya`f#Bg9 Sp2AZ&izZg>y RAXVVƊLy'54vD c?P|f5? +ޥAlZ&ͧmHaxf0pFIVf'A5k +1𙊟&S.gx%k\|~Rn?nl!_3yqKN`#ܦg#?*ZjQ_ݝ&~̙k<=yE[D$)1h6{ĕе//|S\r=V'5jGKBr7s`ׇuO{?(?9ϙ +ݛ{:VWwzX(+b讌 +\޵:kd< 0ZɂvVPǓƈX9AW-i9?(oFE($ +4?O3bV7B%k$osdp Ox +_*Zn[JJT1Zb|@~]GOٷBu3Yyj!_줿u + p]n'` pm ƒ"m%cR}-? \\C`47 +;ĎҡcH9p(*"6Pa^d/N#Oq +Qz;?ײjG_UآkQv_q%ʐ6yc#Ǻ +oTR.CR5OLHt'.5Ș!G00<={ᆘBCD{ȾxFz0>.+ڌE⨗T&bŅ CBtJ(A۱s sp;Wy3^}B.ދD7)E%/3NfU9x9F]Uz+Pf֩\E9gC<t/fݿ̳PQm;S.Ȼt" ף{iu;lcS |Ͱ>*ߨJ(;HZhV,(P$j] +2D`c| Be;O| yǦ|z&lXfA{t+mNzɸއ~=3ia;zu6WIaQJBVnYc^d^bZhl%!+/3 PY[&+/uJ&1mCiS+ejɴu,#x{ 72o|y?T2$rMfPGhyO,c]{z`"䗭6P[n'Fiwmp>\rQqZ7n|Grp)jZ>"t[QqpG!Ji:TƴZ$dembP.˷EAs<B[ +n)N{'zMɇM* +9$Е +u2-c6R?õ +%Z 06&'_׸LMm7j\ {ruK!k:[5nиw6\!il=?FIX:t\.LC62zXpnQYE,JnQbʼn,.3_pfXw,u\c9[|fZ +Zd-Z\`CH̺l?{Bz9YNKxs3pkG}8 UQJ$%(h WSN|tā%;Cwxik^쪓 ד+I–Pҳ; azGBISeJT}^3xTEm+-HDA#e3`uz+{-ՂSöMuk9T,{ұZ;ÔHY"ɒ6NlM4vL[798w1%.A+J6B߳e sX8SBM(AF`vat2lR:#v |.yONg0kuzvJ4ˠ1y)kk!Au8[i.7B8C›lvPĭk@]K$ܜv7ʶ֘w 8PS8U:g<8h:wDpz7rzmڙIz2<7Zk{g'dݺ'%NYԂf/4m Iy)2R [8+鮁VsXwpd< P94=cO6=yԍ si~مiSwSi#xCT?T>FaprQm_Nz\nWHkWvD-&{!FV;IR LΆ]tDw{Y ۲(kLl`$Ƿ@^Tءz@k +efGF`2p1|X%ϊKo|m?4IS!X?^&vSvpXmh[GXDkc↋^E ;nr tz\b#+_pVؕOTgxp)Kw\#{|S:gTYAvO5&I`:%ggWp,"+}^.t羽i1ASxs"hˮ⹒I#aܱbD*:.OWhkjU {-kY"^0c!x@eu0(=qM=1$D$aF,hFaxĴu% \eQքjWk@NMmX{pv{^ߡ`I +{ڲj&(ݳ-!z0^JtI^_+rҗ/k>1kz^DT;bxDԀ +;ul *I#b| qHHݎ&_9Z8.-B?&OyA;tyaנGui[߯zyK21̀9tj^#Gئ,pXtQ]lS|?jyGm#'sp䆫쑏\YKSr8}!xW +w*E: >==~Җs.׈PQPo]o~0-@^]шY$L}St5޴q;}ӟM|q̰ kGtOl??/0n˿Ɖp1 ܃[Ws?j~xkoXi-Vw?/ns#5c2$<év&д~Юr#q^5ϋTv7MX< ~qY ǭtŮ2wWqE|kw6t+: ؆N D+&XuįSDxZ4._ \ +endstream +endobj +340 0 obj +<< +/Filter [/FlateDecode] +/Length 10666 +>> +stream +xڽ}]s$7r;E=6v᳀#]B=4\Ns6%9C~YP3aMg*H$2 gn迗ټexӷg9RSvqW +m,s7d)rIww..^m^vKߵG{~ߥ<.l.]0уM$LU?I S*:ƥ&ĸ ݌,,ܤ:a䨟CҺFI΢;秜.PAV}&&"1D;FozJnk֡>.ޜm#j@u( !RUp"wTu.l5>~ b\hӢ\ǒZD֫#Y1iD87g?1+Uk4sCy 뗇_1j?hrt  X,>Lq\hV <- 6Ag ̮5grI:~yZ#:W;04^!{=%NOp&7Gji,)]M?cۂ}t\@,z#SVG.Rlg(h$B|:xwXu][U^Я&7Qx. k4K< +5èAH:GUTWM#y 9֧] #y-\3(-S=> }_<4'ڢ@y }|4~},{zt#@Q+C*>A ~ZWFgGN.aa8wGDJoѣ&ACs뛓KP ΦmL"Ze l&>@}0ą#iddbĠ]<_JcE(EhÉ(`!iBWcȋ%_@:˔KP ]bIέ%z?qaXH߾ }ZrJ߬%N-xבhU9p ~qc(PixW"dhzus Dx_+,vl~Y;:\}ٜpMSOj~5+`cB05fN,y~!dƁJB&DR;##Q ͓ĢU|Zꯣש:Z|ɋ{!Q9e4^'N*ZO L SJQ'L'~5k5./$8Cznʀ, >M-NO +TEcŋ ϒ?O=OѼp +3hoCsrs4#:)B/3o=ɘ\z9<' T`_D)vo8nS PEv Abs%H! V!aVBrqF(X;2 CC$LPKK ,u@~tp*p#n#MK-Ye+Je.dkJڢ 5ԣA:VSYd9ܝ2XiC8q5˛WadgYsw`Yz \UFz-Kh佌JfTbyYV7O&^ +:(ܾ2A؊hqLŕY%} *-kTx;Fgk-Fo0V*=eH:F]'׭ldZ9Ž4ʫ鵦f=ʚrraȋO]&qr|*)6nyd}LPLuJ*iAtx.RM 0TA2&lBlqƙb:0/ +UkK1γ+5cvvni/+)uՙ!Jrko +1^ijX]:.N;9NNy<7Ibrc Ɇ^60a@Ƣy'D@sT}j :bz瞔3kgqQ.$6f0-tSk[ J V:1r `9"gK.bSqo< "rnB$CNqe[5:A+sy}M/ۏLM?9$K{ BA?ԖtWg|fcx a{8ߺ>_sϳݜn)?yx>^x|侔9cP.֖6Ŗ! !6J#Az`OPwʅt0,i7z< 衜$u[|20\|p '[CQHzD&Ȥ + +I/o&H¡?EpƇz|=K?u{ω02Y aF؟Bjy$;򼔅{3et#hֱ, PLL ?D bSK3Ӣzлe!Cי3RD#MAZVx9Ɣ$+i.޸%H"mqCqQɘ)6QKIq=ba<"L2E># e0[ RwIa$)D A^L9y3PT^1 ƚ_6pSH,XۿTYCnqFF0S.] χ29jzx.)}q=dPA(i<*&u2l!JS/xDdRhi0Zr}R$ڇ|MEq\:omO$T*!J, +ʡ)>eyA <G)BȨW]cᎄ`w>ut<"_^zӅdtEW[7S ?s;wK)nI .Aqz8KE1 ͉~E6.{Zk(Mkk#I ɿv~]b.c: TvhdT*J\et8? _OZ\7-`ʛW׷ۛ >esq؂S`:n|C';~C"o靠ݝ +ISd,Ԑ2)W aWq9Jve˓q5S22%UIi1H/# EdB2I+&gL2qEdZ2"ŵdc}ا8s d9fشСV:1*)'sWW d$H_ZPF_VQF,?UQfjy3ۉcUVK1(٭^aƇNq[hZFK՞X|u}r :#SmHɌQk;J=P/EcAA +C9Sܱ'/(xu&-HJ;IBQc뤞{UeƂyZX~T|uk +:{oyZlm"lOg \d-TLZ]Kkdb5q\yj+fSU] +DcKgĠKO?e<=4Ծ֬d2(:LI=Ni%Aa+e^vpXF޿a0&)g +:b";,Q "fwnU5VUnU5f+I ¹D_ƶŃ8욳Y _ |.LuR7 Φ.EAc +]PvQc|u=kϹ:dS-FnҮ<EۣZ0-c(>aÖR9|A`9*11R56˨ OVjJ8%ZӵZ?jjb--ZrJR +~?RM[c,$peP(t#G +-=q0aQln2\5ccPњ':kV}f9)ŵ8T}fu xʅv⋭dβ $JqJ0a/7>^o'{Uc8ۊ%|ʑsK5?ftK-%i+ڕdJKC )u]%?]/3Kc\ws;sxg<{jT,sΌ6lR[4*ZFz ^Wi {XUcw:XdgBe ZF1z)ȫLjWz=|@@@H6LZ+7TY58϶|yp,QԺ0^t(Pi<״.We[2yW]50 +YGL^a'^tԯޜdxXh9Pf=R&{{G^+G m˧q 92ؠ3~VX;>x3}gs(O"P%%YBs/gQLVU#묕1%#XGA0'=Ep|t}m-Fg8>&FM.Q]B_5axuY m|11ko^VV#-fMΤV9-%7u2Údbad6ٹkbF2]gw`>yS,Z^M P{wy跘=M3s&Bg_Y⹘XCoC.S*,nJpyEe<(ܻC AMQZ4Lwj)9!]&śY`RP$Q>EٮLogЛ5D]V V ZewN_ XaˀS8(+S"pn% +\v98:+oa[EU :9˨K{g.T}&h~;Z%F8{` 86[ז&ld1b˰xN)x[pI`:(Oœ~$Áک>@N!C.pVJʕ\`+oTHi l¤`V;}`7z rk%urhu< ~5 KdYsBvf96ցA,) 8{e^m.IX\jV[!֑ PGb(:we6 W3?VKz]`-q, |aNbXBp_:TLe\_`\ يFPI%P7A2taMb0B- :^Yg:Lk|XnFA/HAˁTF}H( `Z&namY m0<`#.%R\712z"B p +yP($\v|AN!IJl6͕7xO]祾s EDʂ,C2=b‰ͪ dC?uzHX嚂N,J<Ca~]rr6;!Q?kDTABH7hZzn!8^ XЧU$R_O\DrD}*D]AyPbEB!cOJi930(3]F ^ڴ| >_eOIOUXI2ip:}ad6,>d|-Vu:(S*ZVŽY?gկ?aY'"UnNNQ}"t/)ǡrډMn-S!d<3{aϮOkh`j#eEu),sz7HbIb*1WEGCұ替W /xGTO* џT8k*_?GkE}"EbRRiF3eꥮU]{UڕĭUn_0S[ɃʼT8x++8|jnU J>*6Y.z"另*Ѵ &$˹A?v G݇E 10]!6lp:L8djN;VNHY.䂮AlϪ-V(R5Qr9e՟NK#$.8ړN>Q{/“E[u)_Zy⍕R O˿GhUpfڟddeUÄr++$[de}.꧁ުz:1>! +1g= [Um:ƚ$T[nGUIIUR1IUQFXDjKITr ;yR8<[o}5 +P2*ЍV+ +!SOkgOL_qwT"~UhB'Fr<1-kܗ9! Ce;΃faC+%ſ{x~7w\7W~\ڃ2/Ir'2#O7xO$ӫD k +=iseY N \A;hp?>t~tZ󑎨j)e2[N ԠWᜧ_mpC%6DW9ىԝlYzve=Ht8ogB;x@7rhb{g ߝxj?"CPC >O3;uz~ `Є?3/|iuvTyO[)w"m:9\m`"=.wX#&p2νQ\OhIzFZBoΧ|׿xg冯/],xR3*_M~{x2㵻+zկw>GvUzp_%5 ΛWN +zm?4hQhqmaEO77-W*Ҧt-wtsr_:O s|[XdYSf6؜=vo>e _m"_<*m: My?L|g0A"K{ +<=xU{P|^.Λ.|'Amzwp/n !nj: l ? Оo x%pnL3\ 1''~ E{]`+-%/. z8́n(9A~(v?N@#2IW?=\/wJƆ6݅`9}nqk-;¶YnV60-Jk$ohӝx77u_Hנt9ew>^7\7V~grώ)c/D{RKd4q&O2Cu0tap&"%_O4,e{8&XB^R0>5MQٓD\cra*bö{Ȫk45R';pנ4mϵ]mQALSߖaH&e83N-0W`{J@'fA U' +'N5"9Pz$:3/c":=:nn}Qal-Dp*hZ̔J!#jzQ:*ZB x08q$lךMi-O\(j/ܚ +C儏A$a>:Âgu9sQT +endstream +endobj +341 0 obj +<< +/Filter [/FlateDecode] +/Length 5830 +>> +stream +x<]7n+q6켤{Y[yqAƒ.ӒO>]C|Y׊U  ȞT1M~myK\XPai,>*<_ nJ?ܘ2ߟƠ6IyN32jOsM3p!̩K4c^K7 u~ h@qO +ꋲUˑԮir~.a.}1LqS2O2 >E9]7s=0)q/l D_0i.\,#odA~u)Ue aeLgZזP_YțE6FN =<ϦGbGXuɚ JQ Vr}9?nPZ{mmi#d@=ZfT†*3ސE1EðA4|` x~.lH  e ӶVt_plֺSu0u)E;~I)g/ :)"u*mb%" qg!X<sg:x"FFڸ$M<%? #v! g8K`]v<HH9Lbκ˸2x0;2kQq p7'fa,0sVK (L[ ǜj`uL/,O>!+@']}6:f畮|J5EisxEmgTU%OiVU&T8BCӵ=Q'WK"&kV&L|A<=bCMe08UoWH[n+,oaMlxGR[!/8O-\14B6>F-wo3ǩe-hi&qv䯽N1`߶1#A= JKNB˥t2[+hz0"oe,U (vXՇtO,$ +Â&(}ѲY{"2k%Z>v M,a>ؑsH[# B4:Q4 dW ~83rN Yu4Lf^=[@+AI)p +3f(XiX{Fg犽_{ZuӢb@lN^}H BNmPG W,5P7=5|eb4 f/ L mp(==jvʞ`5hmV; +gJC-=jwi^E'/@/8Y:z^HbզL =@ӑC5%Z+׺aCC8-o6h :=A] RhF߰S1-;^CyFg98yXcii("sLJYgÈ8ܠ7T?7 rns-2kODۤb::fOӑ +Hڴvw4̷q5%.>ZA;&l@_7$8"W뭫 h1:]j;[#ljh%Yy:F.m*3C;Il/,BY!QYxCi'&o K'gkfu ].u>KD\K7 6ЬWZۧ6=[7c.5s!cnγqrmҳ]خ,=lebY_6mm*Pvۘ &ݮb_f8={R0~t;2.zń.X6tYSbngFSM_;ԓFmUeX<;cFG;0 +.{Zgu +mCC= +&E&>:D!-\māԾz Zea@񻑴_eM?خԗ86g囁Om6C$R8[:0Fb i Q{ εwQ_VVVb"# +i󉩯rsߑhMY(@(C;ڿ LGWU +ԇmĆ%W魼,1YC G ʒҾ>rA\dA4帝WLhm߼=y뱶ްhcN/h%lMMuf7R5ӈ:9ͩ>zm08.h"LLx3i +!=ʉD}c&:K+u5Q#^rL)Ϯ\ؠ+RSq9Ȋw9zۇ&6`UlbOr_u߳{?&׽NOb⾈_87egTGMޣ6k!>`6Gb#N|-Kc )GU/tBg٥C[n3KFlڏ!:Hʫ3[xL2&ox,!o؏v~Z +I򰨿$I~/ѹy aΏ1w>Pbÿy9BO|~{~psqz ~X濆?/?S~{X۩<xs7~JۏMn2+)#ц^Sm9RMXp[ uiac\X&,EDĢz7 +"wws A\;*O~{g2\h32Hy5M{$쑵/FNq03Kh,>܆eQAFQQPR,$Ui~Tk +Q#⹀I" (Icb+TT,Q%)4G. gq&P3Q+p!3UYn,F~$W!u>O54yT*sG9`#FsuTJ]y $ӘdHIe%:dP;I43;MhzgJzAX< C~X2ҌAnGfK`,v(2jG8Ld4 Nɍ㑙4S1fy홆x2*::3ˣC48DĚ6XiKPg_HcuWBVy UVͲS]ad HC%q2 d-"KM$d@DZ. ; +SY()` )wd3uLKǏ•A>]KoH>/IQw UȋkM.fs#)% h2˦[Fu3H'U.2ru!u$vQN2-lga֓VO>KE0bއnb +,J"\I.|,!d6P  g^(NA_cK_hbVr)J]P ΤJ$WQdG"-m"*qnbYHEst ),hBNN,s rz+SS +AMbl&g]7$^-=%8EL?A3ENS^ÞX Hٶ| +]䖶Ot9]|uNy$MTy& } U9i3 e3X$qo\̂3]S.6DEuJv]V́ sO{+8> Vf3KwԶ m(hFq(%@ ޹!B9s(_Эdo[&$?,{D&%'HA +~V7]Uݼ9&ri?KCA(:`l +BJۄb0$_NuG.8iŋ~|V`۵:Ф@4 J8hn +g&x R +#/sBAPŅ:@Dl֪N+1%P(^. >d 1="iuL h +']D=W~6k 0!փhێt9 U$d+u#fM4/6 ^!=jGy S䵐L[MBf4&-(TBL!{-TL^&r2s0Eˌ,aR:f#d9 ]#Ufƶ]iy +b< mPy2=4k<.(m.DB]\;\G^XyVhJѢ&ى.d'::RbdE-[Aۗ|+{g]#1n5a aYYaұ ]w^kʋ@2JtΪM%\X>h.]{=l8@$ +چ6ҽ|zM7D?S!b[]~2o_o#Xnu`6|5ZvFDja1'J? &P³- +&xiە j6{~޶q2,:H5i㤩9Mp7)Mf΂aS?$"9R0#hDibn 7!4aOwîg2$]w(֫}dƗ>:?e?zt:c\I\KֱMf3Ox }x㟑{sU]5W I]˪]~JoOg?_ENx{'(뛪jw_X;^ ^}zTUNH)&-D? zWlb=k5H3JP{DX% hd·6O> +U+~(pg"8<1I'Tp^8R&wxeOHQu +endstream +endobj +342 0 obj +<< +/Filter [/FlateDecode] +/Length 2378 +>> +stream +xڭYY~ׯ:pӤ$n6&6ytkHv;C3FUT]5~U3~~ +ut.:menm;۩)VmB~SSJZզӶ []J<@);f֚B-=/[\6u>Rm?A]1 ;,Tt +dO)REl$VtkJuy6U}Mmguk8Z}G0Pٗ.Mmg6ffk;e+y/1L-(I ?OTڀ`ϙ5bڢӥ]+`ѵlQ8^ Թ< n͏H:\Ծ:_d8.çgبy&qyjvm*:fU))Raz.i@pk2avI{"ҥ= +`J hi~lDLF(̿@Vt vXG?qPLOJvɁ`FZ}Œ!tmcclDp M IK[DcV6H8Sah0c4i'e]rSY'H$x®W'xnC('C2-t@B|;xzOaP_͏Thr6ͿnpC5|/cx"Z*@&iN4< *n@@q.4t`MkCF׍W>F ~o'Y8ɱ.h L'orԾ_à$yhLE_F`47Z?k$WɆ ΀VxP}~.8ڟGpꗃC-y]z2a Q2r4Apr7\c;ImcҰ^b^;%l:gJ,!LI:3wfQHq_8Q' $!4^$8 `嬃d /y8O!1 ͘ Bu柳Tb u9T:SFyi;s{:.WSm C%k?;3pm^ܛ挺eU]RiZմߌ`Lir,z-ly_1%}Yh?q=<[3t-tXi,P5tǽ%4ܖvv's~?f +endstream +endobj +343 0 obj +<< +/Filter [/FlateDecode] +/Length 887 +>> +stream +xWKo1+X㷯cU!!K-H$_&Mr@Bj+yo>x?oΔ# '/#ÙPdhy_( &WT$9[ +Rk2鹦Ԛef)#ę; +-q:zy 2/"zfNEYVۨ9.ɻݼ*kw@<Lل +86 d` UU$[2RuHI0!g$)2RRA*t 5|+HJ%:4f z&lZ@;9ɣ'|?{ hP>Kuo:ƍ#"t%m:2jv?o^`GWGa3Z:xl 6t9DW '=;A)F 4X 4N [ c`e+]׭ttm$&dH#lq[' rHb[~[!S!bxT!-D:^-12YI#!!e9 HΚ;ϣ.}@3>%pR@< &\DA*$OTZE:BY=<5f!,M%:T1x)23*n&\ 5=#>Ё4 8馻g8&Sn{;R=IԝYd p)«;/ʃl\hh< ?>[ akWGm%X /- 뱜k<:_1*[Cj;7|%r0x MQ^28e3|#IPy)8 +endstream +endobj +344 0 obj +<< +/Filter [/FlateDecode] +/Length 2763 +>> +stream +xڥX[WH~G ,pvC2y5c[$0~dcf;sW:r=_czّz7 +=Tj= +cNna5}d07%i3kXpQ8 + NýfIǑkBĎ}8]ONh!<;d\?8uk{ ,tSem$xx~, v1id^oRۋn{ŬF lyv'Ƭtb\9:5a<1K.ʇCyFD߽QGqcǏ54pJ`W b!M;cUy֊oӑ8Gq#5} !l/.8~8O?*ع}j<|koEnhXHeƞcv&Vgmь?`+\ UsBgxZ:iU۲ژ7ۼnUUy[ jV7ZNv8l!cW0ڱJز8RSWi<⽰H~V9ކؐqCT]jQ/b)J6`ު4)8J*j\턜@ゅsɞsܿuW<_*w&|_ޟ'96J(&}=j]h%#N=x$##dx[4A +~lmWX_-[JޱZpD8/v\W,ߏ c׼4|$;|x=^#p6Zcp^0 `bIECNrDwXxÂ0 Y%G eՖ EJ10nԥ$ߵo*!Oy$zKy˪Be+;j;A'::zA@D 8ȎZSW5-.. ҆t.'Q"4:m Zˀ˒-AeԪ٭y]Q놫n(>~{EMsj\8QcZ #tX`CKzDb׎C-Uϋ=֞Ԙ67̜#1kU]0en^Pv H-BRz]5mO5k0%m;.M':)tiSZ--p m,'iGL໶g@N-s1*d"a>)g;4`% -[]jJfaF-Dx3I5}ԯ`B͊U?2A9'X%Bʺar^{b0ޜS`|Sr)m_P)7rmkrEricZ&䠡H/93D2iTn#ݍdt:Q]تqvl\gBh=΅[&9BNABHdf+qުˠQ<ʠHXbґ* !|Q%yQKz!eQRYcpI3 ytzB_'EנQ* +ޏP\[) ^$c#C)OoG fCx"p(C5|kQp8f &_ǎ!0D3h3_LbXeQ`ٶm*_?Hu}_{ xHs!ۉ?2IVU6{t磞^ + #TsQE~4fW;`M~v+B!|ʁop3M0ZRecnARd#ʮSZB7ա+ _D6퉭o &$"!ʮi]'?/pMiQC>5EMv\CaI@ X%=2r~l}џ, @tƝ:Jdk9W9%ޓ\2krUp0?}T3R?uo`'f̧]@2HM44zXu*FVl0Tnx):UJ!TW7 ={g|#DpGfPG F\3h|&J(xpϮcx'ša=J7zPXb04ْ dfȗ]Jb9\7l6=E1ƠL򎭦VdPfǯ9 YKzîU|km> +stream +x\YoG~p9c398A" +Dɡ5~ΈP`̙ꩮ㫣ks +/ UP׋?MmͲmڴ=ۅ7ϷyڶV_" ׽{7?-~ݿ\"%qm3:W MW[gqAֽYՠd;kuzBv]Cmlmݴ⥨Փ4eu`a1aKrsq>%\־nA4];2}\õk}Xp|1nkcy+7Yd>ɍ' #Îm6qC4A\K.UYZ`ݩu&1{asCǚ G~}8[{;ox*&WRKB%?8Eֱ-g2xR>݂u:[7.7Ev' iprwkƗ5smd +ɓnr+%\C]8*WM̑X;?$Y^1QwYr[;0y%1tߡ'r5Օ 6\bpDz67ds#+jt\eݍyfO5Hno) f S7A<(&2VkqӸ%*Ҏ|Աަ~Vu4 +)Fl/jjk Kj"ago\L^qjIeG5"іvi>'1ìbK1`6z|kj;dLrtkB]BP7)<_$obuR/*JUocGm'UpU yND!,^3gزU/x-Iqˉ,5ߓFOcl&|-ԫjCB0W^P: +d0Ujk֠Rx ^fy̤7R9(O`Gp +S22{7;%uRFzj6W̠Gzs/,^/q[ 1r/YkY/p,h9lf'yCx#`/$YN iJO0O`T@g(:tNJyLJ^T)a%ca%aJ*L ~U***4U2Ui@WY1J\*mU٪8UiPdFxVdVyX%SX%XfJƮ*N\ [UZt wȘFb+%2y-uLK䖣%PɓBdw&bN"3%{7dIBD-nOB]aB\D M @I 2!'Xj1c *p#TEZk1"1X5"5JȌ*!T Q%d6j2"1J9)*!AEB* \P0@B]SDPs$TEMP% UB̍ R*!eNvu{A_TEZ"1X5"5JȌ*!T Q%d6j2"1J9)*!AEB* \P0@B]SDPs$TEMP% UB̍ R*!ȨDw>+6\\ 5V,! +9`K\i+-J _iW0!%rAd&b@YZNƈ@K4HpE +WhEd/l@vK*=P2@/- %.}q=3<ތ+n݋}x<?̾6M [V|zك`ů~e_o=1x'|it7P5_ݳyp}[>~Z-] Q|pNjZSڴV%djJjmꁭ.;0~a]=twYni߿S;MuswhqH]O sW].Ay+J__"ڎ2E B 0nWF˛;tq[2UdHG !;  +}ws[Y]]n./V`uP5A?W܁kZ RҘ~=WHo-Js g/r:^ɤgіg_:lŅ ~UI+7g75|ջڐw*m.sYo z#YW(?'I1 8JXWLe Hqd9:~yF0B$o_h20wˏ +@Y7KG{.+T?c +}E 1JBy %byYRT~A|^yKIB%Ko$QWl-r1tls^m*@Ur*(!4vټ}HM." 8~$D{$}  "ڨJts,) + \ah$r=g$ j5fۡ)&e .A!dM@+]qƆ­5Ç=8.PRAOa*hc8(\^w:ƇB\J},F$"$\h;|z$ A[I]RqGC_?[dJ4ox{= +um_kGV9|= +1 X8?6TQuDZ2Ue2h⯍ QCJ'{<`,J*itCۺ' z,/iaA2vؒ~\Ӵ,ސRM|r󄱄9Hu:J!<5 =j⛊-) sn*vO#H5ݫ{QޥtIx8Tۂ9(` +<&I\hЎ%B"5ւ(2Aͥ-J =3}TI9_TW/ ($6,P8熸͙k\ԝN"tEh:n1okA8EQx(E?<(ϺG+^/63JE +endstream +endobj +346 0 obj +<< +/Filter [/FlateDecode] +/Length 6012 +>> +stream +x\M$qcϡڅBUesMSA!jzMT̐%-z|/3FGD?\=W?K?DmrKSnS,>?9rl%tS%.Mלoj<]ʲ=\Rykc(,%fw~غݶxql0cnk̔.ifZ/9흛˖Űƭ$e]˪} H}ݗ˪{qVsv+<\-^Pm]5:jZ]zS}JB%%%#phLiMi:Oiz4Kp*hAtL]` +۴oUj,Ma ɞe'>$?W@h4C4=EF|=I|ʁd`d<AJ}M>>>>*_>JJJ}}>hx}}>F x x z x z[WWW +MA0 +M1Zx4Owd`d`+%]eՊc˫ר.Ik[ikkk@6B6ٻFW$Q<(EC ʀʀʀʀʀʀʀʀʀʀʀʀʀʈʈʈʈʈ' v7h}+7h쾕4vJs(KI6oc -SRV).EJ!iM %nr(GI$-&)I@(ih4'Ҝ(JsD(1QDbD;0QD L0l[ߎ\%*$SUHTBZ*4ڲTi&жBV^ixn>^h+]xmwp wʰ <ܿ+ޏBE8Z`2 +9,YA"Z [aUٶK(^e/88}VJhdž1!!(^LA:}PAxUƚJXG<9dep`X.T\%N0t)NE º^NbMrb|Kl'lQg6SfglllT{݂ddi0FV@TMɽ\ȝuJGam2e?-޿ L맰JSn"=ʋB"Eʳl$)dZ(f.RŔZl\0M +5unU +=PBXdP.3n9CR׌0s8F;(fC-lܭ*-T謮7m[Ԟl/λOۚcB|ڲ%K>.X%NGSh:MCSZk2:MG t4%$hZnKhhj&ihz$)h&ih&ih$)H*KYgJӖҡ;.aFqw%ﶤOƃMIpCEJѹ H=kceYsi:Ѱ|O_.;"E5&:N܀s^V;SZJQ%h)-JٲAAr %pA~mr +M#:0һz &էzYҚ6]|Ds2+(פb!aPe%u8B!7VJ]([(@əNF+4h*7dޝ ccm 4j1j$PwS@)%XF#| $$+>͊xm-ę^m?GaV۷>&Nkd&YMD㶵T>N˂6<[}3tBAܽp7n;oY1FB U((\zQ(Z#wtKS;mN1:XGW5٭cˍ۪oUG`6S~/dfm*)eFOg)/ NZۖ[Ll[I!lr ςUVdbYhIBF+ %:#5<킌P]:P7g!ݕ=@fdM)=:w HKlJШ^obcΖ td%[6d^|?v}-&R;Kނ﷣QЍ$۶%wW3աxtT6%䦬jg(S$2 {]_b\&]qy [L.gITh;0͔ĸ?jymWUW SMa BlIV%;7v+̤ +gi3">ǥ(~64o%HK\)&YǬzRrx-buSm|nbjcv &I6 +_b{l"-a^gخC^Ip*).awnM$ZPh[,x;ӱ=o4+EאX䫩!?bxŲ2^qՐ>};ǖq:_v]%@-0qKdlWyj\j\vm864mA +]_ 6T';NLߝ[?g&I-0W'ŝ28"$Pe+P +ŽJ1KJ09e+Okrw/@emN}u\Cݩm o&]ꎬuwgZ4Żx 7_>vXiuP;?4mk/)n/vKr>x<_8]:kw*R 9ӼeOxKPCZQcV0c龜ֹyQ5W\-X}; 8%슟ږο3Qۖۚ9H7|Wok~ -6mA t_|-B^yj؅أ\`PB `uU Mz#i!)"|t x}=1{;uUOh{/LV/U+5GUΟ4w3lCKo8rW/H禤јiǚޜtVq_i) +kժ afR4c +t=>k%jW_vs5{Mc뺙}b;ii?1D351ޚܷ&Z(=gG7ܝkT궪*EaW@[r8[Q%??s׎.oŮr/U qpvFқ/B]Sl*cl P-Pql}[l TtWyTk?{\7TK暊*{>+sTo.T^0*fn:ͅ R徹Py\ @MDSF`nU;-i]Έ-ϺE"I|Eh8f4(3˶*·Umh7E3yw\XLˠoaD;!VAX@۫iP*sw0<'z#Zu'QuW諱_.__u]%by(Ŝ#'ױe`ŧMw-ǽ>"c\KQ>TI{Iz 4)(ks"7ʠPY~87>q"p(Θ$Ooޞ~s^a +endstream +endobj +347 0 obj +<< +/Filter [/FlateDecode] +/Length 5887 +>> +stream +x\[d~_QՋZI5oxÎ@`av28q<_.?uϵF!ţ#R$b?hO.s!Bކ-9TntPsyNTяk?g^׻Ηs( ۨ:Rt^e|L8ϩ, +C2_%Mƍ5NhխLq3Ns-^ZoǺT>U֒=zuk7mں!ҟ:y/άeK8lCt6~9uLmgRSf{Kg;FQШמGϼ~&ӟC6x,v|Λc/㹏MZg4kctvj?]wllۚL 짢6,`mc-ln| 2';TsdoI9& ~:k6Ԟ9nc2Vgvutk\s+ұ6ߝ!}g2NP~tXgfs2El0c[i}wLb.xT9څ*VthTΟ Qg +gzHXоTkwEaɤ]L۹>Kx.8.RVVIJ=Fe*F(X+p6t*p +L/ɀM5S$: +dO#BV,d1`ZÒ,'4axô%9V[9K"t3c9B|A!1dS)yɣMl +Ѧ6p)Mpَ]OKS| n7%)M k)$ZVHy +Ҹ_y/N78 dhq⮴1A~/Ƹ-Nvq5pSl[*1Z-UFC:#ŀ}D +4n +mm #$*mAvn EG^<aƢUc,ļmRv D!o@InC~AZeo`OyC}e )lZ$I))IOI Xwvzސv~r#Pt ?"]?_A + $  $ ,OoyNV?~'V ='2VZgXvkce$'B /'tJIV$_{wJ/s}uE߮l<}O맞n篾T_.n(^ǫNSͧp9w}pdT7ś1Ρ(Xakmp:5*z_o^ZvKZ*:X~?}2.-P{ +h=N~s|٣]Q4?oS#e™t\9}%/'O|Uoy/ȟP+*y. j񃻹c#?xI]]c[xwv2r9]^v_osFG{`{{ï]DZU"kfwoeʲdnJwO=޷{{ݛ^=~/ܐenu׶\g~^^V1m$}tU<UUݰ*;F4꯯ZAx%-ߟ{NG~~[y lx73wؚoM^¬m*T` ]@\K=UOz,Җ:|ӛ:?x3i7f`?V> +/Prev 420 0 R +/Title (-900- Variant) +/Parent 142 0 R +>> +endobj +349 0 obj +<< +/Dest [23 0 R /XYZ 0 826.756478 null] +/Next 142 0 R +/Prev 421 0 R +/Title (5. List of processing *****) +/Parent 5 0 R +>> +endobj +350 0 obj +<< +/Dest [24 0 R /XYZ 0 791.511876 null] +/Next 422 0 R +/Title (-010- Cut) +/Parent 142 0 R +>> +endobj +351 0 obj +<< +/Dest [11 0 R /XYZ 0 811.180621 null] +/Last 423 0 R +/Next 424 0 R +/Prev 143 0 R +/Count 5 +/First 425 0 R +/Title (2. Basic Structure of the btl-File) +/Parent 5 0 R +>> +endobj +352 0 obj +<< +/Type /FontDescriptor +/Flags 32 +/StemH 84 +/StemV 84 +/Ascent 1000 +/Descent -207 +/Leading 207 +/XHeight 545 +/AvgWidth 444 +/FontBBox [-600 -419 1852 1034] +/FontName /ZVFWVV+Tahoma +/MaxWidth 1886 +/CapHeight 727 +/FontFile2 426 0 R +/ItalicAngle 0 +/MissingWidth 313 +>> +endobj +353 0 obj +<< +/BBox [92.110679 331.996216 391.408716 345.54599] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -92.110678 -331.996215] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 427 0 R +>> +/ExtGState << +/GS0 428 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +354 0 obj +<< +/BBox [92.110679 303.676209 532.545016 331.385987] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -92.110678 -303.676208] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 429 0 R +>> +/ExtGState << +/GS0 430 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +355 0 obj +<< +/BBox [322.053274 284.193512 522.280018 295.210999] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -322.053273 -284.193511] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 431 0 R +>> +/ExtGState << +/GS0 432 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +356 0 obj +<< +/BBox [335.963979 272.913514 396.902843 283.931] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -335.963978 -272.913513] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 433 0 R +>> +/ExtGState << +/GS0 434 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +357 0 obj +<< +/BBox [42.179528 192.227877 51.179528 204.227877] +/Filter [/FlateDecode] +/Length 117 +/Matrix [1 0 0 1 -42.179527 -192.227876] +/Subtype /Form +/FormType 1 +/Resources << +/Font << +/F3 435 0 R +>> +/ProcSet [/PDF] +>> +>> +stream +xPpu*2T0BC#=CsKS# #=##s s3\.]C#K QʥeWeTZ[(ptq)dqpr-@e +endstream +endobj +358 0 obj +<< +/BBox [93.330178 275.456627 156.930178 283.456627] +/Filter [/FlateDecode] +/Length 137 +/Matrix [1 0 0 1 -93.330177 -275.456626] +/Subtype /Form +/FormType 1 +/Resources << +/Font << +/F6 436 0 R +>> +/ProcSet [/PDF] +>> +>> +stream +xENA +@+v "X<( >@"(ؓw@H_+y֜I\c w!f \Dx\倇tYojt' 2'T%idHǿ) oEk@Ie'}9" +endstream +endobj +359 0 obj +<< +/BBox [86.160004 580.214966 284.951691 581.214966] +/Filter [/FlateDecode] +/Length 52 +/Matrix [1 0 0 1 -86.160003 -580.214965] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr. 3=C3S =sCS\.# =KS#HW0% +D +endstream +endobj +360 0 obj +<< +/BBox [86.160004 568.935975 231.499939 569.935975] +/Filter [/FlateDecode] +/Length 50 +/Matrix [1 0 0 1 -86.160003 -568.935974] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr. 3=C3S3K=c3\.#cC=S8?+ +endstream +endobj +361 0 obj +<< +/BBox [86.160004 557.416993 306.262665 569.935975] +/Filter [/FlateDecode] +/Length 75 +/Matrix [1 0 0 1 -86.160003 -557.416992] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x=ʱ0 \UB/rĴI> +>> +stream +x3T0 w.=3 Kr. 3=C3#S3=3\.c=KC HW0S +s +endstream +endobj +363 0 obj +<< +/BBox [86.162003 534.864991 124.073777 535.864991] +/Filter [/FlateDecode] +/Length 53 +/Matrix [1 0 0 1 -86.162002 -534.86499] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr. 3=C3#ScS=c3S\.C#=sHW0 +l +endstream +endobj +364 0 obj +<< +/BBox [129.824769 534.864991 280.103638 535.864991] +/Filter [/FlateDecode] +/Length 54 +/Matrix [1 0 0 1 -129.824768 -534.86499] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr.C#K= #SScS=c3S\.# =CHW0' + +endstream +endobj +365 0 obj +<< +/BBox [86.162003 512.065003 276.425629 524.583985] +/Filter [/FlateDecode] +/Length 71 +/Matrix [1 0 0 1 -86.162002 -512.065002] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x=ʱ 0 DSxm93=j'4゙S C_):"aHL"}܍<0860Ϗ>(" +endstream +endobj +366 0 obj +<< +/BBox [324.239991 432.853974 493.276398 433.853974] +/Filter [/FlateDecode] +/Length 53 +/Matrix [1 0 0 1 -324.23999 -432.853973] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr.c#=#cc=cS\.Kc=#s3HW0 +g +endstream +endobj +367 0 obj +<< +/BBox [324.239991 410.057984 439.410767 411.057984] +/Filter [/FlateDecode] +/Length 53 +/Matrix [1 0 0 1 -324.23999 -410.057983] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr.c#=#C=SS \.cK=CCHW0_ +` +endstream +endobj +368 0 obj +<< +/BBox [324.239991 398.778992 537.723633 411.057984] +/Filter [/FlateDecode] +/Length 74 +/Matrix [1 0 0 1 -324.23999 -398.778991] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x=ʱ@Dќ*nsmCcۗKn67X{I*,15DL~)FJ:> +>> +stream +x=ʱ@*8+064}5!YpbZsFj$btܲ%ŖKNE /q,uo 0M +endstream +endobj +370 0 obj +<< +/BBox [83.974276 511.000519 125.938028 522.018006] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -83.974275 -511.000518] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 437 0 R +>> +/ExtGState << +/GS0 438 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +371 0 obj +<< +/BBox [83.972275 726.518494 136.098319 737.536011] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -83.972274 -726.518493] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 439 0 R +>> +/ExtGState << +/GS0 440 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +372 0 obj +<< +/BBox [324.239014 704.784974 523.999268 728.583008] +/Filter [/FlateDecode] +/Length 82 +/Matrix [1 0 0 1 -324.239013 -704.784973] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xUʻ 0 Sx'`O@k@ўNYYx[Iг"'9lA\ڑҾU5$`j!{ +endstream +endobj +373 0 obj +<< +/BBox [324.239014 614.30597 518.70282 626.584961] +/Filter [/FlateDecode] +/Length 72 +/Matrix [1 0 0 1 -324.239013 -614.305969] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xEʹ0 \U\} +q>&1* ᬁ܂ҒnjZŷ\4%V\[L +endstream +endobj +374 0 obj +<< +/BBox [324.239014 251.414994 537.786622 263.694001] +/Filter [/FlateDecode] +/Length 83 +/Matrix [1 0 0 1 -324.239013 -251.414993] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x=0 zO P>IBS-!MC,}ŒR9 \ KmnkRm5k +endstream +endobj +375 0 obj +<< +/BBox [83.972275 261.642518 141.769512 272.660004] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -83.972274 -261.642517] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 441 0 R +>> +/ExtGState << +/GS0 442 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +376 0 obj +<< +/BBox [322.052275 216.269501 371.486949 227.287003] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -322.052274 -216.2695] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 443 0 R +>> +/ExtGState << +/GS0 444 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +377 0 obj +<< +/BBox [322.051268 182.2025 357.514193 193.220002] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -322.051267 -182.202499] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 445 0 R +>> +/ExtGState << +/GS0 446 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +378 0 obj +<< +/BBox [322.052275 148.110505 468.469332 159.128006] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -322.052274 -148.110504] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 447 0 R +>> +/ExtGState << +/GS0 448 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +379 0 obj +<< +/BBox [322.051268 125.562508 413.376812 136.580002] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -322.051267 -125.562507] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 449 0 R +>> +/ExtGState << +/GS0 450 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +380 0 obj +<< +/BBox [322.051268 91.483506 405.368441 102.501] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -322.051267 -91.483505] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 451 0 R +>> +/ExtGState << +/GS0 452 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +381 0 obj +<< +/BBox [356.132284 703.712525 453.338046 714.729981] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -356.132283 -703.712524] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 453 0 R +>> +/ExtGState << +/GS0 454 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +382 0 obj +<< +/BBox [455.220968 703.712525 535.710543 714.729981] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -455.220967 -703.712524] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 455 0 R +>> +/ExtGState << +/GS0 456 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +383 0 obj +<< +/BBox [186.213277 692.440491 244.162075 703.458008] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -186.213276 -692.44049] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 457 0 R +>> +/ExtGState << +/GS0 458 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +384 0 obj +<< +/BBox [356.132284 692.433533 461.352397 703.450989] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -356.132283 -692.433532] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 459 0 R +>> +/ExtGState << +/GS0 460 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +385 0 obj +<< +/BBox [356.132284 681.15448 471.599642 692.171998] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -356.132283 -681.154479] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 461 0 R +>> +/ExtGState << +/GS0 462 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +386 0 obj +<< +/BBox [356.132284 669.879517 408.982769 680.896973] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -356.132283 -669.879516] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 463 0 R +>> +/ExtGState << +/GS0 464 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +387 0 obj +<< +/BBox [61.411278 564.993531 108.845979 598.570008] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -61.411277 -564.99353] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 465 0 R +>> +/ExtGState << +/GS0 466 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +388 0 obj +<< +/BBox [110.186746 606.839539 150.27659 626.579163] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -110.186745 -606.839538] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 467 0 R +>> +/ExtGState << +/GS0 468 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +389 0 obj +<< +/BBox [213.572275 672.989502 257.060283 684.00702] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -213.572274 -672.989501] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 469 0 R +>> +/ExtGState << +/GS0 470 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +390 0 obj +<< +/BBox [311.511165 528.342591 355.443394 545.7865] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -311.511164 -528.34259] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 471 0 R +>> +/ExtGState << +/GS0 472 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +391 0 obj +<< +/BBox [117.52459 510.056 159.362727 533.88794] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -117.524589 -510.055999] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 473 0 R +>> +/ExtGState << +/GS0 474 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +392 0 obj +<< +/BBox [61.411278 564.993531 346.925975 598.570008] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -61.411277 -564.99353] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 475 0 R +>> +/ExtGState << +/GS0 476 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +393 0 obj +<< +/BBox [190.899247 527.593086 214.213686 543.095944] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -190.899246 -527.593085] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 477 0 R +>> +/ExtGState << +/GS0 478 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +394 0 obj +<< +/BBox [216.909301 541.182113 253.163467 548.356879] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -216.9093 -541.182112] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 479 0 R +>> +/ExtGState << +/GS0 480 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +395 0 obj +<< +/BBox [231.740785 633.928279 254.85554 647.097256] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -231.740784 -633.928278] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 481 0 R +>> +/ExtGState << +/GS0 482 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +396 0 obj +<< +/BBox [187.16444 625.689474 213.456864 635.704883] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -187.164439 -625.689473] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 483 0 R +>> +/ExtGState << +/GS0 484 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +397 0 obj +<< +/BBox [67.439003 78.37999 260.316407 79.37999] +/Filter [/FlateDecode] +/Length 51 +/Matrix [1 0 0 1 -67.439003 -78.379989] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr.3s=cKs = \.#3=cC3(?+ +endstream +endobj +398 0 obj +<< +/BBox [260.251557 78.37999 416.075715 79.37999] +/Filter [/FlateDecode] +/Length 52 +/Matrix [1 0 0 1 -260.251556 -78.379989] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr.#3=#S#s = \.C3=s3(?+ s +endstream +endobj +399 0 obj +<< +/BBox [193.872435 192.848952 291.133893 232.496426] +/Filter [/FlateDecode] +/Length 81 +/Matrix [1 0 0 1 -193.872434 -192.848951] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xm @ L N%!P>/jβ]mqb(}gjS[8 T#2S8 +]aߊ6l {y +endstream +endobj +400 0 obj +<< +/BBox [188.391397 233.826856 201.130027 246.816989] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -188.391396 -233.826855] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 485 0 R +>> +/ExtGState << +/GS0 486 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +401 0 obj +<< +/BBox [182.254014 232.36601 209.732727 248.629947] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -182.254013 -232.366009] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 487 0 R +>> +/ExtGState << +/GS0 488 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +402 0 obj +<< +/BBox [67.439003 68.540986 496.878968 69.540986] +/Filter [/FlateDecode] +/Length 51 +/Matrix [1 0 0 1 -67.439003 -68.540985] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr.3s=cK3K=C\.K3= s@W0 + +endstream +endobj +403 0 obj +<< +/BBox [71.464745 512.05597 394.998261 513.05597] +/Filter [/FlateDecode] +/Length 53 +/Matrix [1 0 0 1 -71.464744 -512.055969] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr.sC=3SSC#=SS3\.cK=KK HW0 +~ +endstream +endobj +404 0 obj +<< +/BBox [143.039994 342.138978 454.063599 343.138978] +/Filter [/FlateDecode] +/Length 52 +/Matrix [1 0 0 1 -143.039993 -342.138977] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr.Cc=c#=3cK\.S=3HW0 +f +endstream +endobj +405 0 obj +<< +/BBox [275.56201 341.074494 320.316653 352.092011] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -275.562009 -341.074493] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 489 0 R +>> +/ExtGState << +/GS0 490 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +406 0 obj +<< +/BBox [420.886412 341.074494 456.250338 352.092011] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -420.886411 -341.074493] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 491 0 R +>> +/ExtGState << +/GS0 492 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +407 0 obj +<< +/BBox [478.625326 693.296428 487.625326 705.296428] +/Filter [/FlateDecode] +/Length 118 +/Matrix [1 0 0 1 -478.625325 -693.296427] +/Subtype /Form +/FormType 1 +/Resources << +/Font << +/F6 436 0 R +>> +/ProcSet [/PDF] +>> +>> +stream +xPpu*2T0BCs =3#Sc#SsS=#K3#s\.]C#K QʥeXeTZ[(p黙tq)dqprm\r +endstream +endobj +408 0 obj +<< +/BBox [211.440995 190.934983 436.170167 191.934983] +/Filter [/FlateDecode] +/Length 52 +/Matrix [1 0 0 1 -211.440994 -190.934982] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr.#CC=CCK mleblgh + +] +endstream +endobj +409 0 obj +<< +/BBox [408.10295 621.042702 506.65295 630.042702] +/Filter [/FlateDecode] +/Length 143 +/Matrix [1 0 0 1 -408.102949 -621.042701] +/Subtype /Form +/FormType 1 +/Resources << +/Font << +/F6 436 0 R +>> +/ProcSet [/PDF] +>> +>> +stream +x- +@yvxhi=yP|*=N2|& H_t^>Rv%+F7Dօ&xopSm\EEJ1VHwْ!ѓh5Bƌf6?wHOe?'b +endstream +endobj +410 0 obj +<< +/BBox [0 0 133 71] +/Filter [/FlateDecode] +/Length 16 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 493 0 R +>> +>> +>> +stream +xw5Pp  +endstream +endobj +411 0 obj +<< +/BBox [68.022858 703.432324 111.537479 713.931314] +/Filter [/FlateDecode] +/Length 56 +/Matrix [1 0 0 1 -68.022857 -703.432323] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3P0P0Tr23U(2327V07030R01304UԳT(J +9 d +endstream +endobj +412 0 obj +<< +/BBox [315.105883 701.932468 362.621849 715.931122] +/Filter [/FlateDecode] +/Length 58 +/Matrix [1 0 0 1 -315.105882 -701.932467] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3P0P0Tr23U(264365S07030R01304S043T(J + +endstream +endobj +413 0 obj +<< +/BBox [66.022185 283.97268 126.042353 295.971525] +/Filter [/FlateDecode] +/Length 56 +/Matrix [1 0 0 1 -66.022184 -283.972679] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3P0P0Tr23U(23327R00322V035R043T(J +ހ X +endstream +endobj +414 0 obj +<< +/BBox [305.102521 283.472728 371.124706 296.471477] +/Filter [/FlateDecode] +/Length 58 +/Matrix [1 0 0 1 -305.102521 -283.472727] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3P0P0Tr23U(260365V00372V03352R043T(J + +endstream +endobj +415 0 obj +<< +/BBox [265.41329 613.231507 305.924724 624.249024] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -265.413289 -613.231506] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 494 0 R +>> +/ExtGState << +/GS0 495 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +416 0 obj +<< +/BBox [265.41329 601.712525 312.645998 612.729981] +/Filter [/FlateDecode] +/Length 24 +/Matrix [1 0 0 1 -265.413289 -601.712524] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +/XObject << +/Fm0 496 0 R +>> +/ExtGState << +/GS0 497 0 R +>> +>> +>> +stream +xw6PH/w5Pp! +endstream +endobj +417 0 obj +<< +/BBox [298.059723 500.776001 469.460114 501.776001] +/Filter [/FlateDecode] +/Length 51 +/Matrix [1 0 0 1 -298.059722 -500.776] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.=3 Kr.#K =3SC=#s3\.3K=@W0 += +endstream +endobj +418 0 obj +<< +/Type /FontDescriptor +/Flags 32 +/StemH 78 +/StemV 78 +/Ascent 905 +/Descent -212 +/Leading 150 +/XHeight 519 +/AvgWidth 441 +/FontBBox [-665 -325 2000 1040] +/FontName /ArialMT +/MaxWidth 2000 +/CapHeight 716 +/ItalicAngle 0 +/MissingWidth 278 +>> +endobj +419 0 obj +<< +/Type /FontDescriptor +/Flags 32 +/StemH 79 +/StemV 79 +/Ascent 833 +/Descent -300 +/Leading 133 +/XHeight 423 +/AvgWidth 600 +/FontBBox [-122 -680 623 1021] +/FontName /CourierNewPSMT +/MaxWidth 600 +/CapHeight 571 +/ItalicAngle 0 +/MissingWidth 600 +>> +endobj +420 0 obj +<< +/A << +/D [132 0 R /XYZ 0 846.560236 null] +/S /GoTo +>> +/Next 348 0 R +/Prev 498 0 R +/Title (0-250- Free Controur) +/Parent 142 0 R +>> +endobj +421 0 obj +<< +/Dest [20 0 R /XYZ 0 12.76844 null] +/Next 349 0 R +/Prev 424 0 R +/Title (4. Example File) +/Parent 5 0 R +>> +endobj +422 0 obj +<< +/A << +/D [32 0 R /XYZ 0 846.53479 null] +/S /GoTo +>> +/Next 499 0 R +/Prev 350 0 R +/Title (-013- Saw Cut) +/Parent 142 0 R +>> +endobj +423 0 obj +<< +/Dest [17 0 R /XYZ 0 841.919 null] +/Prev 500 0 R +/Title (Processing for Parts) +/Parent 351 0 R +>> +endobj +424 0 obj +<< +/Dest [18 0 R /XYZ 0 839.314053 null] +/Last 501 0 R +/Next 421 0 R +/Prev 351 0 R +/Count 4 +/First 502 0 R +/Title (3. Caption) +/Parent 5 0 R +>> +endobj +425 0 obj +<< +/A << +/D [11 0 R /XYZ 0 811.147113 null] +/S /GoTo +>> +/Next 503 0 R +/Title (General: Identification) +/Parent 351 0 R +>> +endobj +426 0 obj +<< +/Filter [/FlateDecode] +/Length 31263 +/Length1 74128 +>> +stream +x xTE8{Iwn 4+V" + :2(:Aq}Q}De^ sf~{?nݺuN`-P6 u VZnDmEgdثvYq£\-^0;dgjcA%4`uV櫒khбl\s-og][_C?|6xv~x?<]a/.[x އew(tbv]F^z?< O y? +^+ sЈ<a a ^ zp!n ǿ{m}/cVg/<WanQ:~ {?l==+?#'Lބی}?l)֭Q%t$b7!%hÿ-񈇅0aD.XԶKz_R9p#ii\ +g!샳6Mai`"4`Uxc˶Ķe35ي-l>Y#܃ +a)M'ffoNK7WVl-A׳l&| glglxOlX`ѽ=Ѻ٧gmIff#,-kfl12EF&'\ٟԫN8xfh_0wK:-6s6V673[ה `pw-؎ҎW#ʱGnN虌 #ؠLfvfN^2tsf l +c1[E/ۃ_^ bu8u~f1+8 +AVjV,fkjX%8 +S/r;" .V7==v{^v6n|]NCwo0 Ö^x(u_`?=wÖ́fc+jܛCc'n^y捛;7ֽ,\=햭k'>ڲۘsU?:D<+,p=ٖw"|lµ 7.\(=`LZv˚[e7׳5sv#y'.+gf8SVvx+[J`7?~W(RHXu 0!o}?0*؎K yAr/y +e l[Þd{+;`V0B5("+`Zj.% + !!JvG,ՉB:qDm;) ɍ2*:'5^_4v6nڵ9-57u[:q,DϹ+߹+;ŦNiN%2\p҅323.ʻ"#Xiq72"zn4ad?Qr ivF<\fa9S{{v >;#Y_pIm;Q܎.PG0$8!ސllChVT+USUչW>Jy (/+PR-_د ?/7 + 23|4tmV*$ + Yg雲h םbp'P^9sקwsddjx;-,4|PSHӒmmĈ;9R+M6֒bdaֆ9|90i&4GIqgZSo"X 3IテDz]-\cN736 m*޻nGB>n1icAP6DM72:a9g .7ЙiS'9 +kӀ)kI.7lXxԻamiioh`XFJViI>&mKKR?6\:^i1Nܓڰ=>Qo}xgl +O`ʌ|-FQHNۈlaéc#'Kڌ,h2ocP'Lg@0 'p ç&v?)# N9MϒF'Pvdddۆ ##6ݞX;/rG6l7n6|DX@Z:m =QIaOy9Ѽ$)$,b12LZNo S~ + w α6тI 70Qc0/:מ1]fFq>^o*YkI>l3}\Ń:Yƿ@ߙ>|Z)g"wfF1_݀j픧 Է4{#Θ1=Դ!Iz1R$ V"?q)CD"[D^G'9p I ՕRWSLxc o"ʥMM1~; 2}m-!/ +"D0a1 xf1] +bh.wbfm 4l^Ш7ى)ztS 51bT!Qf,ىu- ؙ6axvv%k1vwl[쀏_|Q#1f.l7S* [2-nNYw6G.ca35+mQ}Z6ly~tn>R Y7Ч%riG<҇&̷ouO6}'I +naF$ wЋ~ॳO o{rIDՆ PEpxF~mK(b^U{xJp$"#C߆M$6DƴoL^0% i҈Z4Ҥ)eken ciZgz$jM~q m-dR@. N!2{;H#7Py^PiDR8DcC[I? I,ߍR mO$Pml 򜅀m rFaεR?Pѳj$*c:-؂hkϠAGZY,FgmKgK^:} 5 +;atdPR)ЋJ[6E*uwZQbj^K|Y$Վ=[B:L6KA5`osX;-AGyl--z:ixP_:*U=5svY|N-xӁJyDc[/6*܎xG= ?(; dT@Iӫs&pwoؠ9N/͑Ly?3ԶS"8Noӣt9 #k xSM"G0$lӹvb%Ԇ*;UB¹\RLD +KSEsE>Q26DPÍ|2JhdEz_hH.h /bKD +y3C[kmC+0߳!mCn +VR6TRB| +0Z!%*O9+U.Eo*(́x&qK(nAƐ4)m?? ?%-厜)fu43-M& +p9B@Oهҷ-~״xiw0}AP| +ާA?eaOؓ? kY+QJ34#&SAWEǼʠXbPjHփ,Q'a_e龲&F_a_Ya8mRM&"]-V[-oٔbi4/,Wluh7;~l3x՘]Gu[~ +By8Z>qGQkeր]AX+P=|o6R xi>EQM<4ԏ3W_a/u̞5߽k/&XgQ_w@:;JE1JO 7򭶬vӘdOk`W%['^Y Q^2=h#f݂IHg5h蘱Cjp}KBP>;8@ޒUhfmO|;- Ao94iAl2Tǿ[a/㻄w D/ EJwրc]'d_`.m2ݮ #$'''>lw8U&6vG5%t nL>kcvls{ͭ03oym'H@NVVn) frl|U|Yv)[na/=m'q'L8}7&O nvmD.>k~yXD ؓXIb L 츛mb!q-Rķ|0h'!>g9 tEÓVg` e%(ސW@CW=8"Ku1q{>I( ߇+jj]EΛ,f]p4ڳа棭όz&.2^9&2%sFxfm. +:wf BNzS6wmAMf-gB'#?X*s% ~o]YYZj rכف`;U4DnǡA\mUVd +%ؒS_Ȭ*Nϲ p_oMlMUaM3lƟypSy݅pC`m@dRD?DH9Z[#yJ0g4oHJ@X& k= +<XC vvPwv9'3Q(>B\ȅ|_SH_n@wvOW/NJi.[+8d5 ]:=%}erTB[Mdf)p Uz*&E7:[MV∔ׅıW];/FZ1T^R jucޱ3)K 5{(PVNd& u[sf#fn(C:pݔ/3_PȔ!"p.9Cj0 ѷQk}DViRIf(T{Cz>+Juåf]$xO؇icІgVxgfsyC/?zig_.wݘ72眻nj>|oxhY 6!d|$|t*  6BGd"uU6V"LsOLk筬JQwBJZFg0pbe]|)S$SoD =,) +CY+{킝"EРnέ]7)bf;7 ܀s4f#=ʊY 8$p$g(:;;ecQ}4Ui5y4>'3ch_ӦM|*ÖA;?󍺭e&M|WaHItf_aMF ?խ\j>Hg]\fzwyicʋܨDl 1J0f2X Vĝ(hhFh 8EV%nG!S4ker jJSghSHޮ97I?u}Dyl/ 9Hs݇ӨЬ I)+ieβ슊sƲ+Z y63#mN)9Olm./_^UՖ4%W|z؞kT5 +h/{F5z|Q@ɍ\ڞm[έJ8:0$Ƽy)]to=y㴝G i;v^i7)W« CE*FW9\PѪN55zqEeDU5<1%)kWֵFTMg+FMۋ.#ma]t_yg_~uҪW/3]+fu L/έwѺo6ݬ ^WbwGo=оV5{n'&Y+"LmTnQ?0D&ӚlS28́u +W\;);kg?kE6,CS[8E 6[lasE|([.$-{KxoooOgJ7_R2}||I޾4U4K5aX^<梛j +jc2K7lYrg4cS~쥵>rMiM'gݱ,}%8iؤO/?u -=N?ȫ iDj嫈C98X +ͲBLF93c+dݓo88?1s paz!xBbX.QApi:UΓΑlh5kԴ$YBk%]%3nV$;b| 2HK#-PwK ( Qy* +^YV$Q(FeIdQT,C\@(3zw}+VfUfт:. Ȣd3lք^{ϪڣG_*Mjm?-'8ty=** Biek}i=4Q"AgT`{ -AiG&΍]66ށ %4=Pغ$+@Q¬DG$0Qd5Oc'RGx<6R8 dїaHĮfv-vsWh}dFY} {Z [}֨Xh5%k{AֹscW,Q\ZNN0;̗g0Ted6o68Z2$c]4x ƥ]Uu`'r fxLWÕc裉7f,M/c& + AXu*Sg2 +> +X Ʋ&ax\(ڕ2k̊iE/&vYG}C- +Xjݻwh{YkKg *U2iۋw&*YD x~:~zm]3#lcM#jD{;58O>ȃJ;K!ו-*4D.̶]4OqU. r)ss՜*M,RaVtL(#i +ǚ3 _Z1b.ѕv+]Ԃ۰.;Y3.+\R{oλ8SfbVjXghSK7]ձWb65b\U'l$Y=*_fUQj{'>?RTxr5^YIFI--l9t+-(w' zGb #Ɔ>4ډiC- ̛; XԾ$* |5",<}oc2,2P"%U"1F , dLdpWFtp>;Jr!6kލ9- +icz&eyK*5i`ƙd?kL! i Ӿi -Uf7[zԞ#_=M~)79'lۯ?ib዗g*_k~QVt􊢺_!Wt3YZ5R5-(RDta[p9R4a1c1b0B;qz9@8VC EEm3ꒇV݁bRuR)SW$u]mWDxkZg|qg;`4 GjM|ZTVր.=$_ytksق6A`esr8^ {>7Sƪ;xh񄥴q]ήJnҭ-R**џQQ*!l=wf:֟o5Lrn+z0RF"wPܢE 4"jy]g +WEB1Q{y$w^{?^rrwtU-儆SLѿpcK2e^Ty \X#g/=YOwx'VLy.Ч`MU9m泼[Y΂yK3]߅-xGvFV쉮U*WFI7_|CS!{={D]{ᾦ1Ͷꕅ7NQ|C_\,P#݉h`EAD +g8 N"Ut`Lз+=0=]wwC;!Y=]g[X;뼂i>QUmU%=]rMGRxAC򹩺~ٸr!T¡u=Knv9}iV!ZKRCLBwϗ[cAìW9+?[ԯpxqiFige[,XhhkYlE\-<[Tư1&,v11qYBge`֕6$mժGw- +3'ODSݐ$oRYJ4hqs{aW4Kڋ Z\qN fIv:N=L嬇f<4dyCxj^ǻS )=RD;Hr`.TdT2s$"ua6Cc>>>8R>TO "7mtwdӱ{ wGWw-;;[: +2af]#[-yo-Z3l* h4T-HgJ>KjL,V(L="S8^n!=MùFU0KKzG nP熍rNt +bXΞV,[ jg'ͮú$SenATOI^fk=#,LP#|ūkv0'[tY|CYcN`.YHp)KYLژŔIQ"T!AJʍ9K=1s("퐥#׎.~MkލE YCv:-VlɢkKs|B*5/e|GRJQ_o5B>2c1cjb\O/AJD%WFv^CV W.S洋.nHsy7]z\]2r9Eн,kM."VuKKJlc\ +Dzj|N=koiͳZCuA\q ??y|*.>Y8Үy~:MM?ǟg +4>18_ 39ŵ]E!T*h<=&דEx|)o^87+̲US&zUdK(Eu +uaOfkiU8kVU*!zC٪+wya0J*qsssSl 2XnП#蟜Gs_䈮 ,Ѓ)0-`2[d-xBb6/8UD)^rճjY|jCi7WsfKeTK2!s?c'dkdbC'ӡkHFyhrLr>͇ToH4[P1aq)wԜ?׬,?6'9tٟs2 / +ѓa:X4?Uۈ>ɶ{@cu0"NQMMʲY1Cx6;x[rdKy]6ܪJ U kgRs9Ћys <:xxGz;xk[Na?캩>Ql؊a L̙$덅yp^EU_ՁQ뎏@iqRO ?֮}g>peE'{bhabWZʊϻj>]/$+gR#_gRGo4Z'9jT+4YڛolmqȚgveizoaւ> ۊBB0qJ;:(3Y}04wM۷/̑nג\.V/Ǩ,kU`͵64Lmg ؝:)`cVv桃d .3lL$)_H|Q|L!M/L|)ˋLN[o(MiDfqJԜYSBVēFA^oD ~s}i\A/э]KAUQFܕ,vsOt@%q˅iӰW׏~*0,oY3C+ʯ?+6%s=ѴN{dqjiX-Q{8g)%pjMaմ_)B!c2-7% B^heiL+tCn l,N}K oneEH|)-wX4Y[a%~ {؏qD.;;xUci'b,M|iQX1%QؗqLU쇪,KYQUjP/SlxfXr34z]dr"ϩpi.Gf fn5#h4Sjh]xSrT%gKZsKTM1z4 Q~>{p1W[g趧K\~A5[o,o0`ӈ߻G؜EX?th}݆vcs~ӚFF*_#UNKbYIdϴ(L!H_=|A␹P{$EHtDAE +yUDV(E +qL6*'}̓@e˜$s0΅^o7)6+)4T,*8F&y*kV#ԅ*#U#W/(RQ:Ar,c㰸WvY{u$K\CKf؎[-)(IV2kRuQ&83Q .Q^fF<*.[-jc:KTܵL(=p?S~Ec̓jmؤiKE5kI_iX-TFr ['j}\UmHv<(m}S[?>gq8bs +L5nU;d"(;RM!>^Rw/.-rfETh׾g.aF%=ܵ.:`c)޺SzVe"#,j]z8,ܮ4\y>UzCe@Ү8qHoP.V\%>HjLzi ػ]6N115=86(0^0@Kҭ5AO5jdmc}55kl;XV6ayR60v,Wr­};7H3lӯ99 bԥ[2)$-k->Բ!U֍[۲hXk<##/+/tK$豔#gyzciJ2OSӭ1v1>wv"Rr8Yj:OQt_һX~5޽ [^iԡ`&pX95ڛ}9Owt)NDs0D0㳎0w +:RLRGk͎AݦS]nN>% !&}gv0קg6ZQ!JV@l0G:Y-գKn Si,M\v~uv!ӟf^`5%Ͼ/Tѵ]k#9/=m|sIAz36%c'Gvn +Ԕ܂ە`ea!W߾ J'JaaOe{["ա;J;8E 쉔-3ӛ^<Ѭ|W!2ͷ#^dh. +KuA''~i. H4E*>_^bބ,eߝHGʗM6#p4Ù''oɩɩù_rG=ӑD21ysuШpXiteT-`9S.nڵka7co;'̛?f{坉c&c9&\ށ^SHC.z3])T;?DBY,+˃̖tk|3Za; 38꤭\N&" 1o;qT%IA%M?l34\͜|Wj{g]fwɢ\(Hp^Ky~ +ύ?$Z|(E9Ho*")sG=CXf<6G^py [N4tp/tBkoR2Qi:|%W02/vϠĠ z`to?RFG: OjyC;xgn<>=9R]޴f?k͚?0\f] CoS܏b&/~,~OXL#L9Yl'&=: + 漾o'i=y ^θѧ/(;7i'>DSD!+lo +-:ln1]r29h0wC(#3cYnݑt]tv]L*%K +~BeVDC}?q(%/5 pG6Q [E(4ò,wÔ3S8rH4>!pWPϘ̤5L/W7_@sZc `G<߿1 ./sҨkהgnpiWWl7:%M|eKk }2̈&SAǡ=i껜z to*);BJjG( 3M  c),,?|(Yfw5urN6=s:տv@nz$V@/# T"hC 8d{٫Lb%?@C1daD$""JmhkFہ[-pYyDQRi Fe-06z.oKQ@DJA6kr7l,L%ʪjkޠZ +jB7{2hzPPbnZIK i +W~>gx):D1's\85xZ-:kܬ jۡ=RdK~a[BDW*@kckSS4$[eQd;s:+3+D$MXB+$mɅ>6 ۽Ƃ ](l-,rfU-7gIԈqEF[M/ypVOQF߅6`. hsa9E_6C&|Ky93Ȝ S?{<z~ruE m%Kdmw~sv~% +nqNhZg\J?+~FXznxtTſ%~ oDbh 2)?'dkP.Ր*~[ /D@PVnؚ6h RvN3tͬ?B0q (2Bb^7"aJ]<>rܹWGWi HC +p +FKj PVDGO=݇ܦAOeeq*G"_WT)( ּ~ٹjFc? VbK/>{%~-LC2 KX}Mݚw ; ;5]v$p\| G5'Wlğf[ &_AjuhPx^{lnrt.WYilMez(#pw;[_]A^hHb$>u/u[S|;qb{wlàF1qa׮7Mg^U\R.\}{JC]ajc֋Ǟ1cќy%w6-s[[G{\eEY˜f%Cde5V4ڳhmWg|XH0G˼.DJA&۟J Qs5X$;)Gbٚ<$cFʙaBR0d6zK6#-;I|`]19=;. {hV#"n@נ #F[Ơ3wlͰ";4I3(#9-p3 ?m[liVg<븖)hOe:,klشbUW?a?}-sM!ͲXM{Aۥr7䰯RcSDoSȁhT +8 +I~/`-S5%ƥfJ M-H@$uױ N+ƥr}^O +xRfcO O~g7G)L#+8bS8Qeq׸xՖf=5sc"=/x2&NocaD :'<~K: +%IU)w肽k&r%#nO*TAaX_}vw&|u2Bl6[/3$4^g\HKsJ̞([<^rϭ mgJDCFp&~oqL FR eh7W76s|8h5堖Iu2O>}GmygRv&Hs`?άXaHm-ƖҿBxܪ_IwɄaCkm6nݸv݄BƸ&V7~8n~eǞ.y}oЭ]X:RoX|nGQPDni%[i<8%w8{ͪf<;?m$: rw-{,ܣn?.n{A?>vvz"KSh<9\҈}H|^Owېg9:''MEBj}`8QDO|&)>E) Hd +p{ɄAsBA;_W֊~$?Me$6|'^WHϫd),_i?RE +M%kJpbaApA U+WF2ٙ3{g*̭htyk2fCCT.= _+7ą.'s[V $ayR\GY) +My]h:}݁ n]iԠ8*?NP [ɔuQ%}")3 9C;=`jJϖ33GUضYՔ;dav$85oeڕ>ۺ+fiFS]|I]mosgVU irw<_xM63xţ/PQE޸/|7*@bE]& rV, 9, ln[&L/}{6[ա/ntɀRJHh=Rum7Nǹ,czn]~ -WJy\kP|5bwHZūkJX[f@zМn>+g3b{:8uVa$<AߢfϤF5l2P(%ee +Fٚq?Λ~-g32-7D2$׌ҿʸ.K ,+32Jп fq|Y$?b\eq.^2.;Eww% OlEځ/۸f;,I+|@B}raXFKN3CB"TvWۘʪw923'mkخO({Vו-G O˷QJ"Dr\CHAbG<|sG3EeAu;  !1&dKƹҨCH :9&H +e&K~Q S,~!F~:f!0(β`k1̥RmLCE: `|!e(?Wn{Op@F)>Y+ZVj=v8 Xw9=K +r,u՜ ;{! mbqPK̗0P!G[d*k`)* Q6C2aeŌ`i.[놯_KN0zaj}Q7ӭ|-/<°b̧LK REmUl<ym ,dKviܮ-[ϴ],+WiZVZ/-E;QWdΠ I(ܜ.~<))qP412lU==]y]>,Zu߱8r텈C ܫOI%}߼Detfyf(*@)!dR[)ZE~}_ܲr`(X^ZWo~A0;mv麊ʻ*+*k6d.=Iˋdfe)._>ӖdxĻ8ױVXGY kՕ#*gIS*J Ӗ,<7muOv؋vEc-3= 򨬎ڀ[i,s1hJ['dW7&j`w6-evǮ 0i&)"ZwRɻNaB`y$#pl`8G;~*=߷[]QEYj_v4 ?}6)z~4JEkwE}鎟,{~mmkhm[+-mmW^6⧉Ϥ2(oxlΐ]ۇ +\Po߼lkvM(ҘҔ\A[*Jh!/kׂϕgRIvJ߬wӊhz_wVo-iu|F-9 'O?t |?^E[C+2hjvT!И&!] K߅!eYخ_<@ k*@7{ p?@a3@JyehcU~ g=P +{`Y{BucNYЌ)@3>@KB"R{nЉZ1 C+Ԫzο;N)8Sp +N)8Sp +N)8Sp +N)8Sp +N)8Sp +N)8Sp +N)8Sp +N)8Sp +N)8hY<5p:\/͆꫰Pnn@o+| 30-_bdOBPp1TpMBly/YHRz)4. Y^P z.Vq*XpxnW凡QZbg΃Ӥ '~tWPx@tAWIcK0H&` AϯMX# K< ʥPGQ=|f{k"O`x=b\ +Sz|8n9& '`V7 O7`zlX'Ђp[zlh l{,SOOGĹ;3?Pߍ-g¥ +K_swCTXCAD{DWg|n6Xp6x| 7;qL8&$":{^mO8yW%u?9viP;0>8 q=D{fzN{E)'.E؆9l 0G0%^x[ʃ,^f8m} mȷa9Nc4cچ*0лpZ~&F4c! ?q])>x:J:YdJHHNHfj" vcm~tHV .Qp!X#o0_kH Kz nކ+0 I{$I.%hH;7w'1Nb#;'ugOp>> @ ~"y7 pw%u!L@xB)(gu\Fx!eH?vtBZ]ú:ӉIC-RT\ϊGG姑^ʸL߃qLA\d<ͽ&K+ٍu^:BݵȐ?ՐFm?Hqga=#wc'&.H.Mć|ɀV:l_H(üQ.L?M弰i> qr>PwAs}09s}u)'NP҃-N2+uȿ/,סl ^Cwcoc.X|gH/YB8] C:yNxZ<{-#8>cq5|O)Res?KFVukO}C&-658L G D vF8(KğP^B+pQv%yʳ\ҩW¥Hc_ҵti0 A/f3i+a:ȵhv30R>s=*7PNv YD/q>BbGϥ 9qHx)qHoP6'iDqRՑW=Bނ/ K{b'rna#5"#܂0aB B"6 NNY[mރIR'{79Nnұy-w-Of#> |LC[$/c}xmx!^cKDw| cZib{ M)O=~/#?i+Lx1.棘ގ|? +V!?4ak|籙"t`r]gvM3a1}8Y(۾@9e7u=yBQB 3x@yaOBr56vbI,}m[y'<,Iҋˠt -@h3R_ay;#lD4m`u0?.=QO> m;_~Hڅʄ6Cs -QQ]Ky5h >X#h@J9F Ѯ^6 Z߉;^lF_齠<a_1x 礎bq6|̵#h P&~PeӐJѾ{]~2K]sJv/ٞvS5PcjCfi;d^/dTTGDHO8fH +n#7`v:b G;y.Sc>d8 PV;PV;0uaJI 7e؜xNE⹤L9 ouO޺?MOukݾ?KmtIOf׽u}K?W~%,ޭrgt8?/ eסL8T5=t'C!^_6;]xdכ&Pw\K±Afb`\kkvz7Һ qk{'Y;no73jUԴN͞(=br w0׽Fz@AfjkfJsx5B%;0 nFM0h-D uEPӁ~:( + uEp؀n @Q]ـt +Zud7 @ ,-܍Pg렼:LI<x1{I|c}m 2zIXL K :E\?^8ʼn\WO{HGY* D/i%1U8hDk߷YS= 'D#|^8/|?z4 +JhACwA:-- +J`)Ա7aikl&^o 8b[:?i+^sOEig:NopLVgSl> U>?)c8jӃ'#l>I|cLLI@X DCH|֜sod6û {q>֐P8xy/pI ؞s:av#SA ʺ6XkMp; ;#n) Rc;(bZw=Sɸ3O9-[9clBc}4gc[Gw] 8_s&|*q9p W}\Ƕ,)/Lfu,>Ϡ^ _6+?(<#0\^q,_cDtې+unDy2:~x}c?J_0#uiդgFjFgw=cNԙ5,/* @^Ex jc\:%Դo{CѥZǺ^co_aK3=IA !!R +j uҞkr\|2̘jt˺r*`}%7b'sɴ7Qگed&`8, :VG@P ж(i0MSEO-~P#wgt?3dHp=19Qmg}6b} ŸzRJ A:^RQ2d:~L#&8Q ʘ<(\GR7!܊t,PK;DT1bYNaO9o@y^XLL};@k&Sql<֓sͧsNPG] +# a FZH,'z= _|CGܵM‚0dך)*=CFS^ ʻhheC/ <@q<״SrLe;yL;#ՃTZW +ꞰZ +kgT;_.aAGW]ٸ^ =)A>:BZ}ɾ?ٗbӈtes1X 7_B ňk֐C{SfS >Ti,&ݷoEz ,׽MN%u$˕퉇ЧzZǜ..~Vx<.^O(k@F +f,Q^/q?' _,qOO4Jx}w$d+P E3'b.s7\waSiqA ccp].I9Ќ|SwB=hVV䉡܅|!?Sd߃Rшr'kʣ^jN|>_Fr x3J_{llqlL'~:zGn@?lKgB/q>1Rf߻lRt4񣔽Z;BZ0}%7GCX.H>@>({,&h_gKhg@k% H9=Bz<e@'~R8Oz!$#!yE:9Uy5O~ux/Yay15b,Djbiqˑ7>Aq~a*/A;Co$lbǾCa9,X8><ݵ_J~%_^KO5_r`4{4@ZE(p-PeJ`;c1F)N:!&s~c6Y[\! !P`C(4S,"|/a&i=ņM}t^onط=L]͉ !L9Yz_=@_/thõjbX>!^7a5'i!PMiqMnZUO~&I|/~&[EԼ=t-DNfo vꅟ*&dvm87iƾ| 174 ]62*t[J>%о-c2uؿah + +4cx++!M,v-ǸLoM|ϐ= o^mq_@4F׶r`8[t +gŹHo:&}UJ| u$!(`0Au"|܃[axـVsJOR^z2$o?pl7XA{xNj0/0 3V9RwyHtd6<5j^|3Wc7`^\] @e?80!|,mOQJeɁd:ylc0E?]KīL{8d>PR#zW;ԮñC5nFCc^d 9Xyȅ׌$xQg! "0Bu/ &l5,>yCPno Tz,7A!`XּĨ + xͺdMOww5K>#j?ru)>#. ?WxOPh 'pH# Y ~@A-=C_@C7"B1(2(GyP U@- :C`(4 A# Є( c`,ph8Ca +LfӡfLa[a6́6 +*a0\oa6d\;QpfqFh`</Ë/`!,o&x^7`1|k`),3 뀳a#,΁s> +/Filter [/FlateDecode] +/Length 89 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x=;@D{N &.DmƕL&i,p|R + Uy%, ֥ +spny +endstream +endobj +428 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +429 0 obj +<< +/BBox [92.110679 303.676209 532.545016 331.385987] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 145 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xڅ1C1C Er (؅kĕ@- +endstream +endobj +430 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +431 0 obj +<< +/BBox [322.053274 284.193512 522.280018 295.210999] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 88 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x=0{`yr4IPؔK`p&Su D#kVIbn,ct + +endstream +endobj +432 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +433 0 obj +<< +/BBox [335.963979 272.913514 396.902843 283.931] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 89 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE 0{ 1<&iSI/<' j( +i4#8c^9afc5[⵹uA/M' +endstream +endobj +434 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +435 0 obj +<< +/Type /Font +/Subtype /Type0 +/BaseFont /HXQIYC+CourierNewPSMT +/Encoding /Identity-H +/ToUnicode 504 0 R +/DescendantFonts [<< +/W [34 [600]] +/Type /Font +/Subtype /CIDFontType2 +/BaseFont /HXQIYC+CourierNewPSMT +/CIDSystemInfo << +/Ordering (Identity0) +/Registry (PDF-XChange-Viewer) +/Supplement 0 +>> +/FontDescriptor 505 0 R +>>] +>> +endobj +436 0 obj +<< +/Type /Font +/Subtype /Type0 +/BaseFont /OGQHTC+CourierNewPSMT +/Encoding /Identity-H +/ToUnicode 506 0 R +/DescendantFonts [<< +/W [3 [600] 17 [600] 20 [600] 23 [600] 34 [600] 51 [600] 68 69 600 71 +72 600 74 [600] 76 [600] 79 [600] 81 82 600 86 89 600] +/Type /Font +/Subtype /CIDFontType2 +/BaseFont /OGQHTC+CourierNewPSMT +/CIDSystemInfo << +/Ordering (Identity0) +/Registry (PDF-XChange-Viewer) +/Supplement 0 +>> +/FontDescriptor 507 0 R +>>] +>> +endobj +437 0 obj +<< +/BBox [83.974276 511.000519 125.938028 522.018006] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 91 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE;0 C"'~> +endobj +439 0 obj +<< +/BBox [83.972275 726.518494 136.098319 737.536011] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 90 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x= 0 D{O N8 A H>ҕe軩ċS/uH`2^> +endobj +441 0 obj +<< +/BBox [83.972275 261.642518 141.769512 272.660004] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 91 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE 0 D{O ,Ύg$haHFW}6n ֮7 YcH IH4`C> +endobj +443 0 obj +<< +/BBox [322.052275 216.269501 371.486949 227.287003] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 95 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE;0D{N IɌ6xBMlѰPt*F"NT8> +endobj +445 0 obj +<< +/BBox [322.051268 182.2025 357.514193 193.220002] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 96 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE10 "/{`AٗHF磯= h! (eh >,.33eMc$`|v4嚶t4 +endstream +endobj +446 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +447 0 obj +<< +/BBox [322.052275 148.110505 468.469332 159.128006] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 95 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xEA0}/hD/z1$V0o9>Jhӕ%1T7Z9wWFs03 I*}:+?񷎲a +endstream +endobj +448 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +449 0 obj +<< +/BBox [322.051268 125.562508 413.376812 136.580002] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 106 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xڅ10EwN HҴi..Od`V+dZ*.0XR$0o;d7C\+Oa|L |/ +endstream +endobj +450 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +451 0 obj +<< +/BBox [322.051268 91.483506 405.368441 102.501] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 108 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xڅ10EwN c˜RK?(":$ =A?;5sXbNF{nk?9=.rii%^)̼/> +endobj +453 0 obj +<< +/BBox [356.132284 703.712525 453.338046 714.729981] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 87 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x= 0 {O ^ylX &iz/2 Z:2B+h.ee^MYw!/) +endstream +endobj +454 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +455 0 obj +<< +/BBox [455.220968 703.712525 535.710543 714.729981] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 86 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x= @ b+X~ N9fW<(L:p/ᴌ%9'%Y@}c62;1^/5 +endstream +endobj +456 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +457 0 obj +<< +/BBox [186.213277 692.440491 244.162075 703.458008] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 88 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE; +0 CwB'vbs@K?4PL7=xN1Z1po֭* mcIqƵڟOν,C^e +endstream +endobj +458 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +459 0 obj +<< +/BBox [356.132284 692.433533 461.352397 703.450989] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 89 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x= 0{`R$M/wҽ'(0|ҐA6N qase`QJ6 I1X()4fN +endstream +endobj +460 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +461 0 obj +<< +/BBox [356.132284 681.15448 471.599642 692.171998] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 90 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE10 /H4{* O>[ pTqDMe 5Fd)XX20&,nd5F''Y(tV~'}vQ +endstream +endobj +462 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +463 0 obj +<< +/BBox [356.132284 669.879517 408.982769 680.896973] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 89 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE;0 C'ڔS X@%'=>ip ‘keqsbu4,9bi?84V}v,] +endstream +endobj +464 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +465 0 obj +<< +/BBox [61.411278 564.993531 108.845979 598.570008] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 174 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xMPA  +_(tf{^S^! RX.!LּYG'Fd Ԫލ|ZL S1&>o!<"ؚ̪4 A\ BD:콂 *.|5qE\ɓk`)ڧݝ*P +endstream +endobj +466 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +467 0 obj +<< +/BBox [110.186746 606.839539 150.27659 626.579163] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 110 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x1C1CXv$R.PXփg"*㝷!9$YDobMoX} esZce +^CX1-PZՠ S⠶/oAw=r +endstream +endobj +468 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +469 0 obj +<< +/BBox [213.572275 672.989502 257.060283 684.00702] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 95 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xEA0}/P,PD/z1B 24[w"UdJ"IԔVvoBpA"нMp&pDߘy~9^ +endstream +endobj +470 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +471 0 obj +<< +/BBox [311.511165 528.342591 355.443394 545.7865] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 111 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x1A{/` ,H&i"NČvisI/Fb-XehÑ{8J{k0i/B?TmV.8bb^[ yj +endstream +endobj +472 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +473 0 obj +<< +/BBox [117.52459 510.056 159.362727 533.88794] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 119 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xڅNA ʷ +UY=[g|\ĉ )(le6,IW"%Sn&7r1w2` +e~TK-eŏVGnXH[Df7 b( +endstream +endobj +474 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +475 0 obj +<< +/BBox [61.411278 564.993531 346.925975 598.570008] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 276 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xeRK!{ +O@> +endobj +477 0 obj +<< +/BBox [190.899247 527.593086 214.213686 543.095944] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 88 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x=̱ 0 DSʼnxz"DNռ7xḯWSK,T&E"fhTϲJh)b#'8T +endstream +endobj +478 0 obj +<< +/CA 0.600001 +/ca 0.600001 +/Type /ExtGState +>> +endobj +479 0 obj +<< +/BBox [216.909301 541.182113 253.163467 548.356879] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 73 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x ɫP @*ˇ> +endobj +481 0 obj +<< +/BBox [231.740785 633.928279 254.85554 647.097256] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 75 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xʹ @ Ul+AW9U@D@HG,DZ[5EPDgQM9K&dohzn1 +endstream +endobj +482 0 obj +<< +/CA 0.600001 +/ca 0.600001 +/Type /ExtGState +>> +endobj +483 0 obj +<< +/BBox [187.16444 625.689474 213.456864 635.704883] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 74 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x ȱ0) L`ZY\yԠa C>9u4z4= ˳_g +endstream +endobj +484 0 obj +<< +/CA 0.600001 +/ca 0.600001 +/Type /ExtGState +>> +endobj +485 0 obj +<< +/BBox [188.391397 233.826856 201.130027 246.816989] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 56 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.r.C K= c#S=# \.CKK=3KC#cS=#C3`.x +endstream +endobj +486 0 obj +<< +/CA 0.600001 +/ca 0.600001 +/Type /ExtGState +>> +endobj +487 0 obj +<< +/BBox [182.254014 232.36601 209.732727 248.629947] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 55 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +x3T0 w.r.C c=Cc #c=C3\.# = BW0 +endstream +endobj +488 0 obj +<< +/CA 0.600001 +/ca 0.600001 +/Type /ExtGState +>> +endobj +489 0 obj +<< +/BBox [275.56201 341.074494 320.316653 352.092011] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 88 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE @ L 8~$ha)}a87*jq$lBdWkc*YBRge K8CEV +endstream +endobj +490 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +491 0 obj +<< +/BBox [420.886412 341.074494 456.250338 352.092011] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 88 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE 0L ^(D/Ig;ĵ'0@l$4#ԍ7,A>SIEƪEI9L~9ҖnN +endstream +endobj +492 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +493 0 obj +<< +/BBox [0 0 133 71] +/Type /XObject +/Filter [/FlateDecode] +/Length 29 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/Resources << +/XObject << +/i 508 0 R +>> +>> +>> +stream +x346300PAsC839K?S%[qA +endstream +endobj +494 0 obj +<< +/BBox [265.41329 613.231507 305.924724 624.249024] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 86 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE 0sW|L=H@B g@PE#uo;[&KP1bTSŪ1/s ̿[`C +endstream +endobj +495 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +496 0 obj +<< +/BBox [265.41329 601.712525 312.645998 612.729981] +/Group << +/I false +/K false +/S /Transparency +>> +/Filter [/FlateDecode] +/Length 88 +/Matrix [1 0 0 1 0 0] +/Subtype /Form +/FormType 1 +/Resources << +/ProcSet [/PDF] +>> +>> +stream +xE10w^ TjvFJglB^T"9Z8 !5l뢜j8Tz_=csq>xE +endstream +endobj +497 0 obj +<< +/BM /Multiply +/Type /ExtGState +>> +endobj +498 0 obj +<< +/A << +/D [89 0 R /XYZ 0 846.53479 null] +/S /GoTo +>> +/Next 420 0 R +/Prev 509 0 R +/Title (-060- Marking/Labelling) +/Parent 142 0 R +>> +endobj +499 0 obj +<< +/A << +/D [34 0 R /XYZ 0 846.53479 null] +/S /GoTo +>> +/Next 510 0 R +/Prev 422 0 R +/Title (-016- Slot) +/Parent 142 0 R +>> +endobj +500 0 obj +<< +/Dest [13 0 R /XYZ 0 829.936242 null] +/Next 423 0 R +/Prev 511 0 R +/Title (Parts) +/Parent 351 0 R +>> +endobj +501 0 obj +<< +/Dest [20 0 R /XYZ 0 453.279614 null] +/Prev 512 0 R +/Title (11. Camber) +/Parent 424 0 R +>> +endobj +502 0 obj +<< +/Dest [18 0 R /XYZ 0 810.659632 null] +/Next 513 0 R +/Title (1. Part coordinate system) +/Parent 424 0 R +>> +endobj +503 0 obj +<< +/A << +/D [12 0 R /XYZ 0 666.980118 null] +/S /GoTo +>> +/Next 511 0 R +/Prev 425 0 R +/Title (Rawparts) +/Parent 351 0 R +>> +endobj +504 0 obj +<< +/Filter [/FlateDecode] +/Length 232 +>> +stream +x]Pn +׉2EYtRUU2Ԓg?Oyt6WF0ion8[ZڪxʫOi_#.3= \#p/wHy`4u3F.ڸ괅K*@Æi4i rAygc׵Tm,5A*$fd}ll`?κ.DjWej#JY: >dVs +endstream +endobj +505 0 obj +<< +/Type /FontDescriptor +/Flags 32 +/Ascent 612 +/Descent -188 +/FontBBox [-121.582031 -679.6875 622.558594 1020.996094] +/FontName /HXQIYC+CourierNewPSMT +/CapHeight 0 +/FontFile2 514 0 R +/ItalicAngle 0 +>> +endobj +506 0 obj +<< +/Filter [/FlateDecode] +/Length 320 +>> +stream +x]Mk09nO~$j˂Kފ%Pc.ߘwk}g23L}shytr:{m:Gxsڰ$V +5E>L3 GVU,ziv ߝǏoriבwMGf/<1kQ>Gkϲ(DQJ7bNp*5v4Vk͕XUWt@إ/MҸ^a.)J@H @) P]2H& 9rJ$)[@H^*@H^\*FYX)Dhooަn'ƱB^DA +endstream +endobj +507 0 obj +<< +/Type /FontDescriptor +/Flags 32 +/Ascent 612 +/Descent -188 +/FontBBox [-121.582031 -679.6875 622.558594 1020.996094] +/FontName /OGQHTC+CourierNewPSMT +/CapHeight 0 +/FontFile2 515 0 R +/ItalicAngle 0 +>> +endobj +508 0 obj +<< +/Width 133 +/Filter [/FlateDecode] +/Height 71 +/Length 690 +/Subtype /Image +/ColorSpace /DeviceRGB +/DecodeParms [<< +/Colors 3 +/Columns 133 +/Predictor 12 +>>] +/BitsPerComponent 8 +>> +stream +xMR0 F;={@, +4Od@~1q,0q5L.탋E}p>pTGmG(lB75>FRuX o_a N *+>s~%Vr},;p4JeJZDcnj6HX(>&b/Jޥ#}đIyJ|Ld,?e9:MZV2崘H{ّQG2 1a4%)][4X>΃eqn}8ҎԘ]> #/"ǎ7kw'j},˯MR{~p>h\.>o7Wib_Mv~InrS]597D)GܒF<+Ѷ4?hĔ̃'*z'9$o$oӞGS[)3{T<ϣ e.`#5̓+4?T̏X+Ub< +-acue6AJ*#G, ϻtD܃8?5+I(IΌVˣ:p5{?.탋E}p>h\.?U:< +endstream +endobj +509 0 obj +<< +/A << +/D [75 0 R /XYZ 0 796.423383 null] +/S /GoTo +>> +/Next 498 0 R +/Prev 516 0 R +/Title (3-050 4-050- Mortise) +/Parent 142 0 R +>> +endobj +510 0 obj +<< +/A << +/D [40 0 R /XYZ 0 846.53479 null] +/S /GoTo +>> +/Next 517 0 R +/Prev 499 0 R +/Title (-020- Birds Mouth) +/Parent 142 0 R +>> +endobj +511 0 obj +<< +/Dest [12 0 R /XYZ 0 658.009714 null] +/Next 500 0 R +/Prev 503 0 R +/Title (Processing for Rawpart) +/Parent 351 0 R +>> +endobj +512 0 obj +<< +/Dest [19 0 R /XYZ 0 603.308782 null] +/Next 501 0 R +/Prev 513 0 R +/Title (7.) +/Parent 424 0 R +>> +endobj +513 0 obj +<< +/Dest [18 0 R /XYZ 0 446.895394 null] +/Next 512 0 R +/Prev 502 0 R +/Title (2. Referenceplane) +/Parent 424 0 R +>> +endobj +514 0 obj +<< +/Filter [/FlateDecode] +/Length 8583 +/Length1 725315 +>> +stream +x}{\U&"#eF***%b7Kje.j骛m[9mVkon7\k۲ݭ{33cfϹ<9Ab" +*Rl(V/W+(@ 6ӏ Ko|gSnuMǚ5}b7(za.9iYc.c ^h܎c1Do9X|*xo0cJ0f4`5<.j[*%kiZ6L+jzjK;IzZ0;`K|8ݫ#i|>LvSд/;;0ZV1/@bهxLkSd-༑&(H2-fiaUbLf)aޥEءtm'cI1`0,5[!~2v.ZoZ͋tx+y2}k#N؛nbY®ő'.u\MiGL\{΍µ(77==q2Z2f4Lh(B\_[ioƿ4ʵboigk}&9Ma?aƹ*ȴ2MB.Jpg:QG8ǖSFlma-w*!:e +21)w-7ٖ+g֒Jf &Y47Jd*q渃0yr5Rvz}}8Cff(rk%.9F;sGײ4N΋gYܻ',Bh+FWI&ֺܼCZJ<+ɜ[,vᶊ[5nZl0>̛rw)7%4U +\Y>$*]dTp`67![Z34ݙCZ=^H "pZuup@#l%FUnn \0طuq]XDgBZ j|iE p~/,qSMlw +>%+3s$ϹAX? +[g']E <*Tۯ% w'Q8%"+b(}L7rUV*{̦#,(BiNilrz^AH4 =]A/|4K?Ҽ |#ߦf. Db S)=L#7> 7g||!_9U?{= l / +):F?>;"pC&):8ĵ|po +lg0.(K2e +}ڕXj817)s#FRB>$*"lĎHL%0 JPxhEwaW C!m"UGxU[}nG%%~'0l*ַ0vdcLy 5Ď-GyNxoEQB:г|>whn/^kq> +O'U'i7vy-Jпh:߁W+wxK繜٢ߵOcsc'ʾD܍_i@ +\= >lho y 8Sh M16fNwB?Or /\ KRUSy&p^-RÃU,4?h+ډLo,f4@x샽9 }UNy0 mo5O,_{x'OP<9n s,E-r-Rqש&H|sGYZ⌮h@tnC.n?C6̐=LP,vnQvU˟r(87ٔ!S= S| / OaY~A_B^ǡ?噠Aq %eW*jG>m|ЃBr؎7s^WwK[~_*288 Gmhyw.A+;w;R9ZL91nІ38ЅQУJ^Uw1gyXyRt:ER}gNOb+ ڞܟ9ם؟!rb6Y; i F ޼7BNWz&X[qMV9ʻqCނKMsI^KVס4;Ek g-VD8A-U*aEB&iEG4]A֨},s1l8M*`GJ΁vewCЬ^v E-i)FyX#!sQ:|ϩ p^@8llN9OCV*P = ^-)-C*#^e82ipAgIz[IL'xfi/$] +`U`/67 ZNmȰq \I+(:pOwMr}y,?;>ݲpv"1Ϊ/O_MU=Ϩ17M=19YNWaØg*z7vs/zP +zq's'vmpanUBGš%>^>9ǭ,w#+Kx"(.Ha:v5N*3qη.g!^BݕH}Yh֕faV>RTNn ݤnNGs4[zpwC@ |OC}H>yprW9D+ ٓ@_Kp2±"y'@y~/hX][4N E˄]*Ew>e_*$|W[tGHO:% zWBDjZ3T{]BKW2Y|m?D8dF#KEBj){ +h?y6cq܂ZYPv̗K[ۼr6;@ǍnjId,ጵ&2nLArjMw˗n-d$O#pF} /W{*4p|])Ś dKX4n-!R>b2[&}& }/j'RKRÎЧdGJIDA&z4!ٸSt7)7rl,:c:;;)|,a)Er>k>{4T! CMhFXr'sz˜B vս@ۙ _}~Ifu`KoSVs-o*;tPNi`ǻQ˦,II-:ƒ( ?Q^)ˋh{ʶ z&m,k% {/#7vw.Hǝas̋)4jhX[t%rԟ=Y=Z^a{lK@⥠RXvtQ(.qJzFqxWy~#% ;dH_쩼+q+2C!j82_Z/t.Sw +!%uxCꍝO{77Oc_]]%IuDN#i;0VOJ[t^ХAUJ*Kz'c*eE\Vsx/n"ԎzQǹ +Ag|_.o+Ͳi.bU6ye ຾|=:q҃{_|ɵ=7Af黎.ދ4g4G(PNm,(vG=zz+.SOl]=p֫~x+Uo &poV߂ y!=M?\Igk'lAr۹ʵy.$4j?b=~NtнI?K~R5_}n؂p~i0R(C8O k#FCTg-w"Ca|2zʁ_5^E]t+G#N?"ނ2>Q2;OqڢVGQ܀k1{fPC$E18Ѭ+}[L](z<9ʊRfYޤAɍn}{MO_|voj G~h7F'%~~~~~~~~~~~~~~_`=46Q + Swuz785ht +Ѻ}2U?[*7]߬ (-f!h0 Un[99ꉵuKwXm?6kȊoƳF=ouuCò+ u#iPپ9ٝjf +!ߎ߮ݽ]y;¢9Hdk.m +AEx6Obm2ާZ!**T*}JߦY*M0E0jI91*.( xaٷk 0rw,N +N)`F +}}!JA։@F^dn*rR6j! oYW%]pvE_]1 Y*0QZ'څՃP(6 RyTMGj=ZlZ;( + +, 쨖z~.fewHCT, a: 3½*]Nvr0_a~}Ggf0aΘaRg'ݼnb7}vsvx*eWavUa@c\mJumy@{ݲ-, k'B%|VαZjǬܽRʼ¢ڕܺ11y\%=p=J~Y9Ƚ?QWccctTc)Xh+g'/C㬮 )ibYwP'~]pEٲLʿ-Y=w#;6bgbo,%7/Yg񒥀(KkQZ9Y(,5Ů%vuR-SK3/n)Gʆ<@w2jɊK#6֎nHN* +endstream +endobj +515 0 obj +<< +/Filter [/FlateDecode] +/Length 13205 +/Length1 725315 +>> +stream +x}y|9;[&̒I2IfdB [D&r\Z\X*E(aQ.U`VV<3B,|9g޳=Lb"2R{ +hyH d"C%W|]%5D3 ϞwfiQS Ƨ(QW\V^CuUKn"&-MM]d<6Yz]Gg~N_R1 i;+`V%MiTψ| ` X(bD}1k22G"+9s*'4O5>9鬚|wd1fMFZI7Mzer8r'T3}4i$Mô73m~GKG;FFFDP-Ԅ,!tuS}/#n=z6zHﳪu'hM9}8 +b)~2TPI{h3h EGMz k~ O|#~?OgV7k^|q"b<y(TTҥ1+b5I5"1v4zJE=FF^D+q%+i_rҢcitvt|숄#G^} K>/o:=tY/xއ)dPnRR" uƩycl⎇;vGF@TҒBP=־NO3!=' vx$O:n䅼2oU=|OQtJ*P*(){ J$N]^ާQT?X4Ś2Mff.?,nh:j:X\lj#ÑHGe8c=-oFwVǓ8 }Z8Gm='|9`!_7nC|W5=/{S *;G9jZQj#v)_LvfOSd75Gu&OM7R+)K>D+@ҮQ)۔Yfͽ.[BCx0x6-J]߉b]VQ;8Um<^IȏېQ洺A>~xRJ<&^j +)[YdCN~(F5)s\mJ/ r:*v>B+P?>@ڸY{+W Vz,ABFLfx)9g2Cx4Vi$TFXh,Oq'7 z\yh_z ;m x~Io)O*[UrrޣԗOw4wj$ʡ Ky ֿ/r,r"7/q{uC30*q&auS& +V PٿoyeJEy9lte8ibN6%% zV*Lŵp^cXQF. a/_8&mü aF#C# R[<}Bkp,MlBoca7̍kmr͉aa%lLD1pi3fYPk6+d0P Mm'Oq|%a6?'Las@arnXX/.OCGmhМ@<3z5}k8WmX]{]Z"[w7mB]^H* @ѓMY[_+DYEiNʲ8$"IxJ̯us+1 zƬevEk9G(S/pQ0g,%״*K-^d mg,}>!JiB]9 +J9I"z==$԰!ْRp`ѓ'L֮kv jξX)2Nu)Re/rf`QK +krO'z^-4^M>85%b  \X~֩8&O=yu [7qH_.H޺qFwoC,䁐V6 !c?wLks3qh}s# +VEFQ +fz \G1޵?D${5A26CinmD7ʓmD{BmMXD=piDg#ưu]A*4 ?|:_3&ua/l Ff֯[ܩu r~ȇ`u3M`CJ'ərL($XC}_2CFn1$jL^Fmr*y})Sr*O/U+D=OSwL[lWk仐٪#C+o$(OPo%X̖g hѢZb@O>aϪɇ߯ wU"eohpj~fzᰥkʦVɐ!:J + [!xǠ},Of?MVֳiT[+7lϦz}jWUyp-اmr܂0U%++ Ϡ42--UmUn Y +Cf7"%hR~v Pu5ƴ۰,3d A FlWFQY@wܻl*x!FrϪ6k'#3\/xl5:ũdzS>hQ +3 MφɏYSVfſ+YSb0_a-Ü81m.u+n3Y7rU('Cb_Fy CV6*c-ߎiB ζHKTˆ +]^53ϒeWF'.s>8@曹a-k`A_~}:}(Bp?d-CWNk_Ń& V)B +7NPRtp&etL(** ' ͽe }rh24.<).'Uul/B?P E2( VPbR@iTֵf6QڬYb[ӡɝk3T(990לə%Z]KǴAa] w sBPI:ۃo7ef(3-:/VLe'YpT;\"]L*;gS;I G?yKq>ݱ"._SR_s-)']7xc"4S& xNh“=OR*͊k3q5fk c~K%7dw|w[ZPﵮ^O&B?m(nUers}~>WjyRBqV>wܧ&&RX-.JJ*oD^/dJ6W;;32*.DVa)F_t 2⢀3JP +RXtI9!>|E@gnR~ 4:v =Hn I=в_.>iR[YBy/՞Vާ_nߛ=y݁wkjMne0U/Tdcz}dߘ-w^>Y挢mGjW5҅f ޗ`3sM)WRŒb6ez4LKtUN%5$ܽyQ +A Y>3(2)ɛj%Sv,쮮L8WrfisqOpRW$pYbYΈ +E>ޟx hNhjizsa<.q{*O6ګW*w>y&{onmIFN|[VVROwUf30.zVu}^8c{{5bǹ_+y V sCE"7#)´=J--v&4rgi F0fw/)M0ț))Ѯ^T'$/3g݁({,.kUv +\- /i1N6 Bsj?E>o@{"rZÝwAQ:=Nܔ.(QZ'x?B^wj^Nmh[ +$/ZdL{$U U&*sS^ug{yGE}J(ץ%<76|ĽOk^v zJ+nk ƚKk|ĤUۈlB*f%7WyX6M0팴R T.4Be9Ҥш^zI} ϓ7_}elqXSl~wl<~}dO4Z-}}ݼ6 +qcM@|*gww}]9{;sߙ}gstW..[:|e +ZxOmɊAH) Z!![!wkIbd}}^cG Uu\ehIؖNP f%Jx#AQ5oOkξE/ K"V}=S Z.n "g)#raB@DVT.KJa,*|+:]O>YN=Bҕ>][9j1rKgBum~w~㷿q㫯nROZ|Y.w_:he}1ViZ+ +{ԙy+57uά kd 9\qqmsp"GK,ʦ(Ռ:vex?c}ep=a 順P9SoMx$Y, A[ǰ6GVk xbg9lQ-Ng⧾߈ y.z: ZSɷ7(GuG vCŠ.7镹yy.u:znޣ+< +FQxiͩT%u35̶kxfYqqiYv51zG$spcrr1,kUrg\>T1wEE}*u|O7FJO/,(}H0z3N9٪lY{Sٶ29`.G&(ŠЮuj։#GvrV>bKpecwej zΠ2vg2)'N ~g)g~:􇔳}jKLѥi' v ]@߃i)+U^Q;+njG`zf8ԤԷO_ӫ99I5juV ˫أz{qV~0*qY%n՝1dUa/$d /)Bg03/y}͓/\Ɯ@=꛷`xv+hdJ(%ڼ)S=T^$U;<56bг?]0bv1YMұ]^M?_/)zejhtC6=JJ" B# %ogׇ&0clR^oVRqKflxšh1 To~9;lO^7ћ5yf/* L\Y`]d_߅AOB;,CL(}G|WT,Rjk5,lՖ)}&Þ~'۟U:W:LES8JMPcG=eO*^'))1*33T*c_eo+B)JUں˪Z !Se%m7m3 >rW"lCڄn۵x^9)_7B(ԻUE]A|~ݤ[]zJo. 3E5 K?q/HZK{K,s! ӳ=wl(s{Cg9>XD>kAc$b=vJЇ >FGA :6z>>ƕ4Bzh+5ѕ@"^vh?M~7t\D'>D3nŒwFmiR'܃&A H%v}%cU~N4 +1aF ~ 8 t7/dAW}l8b4N0>ΣAx1缓qIx5'δh5}n\' Je2%S +}J4߅XEaIp{y ŸfX*~ԛ=2ǩM Ff+sc|kko|Ş$>z;vo؄ tTPNF|cEJOV&%Kd4߈^1Z~.VGY/oFi;P+Rme3Ν:>"z!h\JQJ؉WBv. fdl3N(=Ww2ww6HxZ +qD?+HwIH.8 +E~ |KEwqpy8\EAΥ9z>HXCy*݊2&(_Ź PRJ~);&-'O (|OWSZpDS)9꩐4i4whw=j:r;jQ9y0$s꿤[(nŬ0[ؓg`Py p:̸;? M AHJP!ۏq*mm|-wrjX ˤq(C?z^mZ E0uK+/]]++v5C?)eoF%^|OC*ylgy O OA>VF[76q>[*s~wb-<!{rH"H !>@y[$o_C01'v:q_>:xoa#S١Fz zwX{>~س('4Ҧ3I's%{B{@d-R-Y#IF@GoX!4.=އl A|xpܸb-Jg/Л!ǧÊ/ +aw7' DµR$ƥEhćhŰ \htǬfLǭ;Ewy'=aUuM_ -Y nDuU6rțP4Gx9+; +_\SEROM\WzrkI"I_%~ 6އ(4H#v?-Mz5mB< +m +UxvAhW햞QN² +9-QSK%i>( #cݠ\}Ns6@VsE'fw1.@@ܻ'U\`mYHz`W$⹱_Hn1vygK + J+(@[Z.a(t]7g xK|'m?DL86Dfh'$loO ]1`Ng D6b."@ }ې!jv%YIFQjZÍri!qKBp=Wp ?DV ݩ fG> Ur +_M<#Lă6x1/OW9 ÃTNJ +S|xIHaI>|ͿŬR۰!"Dnj/D "O3T1뻄[ʒNK=Cww+Z 31X ++O!p +WmuN7".xAy?h*N=]@89*瑩@tB瑩^]g?(ם&ݳ'{wu"vBG.k+1RvI]R7@_D> f£u+rAVj#) ;ij?3f*@# @DbCI# +G.$QE1Cހ6?HnDBjì0FJe|@'}[9 8]FG܏HZO ^UA`z֥sYO̽ΧM-]r^^ U2g `7᝔mvSu(k;`6 hp|py<̏+iJ*"::XCU,s_E]c_=WԻx{\#:w6޳Hō]=Ʋ>'<J;ߒHYl,MA%͘1͈{< +OaR+sз8;ORz.Dxf%P|,᝽x?q^SV 7}vJ_vF\xTV +hx4G@S:1]T ;#:paH,6QGK ȓ[=| )͗R5Mi7 "=Ǥ[1܌ěF"8oSJ6dg4| +GX.OSҨNһdMnΒ8kdy,/jYEZ%,Ru: +2A%j-"Ǫ#e>F!K@>lG,#QA~ "o Y,)O 58S $Zn-THVkC!!HUCj`u0za !5(1QAX9 RZAep<:ŘWscbrO@vXQ֋m-nOhHKMʞ<Ďqbl)ppp p+p@ўPRTq];#~<3+'e1Z- +i+Pő qBNe#t(L",XyJ(>n.N( + GU7 p7.FzpǾ+p8̪XR*W*JcHii06!cEL2?eSW4$PLәgiz`niLҙVJ6LS~SET0LC\DtL4[Y/~Go7 C!`4 :Ơ`o bYDӈT#۟įFQ8E4G̥so'[8azXah=y#?0U 'Q|W=jaVuMk]']^̩kƍvM6:`xͿHcixIT~2>G"YA9+JښJ76)E8f?D&ǑW#oqn+8`\ _mM3HtY ,Qc|]OOOh?/tihv_;^BC4O.oXk3wgo5ao?ݣ5ʹvr]QQ5G.yvwƷk./-+{/wbbbr/)K 63VF~he`)U>M_Sb>6EWɐ! Z&lu9nc]4[CQ/ge/|J`+_$YYXdaWD($[!wVbe^U hyE-_wP ,C␱U#6 +endstream +endobj +516 0 obj +<< +/A << +/D [73 0 R /XYZ 0 846.53479 null] +/S /GoTo +>> +/Next 509 0 R +/Prev 518 0 R +/Title (1-050 2-050- Tenon) +/Parent 142 0 R +>> +endobj +517 0 obj +<< +/A << +/D [47 0 R /XYZ 0 846.53479 null] +/S /GoTo +>> +/Next 519 0 R +/Prev 510 0 R +/Title (-030- Ridge Lap) +/Parent 142 0 R +>> +endobj +518 0 obj +<< +/Dest [71 0 R /XYZ 0 838.318492 null] +/Next 516 0 R +/Prev 520 0 R +/Title (-040- Drilling) +/Parent 142 0 R +>> +endobj +519 0 obj +<< +/A << +/D [54 0 R /XYZ 0 846.53479 null] +/S /GoTo +>> +/Next 521 0 R +/Prev 517 0 R +/Title (-032- Notch/rabbet) +/Parent 142 0 R +>> +endobj +520 0 obj +<< +/A << +/D [69 0 R /XYZ 0 846.53479 null] +/S /GoTo +>> +/Next 518 0 R +/Prev 521 0 R +/Title (-039- Pocket) +/Parent 142 0 R +>> +endobj +521 0 obj +<< +/A << +/D [58 0 R /XYZ 0 846.53479 null] +/S /GoTo +>> +/Next 520 0 R +/Prev 519 0 R +/Title (-034- Seathing Cut) +/Parent 142 0 R +>> +endobj +xref +0 522 +0000000000 65535 f +0000000015 00000 n +0000000272 00000 n +0000000443 00000 n +0000001486 00000 n +0000004395 00000 n +0000004455 00000 n +0000004615 00000 n +0000004801 00000 n +0000004961 00000 n +0000005121 00000 n +0000005282 00000 n +0000005485 00000 n +0000005720 00000 n +0000005915 00000 n +0000006094 00000 n +0000006345 00000 n +0000006506 00000 n +0000006725 00000 n +0000007024 00000 n +0000007227 00000 n +0000007414 00000 n +0000007575 00000 n +0000007736 00000 n +0000007897 00000 n +0000008058 00000 n +0000008219 00000 n +0000008380 00000 n +0000008567 00000 n +0000008728 00000 n +0000008889 00000 n +0000009050 00000 n +0000009211 00000 n +0000009372 00000 n +0000009533 00000 n +0000009694 00000 n +0000009855 00000 n +0000010016 00000 n +0000010177 00000 n +0000010338 00000 n +0000010499 00000 n +0000010660 00000 n +0000010821 00000 n +0000010982 00000 n +0000011143 00000 n +0000011304 00000 n +0000011465 00000 n +0000011626 00000 n +0000011787 00000 n +0000011948 00000 n +0000012109 00000 n +0000012270 00000 n +0000012431 00000 n +0000012592 00000 n +0000012753 00000 n +0000012914 00000 n +0000013075 00000 n +0000013236 00000 n +0000013397 00000 n +0000013558 00000 n +0000013719 00000 n +0000013880 00000 n +0000014041 00000 n +0000014202 00000 n +0000014363 00000 n +0000014524 00000 n +0000014685 00000 n +0000014846 00000 n +0000015007 00000 n +0000015168 00000 n +0000015329 00000 n +0000015490 00000 n +0000015693 00000 n +0000015888 00000 n +0000016049 00000 n +0000016210 00000 n +0000016371 00000 n +0000016532 00000 n +0000016693 00000 n +0000016854 00000 n +0000017015 00000 n +0000017176 00000 n +0000017337 00000 n +0000017498 00000 n +0000017659 00000 n +0000017820 00000 n +0000017981 00000 n +0000018142 00000 n +0000018303 00000 n +0000018464 00000 n +0000018625 00000 n +0000018786 00000 n +0000018947 00000 n +0000019120 00000 n +0000019281 00000 n +0000019442 00000 n +0000019603 00000 n +0000019764 00000 n +0000019925 00000 n +0000020086 00000 n +0000020247 00000 n +0000020409 00000 n +0000020571 00000 n +0000020733 00000 n +0000020895 00000 n +0000021057 00000 n +0000021219 00000 n +0000021381 00000 n +0000021543 00000 n +0000021705 00000 n +0000021867 00000 n +0000022041 00000 n +0000022203 00000 n +0000022365 00000 n +0000022527 00000 n +0000022689 00000 n +0000022851 00000 n +0000023025 00000 n +0000023187 00000 n +0000023349 00000 n +0000023511 00000 n +0000023673 00000 n +0000023835 00000 n +0000023997 00000 n +0000024159 00000 n +0000024321 00000 n +0000024483 00000 n +0000024645 00000 n +0000024807 00000 n +0000024969 00000 n +0000025131 00000 n +0000025293 00000 n +0000025455 00000 n +0000025629 00000 n +0000025791 00000 n +0000025953 00000 n +0000026115 00000 n +0000026277 00000 n +0000026439 00000 n +0000026601 00000 n +0000026763 00000 n +0000026925 00000 n +0000027087 00000 n +0000027253 00000 n +0000027361 00000 n +0000033376 00000 n +0000034008 00000 n +0000034375 00000 n +0000034829 00000 n +0000036803 00000 n +0000040277 00000 n +0000043999 00000 n +0000047672 00000 n +0000048049 00000 n +0000048431 00000 n +0000049179 00000 n +0000049951 00000 n +0000053448 00000 n +0000053823 00000 n +0000054198 00000 n +0000054661 00000 n +0000055038 00000 n +0000055415 00000 n +0000055801 00000 n +0000056256 00000 n +0000056634 00000 n +0000059041 00000 n +0000059419 00000 n +0000059883 00000 n +0000060341 00000 n +0000062989 00000 n +0000063372 00000 n +0000065941 00000 n +0000066324 00000 n +0000066868 00000 n +0000067326 00000 n +0000067813 00000 n +0000068196 00000 n +0000068596 00000 n +0000068994 00000 n +0000069394 00000 n +0000069794 00000 n +0000070188 00000 n +0000074082 00000 n +0000076487 00000 n +0000076866 00000 n +0000077251 00000 n +0000077625 00000 n +0000078001 00000 n +0000078378 00000 n +0000078756 00000 n +0000082213 00000 n +0000082766 00000 n +0000083170 00000 n +0000083569 00000 n +0000083973 00000 n +0000084374 00000 n +0000085173 00000 n +0000085612 00000 n +0000086006 00000 n +0000086400 00000 n +0000086794 00000 n +0000087163 00000 n +0000087541 00000 n +0000087922 00000 n +0000088285 00000 n +0000088648 00000 n +0000089019 00000 n +0000095728 00000 n +0000096109 00000 n +0000096487 00000 n +0000096871 00000 n +0000097256 00000 n +0000107020 00000 n +0000107770 00000 n +0000108150 00000 n +0000112689 00000 n +0000137574 00000 n +0000179336 00000 n +0000181484 00000 n +0000187937 00000 n +0000189073 00000 n +0000197786 00000 n +0000198567 00000 n +0000198879 00000 n +0000202349 00000 n +0000206979 00000 n +0000208123 00000 n +0000216739 00000 n +0000220396 00000 n +0000226380 00000 n +0000227663 00000 n +0000239725 00000 n +0000249833 00000 n +0000260198 00000 n +0000261950 00000 n +0000269368 00000 n +0000279027 00000 n +0000299621 00000 n +0000317879 00000 n +0000324001 00000 n +0000335070 00000 n +0000339354 00000 n +0000354646 00000 n +0000356215 00000 n +0000360527 00000 n +0000364680 00000 n +0000365825 00000 n +0000392866 00000 n +0000419498 00000 n +0000425438 00000 n +0000442504 00000 n +0000447161 00000 n +0000457625 00000 n +0000461198 00000 n +0000462309 00000 n +0000465206 00000 n +0000466116 00000 n +0000482652 00000 n +0000483685 00000 n +0000488598 00000 n +0000489850 00000 n +0000508232 00000 n +0000516419 00000 n +0000518226 00000 n +0000527802 00000 n +0000528990 00000 n +0000536281 00000 n +0000547215 00000 n +0000547538 00000 n +0000547862 00000 n +0000548184 00000 n +0000548508 00000 n +0000561439 00000 n +0000561813 00000 n +0000562187 00000 n +0000562573 00000 n +0000564025 00000 n +0000573344 00000 n +0000583499 00000 n +0000604261 00000 n +0000614384 00000 n +0000621998 00000 n +0000632428 00000 n +0000635278 00000 n +0000636149 00000 n +0000637421 00000 n +0000638222 00000 n +0000645595 00000 n +0000648413 00000 n +0000656270 00000 n +0000658806 00000 n +0000667898 00000 n +0000671775 00000 n +0000678269 00000 n +0000692039 00000 n +0000694009 00000 n +0000699645 00000 n +0000700199 00000 n +0000701817 00000 n +0000706409 00000 n +0000707548 00000 n +0000717962 00000 n +0000719515 00000 n +0000732133 00000 n +0000733315 00000 n +0000755651 00000 n +0000766618 00000 n +0000770127 00000 n +0000771115 00000 n +0000778310 00000 n +0000779532 00000 n +0000783650 00000 n +0000784611 00000 n +0000788827 00000 n +0000789768 00000 n +0000800871 00000 n +0000801240 00000 n +0000802380 00000 n +0000804771 00000 n +0000805648 00000 n +0000816666 00000 n +0000825274 00000 n +0000837808 00000 n +0000838901 00000 n +0000842359 00000 n +0000843546 00000 n +0000853796 00000 n +0000871824 00000 n +0000887003 00000 n +0000897380 00000 n +0000907007 00000 n +0000923984 00000 n +0000939115 00000 n +0000949015 00000 n +0000950964 00000 n +0000971600 00000 n +0000992131 00000 n +0000996503 00000 n +0001009478 00000 n +0001062207 00000 n +0001072951 00000 n +0001078858 00000 n +0001081313 00000 n +0001082276 00000 n +0001085116 00000 n +0001088973 00000 n +0001095062 00000 n +0001101026 00000 n +0001101155 00000 n +0001101295 00000 n +0001101405 00000 n +0001101590 00000 n +0001101871 00000 n +0001102179 00000 n +0001102488 00000 n +0001102799 00000 n +0001103107 00000 n +0001103475 00000 n +0001103864 00000 n +0001104143 00000 n +0001104420 00000 n +0001104722 00000 n +0001105002 00000 n +0001105281 00000 n +0001105563 00000 n +0001105861 00000 n +0001106142 00000 n +0001106423 00000 n +0001106725 00000 n +0001107023 00000 n +0001107332 00000 n +0001107641 00000 n +0001107952 00000 n +0001108251 00000 n +0001108563 00000 n +0001108872 00000 n +0001109181 00000 n +0001109490 00000 n +0001109801 00000 n +0001110112 00000 n +0001110418 00000 n +0001110729 00000 n +0001111040 00000 n +0001111350 00000 n +0001111661 00000 n +0001111971 00000 n +0001112282 00000 n +0001112590 00000 n +0001112900 00000 n +0001113210 00000 n +0001113518 00000 n +0001113824 00000 n +0001114132 00000 n +0001114443 00000 n +0001114752 00000 n +0001115062 00000 n +0001115372 00000 n +0001115645 00000 n +0001115921 00000 n +0001116231 00000 n +0001116542 00000 n +0001116852 00000 n +0001117127 00000 n +0001117405 00000 n +0001117686 00000 n +0001117996 00000 n +0001118307 00000 n +0001118679 00000 n +0001118960 00000 n +0001119355 00000 n +0001119575 00000 n +0001119858 00000 n +0001120145 00000 n +0001120427 00000 n +0001120714 00000 n +0001121024 00000 n +0001121334 00000 n +0001121611 00000 n +0001121866 00000 n +0001122126 00000 n +0001122277 00000 n +0001122403 00000 n +0001122546 00000 n +0001122664 00000 n +0001122825 00000 n +0001122964 00000 n +0001154320 00000 n +0001154664 00000 n +0001154718 00000 n +0001155120 00000 n +0001155174 00000 n +0001155519 00000 n +0001155573 00000 n +0001155916 00000 n +0001155970 00000 n +0001156314 00000 n +0001156769 00000 n +0001157116 00000 n +0001157170 00000 n +0001157516 00000 n +0001157570 00000 n +0001157917 00000 n +0001157971 00000 n +0001158323 00000 n +0001158377 00000 n +0001158728 00000 n +0001158782 00000 n +0001159134 00000 n +0001159188 00000 n +0001159552 00000 n +0001159606 00000 n +0001159968 00000 n +0001160022 00000 n +0001160366 00000 n +0001160420 00000 n +0001160763 00000 n +0001160817 00000 n +0001161162 00000 n +0001161216 00000 n +0001161562 00000 n +0001161616 00000 n +0001161962 00000 n +0001162016 00000 n +0001162362 00000 n +0001162416 00000 n +0001162847 00000 n +0001162901 00000 n +0001163268 00000 n +0001163322 00000 n +0001163673 00000 n +0001163727 00000 n +0001164094 00000 n +0001164148 00000 n +0001164520 00000 n +0001164574 00000 n +0001165107 00000 n +0001165161 00000 n +0001165506 00000 n +0001165572 00000 n +0001165902 00000 n +0001165968 00000 n +0001166299 00000 n +0001166365 00000 n +0001166695 00000 n +0001166761 00000 n +0001167074 00000 n +0001167140 00000 n +0001167451 00000 n +0001167517 00000 n +0001167861 00000 n +0001167915 00000 n +0001168260 00000 n +0001168314 00000 n +0001168532 00000 n +0001168874 00000 n +0001168928 00000 n +0001169272 00000 n +0001169326 00000 n +0001169478 00000 n +0001169617 00000 n +0001169737 00000 n +0001169848 00000 n +0001169974 00000 n +0001170112 00000 n +0001170420 00000 n +0001170638 00000 n +0001171034 00000 n +0001171252 00000 n +0001172157 00000 n +0001172307 00000 n +0001172453 00000 n +0001172590 00000 n +0001172707 00000 n +0001172839 00000 n +0001181515 00000 n +0001194814 00000 n +0001194961 00000 n +0001195105 00000 n +0001195234 00000 n +0001195381 00000 n +0001195522 00000 n +trailer +<< +/ID [ ] +/Info 1 0 R +/Root 2 0 R +/Size 522 +>> +startxref +1195669 +%%EOF diff --git a/ProgettoRestylingWall/design2machine.url b/ProgettoRestylingWall/design2machine.url new file mode 100644 index 0000000..ab8eef8 --- /dev/null +++ b/ProgettoRestylingWall/design2machine.url @@ -0,0 +1,5 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 +[InternetShortcut] +IDList= +URL=https://www.design2machine.com/ diff --git a/ProgramData/EgtBeamWall/Config/BTLFeatures.ini b/ProgramData/EgtBeamWall/Config/BTLFeatures.ini new file mode 100644 index 0000000..1abffd3 --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/BTLFeatures.ini @@ -0,0 +1,847 @@ +; PIndex = Type, PName, Min, Max, Default, Description +; QIndex = Type, QName, Min, Max, Default, Description +; Type : d=double, l=length, s=string + +[Processings] +0=10,12,13,16,17,20,25,30,32,33,34,36,37,38,39,40,50,51,52,53,55,56,60,61,80,90,100,101,102,103,104,106,107,120,136,138,250,251,252 +1=10,11,30,35,50,55,70,71,80,136,138 + +;Cut +[1.10] +GRP=1,2 +PRC=10 +NAME=60951 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,0,50000,0,61002 +P3=d,P03,0,50000,0,61003 +P4=d,P06,0.1,179.9,90,61004 +P5=d,P07,0.1,179.9,90,61005 +QB1=d,Q04,0,1,0,0=Automatico 1=Non staccare scarto di taglio +QB2=d,Q05,0,1,0,0=Automatico 1=Lama + Truciolatore +QB3=l,Q06,0,40,0,61451, Profondità smusso + +;Longitudinal Cut +[0.10] +GRP=0,3,4 +PRC=10 +NAME=60952 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,20,61002 +P3=d,P04,0,7,0,61008 +P4=d,P07,-90,90,45,61009 +P5=d,P11,0,50000,0,61010 +P6=d,P12,0,99999,0,61011 +P7=d,P13,1,179,90,61012 +P8=d,P14,1,179,90,61013 +QB1=d,Q05,0,4,0,61500, 0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +QB2=d,Q07,0,1,0,61501, 0=Automatico 1=Lavorazione con fresa orizzontale se sopra o sotto (disabilita lama) + +;Double Cut +[1.11] +GRP=1,2 +PRC=11 +NAME=60953 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,50,61015 +P3=d,P06,1,179,45,61016 +P4=d,P07,1,179,90,61017 +P5=d,P08,1,179,90,61018 +P6=d,P09,1,179,90,61019 +QB1=l,Q06,0,40,0,61451, Profondità smusso + +;Ridge or Valley Cut +[0.12] +GRP=0 +PRC=12 +NAME=60954 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,0,50000,50,61015 +P3=d,P04,0,7,0,61008 +P4=d,P07,-89,89,45,61023 +P5=d,P09,-89,89,45,61024 +P6=d,P11,-99999,99999,0,61025 +P7=d,P12,0,99999,0,61011 +P8=d,P13,1,179,90,61027 +P9=d,P14,1,179,90,61028 +P10=d,P15,1,179,90,61029 +P11=d,P16,1,179,90,61030 +QB1=d,Q01,0,1,0,61497, 0=Automatico 1=Lama +QB2=d,Q03,0,1,0,61502, 0=Automatico 1=Usa truciolatore se sotto +QW1=d,Q02,0,2,0,61504, 0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra + +;Saw Cut +[0.13] +GRP=0,3,4 +PRC=13 +NAME=60955 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61015 +P3=d,P03,-50000,50000,0,61033 +P4=d,P06,-180,180,90,61004 +P5=d,P07,1,179,90,61009 +P6=d,P08,-89,89,0,61036 +P7=d,P11,0,50000,50,61037 +P8=d,P12,1,99999,50,61038 +QB1=d,Q01,0,1,0,61503, 0=Attacco e uscita centrati 1=Attacco e uscita interni +QB2=d,Q02,0,1,0,61505, 0=Automatico; 1=Lavora come Taglio Longitudinale + +;Slot +[0.16] +GRP=3,4 +PRC=16 +NAME=60956 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61002 +P3=d,P03,0,50000,0,61041 +P4=d,P04,0,63,0,61042 +P5=d,P06,-90,90,0,61043 +P6=d,P07,1,179,90,61009 +P7=d,P08,1,179,90,61045 +P8=d,P09,1,179,90,61046 +P9=d,P10,1,179,0,61047 +P10=d,P11,1,50000,100,61048 +P11=d,P12,1,99999,200,61049 +P12=d,P13,1,50000,10,61050 +P13=d,P14,-50000,50000,0,61051 +P14=d,P15,-50000,50000,0,61052 +QB1=d,Q01,0,1,0,61497, 0=Automatico; 1=Lama +QB2=l,Q04,0,40,0,61451, Profondità smusso +QB3=d,Q05,0,1,0,61457, 1=Solo smusso +QB4=d,Q10,0,500,0,61496, Massima elevazione (0=Automatico, altrimenti manuale) +QW1=d,Q03,0,2,0,61504, 0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra + +;Front Slot +[0.17] +GRP=3,4 +PRC=17 +NAME=60957 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61015 +P3=d,P03,0,50000,0,61055 +P4=d,P04,0,63,0,61056 +P5=d,P06,1,179,90,61004 +P6=d,P07,1,179,90,61009 +P7=d,P08,0,360,90,61059 +P8=d,P11,0,50000,20,61060 +P9=d,P12,0,50000,40,61061 +P10=d,P13,0,50000,40,61062 + +;Birds Mouth +[0.20] +GRP=3,4 +PRC=20 +NAME=60958 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61002 +P3=d,P04,-1,12,-1,61065 +P4=d,P05,0,1,0,61066 +P5=d,P06,1,179,90,61067 +P6=d,P07,0,180,45,61068 +P7=d,P08,0,180,135,61069 +P8=d,P09,0,179,0,61070 +P9=d,P10,0,179,0,61071 +P10=d,P11,0,50000,20,61072 +P11=d,P12,0,50000,20,61073 +P12=d,P13,0,50000,0,61074 +P13=d,P14,0,50000,0,61075 +P14=d,P15,0,50000,0,61076 +QB1=l,Q01,0,30,0,61451, Profondità smusso +QB2=d,Q02,0,1,0,61506, 0=Automatico 1=Lavorazione con fresa +QB3=d,Q03,0,1,0,61485, 0=Automatico; 1=Truciolatore + +;Hip or Valley Rafter Notch +[0.25] +GRP=3,4 +PRC=25 +NAME=60959 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61002 +P3=d,P05,0,1,0,61079 +P4=d,P06,1,179,45,61080 +P5=d,P07,1,179,45,61081 +P6=d,P08,0,180,30,61082 +P7=d,P11,0,50000,20,61083 +P8=d,P14,0,50000,0,61084 +P9=d,P15,0,50000,0,61085 + +;Ridge Lap +[1.30] +GRP=1,2 +PRC=30 +NAME=60960 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,0,1,0,61087 +P3=d,P06,1,179,90,61088 +P4=d,P11,1,50000,50,61089 +P5=d,P12,1,50000,100,61090 +P6=d,P13,0,1000,0,61091 +QB1=l,Q01,0,30,0,61451, Profondità smusso + +;Lap Joint +[0.30] +GRP=3,4 +PRC=30 +NAME=60961 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61002 +P3=d,P03,0,50000,0,61094 +P4=d,P04,0,63,0,61095 +P5=d,P06,1,179,90,61096 +P6=d,P07,1,179,90,61009 +P7=d,P08,-89,89,0,61098 +P8=d,P09,0,179,0,61099 +P9=d,P10,0,179,0,61100 +P10=d,P11,-50000,50000,50,61101 +P11=d,P12,1,99999,100,61102 +P12=d,P13,0,89,0,61103 +P13=d,P14,0,50000,0,61104 +QB1=d,Q01,0,2,0,61460, 0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +QB2=d,Q02,0,1,0,61470, 0=Automatico; 1=Solo contorno +QB3=d,Q03,0,1,0,61455, 0=Automatico; 1=Lavorazione con fresa di lato +QB4=d,Q04,0,4,0,61499, 0=Automatico; 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +QB5=d,Q06,0,2,0,61467, Antischeggia: 0=No; 1=Con lama; 2=Con fresa +QB6=l,Q07,0,30,0,61451, Profondità smusso +QB7=d,Q10,0,500,0,61496, Massima elevazione (0=Automatico, altrimenti manuale) +QW1=d,Q05,0,3,0,61469, Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico +QW2=d,Q08,0,2,0,61504, 0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra + +;Notch/Rabbet +[0.32] +GRP=3,4 +PRC=32 +NAME=60962 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61002 +P3=d,P04,0,63,0,61107 +P4=d,P11,0,50000,20,61108 +P5=d,P12,0,99999,20,61109 +P6=d,P13,1,50000,200,61110 +QB1=d,Q01,0,1,0,61455, 0=Automatico 1=Lavorazione con fresa di lato +QB2=d,Q02,0,2,0,61460, 0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +QB3=d,Q06,0,2,0,61467, Antischeggia : 0=No; 1=Con lama; 2=Con fresa +QB4=d,Q10,0,500,0,61496, Massima elevazione (0=Automatico, altrimenti manuale) +QW1=d,Q03,0,2,0,61504, 0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +QW2=d,Q05,0,3,0,61469, Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico + +;Block House Half Lap, Stairs Riser Dado +[0.33] +GRP=3,4 +PRC=33 +NAME=60963 +P1=d,P01,-99999,99999,0,61001 +P2=d,P06,1,179,90,61004 +P3=d,P11,0,50,20,61113 +P4=d,P12,0,50,20,61114 +P5=d,P13,1,50000,50,61115 +QB1=d,Q06,0,2,0,61467, Antischeggia : 0=No; 1=Con lama; 2=Con fresa + +;Seathing Cut +[0.34] +GRP=3,4 +PRC=34 +NAME=60964 +P1=d,P01,-99999,99999,0,61001 +P2=d,P11,0,99999,1,61117 +P3=d,P12,1,99999,500,61118 +QB1=d,Q01,0,2,0,61460, 0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +QB2=d,Q06,0,2,0,61467, Antischeggia : 0=No; 1=Con lama; 2=Con fresa +QB3=d,Q10,0,500,0,61496, Massima elevazione (0=Automatico, altrimenti manuale) + +;French Ridge Lap +[1.35] +GRP=1,2 +PRC=35 +NAME=60965 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,0,1,0,61120 +P3=d,P06,1,179,90,61121 +P4=d,P13,0,1000,0,61122 + +;Chamfer +[0.36] +GRP=3,4 +PRC=36 +NAME=60966 +P1=d,P01,-99999,99999,0,61001 +P2=d,P04,0,15,1,61124 +P3=d,P11,1,50,10,61125 +P4=d,P12,0,99999,500,61126 +P5=d,P15,0,2,0,61127 +QB1=d,Q01,0,6,0,61489, Numero divisioni ondulazioni dello smusso sulla lunghezza + +;Block House Half Lap +[0.37] +GRP=4 +PRC=37 +NAME=60967 +P1=d,P01,-99999,99999,0,61001 +P2=d,P03,0,50000,0,61129 +P3=d,P04,0,2,0,61130 +P4=d,P05,0,1,0,61131 +P5=d,P08,0,50000,10,61132 +P6=d,P09,0,50000,100,61133 +P7=d,P10,0,50000,10,61134 +P8=d,P11,0,50000,100,61135 +P9=d,P12,0,50000,10,61136 +P10=d,P13,0,50000,100,61137 +P11=d,P14,0,50000,10,61138 +P12=d,P15,0,50000,100,61139 +P13=d,P16,0,50000,50,61140 +P14=d,P17,0,50000,50,61141 +P15=d,P18,0,50000,50,61142 +P16=d,P19,0,15,0,61143 +QB1=d,Q06,0,2,0,61467, Antischeggia: 0=No; 1=Con lama; 2=Con fresa + +;Block House Front +[0.38] +GRP=3,4 +PRC=38 +NAME=60968 +P1=d,P01,-99999,99999,0,61001 +P2=d,P04,0,1,0,61145 +P3=d,P06,1,179,90,61146 +P4=d,P11,-50000,50000,15,61147 +P5=d,P12,-50000,50000,10,61148 +P6=d,P13,-50000,50000,25,61149 +P7=d,P15,0,50000,100,61150 + +;Pocket +[0.39] +GRP=4 +PRC=39 +NAME=60969 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61002 +P3=d,P04,0,63,0,61153 +P4=d,P06,-179,179,0,61154 +P5=d,P07,-179,179,0,61155 +P6=d,P08,-179,179,0,61156 +P7=d,P10,1,179,90,61157 +P8=d,P11,-50000,50000,20,61158 +P9=d,P12,1,50000,20,61159 +P10=d,P13,0,50000,100,61160 +QB1=d,Q01,0,2,0,61460, 0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +QB2=d,Q02,0,1,0,61506, 0=Automatico 1=Lavorazione con fresa +QB3=d,Q06,0,2,0,61467, Antischeggia : 0=No; 1=Con lama; 2=Con fresa +QW1=d,Q03,0,2,0,61504, 0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +QW2=d,Q05,0,3,0,61469, Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico + +;Drilling +[0.40] +GRP=3,4 +PRC=40 +NAME=60970 +P1=d,P01,-99999,99999,50,61001 +P2=d,P02,-50000,50000,50,61002 +P3=d,P03,-99999,99999,0,61163 +P4=d,P06,0,360,90,61164 +P5=d,P07,1,179,90,61165 +P6=d,P11,0,50000,50,61166 +P7=d,P12,0,50000,20,61167 +QB1=d,Q01,0,1,0,61470, 0=Automatico; 1=Solo contorno ; 2=Svuota +QB2=d,Q02,0,1,0,61471, 0=Automatico; 1=Fora da un solo lato +QW1=d,Q01,0,1,0,61470, 0=Automatico; 1=Solo contorno ; 2=Svuota + +;Tenon +[1.50] +GRP=1,2 +PRC=50 +NAME=60971 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,50,61002 +P3=d,P04,0,4,0,61170 +P4=d,P05,0,1,0,61171 +P5=d,P06,1,179,90,61004 +P6=d,P07,1,179,90,61005 +P7=d,P08,1,179,90,61174 +P8=d,P10,0,500,0,61175 +P9=d,P11,1,1000,40,61176 +P10=d,P12,1,1000,40,61177 +P11=d,P14,-50000,50000,0,61178 +P12=d,P15,-50000,50000,0,61179 +QB1=l,Q01,0,30,0,61451, Profondità smusso +QB2=l,Q02,0,30,0,61475, Riduzione profondità tenone +QB3=l,Q03,0,30,0,61476, Riduzione larghezza tenone +QB4=l,Q04,0,30,0,61477, Riduzione altezza tenone + +;Mortise +[0.50] +GRP=3,4 +PRC=50 +NAME=60972 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,50,61002 +P3=d,P03,0,50000,0,61182 +P4=d,P04,0,4,0,61183 +P5=d,P06,-180,180,90,61184 +P6=d,P07,1,179,90,61185 +P7=d,P08,1,179,90,61186 +P8=d,P10,0,500,0,61187 +P9=d,P11,0,1000,40,61188 +P10=d,P12,0,1000,40,61189 +P11=d,P13,1,50000,200,61190 +P12=d,P14,-50000,50000,0,61191 +P13=d,P15,-50000,50000,0,61192 +P14=d,P16,1,179,90,61193 + +;Mortise Front +[0.51] +GRP=3,4 +PRC=51 +NAME=60973 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,50,61002 +P3=d,P04,0,4,90,61196 +P4=d,P06,1,179,90,61004 +P5=d,P07,1,179,90,61005 +P6=d,P08,1,179,90,61199 +P7=d,P10,0,500,0,61200 +P8=d,P11,1,1000,40,61201 +P9=d,P12,1,1000,40,61202 +P10=d,P14,-50000,50000,0,61203 +P11=d,P15,-50000,50000,0,61204 + +;House +[0.52] +GRP=3,4 +PRC=52 +NAME=60974 +P1=d,P01,-99999,99999,0,61168 +P2=d,P02,-50000,50000,50,61169 +P3=d,P04,0,4,90,61170 +P4=d,P06,1,179,90,61172 +P5=d,P07,1,179,90,61173 +P6=d,P08,1,179,90,61174 +P7=d,P09,0,99999,0,61205 +P8=d,P10,0,500,0,61175 +P9=d,P11,1,1000,40,61176 +P10=d,P12,1,1000,40,61177 +P11=d,P14,-50000,50000,0,61178 +P12=d,P15,-50000,50000,0,61179 + +;House Mortise +[0.53] +GRP=3,4 +PRC=53 +NAME=60975 +P1=d,P01,-99999,99999,0,61180 +P2=d,P02,-50000,50000,50,61181 +P3=d,P03,0,50000,0,61182 +P4=d,P04,0,4,90,61183 +P5=d,P06,-180,180,90,61184 +P6=d,P07,1,179,90,61185 +P7=d,P08,1,179,90,61186 +P8=d,P09,0,99999,0,61206 +P9=d,P10,0,500,0,61187 +P10=d,P11,0,1000,40,61188 +P11=d,P12,0,1000,40,61189 +P12=d,P13,1,50000,200,61190 +P13=d,P14,-50000,50000,0,61191 +P14=d,P15,-50000,50000,0,61192 +P15=d,P16,1,179,90,61193 + +;Dovetail Tenon +[1.55] +GRP=1,2 +PRC=55 +NAME=60976 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,50,61002 +P3=d,P04,0,1,0,61209 +P4=d,P06,1,179,90,61210 +P5=d,P07,1,179,90,61005 +P6=d,P08,1,179,90,61212 +P7=d,P09,0,1000,0,61213 +p8=d,P10,0,30,0,61214 +P9=d,P11,1,1000,28,61215 +P10=d,P12,-1000,1000,45,61216 +P11=d,P14,-50000,50000,0,61217 +P12=d,P15,-50000,50000,0,61218 +QB1=l,Q03,0,30,0,61475, Riduzione profondità tenone +QB2=l,Q04,0,30,0,61479, Ridurre/Allargare sagoma tenone +QB3=l,Q05,0,30,0,61480, Ridurre/Allargare altezza tenone + +;Dovetail Mortise +[0.55] +GRP=3,4 +PRC=55 +NAME=60977 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,50,61002 +P3=d,P03,0,50000,0,61221 +P4=d,P04,0,1,0,61222 +P5=d,P05,0,1,0,61223 +P6=d,P06,-180,180,0,61224 +P7=d,P07,1,179,90,61225 +P8=d,P09,0,1000,0,61226 +P9=d,P10,0,30,0,61227 +P10=d,P11,1,1000,28,61228 +P11=d,P12,-1000,1000,45,61229 +p12=d,P13,1,50000,200,61230 +p13=d,P14,-50000,50000,0,61231 +p14=d,P15,-50000,50000,0,61232 + +;Dovetail Mortise Front +[0.56] +GRP=3,4 +PRC=56 +NAME=60978 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,50,61002 +P3=d,P03,0,50000,0,61235 +P4=d,P04,0,1,0,61236 +P5=d,P05,0,1,0,61237 +P6=d,P06,1,179,90,61004 +P7=d,P07,1,179,90,61005 +P8=d,P08,1,179,90,61240 +P9=d,P09,0,1000,0,61241 +P10=d,P10,0,30,0,61242 +P11=d,P11,1,1000,28,61243 +P12=d,P12,0,1000,45,61244 +P13=d,P14,-50000,50000,0,61245 +P14=d,P15,-50000,50000,0,61246 + +;Marking/Labeling +[0.60] +GRP=3,4 +PRC=60 +NAME=60979 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61002 +P3=d,P04,0,19521,0,61249 +P4=d,P06,1,180,90,61250 +P5=d,P07,0,179,90,61251 +P6=d,P11,0,50000,100,61252 +P7=d,P12,0,50000,0,61253 +P8=d,P13,0,50000,200,61254 +P9=s,P15,,,,61255 + +;Text +[0.61] +GRP=4 +PRC=61 +NAME=60980 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61002 +P3=d,P06,-180,180,0,61258 +P4=d,P09,0,2,0,61259 +P5=d,P10,0,2,0,61260 +P6=d,P11,0,2,0,61261 +P7=d,P12,0,1,0,61262 +P8=d,P13,0,50000,200,61263 +P9=s,P15,,,,61255 + +;Simple Scarf +[1.70] +GRP=1,2 +PRC=70 +NAME=60981 +P1=d,P01,-50000,50000,0,61001 +P2=d,P11,0,50000,20,61266 +P3=d,P12,0,50000,20,61267 +P4=d,P13,1,50000,200,61268 +P5=d,P14,0,1000,0,61269 +P6=d,P15,0,1000,0,61270 +QB1=l,Q01,0,30,0,61451, Profondità smusso + +;Scarf Joint +[1.71] +GRP=1,2 +PRC=71 +NAME=60982 +P1=d,P01,-99999,99999,0,61001 +P2=d,P07,0,90,0,61272 +P3=d,P09,-,1,1,1,61273 +P4=d,P10,0,50000,0,61274 +P5=d,P11,1,50000,20,61275 +P6=d,P12,0,50000,0,61276 +P7=d,P13,1,50000,200,61277 +P8=d,P14,0,1000,0,61278 +P9=d,P15,0,1000,0,61279 +QB1=l,Q01,0,30,0,61451, Profondità smusso +QB2=l,Q04,0,30,0,61484, Aumenta dimensioni P10 + +;Step Joint +[1.80] +GRP=1,2 +PRC=80 +NAME=60983 +P1=d,P01,-99999,99999,0,61001 +P2=d,P04,0,1,0,61281 +P3=d,P07,1,179,45,61282 +P4=d,P11,0,1000,20,61283 +P5=d,P12,0,1000,20,61284 +P6=d,P14,0,1000,0,61285 +P7=d,P15,0,1000,0,61286 +QB1=l,Q01,0,30,0,61451, Profondità smusso +QB2=d,Q02,0,1,0,61485, 0=Automatico; 1=Truciolatore +QB3=l,Q03,0,20,0,61486, Riduzione lunghezza P14 +QB4=l,Q04,0,20,0,61487, Riduzione larghezza P15 + +;Step Joint Notch +[0.80] +GRP=3,4 +PRC=80 +NAME=60984 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61002 +P3=d,P04,0,1,0,61289 +P4=d,P07,1,179,45,61290 +P5=d,P10,0,50000,50,61291 +P6=d,P11,0,1000,20,61292 +P7=d,P12,0,1000,20,61293 +P8=d,P13,1,50000,200,61294 +P9=d,P14,0,1000,0,61295 +P10=d,P15,0,1000,0,61296 + +;Planing +[0.90] +GRP=3,4 +PRC=90 +NAME=60985 +P1=d,P01,-99999,99999,0,61001 +P2=d,P04,1,15,15,61298 +P3=d,P11,0,50,1,61299 +P4=d,P12,-99999,99999,500,61300 + +;Profile Front +[0.100] +GRP=3,4 +PRC=100 +NAME=60986 +P1=d,P01,-99999,99999,0,61001 +P2=d,P03,-1000,1000,0,61002 +P3=d,P06,0,180,90,61303 +P4=d,P07,0,180,90,61304 +P5=d,P08,-180,180,0,61305 +P6=d,P11,-1000,1000,250,61306 +P7=d,P12,-1000,1000,250,61307 +QB1=l,Q01,0,10,0,61451, Profondità smusso +QB2=l,Q02,0,20,0,61488, Sovramateriale finitura +QB3=d,Q03,0,1,0,Solo smusso (1=si, 0=no) + +;Profile Head concave +[0.101] +GRP=3,4 +PRC=101 +NAME=60987 +P1=d,P01,-99999,99999,0,61001 +P2=d,P11,0,1000,120,61309 +P3=d,P12,-1000,1000,20,61310 +P4=d,P13,0,1000,20,61311 +P5=d,P14,-1000,1000,20,61312 +P6=d,P15,0,1000,20,61313 +QB1=l,Q01,0,10,0,61451, Profondità smusso +QB2=l,Q02,0,20,0,61488, Sovramateriale finitura +QB3=d,Q03,0,1,0,61490, 1=Disabilita fresatura gradini +QB4=d,Q04,0,1,0,Solo smusso (1=si, 0=no) + +;Profile Head convex +[0.102] +GRP=3,4 +PRC=102 +NAME=60988 +P1=d,P01,-99999,99999,0,61001 +P2=d,P11,0,1000,120,61315 +P3=d,P12,-1000,1000,20,61316 +P4=d,P13,0,1000,20,61317 +P5=d,P14,-1000,1000,20,61318 +P6=d,P15,0,1000,20,61319 +QB1=d,Q01,0,1,0,61457, 1=Solo smusso +QB2=l,Q02,0,30,0,61451, Profondità smusso +QB3=l,Q04,0,20,0,61488, Sovramateriale finitura +QB4=d,Q05,0,1,0,61490, 1=Disabilita fresatura gradini + +;Profile Head cambered +[0.103] +GRP=3,4 +PRC=103 +NAME=60989 +P1=d,P01,-99999,99999,0,61001 +P2=d,P10,0,50000,500,61321 +P3=d,P11,-1000,1000,40,61322 +P4=d,P12,-1000,1000,60,61323 +P5=d,P13,-1000,1000,10,61324 +P6=d,P14,-1000,1000,40,61325 +P7=d,P15,0,1,1,61326 +QB1=d,Q01,0,1,0,61491, 1=Attiva smusso superiore +QB2=d,Q02,0,1,0,61492, 1=Smusso superiore con lama +QB3=l,Q03,0,30,0,61451, Profondità smusso +QB4=l,Q04,0,20,0,61488, Sovramateriale finitura +QB5=d,Q05,0,1,0,61457, 1=Solo smusso + +;Round Arch +[0.104] +GRP=4 +PRC=107 +NAME=60990 +P1=d,P01,-99999,99999,0,61001 +P2=d,P11,-1000,1000,30,61328 +P3=d,P12,0,30000,500,61329 +QB1=l,Q01,0,20,0,61488, Sovramateriale finitura +QB2=l,Q02,0,50,8,61493, Spessore legno per supporto lavorazione +QB3=l,Q03,0,30,0,61451, Profondità smusso + +;Profile Head +[0.106] +GRP=3,4 +PRC=106 +NAME=60991 +P1=d,P01,-99999,99999,0,61001 +P2=d,P04,0,3,0,61331 +P3=d,P09,0,1000,20,61332 +P4=d,P10,0,1000,20,61333 +P5=d,P11,0,1000,10,61334 +P6=d,P12,0,1000,50,61335 +P7=d,P13,0,1000,50,61336 +P8=d,P14,0,1000,15,61337 +P9=d,P15,0,1000,20,61338 +P10=d,P16,0,1000,20,61339 +P11=d,P17,0,1000,10,61340 +P12=d,P18,0,1000,50,61341 +P13=d,P19,0,1000,50,61342 +P14=d,P20,0,1000,15,61343 +P15=d,P21,0,1000,20,61344 +P16=d,P22,0,1000,30,61345 +QB1=l,Q01,0,30,0,61451, Profondità smusso +QB2=d,Q02,0,1,0,61457, 1=Solo smusso +QB3=d,Q03,0,1,0,61490, 1=Disabilita fresatura gradini +QB4=l,Q04,0,20,0,61488, Sovramateriale finitura + +;Sphere +[0.107] +GRP=3,4 +PRC=107 +NAME=60992 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-99999,99999,50,61002 +P3=d,P03,-99999,99999,50,61348 +P4=d,P11,-99999,99999,50,61349 +P5=d,P12,0,99999,0,61350 +P6=d,P13,0,99999,P11,61351 + +;Triangle Cut +[0.120] +GRP=4 +PRC=120 +NAME=60993 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,-50000,50000,0,61002 +P3=d,P03,-50000,50000,0,61354 +P4=d,P10,-50000,50000,1,61355 +P5=d,P11,-50000,50000,0,61356 +P6=d,P12,-50000,50000,1,61357 +P7=d,P13,-50000,50000,-1,61358 +P8=d,P14,-50000,50000,0,61359 +P9=d,P15,-50000,50000,1,61360 + +;Tyrolean Dovetail +[1.136] +GRP=1,2 +PRC=136 +NAME=60994 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,0,50000,30,61362 +P3=d,P03,-50000,50000,50,61363 +P4=d,P04,0,1,0,61364 +P5=d,P05,-1,50000,0,61365 +P6=d,P06,1,179,90,61366 +P7=d,P07,0,50000,0,61367 +P8=d,P08,0,50000,0,61368 +P9=d,P09,0,45,15,61369 +P10=d,P11,0,50000,25,61370 +P11=d,P12,0,50000,0,61371 +P12=d,P13,0,50000,0,61372 +P13=d,P14,0,1,0,61373 +P14=d,P15,0,50000,50,61374 +P15=d,P16,0,2,0,61375 + +;Tyrolean Dovetail +[0.136] +GRP=3,4 +PRC=136 +NAME=60994 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,0,50000,30,61362 +P3=d,P03,-50000,50000,50,61363 +P4=d,P04,0,1,0,61364 +P5=d,P05,-1,50000,0,61365 +P6=d,P06,1,179,90,61366 +P7=d,P07,0,50000,0,61367 +P8=d,P08,0,50000,0,61368 +P9=d,P09,0,45,15,61369 +P10=d,P11,0,50000,25,61370 +P11=d,P12,0,50000,0,61371 +P12=d,P13,0,50000,0,61372 +P13=d,P14,0,1,0,61373 +P14=d,P15,0,50000,50,61374 +P15=d,P16,0,2,0,61375 + +;Dovetail +[1.138] +GRP=1,2 +PRC=138 +NAME=60995 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,0,50000,30,61377 +P3=d,P03,-50000,50000,50,61378 +P4=d,P04,0,1,0,61379 +P5=d,P05,-1,50000,0,61380 +P6=d,P09,0,45,15,61381 +P7=d,P11,0,50000,40,61382 +P8=d,P12,0,50000,20,61383 +P9=d,P14,0,1,0,61384 +P10=d,P15,0,50000,50,61385 +P11=d,P16,0,2,0,61386 + +;Dovetail +[0.138] +GRP=3,4 +PRC=138 +NAME=60995 +P1=d,P01,-99999,99999,0,61001 +P2=d,P02,0,50000,30,61377 +P3=d,P03,-50000,50000,50,61378 +P4=d,P04,0,1,0,61379 +P5=d,P05,-1,50000,0,61380 +P6=d,P09,0,45,15,61381 +P7=d,P11,0,50000,40,61382 +P8=d,P12,0,50000,20,61383 +P9=d,P14,0,1,0,61384 +P10=d,P15,0,50000,50,61385 +P11=d,P16,0,2,0,61386 + +;Free Contour +[0.250] +GRP=0,3,4 +PRC=250 +NAME=60996 +P1=d,P05,0,50000,0,61387 +P2=d,P07,0,1,0,61388 +P3=d,P13,0,200,0,61389 +P4=d,P14,0,10000,0,61390 +P5=d,P15,0,1000,0,61391 +QB1=l,Q01,0,50,0,61493, Spessore legno per supporto lavorazione +QB2=l,Q02,0,30,0,61451, Profondità smusso +QB3=l,Q03,0,20,0,61488, Sovramateriale finitura +QW1=d,Q05,0,3,0,61469, Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico + +;Outline +[0.251] +GRP=4 +PRC=251 +NAME=60997 +P1=d,P13,0,200,0,61389 +P2=d,P14,0,10000,0,61390 +P3=d,P15,0,1000,0,61391 +QW1=d,Q05,0,3,0,61469, Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico + +;Aperture +[0.252] +GRP=4 +PRC=252 +NAME=60998 +P1=d,P13,0,200,0,61389 +P2=d,P14,0,10000,0,61390 +P3=d,P15,0,1000,0,61391 +QW1=d,Q05,0,3,0,61469, Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico diff --git a/ProgramData/EgtBeamWall/Config/DataGridColumns.ini b/ProgramData/EgtBeamWall/Config/DataGridColumns.ini new file mode 100644 index 0000000..990a756 --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/DataGridColumns.ini @@ -0,0 +1,255 @@ +; DisplayIndex = Name, CanUserReorder, CanUserResize, CanUserSort, IsReadOnly, Width, DataGridLengthUnitType, Visible, CanUserEditVisible + +[DG_FeatureList] +0=colDO,1,1,1,0,30.4,1,1,1,0 +1=colCALC,0,1,0,0,32.8,1,1,1,0 +2=colDESC,1,1,1,1,1,4,1,1,0 + +[DG_OpenProjectFileDialog_PROJ] +0=colPROJID,1,1,1,1,34,1,1,1,0 +1=colBTLNAME,1,1,1,1,170,1,1,1,0 +2=colLISTNAME,1,1,1,1,79,1,1,1,0 +3=colEXPDATE,1,1,1,1,56,1,1,1,0 +4=colCRTDATE,1,1,1,1,113.8,1,1,1,0 +5=colMACHINE,1,1,1,1,20,1,1,1,0 + +[DG_OpenProjectFileDialog_PROD] +0=colPRODID,1,1,1,1,54.4,1,1,1,0 +1=colBTLNAME,1,1,1,1,154.850564,1,1,1,0 +2=colCRTDATE,1,1,1,1,144.698873,1,1,1,0 +3=colMACHINE,1,1,1,1,1,4,1,1,0 + +[DG_RawPartList_BEAM] +0=colNAME,1,1,1,1,28.8,1,1,1,0 +1=colCALC,1,1,0,0,22.05,1,1,1,0 +2=colSTARTCUT,1,1,1,0,95.993333,1,1,1,0 +3=colW,1,1,1,0,40.4,1,1,1,0 +4=colH,1,1,1,1,36.4,1,1,1,0 +5=colL,1,1,1,0,60,1,1,1,0 +6=colMATERIAL,1,1,1,1,102.643333,1,1,1,0 +7=colUSAGE,1,1,1,1,92.913333,1,1,1,0 +8=colWASTE,1,1,1,1,1,4,1,1,0 + +[DG_RawPartList_WALL] +0=colNAME,1,1,1,1,33.68,1,1,1,0 +1=colCALC,1,1,0,0,22.05,1,1,1,0 +2=colW,1,1,1,0,52.2,1,1,1,0 +3=colH,1,1,1,1,52.2,1,1,1,0 +4=colL,1,1,1,0,49,1,1,1,0 +5=colMATERIAL,1,1,1,1,105.6,1,1,1,0 +6=colUSAGE,1,1,1,1,197.8,1,1,1,0 +7=colWASTE,1,1,1,1,1,4,1,1,0 + +[DG_PartInRawPartList_BEAM] +0=colPDN,0,0,0,1,33.68,1,1,1,0 +1=colCALC,0,0,0,0,22.05,1,1,1,0 +2=colNAM,0,0,0,1,65,1,1,1,0 +3=colW,0,0,0,1,52.2,1,1,1,0 +4=colH,0,0,0,1,52.2,1,1,1,0 +5=colL,0,0,0,1,49,1,1,1,0 +6=colOFFSET,0,0,0,0,361,1,0,0 +7=colMATERIAL,0,0,0,1,20,1,1,1,0 +8=colGROUP,0,1,0,1,122.6,1,1,0,0 +9=colSTOREY,0,1,0,1,1,4,1,0,0 + +[DG_PartInRawPartList_WALL] +0=colPDN,0,0,0,1,33.68,1,1,1,0 +1=colCALC,0,0,0,0,22.05,1,1,1,0 +2=colNAM,0,0,0,1,65,1,1,1,0 +3=colW,0,0,0,1,52.2,1,1,1,0 +4=colH,0,0,0,1,52.2,1,1,1,0 +5=colL,0,0,0,1,49,1,1,1,0 +6=colROT,0,0,0,0,105.6,1,1,0,0 +7=colFLIP,0,0,0,0,197.8,1,1,0,0 +8=colPOSX,0,0,0,0,43.216477,1,1,0,0 +9=colPOSY,0,0,0,0,43.216477,1,1,0,0 +10=colMATERIAL,0,0,0,1,20,1,1,1,0 +11=colGROUP,0,0,0,1,131.6,1,1,0,0 +12=colSTOREY,0,0,0,1,1,4,1,0,0 + +[DG_PartList] +0=colPDN,0,0,1,1,35.28,1,1,0,1 +1=colCALC,0,1,0,1,41.68,1,1,0,0 +2=colDO,0,0,0,0,24.08,1,1,0,0 +3=colW,0,1,0,1,39.88,1,1,0,0 +4=colH,0,1,0,1,34.48,1,1,0,0 +5=colL,0,1,0,1,45.08,1,1,0,0 +6=colNAM,0,1,0,1,72.68,1,1,0,0 +7=colMATERIAL,0,1,0,1,61.68,1,1,0,0 +8=colCNT,0,1,0,1,35.88,1,1,0,0 +9=colADDED,0,1,0,0,26.68,1,1,0,0 +10=colINPROD,0,1,0,1,28.48,1,1,0,0 +11=colDONE,0,1,0,1,30,1,1,0,0 +12=colGROUP,0,0,0,1,126.6,1,1,0,0 +13=colSTOREY,0,1,0,1,66.455633,1,1,0,0 + +[DG_FeatureInPartInRawPartList] +0=colDO,0,0,0,0,30.4,1,1,0,0 +1=colCALC,0,0,0,0,28.8,1,1,0,0 +2=colDESC,0,0,0,1,1,4,1,0,0 + +[DG_Statistics] +0=colPDN,0,0,0,1,35.28,1,1,0 +1=colW,0,0,0,1,41.68,1,1,0 +2=colH,0,0,0,1,44.08,1,1,0 +3=colL,0,0,0,1,48.08,1,1,0 +4=colDESC,0,0,0,1,285.28,1,1,0 +5=colMATERIAL,0,0,0,1,63.68,1,1,0 +6=colCNT,0,0,0,1,54.88,1,1,0 +7=colADDED,0,0,0,0,55.68,1,1,0 +8=colINPROD,0,0,0,1,84.48,1,1,0 +9=colDONE,0,0,0,1,56,1,1,0 +10=colUNITVOLUME,0,0,0,1,108,1,1,0 +11=colTOTVOLUME,0,0,0,1,114.08,1,1,0 +12=colUNITTIME,0,0,0,1,98.08,1,1,0 +13=colTOTTIME,0,0,0,1,57.6,4,1,0 + +[DG_OptimizerStatistics] +0=colNAME,0,0,0,1,39.28,1,1,0 +1=colW,0,0,0,1,69.68,1,1,0 +2=colH,0,0,0,1,70.48,1,1,0 +3=colL,0,0,0,1,64.08,1,1,0 +4=colMATERIAL,0,0,0,1,248.48,1,1,0 +5=colUSAGE,0,0,0,1,268.48,1,1,0 +6=colWASTE,0,0,0,1,248.72,1,1,0 +7=colUNITTIME,0,0,0,1,98.08,4,1,0 + +[DG_RawPartStatistics] +0=colW,0,0,0,1,69.68,1,1,0 +1=colH,0,0,0,1,70.48,1,1,0 +2=colL,0,0,0,1,64.08,1,1,0 +3=colMATERIAL,0,0,0,1,248.48,4,1,0 +4=colQTY,0,0,0,1,98.08,1,1,0 + +[DG_BeamMachinings] +0=colON,0,0,0,0,29.6,1,1,0,0 +1=colNAME,0,0,0,0,211.2,1,1,0,0 +2=colTYPE,0,0,0,0,1,4,1,0,0 + +[DG_RawPartList_SUPERVISOR] +0=colNAME,0,0,0,1,33.8,1,1,0,0 +1=colPRODUCE,0,0,0,0,28,1,1,0,0 +2=colCALC,0,0,0,0,26.4,1,1,0,0 +3=colPRODUCTION,0,0,0,0,24.8,1,1,0,0 +4=colSTARTCUT,0,0,0,1,66.4,1,1,0,0 +5=colW,0,0,0,1,52.2,1,1,0,0 +6=colH,0,0,0,1,47.52,1,1,0,0 +7=colL,0,0,0,1,43.52,1,1,0,0 +8=colMATERIAL,0,0,0,1,69.72,1,1,0,0 +9=colUSAGE,0,0,0,1,68.32,1,1,0,0 +10=colWASTE,0,0,0,1,1,4,1,0,0 + +[DG_PartInRawPartList_SUPERVISOR] +0=colREDO,0,0,0,0,28.8,1,0,0 +1=colPDN,0,0,0,1,24.32,1,1,0,0 +2=colCALC,0,0,0,0,22.05,1,1,0,0 +3=colPRODUCTION,0,0,0,0,22.05,1,1,0,0 +4=colNAM,0,0,1,1,47.52,1,1,0,0 +5=colW,0,0,0,1,41.12,1,1,0,0 +6=colH,0,0,0,1,38.72,1,1,0,0 +7=colL,0,0,0,1,40.32,1,1,0,0 +8=colOFFSET,0,0,0,1,361,1,0,0 +9=colROT,0,0,0,1,105.6,1,1,0,0 +10=colFLIP,0,0,0,1,197.8,1,1,0,0 +11=colPOSX,0,0,0,1,43.216477,1,1,0,0 +12=colPOSY,0,0,0,1,43.216477,1,1,0,0 +13=colMATERIAL,0,0,1,1,20,1,1,0,0 +14=colGROUP,0,1,0,1,65.6,1,1,0,0 +15=colSTOREY,0,1,0,1,471.6,1,1,0,0 + +;[DG_PartInRawPartList_SUPERVISOR] +;0=colPDN,0,0,0,1,33.68,1,1,0 +;1=colCALC,0,0,0,0,22.05,1,1,0 +;2=colNAM,0,0,1,1,65,1,1,0 +;3=colW,0,0,0,1,52.2,1,1,0 +;4=colH,0,0,0,1,52.2,1,1,0 +;5=colL,0,0,0,1,49,1,1,0 +;6=colROTATED,0,0,0,1,49,1,1,0 +;7=colINVERTED,0,0,0,1,49,1,1,0 +;8=colPOSX,0,0,0,1,49,1,1,0 +;9=colOFFSET,0,0,0,1,361,1,1,0 +;10=colMATERIAL,0,0,1,1,43.216477,4,1,0 + +[DG_FeatureInPartInRawPartList_SUPERVISOR] +0=colREDO,0,0,0,0,28.8,1,1,0,0 +1=colCALC,0,0,0,0,28.8,1,1,0,0 +2=colDESC,0,0,0,1,0.606414,4,1,0 + +[DG_ParameterList_P] +0=colNAME,0,0,0,1,48,1,1,0,0 +1=colDESC,0,0,0,1,607.2,1,1,0,0 +2=colVALUE,0,0,0,0,70.6,1,1,0,0 +3=colMIN,0,0,0,1,69.8,1,1,0,0 +4=colMAX,0,0,0,1,1,4,1,0,0 + +[DG_ParameterList_Q] +0=colCUSTOM,0,0,0,0,52,1,1,0,0 +1=colNAME,0,0,0,1,46.4,1,1,0,0 +2=colDESC,0,0,0,1,572,1,1,0,0 +3=colVALUE,0,0,0,0,61.8,1,1,0,0 +4=colMIN,0,0,0,1,63.4,1,1,0,0 +5=colMAX,0,0,0,1,1,4,1,0,0 + +[DG_DuploParameterList_Q] +0=colNAME,0,0,0,1,100,1,1,0,0 +1=colDESC,0,0,0,1,200,1,1,0,0 +2=colVALUE,0,0,0,0,100,1,1,0,0 +3=colMIN,0,0,0,1,100,1,1,0,0 +4=colMAX,0,0,0,1,20,1,1,0,0 + +[DG_SParamList_BEAM] +0=colACTIVE,0,0,0,0,20,1,1,0,0 +1=colSECTXMAT,0,0,0,0,124.32,1,1,0,0 +2=colL,0,0,0,0,41.12,1,1,0,0 +3=colQTY,0,0,0,0,1,4,1,0,0 + +[DG_SParamList_WALL] +0=colACTIVE,0,0,0,0,20,1,1,0,0 +1=colSECTXMAT,0,0,1,0,124.32,1,1,0,1 +2=colW,0,0,1,0,40.32,1,1,0,0 +3=colL,0,0,1,0,40.32,1,1,0,0 +4=colQTY,0,0,1,0,1,4,1,0,0 + +[DG_SectXMatList_BEAM] +0=colSECTXMAT,1,1,1,0,149.12,1,1,0 +1=colALIAS,0,1,1,0,67.52,1,1,0 +2=colL,0,1,1,0,67.52,1,1,0 +3=colMATERIAL,0,1,1,0,134.72,1,1,0 +4=colQTY,0,1,1,0,70.32,4,1,0 + +[DG_SectXMatList_WALL] +0=colSECTXMAT,1,1,1,0,128.896,1,1,0 +1=colALIAS,0,1,0,0,61.92,1,1,0 +2=colW,0,1,1,0,67.84,1,1,0 +3=colL,0,1,1,0,65.92,1,1,0 +4=colMATERIAL,0,1,0,0,102.72,1,1,0 +5=colQTY,0,1,1,0,90.32,4,1,0 + +[DG_VariablesList] +0=colNAME,0,0,0,0,146.52,1,1,0 +1=colVARPATH,0,0,0,0,278.4,1,1,0 +2=colTYPE,0,0,0,0,30,4,1,0 + +[DG_MDICommands] +0=colCOMMAND,0,0,0,0,146.52,1,1,0 +1=colDESCRIPTION,0,0,0,0,278.4,4,1,0 + +[DG_UpdateBTLPartList] +0=colPDN,1,1,0,0,60.45,1,1,1,0 +1=colNAM,1,1,0,0,249.25,1,1,1,0 +2=colINSERT,1,1,0,1,81.87,1,1,1,0 + +;[DG_ParameterList] +;0=colCUSTOM,0,0,0,0,29.6,1,1,0 +;1=colNAME,0,0,0,1,211.2,1,1,0 +;2=colDESC,0,0,0,1,0.606414,4,1,0 +;3=colVALUE,0,0,0,0,52.2,1,1,0 +;4=colMIN,0,0,0,1,52.2,1,1,0 +;5=colMAX,0,0,0,1,49,4,1,0 + +;[DG_QParamList] +;0=colNAME,0,0,0,1,33.68,1,1,0 +;1=colDESC,0,0,0,0,22.05,1,1,0 +;2=colDEFAULT,0,0,0,0,52.2,1,1,0 +;3=colMIN,0,0,0,1,52.2,1,1,0 +;4=colMAX,0,0,0,1,49,4,1,0 diff --git a/ProgramData/EgtBeamWall/Config/Dimensions.ini b/ProgramData/EgtBeamWall/Config/Dimensions.ini new file mode 100644 index 0000000..c36a4dc --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/Dimensions.ini @@ -0,0 +1,43 @@ +; Index, DimensionType (0 = COLUMN, 1 = ROW), GridLength, GridUnitType (1 = Pixel, 2 = Star) + +[Project_View] +0=0,0,513.655633,2 +1=2,0,1465.744367,2 +2=1,1,702.223627,2 +3=3,1,310.816373,2 + +[Project_Optimizer] +0=0,0,388.767822,2 +1=2,0,1450.232178,2 +2=1,1,447.275899,2 +3=3,1,493.764101,2 + +[LeftPanel_View] +0=1,1,323.337225,2 +1=3,1,304.822775,2 + +[LeftPanel_Optimizer] +0=1,1,371.895729,2 +1=3,1,256.264271,2 + +[TopPanel_Optimizer] +0=0,0,761.9,2 +1=2,0,325.966667,2 +2=0,1,267.710343,2 +3=2,1,227.053758,2 +4=0,1,354.635738,2 +5=2,1,94.635738,2 + +[LeftPanel_Supervisor] +0=1,1,168,2 +1=3,1,200.24,2 + +[Project_Supervisor] +0=0,0,627.390489,2 +1=2,0,517.609511,2 + +;[Project_View] +;0=0,0,339,1 +;1=2,0,1,2 +;2=1,1,342.52,2 +;3=3,1,341.52,2 diff --git a/ProgramData/EgtBeamWall/Config/EgalTechDeu.txt b/ProgramData/EgtBeamWall/Config/EgalTechDeu.txt new file mode 100644 index 0000000..9ec6be5 --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/EgalTechDeu.txt @@ -0,0 +1,3318 @@ +// Message File EgalTech Deutsche 2022/05/02 +0=DEU +// File +1=File +3=New +5=Open +6=Open
Recent files (Shift) +7=Insert +9=Save +11=Save as +13=Import +15=Export +17=Exec +19=Recent Files +20=Recent Scripts +// View +101=View +103=WFrame +105=HLine +107=Shading +109=ZoomAll +111=ZoomIn +113=ZoomOut +115=Top +117=Front +119=Right +121=Back +123=Left +125=Bottom +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Grid +136=SetView perpendicular to current Grid +137=CurveDir +139=Analyze +141=GetDist +// Grid +201=Grid +203=Top +205=Front +207=Right +209=Back +211=Left +213=Bottom +215=View +216=Set Grid perpendicular to View +217=Elevat +218=Set Grid Elevation +219=Origin +220=Set Grid Origin +221=Rotate +222=Rotate Grid
3D Rotate Grid (Shift) +223=3 Points +224=Set Grid from 3 Points +225=Perp +226=Set Grid Perpendicular to Object +227=Object +228=Set Grid from Object +// Draw +301=Draw +303=Point +304=Point
Vector (Shift)
Frame (Ctrl) +305=Line 2P +306=Line : 2 Points
Line : 2 Points with Continue (Ctrl) +307=LineSDL +308=Line : Start, Direction, Length
Line : Start, Direction Vector, Length (Shift) +309=Circle +310=Circle : Center, Point
Circle : Center, Diameter (Shift) +311=Fillet +312=Fillet : Radius
Chamfer : Dist (Shift) +313=Arc CSE +314=Arc : Center, Start, End +315=Arc 3P +316=Arc : 3 Points +317=Arc SDE +318=Arc : Start, Direction, End
Arc : Start, Direction Vector, End (Shift)
Arc : Start, Direction, End with Continue (Ctrl) +319=Rect 2P +320=Rectangle : 2 Points +321=Polygon +322=Polygon : Radius or Apothem
Polygon : Side with 2 Points (Shift) +323=Text +324=Text
Advanced Text (Shift) +399=Continue : 'L' with line, 'A' with arc +// Construct +401=Construct +403=Plane +404=Surface : between planar curves
Flat Region (Shift) +405=Extrude +406=Surface : curve extrusion +407=Revolve +408=Surface : curve revolution +409=Screw +410=Surface : curve screwing +411=Ruled +412=Surface : ruled between 2 curves +413=Merge +414=Merge Surfaces +415=Flip +416=Flip Surface Outside +417=Explode +418=Explode Surfaces or Flat Regions +419=Swept +420=Surface :sweeping a curve along another +// Edit +501=Edit +503=Delete +504=Delete Objects +505=Layer +506=Change Object Layer to Current +507=Color +508=Change Color
Remove Color (Shift)
Change Trasparency (Ctrl) +509=Invert +510=Invert Curve +511=Trim/Ext +512=Trim or Extend Curve +513=Break +514=Break Curve
Split Curve in Pieces (Shift) +515=Join +516=Join Curves
Join Curves making a Copy (Shift)
Merge Curves in Composite (Ctrl) +517=Explode +518=Explode Text or Curve in Components +519=Thick +520=Set Curve Thickness and Extrusion +521=Start +522=Change Closed Curve Start Point +// Transform +601=Transform +603=Move +604=Object Move +605=Rotate +606=Object Rotate
3D Object Rotate (Shift) +607=Mirror +608=Object Mirror
3D Object Mirror (Shift) +609=Scale +610=Object Scale
3D Object Scale (Shift) +611=Offset +612=Curve Offset +// Special +701=Special +703=Flat Parts +704=Insert DXF or NGE flat parts +705=Compo +706=Insert parametric components +// Scene : Entity selection Menu +1001=Alle auswählen +1003=Alle abwählen +1005=Fenster auswählen +1007=Teil auswählen +1009=Ebene auswählen +1011=Pfad auswählen +1013=Vollständigen Pfad auswählen +1015=Entität auswählen +1016=Alle sichtbaren auswählen +// Scene : Point selection Menu + Statusbar +1101=Skizzenpunkt +1102=Skizzenpunkt +1103=Gitterpunkt +1104=Gitterpunkt +1105=Endpunkt +1106=Endpunkt +1107=Mittelpunkt +1108=Mittelpunkt +1109=Mittelpunkt +1110=Mitte +1111=Schwerpunkt +1112=Schwerpunkt +1113=Nahpunkt +1114=Nahpunkt +1115=Schnittpunkt +1116=Inters Point +1117=Tangentenpunkt +1118=Tang Point +1119=Senkrechter Punkt +1120=Perp Point +1121=Min.Distance Point +1122=MinDist Point +1123=Oberflächen ausschließen +// Scene : Other Menu +1201=Drag Off +1203=Drag On +// Scene : Others +1301=Dist= +// Controller +2001=Copy (V) +2002=Error +2003=Warning +2051=The Point must be different from previous +2052=The Points must be not aligned +2053=Zero or Negative Values not allowed +2054=Two Zero or Negative Values not allowed +2055=At least one Entity is not scalable +2056=Distance too big +2057=Curve not flat (in its plane) +// Controller : Draw +2101= +// Controller : Construct +2201= +// Controller : Modify +2301= +// Controller : Transform +2401=COPY +2402=MOVE +2403=Insert Base Point +2404=Insert Target Point +2406=ROTATE +2407=Insert Center +2408=Insert Base Point +2409=Insert Angle or Rotation Point +2411=ROTATE 3D +2412=Insert First Point on Axis +2413=Insert Second Point on Axis +2414=Insert Base Point +2415=Insert Angle or Rotation Point +2416=MIRROR +2417=Insert First Point +2418=Insert Second Point +2421=MIRROR 3D +2422=Insert First Point +2423=Insert Second Point +2424=Insert Third Point +2426=SCALE +2427=Insert Center +2428=Insert Factor +2431=SCALE 3D +2432=Insert Center +2433=Insert Factors +2436=OFFSET +2437=Insert Distance +2438=Fillet +2439=Chamfer +2440=Extend +// ----- EgtCAM5 ----- +5001=ZEICHNEN +5002=BEARBEITUNG +5003=Werkzeug Db +5004=Bearbeitung Db +5005=Optionen +5006=Werk Db +5007=Mach Db +5008=Maschinenoptionen +5009=SetUp Db +5010=Konfiguration Db +5020=Bearbeitungstabelle Db +//Top CommandBar +5101=Neu +5102=Öffnen
Letzte Datei öffnen (rechte Schaltfläche) +5103=Speichern +5104=Speichern unter +5105=Einfügen +5106=Importieren +5107=Exportieren +5108=Skript ausführen
Aktuelles Skript ausführen (rechte Schaltfläche) +5109=Optionen +5110=Support-Adresse kann nicht gefunden werden. +5111=Aktuelle Datei speichern, bevor Feedback gesendet wird? +5112=Senden Sie ein Feedback an {0} mit dem angehängten Verzeichnis {1}. +5113=Feedback +5114=Feedback-Mail bereit. +//Draw Panel +5150=Freie Kanten von Oberflächen und flachen Regionen extrahieren +5151=Oberflächen und flache Regionen verbinden +5152=Oberflächen und flache Bereiche subtrahieren +5153=Schnittflächen und flache Bereiche +5154=Punkte, Kurven und Flächen vom Schnittpunkt der Oberflächen +5155=Lineare Bemaßung
Ausgerichtete Bemaßung (Verschiebung) +5156=Kreis 3 Punkte +5157=Kanten von Oberflächenflächen und flachen Regionen extrahieren Teile +5158=Fläche von Oberfläche extrahieren +5159=???Arc Flip
Arc Explementary (Shift) +5160=???Modify Shape +5161=???Add Point
Modify in Arc (Shift)
Close Curve Composite (Ctrl) +5162=???Remove Point
Modify in Line (Shift)
Open Curve Composite (Ctrl) +5163=???Approx Curve
Approx Curve with Lines (Shift) +5201=Punkt
Vektor (Verschiebung)
Rahmen (Strg) +5202=Linie 2 Punkte
Linie 2 Punkte mit Weiter (Strg) +5203=Linienpunktrichtungslänge
Linienpunktrichtungsvektorlänge (Verschiebung) +5204=Kreismittelpunkt +5205=Kreismitteldurchmesser +5206=Arc Center Start Endpunkte +5207=Bogen 3 Punkte +5208=Bogenstartpunkt Richtung Endpunkt
Bogenstartpunkt Richtungsvektor Endpunkt (Verschiebung)
Bogenstartpunkt Richtung Endpunkt mit Weiter (Strg) +5209=Filet +5210=Fase +5211=Rechteck 2 Punkte +5212=Polygon +5213=Polygonseite +5214=Text
Erweiterter Text (Umschalt) +5215=Ebene aus Grenzkurven
Flacher Bereich (Verschiebung) +5216=Extrudieren +5217=drehen +5218=Schraube +5219=entschieden +5220=Oberflächen zusammenführen +5221=Oberflächen und flache Bereiche explodieren +5222=Oberfläche und flache Bereiche umkehren +5223=Löschen +5224=Ebene ändern
Ebene mit Transformationen ändern (Umschalt) +5225=Transparenz ändern +5226=Farbe zurücksetzen +5227=Farbe ändern +5228=Kurve umkehren +5229=Geschlossenen Kurvenstartpunkt ändern +5230=Kurve trimmen oder verlängern +5231=Bruchkurve +5232=Teilungskurve +5233=Kurven verbinden
Kurven verbinden, die eine Kopie erstellen (Shift)
Merge Curves in Composite (Ctrl) +5234=Kurven und Texte explodieren +5235=Dick- und Extrusionskurve +5236=Verschieben +5237=Drehen +5238=3D drehen +5239=Spiegeln +5240=3D spiegeln +5241=Skala +5242=3D skalieren +5243=Versatz +5244=2D-Zeichnung +5245=3D-Zeichnung +5246=Ändern +5247=Transformieren +5248=Gefegt (Abschnitt, Anleitung) +5249=Text bearbeiten +// Grid View Panel +5251=Drahtmodell +5252=Versteckte Linien +5253=Schattierung +5254=Alle zoomen +5255=Vergrößern +5256=Verkleinern +5257=Draufsicht +5258=Vorderansicht +5259=Ansicht von links +5260=Rückansicht +5261=Rechte Ansicht +5262=SW Isometrische Ansicht +5263=SE Isometrische Ansicht +5264=NE Isometrische Ansicht +5265=NW Isometrische Ansicht +5266=Kurvenrichtung anzeigen +5267=Analysieren +5268=Entfernung +5269=oberes Gitter +5270=Frontgitter +5271=rechtes Gitter +5272=Rückengitter +5273=linkes Gitter +5274=unteres Gitter +5275=Raster aus Ansicht +5276=Gitterhöhe +5277=Gitterursprung +5278=Gitterrotation
Gitter-3D-Rotation (Verschiebung) +5279=Gitter ab 3 Punkten +5280=Gitter senkrecht zur Kurve +5281=Gitter vom Objekt +5282=Ansicht vom Raster +5283=Zoomauswahl +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=ENDE +5302=Abschlag +5303=Werkzeugrichtung nicht erreichbar +5304=Fehler +5305=FEHLER +5306=Fehler in der Generierung! +5307=Simulation +5308=Ein Schritt +5309=Wiedergabe / Pause +5310=Stop / Home +5311=Pause +5312=STOP +5313=Kann jetzt nicht beendet werden. Stoppen Sie die Simulation oder warten Sie bis zum Ende! +5314=HOME +5315=WARNUNG +5316=Virtuelles Fräsen +5317=Fehler bei der Berechnung der Schätzungen! +5318=Schätzdatei fehlt +5319=Kollision! +5320=INFORMATION +5330=GENERIEREN +5331=Das Projekt muss vor der Generierung gespeichert werden. Speichern Sie es? +5332=Generierung erfolgreich abgeschlossen +5333=Die Lizenz erlaubt keine NC-Generierung +5340=Schätzungen +5341=Gesamtzeit +5342=Gesamtlänge +5343=Details +5344=Schätzungsdetails +// Draw Option +5351=Eigenschaften +5352=Neues Teil +5353=Neue Ebene +5354=Farbe +5355=Zeichnungsparameter +5356=Auswählen +5357=Abwählen +5358=Name +5359=Info +5360=Umzug +5361=Kopieren +5362=Löschen +5363=Speichern +5364=Anzeigen +5365=Ok +5366=Löschen Bestätigen +5367=Werkstück, möchten Sie es löschen? +// Operation +5401=Operationen +5402=Betriebsparameter +5403=Bearbeitung anwenden +5404=Neue Bear +5405=Neue Disp +5406=Löschen +5407=Allgemein +5408=Nach oben +5409=Nach unten bewegen +5410=Aktualisieren +5411=Update erfolgreich abgeschlossen +5412=Neue Bearbeitungen +5413=Werkzeugvorschau +5414=Weiter +5415=Zurück +5416=Duplizieren +5417=Nach Db kopieren +5418=Bearbeitungsname in Db +5419=Das Hinzufügen der Bearbeitung ist fehlgeschlagen +5420=Umbenennen +5421=Name kann nicht mit "Disp" beginnen +5422=Name bereits verwendet. +5423=Die Bearbeitung kann aus folgenden Gründen nicht durchgeführt werden: +// Disposition +5431=Ok +5432= +5433=Neu +5434=Entfernen +5435=Länge +5436=Breite +5437=Höhe +5438=Position +// Disposition Errors +5461=SCRIPT EXECUTION ERROR +5462=Fehler beim Ausführen des automatischen Dispositionsskripts +5463=Fehler beim Ausführen des Bearbeitungs-Init-Skripts +5464=Fehler beim Ausführen des Bearbeitungs-Exit-Skripts +// Mach Group +5501=Möchten Sie die Bearbeitungsgruppe wirklich zurücksetzen? +5502=Möchten Sie die Bearbeitungsgruppe wirklich löschen? +5551=Es gibt keine Bearbeitungsgruppen:
Wählen Sie die einzufügenden Teile aus und
wiederholen Sie den Befehl, um die erste zu erstellen +5552=Möchten Sie eine neue Bearbeitungsgruppe
mit den ausgewählten Teilen erstellen? +// Tools Db Page +6001=Bohrer +6002=Messer +6003=Fräser +6004=Mortise +6005=Compo +6006=Langer Bohrer +6007=Flachsäge +6008=Keine Spitzenmühle +6009=Meissel +6010=WaterJet +6051=Entschädigung +6052=Beenden +6053=Typ +6054=Kühlmittel +6055=Eckradius +6056=Durchmesser +6057=Gesamtdurchmesser +6058=Vorschub +6059=Vorschub beenden +6060=Vorschub starten +6061=Kopfvorschub +6062=Länge +6063=Gesamtlänge +6064=Scharf +6065=Längsversatz +6066=Radialversatz +6067=Drehung +6068=Seitenwinkel +6069=Maximale Drehung +6070=Dick +6071=Maximale Absorption +6072=Min. Vorschub +6073=Zeichnen +6074=Kopf +6075=Vorname +6076=Notizen +6077=Position des Werk +6078=Position +6079=Distance +6080=???Overtable +// Tools Errors +6100=Geändertes Werkzeug speichern? +6101=SPEICHERN +6102=Datei muss .nge sein +6103=Datei existiert nicht oder ist kein Nge-Typ +6104=ToolMaker existiert für diese Art von Werkzeug nicht +6105=Unmögliches Werkzeug zum Erstellen mit diesem Parameter +6106=MaxMat-Wert muss größer als 0 sein +6107=MaxMat-Wert muss kleiner als Len sein +6108=Dicker Wert muss größer als 0 sein +6109=Diam-Wert muss größer als 0 sein +6110=Len-Wert muss größer als 0 sein +6111=Der Geschwindigkeitswert muss kleiner als MaxSpeed ​​sein +6112=Ungültiger Name +6113=Der Längenwert muss kleiner als die Gesamtlänge sein +6114=Der Längenwert muss größer als das maximale Material sein +6115=Gesamtlänge muss größer als 0 sein +6116=Gesamtlänge muss größer als Länge sein +6117=Max. Material darf weniger als 1/3 Durchmesser haben +6118=Der Durchmesser muss kleiner als der Gesamtdurchmesser sein +6119=Durchmesser muss größer sein als das 3-fache des maximalen Materials +6120=Gesamtdurchmesser muss größer als 0 sein +6121=Länge mit Werkzeughalter zu klein +6122=Möchten Sie wirklich löschen? +6123=? +6124=LÖSCHEN +6125=SetUp-Konfigurationsdatei nicht gefunden! +6126=Fehler +6127=Kopfwert muss eingestellt sein +6128=Ausgangswert muss eingestellt sein +6129=Ungültiges Werkzeug, korrigieren oder löschen Sie es, bevor Sie Werkzeug Db beenden. +6130=Unmögliches Neuladen der Tool-Datenbank. Wenn sich das Computerverzeichnis auf einem Server befindet, überprüfen Sie, ob die Verbindung aktiv ist. +6131=Dicker Wert muss sich von 0 unterscheiden +6132=Der Seitenwinkelwert muss kleiner als 90 sein +6133=Der Seitenwinkelwert muss größer als -90 sein +6134=Die Gesamtlänge muss größer als Länge + Dicke sein +6135=Eckradiuswert ist zu groß +6136=Dicker Wert ist zu klein für den Einfügeradius +6137=Der berechnete Durchmesser muss kleiner als der Gesamtdurchmesser sein +6138=Der berechnete Durchmesser ist kleiner als 0 +6139=Der berechnete Durchmesser ist kleiner oder gleich 0 +6140=MaxMat-Wert muss größer als der Eckenradius sein +6141=Berechneter MaxMat muss> = 0 sein +6142=Der Eckenradius darf die Hälfte der Dicke nicht überschreiten +6143=Werkzeug speichern +6144=Werkzeug modifiziert! Alle Werkzeuge müssen gespeichert werden, bevor Aktivierungen geändert werden. Werkzeug speichern {0}? +6145=Position bereits besetzt! +6146=Position nicht definiert! +// Machinings Db Page +6201=Bohren +6202=Schnitt +6203=Fräsen +6204=Pocketing +6205=Mortising +6206=Sawroughing +6207=Sawfinishing +6208=Gen Machining +6209=Chiseling +6210=Surface Roughing +6211=Surface Finishing +6212=WaterJet +6251=Invert +6252=Leave Tab +6253=Type +6254=Work Side +6255=Head Side +6256=Lead In +6257=Link +6258=Lead Out +6259=Curve Use +6260=Step Type +6261=Sub Type +6262=Lead Link Type +6263=Speed +6264=Feed +6265=Start Feed +6266=End Feed +6267=Tip Feed +6268=Radial Offset +6269=Longitudinal Offset +6270=Depth +6271=Side Angle +6272=Approximation +6273=Start Safety Length +6274=Start Slow Length +6275=End Slow Length +6276=Throu Add Length +6277=Absenkung +6278=Return Position +6279=Length +6280=Distance +6281=Height +6282=Angle +6283=L.In Tangent Distance +6284=L.In Perp. Distance +6285=L.In Elevation +6286=L.In Comp. Length +6287=L.Out Tangent Distance +6288=L.Out Perp. Distance +6289=L.Out Elevation +6290=L.Out Comp. Length +6291=Start Add. Length +6292=End Add. Length +6293=Step External Arc +6294=Step Internal Arc +6295=Side Step +6296=Vertical Feed +6297=Name +6298=Tool +6299=Depth +6300=Notes +6301=Overlap +6302=Offset +6303=Sub Type +6304=SCC +6305=None +6306=Standard +6307=Opposite +6308=AuxDir X+ +6309=AuxDir X- +6310=AuxDir Y+ +6311=AuxDir Y- +6312=AuxDir Z+ +6313=AuxDir Z- +6314=Nearest AuxDir +6315=Farthest AuxDir +6320=Center +6321=Left +6322=Right +6323=Extend +6324=Standard +6325=Strict +6326=Out +6327=Extend Central +6328=Extend Out +6329=None +6330=Linear +6331=Tangent +6332=Glide +6333=Helix +6334=Extend Prev +6335=Extend Next +6336=Extend Both +6337=As Lead In +6338=Skip +6339=Approx +6340=Convex +6341=Keep +6342=ZigZag +6343=Oneway +6344=Spiral +6345=To And From +6346=Along +6347=Across +6348=Spiral In +6349=Spiral Out +6350=Advanced +6351=Invert tool direction +6352=Face machining +6353=Not defined +6354= Parallel +6355= Orthogonal +6356= Orthog. Up +6357=Down +6358=Top +6359=Front +6360=Back +6361=Left +6362=Right +6363=Contour +6364=Suggested Angles +6365=Blocked Axis +6366=Max count +6367=Min count +// Machining errors +6370=Save the modified machining? +6371=SAVE +6372=Invalid name +6373=Characters \ / : * ? " < > | are not allowed +6374=Are you sure you want to delete +6375=? +6376=DELETE +6377=Impossible reloading Machining database. If the machine dir is on a server, verify the connection is active. +6378=Oscillation +6379=Amplitude +6380=Ramp Length +6381=Flat Length +// Machining Option Page +6401=Sicherheit Z. +6402=Geteilte Bögen +6403=Niemals +6404=Gen-Ebene +6405=Keine XY-Ebene +6406=Immer +6407=Standardeinstellung +6408=Boden Aggregat Sicherheit Z +6409=Bohrungstreibung +// SetUp Window +6451=SetUp +6452=Apply +6453=Save +6454=Retrieves +6455=Auto +6456=Apply current setup before exit? +6457=???New +// SetUp Errors +6471=Error +6472=Warning +6473=Can't find tool +6474=in Tool Database. +6475=The tool's default position is not valid. +6476=Tools not setup because their default position is alredy occupied: +6477=SetUp configuration file doesn't exist! +6478=SetUp configuration use a head that doesn't exist on the machine! +6479=Error loading default setup +// Option Page +6501=Current language +6502=The new language become the current one from the next software run. +6503=Curves +6504=Surfaces +6505=Curves & Surfaces +6506=Selecting geometry +6507=New machining is the last one +6508=Use disposition script +6509=Measure Unit +6510=View top color +6511=View bottom color +6512=Default color +6513=Geometric tolerance +6514=Generic +6515=CAD +6516=CAM +6517=Grid color +6518=Smoothed surfaces +6519=Import +6520=DXF +6521=STL +6522=Images +6523=Export +6524=Image +6525=Width (pixel) +6526=Height (pixel) +6527=Update Machine +6528="{0}" machine already exists,
what do you want to do ? +6529=File {0} does not contain a machine. +6530=The machine "{0}" has been successfully updated. +6531=Replace +6532=Update +6533=Cancel +6534=Warning +6535=The update of the "{0}" machine failed. +6536=Thick lines +6537=???Extra line length +6538=???Arrow length +6539=???Text distance +6540=???Unit measure +6541=???Decimal +6542=???Font +6543=???Text height +6544=???Dimension +6545=???Current unit +6546=???Other +6547=???Unit of measure +6548=???Scale factor +6549=???Export Current Machine +6550=???Select the folder where you want to save the machine +6551=???The exportation of the "{0}" machine failed. +6552=???The machine "{0}" has been successfully exported. +6553=???Update Licence +// Heads +6601=Vertical +6602=Horizontal +6603=2 exit aggr. +6604=3 exit aggr. +6605=4 exit aggr. +6606=3 axis head +6607=4 axis head +6608=5 Achsen Kopf +6609=Shuttle 1 +6610=Shuttle 2 +6611=Carousel +6612=Gang drill +6613=Multi chisel +6614=Bottom aggr. +6615=5 Achs Säge +6616=Kettensäge +6617=1 exit aggr. +6618=Probe head +6619=Floating 360deg +6620=???2nd 5 axis head +6621=???Horizontal drill +6622=???Mortiser +6623=???2nd 5 axis saw +6624=???1 exit tilt. aggr. +6625=???Extruder +6799= +// StatusBar +6801=Machines dir not found. EgtCAM5 wil be run in CAD-ONLY mode. +// Doors +8001=Create new MTable +8002=Save MTable +8003=Save MTable As +8004=Delete MTable +8005=Save MTable file +8006=Are you sure to delete this MTable? +8007=Save the modified MTable? +8008=Active Machines List +8009=Machine Name +8010=Nc Generate +8011=Make Raw +8012=On +8013=Geometry Name +8014=Operation +8015=MId +8016=Shift +8017=Machining Type +8018=Machining 1 +8019=Machining 2 +8020=Machining 3 +8021=Add Machine +8022=Remove Machine +8023=Add Machining +8024=Remove Machining +8025=CURR +8026=Set active MTable +8027=GId +8028=Property +8029=Machining +8030=Join +// Door errors +8101=Error +8102=Error running Ddf file +8103=Warning +8104=MTable dir path not found +8105=MTable dir not exist +8106=Missing configuration files in MTable dir +8107=Unknown error +8108=This MTable is currently the active one. +8109=You can't delete it. +8110=Are you sure you want to delete the selected machining? +8111=DELETE +8112=Are you sure you want to delete the selected machine? +8113=Can't find {0} machine dir. If the machine dir is on a server, verify the connection is active. +8114=Try to reload the machine? +8115=Can't find {0} dir. If the Doors dir is on a server, verify the connection is active. +8116=Try to reload Doors dir? +8117=Execution error (see log file) +// GunStock +8201=New Part +8202=Gunstock new part +8203=Modify Part +8204=Gunstock modify part +8205=Gunstock parameters +8206=File name +8207=Description +8208=Ok +8209=Cancel +8210=must have a value. +8211=The value has to be between +8212=and +8213=Rawpart dimensions +// GunStock errors +8251=Error +8252=Error running Gunstock environment +8253=Error reading model file +8254=Error writing part file +// ----- Beams & Walls ----- +9000=Trägerbearbeitungstabellen +9001=Ein +9002=Name +9003=Typ +9004=Hinzufügen +9005=Löschen +9006=Speichern +9007=Änderungen speichern? +9008=Fehler +9009=Beam Machining Editor kann nicht geöffnet werden.
Konfigurationsdateien können nicht gefunden werden. +9010=Wandbearbeitungstische +9011=Wandbearbeitungseditor kann nicht geöffnet werden.
Konfigurationsdateien können nicht gefunden werden. +// ----- Fehler ----- +10001=Fehler +10002=Fehler bei neuer Datei +10003=Fehler beim Öffnen der Datei +10004=Fehler beim Speichern der Datei +10005=Dateityp unbekannt +10006=Fehler beim Importieren der Datei +10007=Fehler beim Export der Datei +10008=Fehler beim Laden oder Erstellen einer Bearbeitungsgruppe +10009=Fehlende Datei +// fehlendes Schlüsselfenster +10101=Fehler! +10102=Fehlender Schutzschlüssel. +10103=Dongle einlegen und das Programm neu starten. +10104=Ok +10105=Programm ohne Lizenz. +10106=Lizenz laden und das Programm neu starten. +10107=???Run GetMachineId and send results to supplier. +// Numerische virtuelle Tastatur +10201=Falscher Expression +// ----- MessageBox ----- +15001=Error +15002=Warning +15003=Information +15010=Unknown error +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Falscher Expression +// EgtCalculatorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Canc +20043=JA +20044=NEIN +// ----- EgtWPFLib5 ----- +// EgtFileDialog +30001=???Save +30002=???Cancel +30003=???alredy exists. +30004=???Do you want to replace it? +30005=???File name: +30006=???Open +30007=???ERROR +30008=???Name can't be empty! +30009=???WARNING +30010=???File Name +30011=???Folder Name +// Top CommandBar +30501=???New +30502=???Open +30503=???Save +30504=???Save as +30505=???Insert +30506=???Import +30507=???Export +30508=???Exec +30509=???Options +30510=???Can't find support address. +30511=???Save current file before sending feedback? +30512=???Send a feedback to {0} with the {1} directory attached. +30513=???Feedback +30514=???Feedback mail ready. +// Grid View Panel +30801=???Wireframe +30802=???Hidden Lines +30803=???Shading +30804=???Zoom All +30805=???Zoom In +30806=???Zoom Out +30807=???Top View +30808=???Front View +30809=???Left View +30810=???Back View +30811=???Right View +30812=???SW Isometric View +30813=???SE Isometric View +30814=???NE Isometric View +30815=???NW Isometric View +30816=???Show Curve Direction +30817=???Analyze +30818=???Distance +30819=???Top Grid +30820=???Front Grid +30821=???Right Grid +30822=???Back Grid +30823=???Left Grid +30824=???Bottom Grid +30825=???Grid From View +30826=???Grid Elevation +30827=???Grid Origin +30828=???Grid Rotation +30829=???Grid From 3 Points +30830=???Grid Perpendicular to Curve +30831=???Grid From Object +30832=???View From Grid +// MachGroupPanel +30901=???New Mach Group +30902=???Name: +30903=???Machine: +// ToolDbWindow +31001=Bohrer +31002=Sägeblatt +31003=Fräse +31004=Mortiser +31005=???Compo +31006=???Long drill +31007=???Flat saw +31008=???No tip mill +31009=???Chisel +31010=???Waterjet +31051=???Compensation +31052=???Exit +31053=???Type +31054=???Coolant +31055=???Corner Radius +31056=???Diameter +31057=???Total Diameter +31058=???Feed +31059=???End Feed +31060=???Start Feed +31061=Kopfvorschub +31062=???Length +31063=???Total Length +31064=???Max Material +31065=???Longitudinal Offset +31066=???Radial Offset +31067=???Speed +31068=???Side Angle +31069=???Max Speed +31070=???Thick +31071=???Max Absorption +31072=???Min Feed +31073=???Draw +31074=???Head +31075=???Name +31076=???Notes +31077=???Tool Changer Position +31078=???Position +31079=???Drilling +31080=???Cutting edge +// ToolDb Errors +31100=Geändertes Werkzeug speichern? +31101=SPEICHERN +31102=Datei muss .nge sein +31103=Datei existiert nicht oder ist kein Nge-Typ +31104=ToolMaker existiert für diese Art von Werkzeug nicht +31105=Unmögliches Werkzeug zum Erstellen mit diesem Parameter +31106=Fräserwert muss größer als 0 sein +31107=Der Fräserwert muss kleiner als Len sein +31108=Dicker Wert muss größer als 0 sein +31109=Durchmesserwert muss größer als 0 sein +31110=Längenwert muss größer als 0 sein +31111=Der Drehung muss kleiner als Maximale Drehung sein +31112=Ungültiger Name +31113=Der Längenwert muss kleiner als die Gesamtlänge sein +31114=Der Längenwert muss größer als das maximale Material sein +31115=Gesamtlänge muss größer als 0 sein +31116=Gesamtlänge muss größer als Länge sein +31117=Scharf muss kleiner als {0} sein +31118=Der Durchmesser muss kleiner als der Gesamtdurchmesser sein +31119=Durchmesser muss größer sein als das 3-fache des maximalen Materials +31120=Gesamtdurchmesser muss größer als 0 sein +31121=Länge mit Werkzeughalter zu klein +31122=Möchten Sie wirklich löschen? +31123=???? +31124=LÖSCHEN +31125=SetUp-Konfigurationsdatei nicht gefunden! +31126=Fehler +31127=Kopfwert muss eingestellt sein +31128=Ausgangswert muss eingestellt sein +31129=Ungültiges Werkzeug, korrigieren oder löschen Sie es, bevor Sie das Werkzeug Db beenden. +31130=Unmögliches Neuladen der Tool-Datenbank. Wenn sich das Computerverzeichnis auf einem Server befindet, überprüfen Sie, ob die Verbindung aktiv ist. +31131=Dicker Wert muss sich von 0 unterscheiden +31132=Der Seitenwinkelwert muss kleiner als 90 sein +31133=Der Seitenwinkelwert muss größer als -90 sein +31134=Die Gesamtlänge muss größer als Länge + Dicke sein +31135=Eckradiuswert ist zu groß +31136=Dicker Wert ist zu klein für Einfügeradius +31137=Der berechnete Durchmesser muss kleiner als der Gesamtdurchmesser sein +31138=Der berechnete Durchmesser ist kleiner als 0 +31139=Der berechnete Durchmesser ist kleiner oder gleich 0 +31140=Der MaxMat-Wert muss größer als der Eckenradius sein +31141=Berechneter MaxMat muss> = als 0 sein +31142=Schneide muss größer als 0 sein +31143=Die Schneide muss kleiner als Len sein +// ImportExportToolWindow +31161=???Import +31162=???Export +31163=???Tools +31164=???Tool already existing in DB. Overwrite? +31165=???Tool will be imported with the name followed by "_imp" +31166=???The following Tools have been imported succesfully: +31167=Reset +// MachiningDbWindow +31201=Bohren +31202=Sägen +31203=Fräsen +31204=Einstecken +31205=Einsteckschloss +31206=Sägen +31207=Sägen +31208=Gen Machining +31209=Meißeln +31210=Wasserstrahl +31211=???Surffinishing +31251=Invertieren +31252=Tab verlassen +31253=Typ +31254=Arbeitsseite +31255=Kopfseite +31256=Einführen +31257=Link +31258=Herausführen +31259=Kurvenverwendung +31260=Schritttyp +31261=Untertyp +31262=Lead Link-Typ +31263=Drehung +31264=Vorschub +31265=Vorschub starten +31266=Vorschub beenden +31267=Kopfvorschub +31268=Radialversatz +31269=Längsversatz +31270=Tiefe +31271=Seitenwinkel +31272=Annäherung +31273=Sicherheitslänge starten +31274=Verlang. Anfängliche +31275=Verlang. beenden +31276=Länge hinzufügen +31277=Absenkung +31278=Rücklaufposition +31279=Länge +31280=Höhe +31281=Winkel +31282=Entfernung +31283=Tangentenabstand +31284=Perp. Entfernung +31285=Höhe +31286=Comp. Länge +31287=Min. Anzahl +31288=Max. Anzahl +31291=zusätzliche Länge +31293=Externer Schrittbogen +31294=Interner Schrittbogen +31295=Seitenstufe +31296=Vertikaler Vorschub +31297=Vorname +31298=Werkzeug +31299=Tiefe +31300=Notizen +31301=Überlappung +31302=Versatz +31303=Untertyp +31304=SCC +31305=Keine +31306=Standard +31307=Gegenüber +31308=AuxDir X + +31309=AuxDir X- +31310=AuxDir Y + +31311=AuxDir Y- +31312=AuxDir Z + +31313=AuxDir Z- +31314=Nächster AuxDir +31315=Weiter AuxDir +31320=Mitte +31321=Links +31322=Richtig +31323=Erweitern +31324=Standard +31325=Streng +31326=Aus +31327=Central erweitern +31328=Ausfahren +31329=Keine +31330=linear +31331=Tangente +31332=Gleiten +31333=Helix +31334=Erweitern +31335=Als nächstes erweitern +31336=Beide erweitern +31337=Als Einführen +31338=Überspringen +31339=Approx +31340=konvex +31341=Behalten +31342=Zickzack +31343=Einfahrt +31344=Spirale +31345=Von und Von +31346=Mit +31347=Über +31348=Spiral In +31349=Spiral Out +31350=Erweitert +31351=Werkzeug umkehren +31352=Planbearbeitung +31353=Nicht definiert +31354=Parallel +31355=Orthogonal +31356=Orthog. Oben +31357=Unten +31358=Oben +31359=Front +31360=Zurück +31361=Links +31362=Richtig +31363=Kontur +31364=Vorgeschlagene Winkel +31365=Blockierte Achse +31366=Letzter Rückwärts-Feed +31367=Rückwärtsschritt +31368=Kippstufe +31369=GeneigtRück. Schritt +31370=Vorwärtswinkel +31371=Prüfen +31372=Min dist. Punkte +31373=Max dist. Punkte +31374=Extern +31375=Intern +31376=Verlangsamung len. +31377=Verlangsamung% +31378=Blei im Loch +31379=Radius +31380=LP dreht sich +31381=HP dreht sich +31382=Schwingung +31383=Amplitude +31384=Rampenlänge +31385=Flache Länge +31386=Allgemein +31387=Erweitert +31388=Tang+Perp +31389=Perp+Tang +// MachiningTreeView +31391=Standard +31392=Verlangsamung +31393=Schleife +31394=Aktivieren +31395=Länge hinzufügen +31396=Start +31397=Ende +31398=???System notes +31399=???Epicycles radius +31400=???Epicycles distance +// MachiningDb Errors +31401=???Save the modified machining? +31402=???SAVE +31403=???Invalid name +31404=???Characters \ / : * ? " < > | are not allowed +31405=???Are you sure you want to delete +31406=???? +31407=???DELETE +31408=???Impossible reloading Machining database. If the machine dir is on a server, verify the connection is active. +31409=???Machine material not recognized +31410=???Invalid machining, correct or delete it before exiting. +31411=???Length must be positive +31412=???Distance must be positive +31413=???Height must be positive +31414=???Angle must be between {0}° and {1}° +31415=???Max count must be null or positive +31416=???Max count must be equal or greater than Min +31417=???Min count must be null or positive +31418=???Min count must be equal or less than Max +31419=???Enabling {0} will disable {1}. Continue? +// ImportExportMachiningWindow +31450=???Import +31451=???Export +31452=???Machinings +31453=???Machining already existing in DB. Overwrite? +31454=???Machining will be imported with the name followed by "_imp" +31455=???The following Machinings have been imported succesfully: +31456=???Reset +// SetUp Window +31501=???SetUp +31502=???Apply +31503=???Archive +31504=???Retrieves +31505=???Auto +31506=???Apply current setup before exit? +// SetUp Errors +31551=???Error +31552=???Warning +31553=???Can't find tool +31554=???in Tool Database. +31555=???The tool's default position is not valid. +31556=???Tools not setup because their default position is alredy occupied: +31557=???SetUp configuration file doesn't exist! +31558=???SetUp configuration use a head that doesn't exist on the machine! +31559=???Error loading default setup +// Simulation +31601=???Complete simulation +31602=???Outstroke +31603=???Tool direction unreachable +31604=???Error +31605=???ERROR +31606=???Error in generation! +31607=???Simulation +31608=???One step at a time +31609=???Play/Pause +31610=???Stop/Home +31611=???Pause +31612=???Stopped simulation +31613=???Can't exit now. Stop the Simulation or wait until the end of it! +31614=???WARNING +31615=???Estimation file missing +31616=???Estimation details +//MachiningDbWindow/ToolDbWindow buttons +31701=Neu +31702=Speichern +31703=Entfernen +31704=???Edit +//Db Waterjet +31751=???Waterjet Db +31752=???Thickness +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=???Do you want to save edits? +// ----- EgtDOORCreator ----- +//General +50001=???Width +50002=???Height +50003=???Thickness +50004=???Swing +50005=???Lockedge +50006=???Hingeedge +50007=???Top +50008=???Bottom +50009=???Type +50010=???Corner +50011=???Extension +50012=???Side +50013=???Offset wide side +50014=???Back set +50015=???Top to center application +50016=???Bottom rail +50017=???Lock stile +50018=???Offset from center +50019=???Point to pocket +50020=???Pocket length +50021=???Pocket offset narrow side +50022=???Point to arm +50023=???Arm length +50024=???CenterHung +50025=???Offset +50026=???Offset intermediate +50027=???Radius +50028=???Top rail +50029=???Position +50030=???Lenght +50031=???Template +50032=???Up +50033=???Down +50034=???Shape +50035=???Hinge +50036=???Top to top application +50037=???Center from top application +50038=???Center from top lock +50039=???Depth +50040=???General +50041=???Center +50042=???Thru +50043=???Face to center line application +50044=???Edge Type +50045=???Over Material +50046=???Send Feedback +50047=???Weight +50048=???Angle +50049=???Face +50050=???Secure +50051=???Keyway +50052=???Brand +50053=???Folder +50054=???Main Folder +50055=???Jamb +50056=???Light Up +50057=???Light Lock +50058=???Light Bottom +50059=???Light Hinge +50060=???Thickness Head +50061=???Overlap Hinge +50062=???Overlap Lock +50063=???Overlap Top +50064=???Delta T +50065=???Exterior +50066=???Number of Doors +50067=???Jambs and Doors +50068=???Order +50069=???Disposition +50070=???Customer +50071=???Invert bevel on Lock +//Compo Name +50072=???Flush Bolt +50073=???Flush Pull +50074=???Hinge +50075=???Lock +50076=???Louver Cut Out +50077=???Mail Slot +50078=???Over Head +50079=???Pivot +50080=???Roller Latch +50081=???Stops And Closer +50082=???Strike +50083=???Edge pull +50084=???Viewer +50085=???Vision cut out +50086=???Grove +50087=???Rabbet +50088=???Ept +50089=???Raceway +50090=???Face Decoration +//error messages +50100=???Directory not founded +50101=???Error +50102=???Failed reading DDF file. Missing incumbent parameter {0}. +50103=???Failed reading value +50104=???Failed reading DDF file's row +50105=???Row +50106=???Invalid value in +50107=???Empty file. +50108=???You can not add a compo if there is not a dorr! +50109=???Do you want to save this file ({0}) ? +50110=???Question +50111=???Add new door +50112=???Remove door +50113=???New Door +50114=???File name already exists in the current directory ({0}). +50115=???Caution +50116=???Do you want to delete this file ({0}.ddf)? +50117=???Confirm deleting ({0})?. +50118=???Information +50119=???Error in reading messages. There is no match with the number {0}. +50120=???Error reading name {0} in {1}. Expected numeric match. +50121=???Error reading {0} param in {1} compo: do not exist. +50122=???Error in {0} param in {1} compo. +50123=???Error reading {0} param in {1} compo: do not exist list. +50124=???Error reading {0} param in {1} compo: {2}. +50125=???Error in {0} param in {1} compo: do not exist value. +50126=???Delete +50127=???Error in EgtLoadMessages +50128=???You can not save a file if there is not a door! +50129=???Error in Project scene creation +50130=???Error in reading: line {0}. +50131=???Error in reading {0}: line {1}. Expected ':' after the name. +50132=???Error in reading {0}: line {1}. Expected 'template' or 'shape'. +50133=???{0} has not been created. +50134=???Error reading 'Template' in file {0}\{1}. Expetcted name. +50135=???Error reading 'Template' in file {0}\{1}. File {0}\{2} .lua does not exist. +50136=???Error in reading {0}: line {1}. It does not exist in the list of components in file 'Default.ini'. +50137=???Error in reading {0}: line {1}. It is not a member of the list. +50138=???This param will be initialized by dafault. +50139=???Error in reading: line {0}. Expected {1}. +50140=???All missing params will be initialized by dafault. +50141=???Invalid expression in {0}. +50142=???Remove compo +50143=???Invalid expression. +50144=???Warning +50145=???Impossible to create the current door. +50146=???Do you want to open a template? +50147=???Error expression in {0}. {1} does not match anything. +50148=???Invalid value.ù +50149=???Caution: Weight is setted in OptionPage. Do you want to remove? +50150=???Caution: Weight is setted in DDF. Do you want to add? +50151=???{0} is not a member of the current list of EdgeType. Check Bevel in option page. +50152=???Do you want to save this file ({0})? +50153=???Caution. Weight is setted in the current door. Do you want to remove? +50154=???It is the bevel of the current door. Do You want to proced? +50155=???Impossible to create a template if there is not a door! +50156=???Errore nella lettura ddf: la porta non è completa o il ddf è stato separato male da '---'. +50157=???Script Lua ( {0}\{1} )has not been found. +50158=???Bevel {0} can not be acceptable in Jamb. +50159=??? Missing parameter in ddf! +50160=???File {0} in directory {1} has not been found. +50161=???parameter +50162=???In file {0} param 'Default' must be numeric. +50163=???Error in reading General Assembly in DDF +50164=???In General Assembly: +50165=???CompoDir not found : +50166=???Jamb compo does not exist +50167=???Empty Line +50168=???No matching param +50169=???Door disposition has been modify. +50170=???Incongruity between the bevel, it has been resolved by default. +50171=???In file StdTempate.ini is missing numeric param in [Type]. +50172=???File does not exist. +50173=???Definition type is not correct: +50174=???Missing name of the new template! +50175=???The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=???Error in copying: {0} +50177=???Do you want to save the current changes? +50179=???Doors Compo Default.ini not found in {0} . +50180=???Warning : {0} does not exist. +50181=???Error in creating the print image +50182=???Error executing print +50183=???Some Doors could use this hardware, do you want to proceed deleting? +50184=???Impossible to delete Hardware if there is no Hardware selected! +50185=???Impossible to duplicate Hardware if there is no Hardware selected! +50186=???Project must be saved before copying +50187=???Do you want to copy all files ? {0} (No to copy only the current file) +50188=???Export to machine +50189=???Machine Directory not found +50190=???Error in copying: {0} +50191=???Impossible to copy a door if there is not a door! +50192=???Impossible to export to machine a door if there is not a door! +50193=???Impossible to print a door if there is not a door! +50194=???Properties has been deleted +50195=???The current ddf configuration ({0}) is different from the current program configuration ({1}).{2}To load the current ddf configuration you have to restart the program, do you want it? +50196=???Configuration ddf ({0}) does not exist! +50197=???Top Arch has been modified because of configuration. +50198=???Bevel on lock edge would be inverted. +//Option +50200=???Unit measure +50201=???General +50202=???LockEdgeOverMaterial +50203=???HingeEdgeOverMaterial +50204=???TopOverMaterial +50205=???BottomOverMaterial +50206=???Open Window +50207=???Last Project +50208=???Empty +50209=???Option Page +50210=???StartUp +50211=???Unit measure new door. +50212=???Directory Project +50213=???Option Start +50214=???Current Directory +50215=???Edge Type +50216=???Over Material +50217=???Browse +50218=???Close +50219=???Bevel +50220=???Bevel Up +50221=???Bevel Down +50222=???Door positioning in machining +50223=???Save as template +50224=???Matching +50225=???Brand +50226=???File +50227=???Template +50228=???Enable template +50229=???Enable Order +50230=???Open template door. +50231=???Open window order. +50232=???Directory Template +//Scene +50301=???Refresh +50302=???Add New Door +50303=???Remuve Door +50304=???New Project +50305=???Help +50306=???Directory Machine +50307=???Machine +50308=???Door +50309=???Wide Side Down (BU) +50310=???Wide Side Up (BD) +50311=???Resize +50312=???Design +50313=???Save as pdf +//Launcher +50400=???Launcher +50401=???Open New Project +50402=???Open Project +50403=???Open Last Project +50404=???New Project +50405=???New Hardware +50406=???Elevation +50407=???Project +50408=???PO +50409=???Line +50410=???Save +50411=???Print +50412=???Cancel +50413=???Hardware +50414=???Dimensioning +50415=???Duplicate +50416=???Export to machine +50417=???New Template +50418=???Dimension +50419=???New Directory +50420=???Create Assembly +50421=???Reload Directories +50422=???Save As +50423=???Reaload Compo on Jamb +//Error messages +50501=???Error reading {0} param in {1} compo: incomplete definition (look at StdTemplate.ini). +50502=???Error reading {0} param in {1} compo: no matching (look at StdTemplate.ini and GeometryNameList.ini). +50503=???Do you want to save? +50504=???File name contains empty spaces, do you want to rename file deleting empty spaces? +50505=???DDF is not an assembly, there are only: {0}, do you want to save? +50506=???Impossible to find the first door (DO_1)! +50507=???The swing is not a member of the swing list of single door. +50508=???The swing of left door is not a member of the swing list of left door. +50509=???The swing of right door is not a member of the swing list of right door. +50510=???The swing of left door is on the right door and viceverse. +50511=???The swing of left door is not a member of the swing list of left door. +50512=???The swing of right door is not a member of the swing list of right door. +50513=???Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=???The swing are absolutly wrong! +50515=???The first door is not realy the first, check the ddf. +50516=???The current ddf contains {0} jambs. +50517=???The current ddf does not contains doors! +50518=???The current ddf is not an assembly. +50519=???Impossible to open a ddf with no doors. +50520=???The current ddf is an assembly. +50521=???The current ddf is a jamb: {0}. +50522=???The profile {0} is not a member of the {1} profile list. +50523=???Missing profile on {0}. +50524=???{0} file open by another EgtDOORCreator {1}. +50525=???{0} file open by another EgtDOORCreator {1}. +50526=???Directory {0} already exists! Do you want to overwrite it? +50527=???Impossible to overwrite {0} +50528=???Impossible to save the door out of the project! +50530=???Property {0} does not exist in the list of {1}. Look at file "../Compo/Default.ini". +50531=???The current material {0} does not exist in the list of material. Look at file "../Compo/Default.ini". +50532=???Missing list of material at file "../Compo/Default.ini". +50533=???Impossible to load more than one property at time. +50534=???Property {0} does not exist in the list. Look at file "../Compo/Default.ini". +50535=???Impossible to delete a project if there is not a project! +50536=???Do you want to delete entire project? +50537=???Do you want to delete subdirectory {0} ? +50538=???Impossible to vreate a template door if there is not a door! +50539=???Do you want to change project? ( All doors will be deleted!) +50540=???The current ddf is a part of a frame, do you want to save? +50541=???{0} in reading {1}. +50542=???{0}: Directory does not exist! +50543=???It has been renamed file: {0}, {1}. +50544=???It has been created new file: {0}, {1}. +50545=???It has been deleted file: {0}, {1}. +50546=???Enable single door. +50547=???Project +50548=???The new configuration will take effect after restart. +50549=???File {0} exist, but it is not in the correct Directory! +50550=???Every componente on jambs will be relocated, do you want to continue +50551=???The current parameters have been modified: +50552=???Do you want to overwrite? +50553=??? has not been created. +50554=???Parameter {0} is already deinfed in geometry {1}. +50555=???Impossible to save. +50556=???File has nge extension. +50557=???Error in deleting file: {0} +50558=???Impossible to import a different hardware! +50559=???Open File Dialog +50560=???The hardware part has not been generated correctly. +50561=???Directory already exists +50562=???Folder {0} does not exist. Check in OptionPage. +50563=???Compo {0} does not exist. +50564=???In group {0} at paramater {1} does not exist: {2} +50565=???Brand {0} has not been found in HardwareManager. +50566=???Template {0} has not been found in HardwareManager. +50567=???Error in executing EgtCam5. +50568=???Error in definition {0} in file GeometryNameList.ini . +50569=???Error in definition {0} in file StdTemplate.ini . +50570=???Nothing has been selected. +//Added General messages +50701=???Lines +50702=???Rectangle +50703=???None +50704=???Radius +50705=???Angle +50706=???Pos_x +50707=???Top Arc +50708=???Top Angle +50709=???Properties +50710=???Material +50711=???Mach. +50712=???HardwarePart +50713=???Assemby +50714=???Total Dimension +50715=???Depth +50716=???Overlap Bottom +50717=???Thickness Bottom +50718=???Depth Bottom +50719=???Delta Bottom +50720=???GoToAssembly +50721=???New Geometry +50722=???Geometry Name +50723=???Type Hardware +50724=???Parameter +50725=???Part Dimension +50726=???Apply +50727=???Frame +50728=???Refresh Directory +50729=???General +50730=???Report +50731=???Opposite face +// ----- EgtBEAMEditor ------ +60951=???Cut +60952=???Longitudinal Cut +60953=???Double Cut +60954=???Ridge or Valley Cut +60955=???Saw Cut +60956=???Slot +60957=???Front Slot +60958=???Birds Mouth +60959=???Hip or Valley Rafter Notch +60960=???Ridge Lap +60961=???Lap Joint +60962=???Notch/Rabbet +60963=???Block House Half Lap, Stairs Riser Dado +60964=???Seathing Cut +60965=???French Ridge Lap +60966=???Chamfer +60967=???Block House Half Lap +60968=???Block House Front +60969=???Pocket +60970=???Drilling +60971=???Tenon +60972=???Mortise +60973=???Mortise Front +60974=???House +60975=???House Mortise +60976=???Dovetail Tenon +60977=???Dovetail Mortise +60978=???Dovetail Mortise Front +60979=???Marking/Labeling +60980=???Text +60981=???Simple Scarf +60982=???Scarf Joint +60983=???Step Joint +60984=???Step Joint Notch +60985=???Planing +60986=???Profile Front +60987=???Profile Head concave +60988=???Profile Head convex +60989=???Profile Head cambered +60990=???Round Arch +60991=???Profile Head +60992=???Sphere +60993=???Triangle Cut +60994=???Tyrolean Dovetail +60995=???Dovetail +60996=???Free Contour +60997=???Outline +60998=???Aperture +61001=???Distance from beam start to the reference point +61002=???Distance from the reference edge to the reference point +61003=???Distance from the reference side to the reference point (orthogonal) +61004=???Angle between cut edge and reference edge +61005=???Inclination between face and reference side +61008=???Limit of the 2 ends, binary code +61009=???Inclination to the reference side +61010=???Depth: If P11 is zero, then the face of the cut dispreads to the neigbour-sides or opposite-side to referenceside +61011=???Length: If P12 and P04 equal to zero, the processing is performed along the whole component length +61012=???Angle in face at start +61013=???Angle in face at end +61015=???Distance from the reference point to the reference edge +61016=???Angle between the first cutting edge and the reference edge +61017=???Inclination of the first cutting towards the reference side +61018=???Angle between the second cutting edge and the reference edge +61019=???Inclination of the second cutting towards the reference side +61023=???Inclination between the first face and the reference side +61024=???Inclination between the second face and the reference side +61025=???Depth +61027=???Angle in face at reference edge at start +61028=???Angle in face at reference edge at end +61029=???Angle in face in opposite to reference edge at start +61030=???Angle in face in opposite to reference edge at end +61033=???Displacement to the reference side +61036=???Angle to the reference edge in the cut face +61037=???Depth, orthogonal to the reference side +61038=???Length +61041=???Distance to the reference point orthogonal to the reference side P03 = 0: Slot on one of the 4 sides of the component. P03 > 0: Slot on one of the 2 front sides of the component +61042=???Limit of the 6 faces of the slot, binary code +61043=???Angle to the reference edge in the reference side +61045=???Interior angle at reference point +61046=???Interior angle at opposite of reference point +61047=???Addition to P09 +61048=???Depth orthogonal to the reference side +61049=???Length +61050=???Thickness +61051=???Displacement of the entrance edge at reference point +61052=???Displacement of the entrance edge at opposite of reference point +61055=???Distance to the reference point orthogonal to the reference side +61056=???Limit of the 6 faces of the Frotn Slot, binary code +61059=???Angle between the longitudinal axis of the slot and the reference side +61060=???Depth +61061=???Length +61062=???Width +61065=???Location of P09/P10, if P09>0 and P10>0. If P04=-1, then the location must be defined on the machineside +61066=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole. +61067=???Angle to the reference edge in the reference area +61068=???Inclination between face 1 and reference side +61069=???Inclination between face 2 and reference side +61070=???First cut angle of the counterpart. If P09 is zero, the limit face beside face 1 is parallel to component side. +61071=???First cut inclination of the counterpart. If P10 is zero, the limit face beside face 1 is parallel to component side. +61072=???Depth 1 orthogonal to reference side +61073=???Depth 2 orthogonal to reference side +61074=???Grooving depth in the transverse direction of the component. If P13 is zero, then its value must be calculated:P13=WRS-P02 +61075=???Height Counterpart. Zero means: no limit. Measurement orthogonal to face 1 (P07). +61076=???Width Counterpart. Zero means: no limit. Measurement orthogonal to face 2 (P08). +61079=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole +61080=???Angle notch 1 to the reference edge in the reference area +61081=???Angle notch 2 to the opposite reference edge in the reference area +61082=???Inclination between base area of notches and reference side +61083=???Depth orthogonal to reference side +61084=???Width of notch 1. If this value is equal 0, then the notch is not limited. +61085=???Width of notch 2. If this value is equal 0, then the notch is not limited. +61087=???0: Reference point on referene edge. 1: Reference point on the opposite edge +61088=???Angle to the reference edge in the reference side +61089=???Depth of Half Lap +61090=???Width of Half Lap +61091=???Drill hole diameter +61094=???Displacement to the reference side +61095=???Limit of the 6 faces of the lap, binary code +61096=???Angle to the reference edge in the reference side +61098=???Angle between edge and reference side in face +61099=???Angle in the floor face +61100=???Angle between base face and one face of lap +61101=???Distance (orthogonal) from reference side to point below reference point +61102=???Length +61103=???Chamfer angle +61104=???Grooving depth (length of the lapped scarf in transverse direction). If P14 is zero, then its value must be calculated: P14=WRS-P02 +61107=???Limit of the 6 faces of the notch/rabbet, binary code +61108=???Notch/Rabbet depth +61109=???Notch/Rabbet length +61110=???Notch/Rabbet width +61113=???Depth of the Half Lap on the reference side +61114=???Depth of the Half Lap opposite of the reference side +61115=???Length of the Half Lap / Dado +61117=???Depth of Seathing Cut +61118=???Length of Seathing Cut +61120=???0: Reference point on reference edge; 1: Reference point on the opposite edge +61121=???Angle to the reference edge in the reference side +61122=???Drill hole diameter +61124=???Input of edge(s) to be beveled, binary code: Bit 0=edge 1 ; Bit 1=edge 2; Bit 2=edge 3; Bit 3=edge 4. Example: P04=9: edge 1+4; P04=3: edge 1+2 +61125=???Depth +61126=???Length: If P12 is equal to zero, the processing is performed along the whole component length. +61127=???Shape for bevel exit: 0 = orthogonal, 1 = at 45 deg, 2 = round; +61129=???Depth orthogonal to reference side of the lap 2 and 4. If P03 is zero, then its value must be calculated: P03=HRS +61130=???0:all laps are symmetric to each other; 1:lap on reference edge moved to start beam, lap in opposite of reference edge moved to end beam; 2: lap on reference edge moved to end beam, lap in opposite of reference edge moved to start beam; +61131=???P05=1: drilhole for drop rod, P05=0: no drillhole. The machines defines place and direction of the drillhole. +61132=???lap 1: Depth +61133=???lap 1: Length +61134=???lap 2: Depth +61135=???lap 2: Length +61136=???lap 3: Depth +61137=???lap 3: Length +61138=???lap 4: Depth +61139=???lap 4: Length +61140=???Distance from end of arc orthogonal to the reference side +61141=???Radius of arc +61142=???Distance reference point to center of arc +61143=???Which arc (A, B,C or D) is to produced, binary code +61145=???0:only one lap on reference side; 1:one lap on reference side and one on the opposite side +61146=???Angle to the reference edge in the reference side +61147=???Depth at reference point +61148=???Depth opposite to the reference point +61149=???Depth at reference edge +61150=???Length +61153=???Limit of the 6 faces of the pocket, binary code +61154=???Rotation angle around the local z-axis of the cuboid +61155=???Rotation angle around the local y-axis of the cuboid, rotated with P06 +61156=???Rotation angle around the local x-axis of the cuboid, rotated with P06 and P07 +61157=???Internal angle at the reference point +61158=???Depth of reference point orthogonal to reference side +61159=???Length of Half Lap +61160=???Width of Half Lap +61163=???Distance from the reference face to the reference point. P03 = 0:Drilling on one of the 4 sides of the component. P03 <> 0:Drilling on one of the 2 front sides of the component. +61164=???P03 = 0:Angle to the reference edge in the reference side. P03 <> 0:Angle in the front side. +61165=???Inclination between drilling and reference side. P03 = 0: Inclination between drilling and reference side. P03 > 0: Inclination between drilling and front side +61166=???Depth, orthogonal to reference side or front side. +61167=???Drill hole diameter +61170=???Rounding +61171=???Chamfer +61174=???Angle between axis of the tenon and reference side +61175=???Radius for P04=4 +61176=???Tenon height +61177=???Tenon width +61178=???Margin on the reference side +61179=???Margin opposite the reference side +61182=???Displacement to the reference side +61183=???Rounding +61184=???Angle between axis and reference edge +61185=???Inclination between strut and reference side +61186=???Inclination of hole side walls towards reference side +61187=???Radius for P04=4 +61188=???Mortise depth +61189=???Mortise width +61190=???Height of strut +61191=???Margin on the reference point +61192=???Margin opposite the reference point +61193=???Inclination of hole front side towards reference side +61196=???Rounding +61199=???Angle between axis of the tenon and reference side +61200=???Radius for P04=4 +61201=???Mortise depth +61202=???Mortise width +61203=???Margin on the reference side +61204=???Margin opposite the reference side +61205=???Processident of the associated tenon or dovetail tenon +61206=???Processident of the associated mortise or dovetail mortise +61209=???0:with rounding at the bottom; 1:without rounding, unbounded +61210=???Angle between edge and reference edge +61212=???Angle between axis of the tenon and reference side +61213=???Middle flattening +61214=???Angle of cone +61215=???Tenon height +61216=???Diameter of the curve: If P12 < 0, then the radius must be defined on the machineside. +61217=???Margin on the reference side +61218=???Margin opposite the reference side +61221=???Displacement to the reference side +61222=???0:with rounding at the bottom; 1:without rounding, unbounded +61223=???0:with elongation; 1:with pocket +61224=???Angle between axis and reference edge +61225=???Inclination between strut and reference side +61226=???Middle flattening +61227=???Angle of cone +61228=???Mortise depth +61229=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61230=???Height of strut +61231=???Margin on the reference point +61232=???Margin opposite the reference point +61235=???Displacement to the front side +61236=???0=with rounding at the bottom; 1=without rounding, unbounded +61237=???0=with elongation; 1=with pocket +61240=???Angle between axis of the tenon and reference side +61241=???Middle flattening +61242=???Angle of cone +61243=???Mortise depth +61244=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61245=???Margin on the reference side +61246=???Margin opposite the reference side +61249=???Position and alignment of the text. P04 = 0 if there is no text. +61250=???Angle between axis and reference edge. If P06 equals 180°, then a horizontal line is defined, P12 defines the length of the line. +61251=???Interior angle. If P07 equals zero, 2 single markings have to be produced. +61252=???Width of quadrangle. If P11 equals zero, there is only a single marking. +61253=???Height of quadrangle. If P12 equals zero, marking is limited by the edge opposite to the reference edge. +61254=???Height of text. If P13 equals zero, the machine determines the text height. +61255=???Text (String max. 256 characters) +61258=???Angle between axis and reference edge +61259=???Alignment vertical. 0 = bottom, 1=middle, 2=top +61260=???Alignment horizontal. 0 = left, 1=middle, 2=right +61261=???Alignment in case of a multiline text. 0 = left-aligned, 1=centered, 2=right-aligned. A new line must be defined with this 2 letters: \n +61262=???Letters standard or horizontal placed. 0 = standard, 1=letters horizontal placed +61263=???Height of text. If P13 equals zero, the machine determines the text height. +61266=???Depth at the reference side +61267=???Depth at the opposite of reference side +61268=???Length of the overlap +61269=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61270=???Drilling 2 diameter. Placed at 2/3 P13 +61272=???Angle of inclination of the lapped scarf base +61273=???Shape of the lapped scarf or classic data identification: 1:when cutting orthogonal to reference side; -1:when cutting orthogonal to base side; 0:classic definition, P10 and P12 are not used +61274=???Length of the lapped scarf base +61275=???Depth of the lapped scarf base +61276=???Depth of the lapped scarf base orthogonal to reference side +61277=???Length +61278=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61279=???Drilling 2 diameter. Placed at 2/3 P13 +61281=???Type of heel notch:0=normal; 1=tapered +61282=???Inclination strut +61283=???Depth step joint +61284=???Depth heel notch +61285=???Height tenon. Which implementation (A or B) is used depends on the machine +61286=???Width tenon +61289=???Type of heel notch: 0=normal; 1=tapered +61290=???Inclination between strut and reference side +61291=???Width of the notch +61292=???Depth step joint +61293=???Depth heel notch +61294=???Height of strut +61295=???Depth of mortise. Which implementation (A or B) is used depends on the machine +61296=???Width of mortise +61298=???Specification of side(s) to be planed; binary coded +61299=???Planing depth +61300=???Length of the area to be planed +61303=???Rotation angle of the first curve of the profile +61304=???Rotation angle of the profile towards the reference edge +61305=???Offset angle +61306=???Radius of the first curve +61307=???Radius of the second curve +61309=???Radius +61310=???Depth +61311=???Displacement +61312=???Depth +61313=???Displacement +61315=???Radius +61316=???Depth +61317=???Displacement +61318=???Depth +61319=???Displacement +61321=???Profile length +61322=???Depth at the reference point +61323=???Maximum depth of profile +61324=???Minimum depth of profile +61325=???Depth at the profile end +61326=???Premill: 0=round; 1=angular +61328=???Depth of the arch segment +61329=???Length of the arch segment +61331=???Type of arc (convex, concave), binary coded. See table below. +61332=???Length of lap 1 +61333=???Depth of lap 1 +61334=???Displacement arc 1 +61335=???Horizontal length arc 1 +61336=???Vertical length arc 1 +61337=???Camber arc 2 +61338=???Length of lap 2 +61339=???Depth of lap 2 +61340=???Displacement arc 2 +61341=???Horizontal length arc 2 +61342=???Vertical length arc 2 +61343=???Camber arc 2 +61344=???Length of lap 3 +61345=???Depth of lap 3 +61348=???Distance from the reference side to the reference point +61349=???Radius +61350=???Start offset +61351=???Length +61354=???Distance from the reference side to the reference point +61355=???Normal vector 1: Length of X-component +61356=???Normal vector 1: Length of Y-component +61357=???Normal vector 1: Length of Z-component +61358=???Normal vector 2: Length of X-component +61359=???Normal vector 2: Length of Y-component +61360=???Normal vector 2: Length of Z-component +61362=???Distance between "inside" an side of part +61363=???Distance orthogonal to the reference side +61364=???0:"inside" at reference edge, 1:"inside" at opposite of reference edge +61365=???0:Without rebate or mitre, -1:With mitre, >0:With rebate +61366=???Angle to the reference edge in the reference side +61367=???Width +61368=???Depth +61369=???Inclination +61370=???Height +61371=???Radius +61372=???Length of tool (part of arc) +61373=???0:Angular corner joint, 1:Straight T-wall connection +61374=???Length +61375=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61377=???Distance between "inside" an side of part +61378=???Distance orthogonal to the reference side +61379=???0:"inside" at reference edge, 1:"inside" at oppostite of reference edge +61380=???0:Without rebate or mitre, -1:with mitre, >0:with rebate +61381=???Inclination +61382=???Depth 1 +61383=???Depth 2 +61384=???0:European Dovetail, 1:American Dovetail +61385=???Length +61386=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61387=???Depth +61388=???Mode: 0=contour only, 1=countersink completely. Only for closed contours. +61389=???Contour type +61390=???Parameter depends on contour type(P13) +61391=???Parameter depends on the contour type(P13) +61400=???Reference point on referene edge +61401=???Reference point on the opposite edge +61402=???Reference point on referene edge +61403=???Reference point on the opposite edge +61404=???orthogonal +61405=???at 45 deg +61406=???round +61407=???all laps are symmetric to each other +61408=???lap on reference edge moved to end beam. lap in opposite of reference edge moved to start beam +61409=???lap on reference edge moved to start beam. lap in opposite of reference edge moved to end beam +61410=???only one lap on reference side +61411=???one lap on reference side and one on the opposite side +61412=???with rounding at the bottom +61413=???without rounding, unbounded +61414=???with elongation +61415=???with pocket +61416=???bottom +61417=???middle +61418=???top +61419=???left +61420=???right +61421=???left-aligned +61422=???centered +61423=???right-aligned +61424=???standard +61425=???letters horizontal placed +61426=???when cutting orthogonal to reference side +61427=???when cutting orthogonal to base side +61428=???classic definition, P10 and P12 are not used +61429=???normal +61430=???tapered +61431=???round +61432=???angular +61433=???"inside" at reference edge +61434=???"inside" at opposite of reference edge +61435=???Angular corner joint +61436=???Straight T-wall connection +61437=???Processing on the reference side and opposite the reference side +61438=???Processing only on the reference side +61439=???Processing only opposite the reference side +61440=???European Dovetail +61441=???American Dovetail +// ----- Custom Parameter (Q) +61451=???Profondità smusso +61452=???0=Automatico; 1=Ciclo longitudinale con lama +61453=???Spessore testimone centrale per ciclo Q02 +61454=???0=Attacco centrato; 1=Attacco interno +61455=???0=Automatico; 1=Lavorazione con fresa di lato +61456=???1=Forza Lama; 0=Automatico +61457=???1=Solo smusso +61458=???0=Automatico; 1=Massima profondità +61459=???0=Automatico; 1=Truciolatore; 2=Truciolatore di lato; 3=Fresa; 4=Fresa di lato +61460=???0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +61461=???0=Automatico; 1=Massimo raggio ammesso su tasche non passanti +61462=???Diametro utensile per Q05 +61463=???Diametro utensile per Q07 +61464=???0=Raggio su spigolo; 1=Foro su spigolo; 2=Spigolo vivo +61465=???Diametro foro quando P05=1 +61466=???0=Automatico; 1=Sgrossatura con lama +61467=???Antischeggia: 0=No; 1=Con lama; 2=Con fresa +61468=???Aumenta dimensioni tasca +61469=???Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico +61470=???0=Automatico; 1=Solo contorno ; 2=Drill or Pocket +61471=???0=Automatico; 1=Lavoro da un lato solo +61472=???Incrementare/decrementare valore P01 per fori nei tenoni +61473=???0=Foratura rompi truciolo; 1=Foratura scarico truciolo +61474=???Profondità smusso quando P05=1 +61475=???Riduzione profondità tenone +61476=???Riduzione larghezza tenone +61477=???Riduzione altezza tenone +61478=???Riduzione profondità tenone +61479=???Ridurre/Allargare sagoma tenone +61480=???Ridurre/Allargare altezza tenone +61481=???aumenta profondità mortasa +61483=???Profondità di lavoro +61484=???Aumenta dimensioni P10 +61485=???0=Automatico; 1=Truciolatore +61486=???Riduzione lunghezza P14 +61487=???Riduzione larghezza P15 +61488=???Sovramateriale finitura +61489=???Numero divisioni ondulazioni dello smusso sulla lunghezza +61490=???1=Disabilita fresatura gradini +61491=???1=Attiva smusso superiore +61492=???1=Smusso superiore con lama +61493=???Spessore legno per supporto lavorazione +61494=???Attiva antischeggia +61495=???Profondità antischeggia +61496=???Massima elevazione (0=Automatico, >10=Manuale) +61497=???0=Automatico; 1=Lama +61498=???0=Automatico; 1=Disabilita controllo lunghezza fresa +61499=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61500=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61501=???0=Automatico 1=Lavorazione con fresa orizzontale se sopra o sotto (disabilita lama) +61502=???0=Automatico 1=Usa truciolatore se sotto +61503=???0=Attacco e Uscita centrati 1=Attacco e Uscita interni +61504=???0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +61505=???0=Default; 1=Machine like LongCut +61506=???0=Default; 1=Machine with mill +// ----- EgtBEAMWALL - BTLParam ----- +61601=???SN +61602=???Abilita +61603=???Descrizione +61604=???L +61605=???W +61606=???H +61607=???Material +61608=???Richiesti +61609=???In produzione +61610=???Prodotti +61611=???Ruotare +61612=???Group +61613=???Unit Time +61614=???Parametro +61615=???Valore +61616=???Minimo +61617=???Massimo +61618=???Single member number +61619=???Assembly number +61620=???Order number +61621=???Designation +61622=???Annotation +61623=???Subgroup/Storey +61624=???Group +61625=???Package +61626=???Material +61627=???Timber grade +61628=???Quality grade +61629=???Count +61630=???Colour +61631=???Transparency +61632=???Planing length +61633=???Start offset +61634=???End offset +61635=???Transformation: Origin +61636=???Transformation: X-axis dir. vect. +61637=???Transformation: Y-axis dir. vect. +61638=???Camber: Reference side +61639=???Camber: P01,P02,P03,P04 +61640=???Part offset: ref. side fix clamp +61641=???Part offset: P11,P12,P13,P14 +61642=???Processing quality +61643=???Recess +61644=???Storey type +61645=???Element number +61646=???Layer +61647=???Module number +61648=???USERATTRIBUTE +61649=???Comment +61650=???Grain direction: X,Y,Z +61651=???Grain direction: Align +61652=???Reference side +61653=???Reference side: Align +61654=???Alignment: Location +61655=???Alignment: Endtype +61656=???Material type: Group +61657=???Material type: Specification +61658=???AUTOMATIC +61659=???VISIBLE +61660=???FAST +61661=???MANUAL +61662=???CEILING +61663=???ROOF +61664=???WALL +61665=???inactiv +61666=???BR +61667=???TR +61668=???BA +61669=???TA +61670=???HC +61671=???VC +61672=???AC +61673=???R +61674=???A +61675=???D +61676=???Batten +61677=???Cladding +61678=???Massive timber +61679=???Membrane +61680=???Gypsum Board +61681=???Gypsum Fibre +61682=???Insulation +61683=???Sheet Component +61684=???Facade Panel +61685=???Profiled Panel +61686=???Plaster +61687=???Reference side 1 +61688=???Reference side 2 +61689=???Reference side 3 +61690=???Reference side 4 +61691=???UID +61692=???Project number +61693=???Project name +61694=???Project part +61695=???GUID +61696=???Listname +61697=???Customer +61698=???Architect +61699=???Editor name +61700=???Delivery date +61701=???Export date +61702=???Export time +61703=???Export release +61704=???Language +61705=???Range +61706=???Computername +61707=???User name +61708=???Path & name of CAD-File +61709=???Path & name of BTL-File +61710=???STANDARD +61711=???EXTENDED +61712=???Vol unit +61713=???Vol tot +61714=???Time unit +61715=???Time tot +61716=???Total parts number +61717=???Total volume +61718=???Total time +61719=???Total estimed time +61720=???Remaining time +61721=???Rawpart counter +61722=???BTL part counter +61723=???Added part counter +61724=???Part in rawpart counter +61725=???Done part counter +61726=???Quantity +61727=???Print PDF +//Ware???house +61751=???Current S +61752=???Current L +61753=???StartOffset +61754=???Kerf +61755=???Offset +61756=???S Parameters +61757=???L Parameters +61758=???New Value: +61759=???W +61760=???L +61761=???Confirm +61762=???Save +61763=???Cancel +61764=???Error +61765=???Input value already present +61766=???Input value not correct +61767=???Input pair already present +61768=???One or more input values not correct +61769=???Attention +61770=???Selected parameter is equivalent to current L/S. Are you sure you want to remove it? +61771=???SectionXMaterial +61772=???Alias +61773=???Values +61774=???Quantity +61775=???Min thickness +61776=???Max thickness +61777=???Increment Max thickness of the last range before adding a new range +// +61801=???Custom +61802=???Default +61803=???L +61804=???T +61805=???Process +61806=???Section time +61807=???Part time +61808=???Name +61809=???PDN +61810=???DO +61811=???X position +61812=???Y position +61813=???Added +61814=???Done +61815=???ID +61816=???Start offset +61817=???% Used +61818=???Waste +61819=???BTL File Name +61820=???List Name +61821=???Export Date +61822=???Creation Date +61823=???Delete +61824=???Face +61825=???Group +61826=???Modify +61827=???Save +61828=???Cancel +61829=???Nesting +61830=???Viewer +61831=???Optimizer +61832=???Configuration +61833=???Optimize +61834=???Update BTL +61835=???Go to optimization +61836=???Filter type +61837=???Search +61838=???Export project +61839=???Import project +61840=???Import BTL +61841=???Copy to Clipboard +61842=???DisplayIndex +61843=???Column name +61844=???CanUserReorder +61845=???CanUserResize +61846=???CanUserSort +61847=???IsReadOnly +61848=???Visible +61849=???Variable Path +61850=???Type +// +61851=???This part modification will cause the removal of the part from {0} raw parts. Do you want to proceed anyway? +61852=???Impossible create feature with this values +61853=???Impossible create part with this values +61854=???Impossible create bar with this values +61855=???Impossible create wall with this values +61856=???Value outside minimum and maximum +61857=???Impossible to insert a quantity inferior to the number of parts already in rawparts! +61858=???Impossible to modify these values +61859=???Error in machine parameter writing +61860=???Save machine parameters modification? +61861=???Save default values modification? +61862=???Changing type second path will be deleted. Do you want to proceed? +61863=???To produce part number reached: +61864=??? from BTL; +61865=??? added. Do you want to add another one? +61866=???Selected part has different section from selected bar. Impossible to add. +61867=???Selected part lenght is more then the selected bar lenght. Impossible to add. +61868=???Selected part has different height from selected wall. Impossibl to add. +61869=???Error in macro file execution! +61870=???Impossible create a Macro without selecting a Feature or with empty name +61871=???File not found! +61872=???Impossibie deleting current project +61873=???Impossibile deleting the project because already linked to an optimization +61874=???Impossibile deleting the project because some parts are already sent to production +61875=???Do you want to save the project modifications? +61876=???Impossible creating a new file! +61877=???Save project modification before continuing? +61878=???Impossible proceding with a new unsaved project! +61879=???Type of current machine is both Beam and Wall. Select the type you want to set the project to: +61880=???Select one of the available machines and/or types. Otherwise cancel the project import. +61881=???The opened project type is not compatible with the current machine type +61882=???Do you want to save the modifications to the DataGrid columns? +61883=???The columnn specified as "{0}" in the "{1}" table in the datagrid columns ini file was not found in the program +61884=???Select the machine you want to associate to the project: +61885=???The machine linked to the opening project cannot be found among the available machines +61886=???Machine +61887=???Impossible creating the inserted rawparts quantity +61888=???How many copies of the rawpart do you want to create? +61889=???Long Drill Area +61890=???Min Rule +61891=???Can't send feedback from Optimizer if there is no open Prod +61892=???Can't proceed with an unsaved project! Please save before updating it. +// +61900=???Change paramter +61901=???Verify +61902=???Simulate +61903=???New raw part +61904=???Add to raw part +61905=???Copy part +61906=???Add part +61907=???Remove part +61908=???Copy feature +61909=???Create macro +61910=???Add feature +61911=???Remove feature +61912=???Produce rawpart +61913=???Produce all rawpart +61914=???Copy rawpart +61915=???Remove rawpart +61916=???Reorder parts +61917=???Move up part +61918=???Move down part +61919=???Remove part +61920=???Warehouse +61921=???Add project to optimization +61922=???Go to project +61923=???Statistics +61924=???Reset +61925=???Show all parts +61926=???Show solid +61927=???Show building +61928=???Verify all +61929=???Can't change machine because the Proj is already linked to a Prod +61930=???Inputs +61931=???Outputs +61932=???Calculate Flip & Rotation +61933=???Unlock Flip +61934=???Unlock Rotation +61935=???Length +61936=???Width +61937=???Offset +61938=???Kerf +61939=???Edit +61940=???Reset +61941=???Choose machine +61942=???BTL file already imported and optimized. Do you want to import it again? +61943=???BTL file already imported. Do you want to overwrite it? +61944=???Shift parts +61945=???Shift direction +61946=???Shift length +61947=???Parts can't be shifted outside the raw part +61948=???The inserted shift value is not valid +61949=???Search & Filter +61950=???Parameter Type +61951=???Parameter Value +61952=???R +61953=???A +61954=???P +61955=???D +61956=???All +61957=???Filtered +61958=???Update +61959=???Append +61960=???Check the parts you would like to add to update BTL +61961=???Change material +61962=???Project material +61963=???Warehouse material +61964=???Standard +61965=???From BTL +61966=???Save +61967=???Do NOT save +61968=???Waiting for optimizer save +61969=???Cancel +// +62500=???Supervisor +62501=???Channel +62502=???OPMode +62503=???Produce All +62504=???Done RawPart +62505=???Reset RawPart +62506=???Delete RawPart +62507=???Print Label +62508=???Done Part +62509=???Resume started processing? +// Loading +63000=???Project opening +63001=???Loading project geometries +63002=???Loading machining groups +63003=???Loading production data +63004=???Optimization opening +63005=???Loading parts +63006=???Loading graphics +63007=???Project saving +63008=???BTL file importing +63009=???Reading BTL file +63010=???Project exporting +63011=???Loading environment +63012=???Saving geometry +63013=???Saving data on Db +63014=???Modifying parameters +63015=???Part viewer opening +63016=???Adding export info +63017=???Exporting... +63018=???Project importing +63019=???Loading project +63020=???Creating imported project +63021=???Modifying materials +// ----- FromLua ----- +65001= +// ----- OmagCUT ----- +// Allgemeines +90001=AKTUELLE BEARBEITUNG +90002=DIREKTER SCHNITT +90003=CAD SCHNITT +90004=PROFIL +90005=MASCHINE +90006=OPTIONEN +// Aktuelle Bearbeitung +90101= +// Direkter Schnitt +90201=Verschiebung +90202=Einzelschnitt +90203=Mehrfache Schnitte +90204=Netz Schnitte +90205=MTH +90206=Kalibrieren +90207=Sägetest +90208=Sägesonde +90209=Schablone einlesen +90210=P1 erwerben +90211=P2 erwerben +90212=Laser +90213=Tiefe +90214=Länge +90215=Richtung +90216=Seitenwinkel +90217=Anzahl +90218=Bemaßung +90219=Zahl X +90220=Maß X +90221=Zahl Y +90222=Bemaßung Y +90223=Spindelseitiger Schnitt +90224=Säge +90225=Unentschieden +90226=Breite +90227=Überschneidung +90228=???Offset +90229=???C Axis Lock +90230=Ausführen +90231=???Polishing +90232=???Saw thickness +90241=Sägenprüfung +90242=Probing läuft ... +90243=Erfolg erfolgreich beendet +90244=Fehler beim Sägen +90245=Neuer Vorlagenname +90246=???Probing canceled by user +90250=Zeile +90251=Bogen +90252=Entfernen +90253=Schließen +90254=Speichern +90255=???Test +90256=???Verifica posizione taglio +90257=???Verifica posizione in corso... +90258=???Single drill +// Cad Schnitte +90301=Simulieren +90302=Ausführen +90303=Neu +90304=Laden +90305=Speichern +90306=Speich unter +90307=Neuer Projektname +90308=CSV +90309=Vein Match +90310=Exportieren +90311=Werkzeug +90312=Bearbeitung +90313=Fotokamera fehlgeschlagen +90314=Fehler bei NC-Programmgenerierung +90315=Fehler bei NC-Programmübertragung +90316=Nicht an das Gerät angeschlossen +90317=NC-Programm übertragen +90318=NC-Programm wird von der Maschine abgelehnt +90319=NC-Programm bereits gesendet, senden? +90320=Unterschiedliche Maschine +90321=Reduziert einige Bearbeitungen, um Störungen zu vermeiden +90322=Fehlende Werkzeuge: +90323=???Background photo taken +90324=???Contour recognition failed +90325=???Error saving statistics +90326=???Confirm restart from phase {0} ? +90327=???New Ruined Parts +90328=???Parts Area : +90329=???To be Produced : +90330=???NC program already sent, new slab ? +// NestPage +90331=Einsetzen +90332=Ablegen +90333=Teil verwerfen +90334=Alles auswählen +90335=Alle abwählen +90336=Rücksetzen +90337=???One or more parts with non-compatible thickness, material or finish +90338=???Rotation beyond the limits +90339=???Rotation impossible +90340=???Automatic nesting in progress +// SplitPage +90341=Ein / Aus +90342=Alle Ein +90343=Alle Aus +90344=Vergrößern / Verkleinern +90345=Ext / Red starten +90346=Ende Ext / Rot +90347=Start Cnt / Out +90348=Alles startet +90349=All Starts Center +90350=Automatische Berechnung fehlgeschlagen +90351=Für den Vakuumbetrieb zu groß +90352=???End Cnt/Out +90353=???All End Out +90354=???All End Center +90355=???All Extend +90356=???All Reduce +90357=???Modify +90358=???Auto +90359=Restart +// MoveRawPart +90361=Entfernen +90362=Teil zu klein: nicht verschiebbar +90363=???Selected position already occupied +90364=???Part too havy : can not be moved +90365=???Part beyond strokes : can not be moved +// SplitPage 2 +90371=???Pause On/Off +90372=???Pause +90373=???Start Modif. +90374=???End Modif. +90375=???Elongation +90376=???Invert +// Zeichnungsseite +90381=Teilenummer +90382=Messen +90383=Seitenwinkel +90384=Markiere oben +90385=???Parametric Draw +90386=???Select a contour +90387=???No editable sides +90388=???Name +90389=???Trf Data +90390=???Order Code +90391=???Order Description +90392=???Material Code +90393=???Surface Code +90394=???Thickness +90395=???Select one or more holes +90396=???Part Code +90397=???Engrave +90398=???Csv Data +90399=???All machinings updated +90400=???Top Edge +// Komponente +// Massimo 17 caratteri senza immagine und massimo 12 kon l'immagine +90401=Dreieck +90402=Rechteck +90403=Trapez +90404=Viereckig +90405=Wickler +90406=Sill +90407=Küchenoberseite +90408=Waschtischplatte +90409=Andere +90410=2Seiten 1Ang +90411=3Seiten +90412=Isosceles +90413=Richtig +90414=Scalene +90415=Scalene +90416=4Seiten 1Ang +90417=3Seiten 2Ang +90418=3Seiten 2Diag +90419=4Seiten 1Diag +90420=4Seiten 3Diag +90421=4Seiten 3Ang +90422=4Seiten 3Ang +90423=rechter Winkel +90424=Angeschrägter rechter Winkel +90425=Winkel +90426=Abgeschrägter Winkel +90427=Teil A +90428=Teil B +90429=D1 +90430=D2 +90431=Ellipse +90432=Oval +90433=Bogen +90434=Bogen LHF +90435=Bogen LLH +90436=Bogen LLF +90437=Gerundetes Rechteck +90438=Konvex +90439=Loch +90440=2 Löcher +90441=3 Löcher +90442=Bogen RHa +90443=Polygon +90444=???Bottom Hole +90445=Dxf +90446=Tropfschale +90447=Interne Funktionen +90448=Hinzufügen +90449=Entfernen +90450=???Confirm +// Einführen +90451=Schichten verwenden +90452=Gebiete verwenden +90453=Rücksetzen +90454=mm +90455=inch +90456=Geschlossene Kurven verwenden +90457=Seitenwinkel +90458=???Drip +90459=Winkel +90460=Offset +90461=Tiefe +90462=Verkürzung +90463=???DXF import +90464=???Drill bottom +90465=???Number +90466=Offset2 +90467=???Order +90468=???List +90469=???Name +// Component 2 +90470=???Recess engravings +90471=???Engravings +90472=???TriangleCH +90473=???TriangleRT +90474=???TrapeziumRtA +90475=3Seiten 2Ang +90476=???Nuova soglia +// FastGrid +90480=???Order name +90481=???N. slab +90482=???Last slab +90483=???Piece type +90484=???Insert pieces +90485=???Confirm order +// Öffnen +90491=Ungültiges Projekt +90492=Projekt mit Kollisionen. So laden Sie deaktivieren ganze Schnitte Wache. +// RawPart +90499=???Undefined Raw part +90500=???Rotation +90501=Rechteck +90502=Durch Punkte +90503=Länge +90504=Breite +90505=Dicke +90506=Versatz X +90507=Versatz Y +90508=Kerf +90509=Material +90510=Beschädigter Bereich +90511=Neu +90512=Löschen +90513=Punkte +90514=Hinzufügen +90515=Entfernen +90516=Max. Länge = +90517=Max. Breite = +90518=Negative Dicke nicht erlaubt +90519=Min. Versatz X = +90520=Min. Versatz Y = +90521=Min. kerf = +90522=Max. kerf = +90523=Rohsonde +90524=Ok +90525=Raw Sondierung +90526=Probing läuft ... +90527=Erfolg erfolgreich beendet +90528=Fehler beim rohen Sondieren +90529=Aus Zeichnung +90530=Vom Laser +90531=Schließen +90532=Fehler bei der Laserpunkt-Erfassung +90533=Gliederung +90534=Saw zu groß für Sondieren +90535=???From photo +// ChooseMachining +90536=Wählen Sie Sägen +90537=Zusatzbearbeitung wählen +90538=Bohrung wählen +90539=Wählen Sie Fräsen +90540=Keine +90541=Bohren +90542=Fräsen +90543=Beide +90544=???Choose Current Machining +90545=???Choose waterjet +90546=???Waterjet Cut +90547=???Error in the position or size of the raw +90548=Max. Versatz X = +90549=Max. Versatz Y = +90550=???Scegliere la svuotatura +// Simulation +90551=Vollständige Simulation +90552=Outstroke +90553=Werkzeugrichtung nicht erreichbar +90554=Fehler +90555=???ERROR +90556=???Error in generation! +90557=???Simulation +90558=???One step at a time +90559=???Play/Pause +90560=???Stop/Home +90561=???Pause +90562=???Stopped simulation +90563=???Mach view +90564=???Home +90565=???Time +90566=???Length +90567=???Parts Area +90568=???Usage +90569=???Estimations +90570=???Details +// FrameCut +90601=Entlang X +90602=Entlang Y +90603=Entfernen +90604=Schruppen +90605=Fertigstellung +90606=Seitenveredelung +90607=Spiegel +90608=Oberer Abstand +90609=Seitenabstand +90610=???Trim start +90611=???Trim end +90612=Einzelschnitt +90613=???Arc +90614=???Guide +90615=???Section +90616=???Guide +90617=???Rad +90618=???Ang +90619=???Error : radius smaller then section width +90620=???Error : frame creation failed +90621=???X clearance +90622=???Y clearance +90623=???Opposite Side +// Maschine +90701=Msg_Ita.xpi +90705=Maschinendaten +90706=WKZ DB +90707=Bearbeitung DB +90708=Maschine Steuerung +90709=???Statistics +90715=Neu +90716=Neu +90717=Speichern +90718=Löschen +// ExtrasDb +// param +90719=???Tool holder length +90720=???Core +90721=Name +90722=Position +90723=Kopf +90724=Beenden +90725=RPM (Drehzahl) +90726=Standard +90727=Maximum +90728=Vorschub +90729=Normal +90730=Vertikal +90731=Eintritt +90732=Austritt +90733=Kühlmittel +90734=Korrektor +90735=Aufmaß +90736=Aufmaß Z +90737=Radial +90738=Max. Leistung +90739=Min. Vorschub +90740=Maximale Tiefe +90741=Länge +90742=Durchmesser +90743=Dicke +90744=Schneidegerät +90745=???Notiz +90746=???Serial Number +90747=???Code +90748=???Supplier +90749=???End Life +// Werkzeugfamilien +90751=Sägeblatt +90752=Bohren +90753=Fräse +90754=???Cupwheel +90755=???Waterjet +90756=???Polishingwheel +//Tool Setup +90759=???Default tool position already occupied +// MachiningsDb +// param +90761=Name +90762=Schnittzugabe (RB+ mm ) +90763=Seitenwinkel +90764=Umkehren +90765=Schritttyp +90766=Mach. Seite +90767=Kopfseite +90768=Anfang +90769=Eintritt +90770=Verbindung +90771=Austritt +90772=Kurven Vornahme +90773=Toleranz +90774=Absenkung +90775=Standard +90776=Tiefenstufe +90777=Innenbogen +90778=Außenbogen +90779=Verlangsamende Länge +90780=Starten +90781=Endung +90782=Zusätzliche Tiefe +90783=Rückstellposition +90784=Werkzeug +90785=Min. Dicke +90786=Maximale Dicke +90787=Schritt +90788=Unten +90789=Seite +90790=Vertikal +// Maschinenfamilien +90791=Sägen +90792=Bohren +90793=Fräsen +90794=3D Sägen Grob +90795=3D Sägen Fein +90796=???Pocketing +90797=???Waterjet +// ComboBox Param +90801=Nein +90802=Innen +90803=Außen +90804=Beides +90821=Mitte +90822=Links +90823=Rechts +90824=Zentriert +90825=Innen +90826=Außen +90827=Cent. Verlängert +90828=Außen verlängert +90829=Zurück Erweitert +90830=Weiter Erweitert +90831=Stand verlängert +90832=Zentriert +90833=Innen +90834=Außen +90835=Überspringen +90836=Ungefähre +90837=konvex +90838=Zickzack +90839=Ein Weg +90840=Hin und zurück +90841=Halten +90842=None +90843=???Standard +90844=???Slowdown +90845=???Loop +90846=???Linear +90847=???Tangent +90848=???Glide +90849=???Helix +90850=???As lead in +// param2 +90861=Seite +90862=Geneigt Vor. +90863=GeneigtRück. +90864=Vorwärts +90865=Rückwärts +90866=Letzer Schnitt Rückwärts +90867=???Forward angle +90868=???Probing +90869=???Min dist. points +90870=???Max dist. points +90871=???External +90872=???Internal +90873=???Slowdown len. +90874=???Slowdown % +90875=???Lead in hole +90876=???Radius +90877=???LP turns +90878=???HP turns +90879=???Enable +90880=???Corners +// Barcode +90881=Barcode +90882=Block +90883=Anzahl +90884=Plattendaten +// param3 +90890=???Dist. tang. +90891=???Dist. perp. +90892=???Dist. tang. +90893=???Dist. perp. +90894=???Leadin ceramic +90895=???Length +90896=???Step +90897=???Last cut +90898=???Side angle cuts +// Alarme +90900=???Current Waterjet +90901=Aktuelles Sägeblatt +90902=Zusätzliches WKZ +90903=Laufender Bohrer +90904=Aktuelle Mühle +90905=Sicherheit Z +90906=Schnittverkürzung +90907=Ecksicherheit +90908=Ganze Schnitte +90909=Offset Durchmesser +90910=Löcher überlappen +90911=Bohrungstoler. +90912=NC Bildschirm +90913=Material +90914=Hinzufügen +90915=Entfernen +90916=Aktuelle Werkzeuge +90917=Löcherparameter +90918=Außen Radius Minimum +90919=Sicherheit Parameter +90920=Keine +90921=Fräse +90922=Mühle +90923=Beide +90924=Innen Radius Maximum +90925=Saw-Parameter +90926=Einziges Loch in der Ecke +90927=Direkte Schnitte +90928=Parkposition am Ende +90929=Fräsparameter +90930=Immer drin +90931=Schachtelung +90932=Ausgerichtet +90933=WKZ Magazin +90934=Neues +90935=Löschen +90936=Zusätzlicher Tisch +90937=???Camera +90938=???Background +90939=???Threshold +90940=???Tolerance +90941=Waschen +90942=???Are you sure you want to delete selected material? +90943=???Default setup +90944=Immer an Ecken +90945=???Select tool to probe +90946=Vorshub Start/End +90947=Länge +90948=Kürzung% +90949=Verkürzung +90950=??? Probing +//Maschine +90951=Start +90952=Stop +90953=Aktualisieren +90954=Auto +90955=Einzeln +90956=MDI +90957=Manuell +90958=Startseite +90959=Herunterladen +90960=Hochladen +90961=Aktivieren +90962=Löschen +90963=Vornehmen +90964=CN-Modus +90965=Maschinenbefehle +90966=MDI +90967=Teilprogrammtransfer +90968=???Do you want to change table? +// Optionen +90981=Sprache +90982=Die neue Sprache wird beim nächsten Softwarestart angewendet. +90983=Maßeinheit +90984=Ansichtdrehung +90985=???Side angle +90986=???Same value +90987=???Multiple values +90988=???Direct insertion of parts +90989=???Parametrics and DXF +90990=???CSV +90991=???Fast grid +90992=???Enable standard pieces creation +90993=???Text color +90994=???Slab Dxf +90995=???Slab Layer +90996=???Parts Layer +90997=???Scrap Layer +90998=???Std Thick +90999=???ColorToSideAng +91000=???Enable +91001=???Tolerance +91002=???Heel +91003=???Side Angle +91004=???Feedback +91005=???Themes +91006=???Engrave from color +91007=???Depth +91008=???Width +91009=???Start program +91010=???Select start mode +91011=???Recent project +91012=???Last opening +91013=???Last project +91014=???New project +91015=???Open folder +91016=???Show window +//Alarms2 +91051=???Machinings +91052=???Sawing +91053=???Drilling +91054=???Milling +91055=???DripSawing +91056=???DripDrilling +91057=???WaterJet +91058=???Waterjet parameters +91059=???Automatic +91060=???Aligned and Guillotine +91061=???Engraving parameters +91062=???Use Mill +91063=???Depth +91064=???Width +91065=???Precut exit +91066=???Guillotine +91067=???Add pause +91068=???Frame +91069=???Pocketing +91070=???Scasso corrente +//Statistics +91071=???Day Production +91072=???Week Production +91073=???Project +91074=???Parts Area +91075=???Cuts Area +91076=???Day +91077=???Week +91078=???Reset +91079=???To Produce Area +//Lucidature +91089=Offset +91090=???Polishing DB +91091=???Polishings +91092=???Move +91093=???Count +91094=???LeadIn/LeadOut +91095=???Height +91096=???Tools +91097=???Length +91098=???Up +91099=???Down +91100=???Load +// EgtMsgBox +91101=Änderungen im aktuellen Projekt speichern? +91102=Änderungen am aktuellen Tool speichern? +91103=Änderungen der aktuellen Bearbeitung speichern? +91104=Bereits benutzter Name +91105=Es gibt Kollisionen, einige Stücke werden geparkt. Fortsetzen ? +91106=Eine andere Datei mit demselben Namen alredy existiert? Überschreibe es? +91107=NC-ANSCHLUSS +91108=Verbindung herstellen ... +91109=Verbindung fehlgeschlagen +91110=Erfolgreich verbunden +91111=Tabelle zu verwenden? +91112=Auch Teile aus der CSV-Liste löschen? +91113=Teile nicht entfernt, da frei +91114=oder aus anderen Csv-Listen +91115=Error +91116=Option Produktionslinie nicht freigegeben +91117=Fehler beim Kopieren der Datei für OmagVIEW +91118=Parkplätze aufbewahren? +91119=Fehler bei der ruinierten Teileverwaltung +91120=???Characters \ / : * ? " < > | are not allowed +91121=???Are you sure you want to delete selected pieces? +91122=???Warning +91123=Tabelle +91124=???Salvare la lucidatura corrente? +91125=???Salvare le modifiche correnti? +91126=???Export +91127=???Import +91128=???DB WaterJet +91129=???Origine da laser +91130=???Start program? +// CSV +91201=Öffnen +91202=Einfügen +91203=Neu +91204=Entfernen +91205=???Error saving CSV file, continue anyway ? +91206=???Error reading CSV file +// OmagVIEW +91301=Alles Gut +91302=guter Teil +91303=Ruinierter Teil +91304=Label drucken +91305=Bestätigen +91306=???Print +// OmagOFFICE +// OptionPanel +91401=???RawPart +91402=???Disposition +91403=???Work +91404=???Simulation +// MachiningDbWindow +91451=???Material +91452=???Min Thickness +91453=???MaxThickness +// Errori di stampa +91461=???Error connection printer +91462=???Error formatting data +91463=???Error during print +91464=???No selection +// TopCommandBar +91501=???Save project is mandatory before export +91502=???Select export directory +91503=???Error in export +91504=???Export completed successfully +91505=???Export to machine +91506=???DXF export +// Rawpart +91551=???Error loading photo +91552=???Import photo +// VeinMatching +91601=???Export +91602=???Show Info +91603=???Edit +91604=???Verify +91605=???Magnetic +91606=???Part not selectable in this situation +91607=???Part not selectable because belonging to non-current workgroup : +91608=???Dxf parts BoundingBox too big for VeinMatching +// Generic +91651=???Ok +91652=???Cancel +91653=W° +91654=H +91655=Start +91656=Ende +// ----- OmagPHOTO ----- +// General +92001=???Db not found! +92002=???Unable starting the program +// OptionPanel +92051=???Save +92052=???Add +92053=???Cancel +92054=???Remove +92055=???Are you sure you want to delete current slab? +92056=???Etichetta +92057=???Etichetta Freccia +92058=???Sfoglia +92059=???Stampa +92060=???Seleziona +// Slab +92071=???Id +92072=???Image name +92073=???State +92074=???Project assigned to +92075=???Warehouse position +92076=???Date +92101=???Name already used +92102=???Name is mandatory +92103=???Image is mandatory +// SearchPanel +92151=???Search +92152=???Thickness tolerance +92153=???Start date +92154=???End date +92155=???Reset +//Messaggi +92200=???Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=???Avviso +92202=???Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=???Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=???Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// Allgemeines +101001=Import BTL +101002=Unentschieden +101003=Ort +101004=Optionen +// ImportPage +101101 +// Zeichnungsseite +101201=Wand +101202=Tür +101203=Fenster +101204=Hinzufügen +101205=Abbrechen +101206=Anwenden +101207=Entfernen +101208=Abstandshalter +// PlacePage +101301=Generieren +101302=Trasmit +101303=Platzieren Sie die Wand +101304=Hinzufügen +101305=Park +101306=Entfernen +101307=Schichtdicke +101308=Tischanzahl oben +101309=Fehler beim Hinzufügen +101310=Erzeugung erfolgreich +101311=Erzeugungsfehler +101312=Übertragung erfolgreich +101313=Übertragungsfehler +101314=Übertragung erfolgreich abgeschlossen +101315=Übertragung fehlgeschlagen +101316=Alle Gantries deaktiviert +101317=Erzeugungsdatei fehlt +// OptionsPage +101401=Maschinenoptionen +101402=Klebeparameter +101403=X Extra Raw +101404=Y Extra Raw +101405=Extra Kleber +101406=Plankparameter +101407=Breitenbreite +101408=Tabellenanzahl in einer Ebene +101409=Gantries-Aktivierung +101410=Leimbrücke +101411=Säulenbrücke +101421=Softwareoptionen +101422=Sprachauswahl +101423=Die neue Sprache wird beim nächsten Softwarelauf zum aktuellen +101424=Gespeicherte Projektnummer +101425=Bretter an Türen und Fenstern anbringen +101426=Vorschubklebstoff +101427=Vorverschliessender Leim +// OpenPage +101501=Ungültiges Projekt +// ----- Ende ----- diff --git a/ProgramData/EgtBeamWall/Config/EgalTechEng.txt b/ProgramData/EgtBeamWall/Config/EgalTechEng.txt new file mode 100644 index 0000000..49f7e5f --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/EgalTechEng.txt @@ -0,0 +1,3318 @@ +// Message File EgalTech English 2022/05/02 +0=ENG +// File +1=File +3=New +5=Open +6=Open
Recent files (Shift) +7=Insert +9=Save +11=Save as +13=Import +15=Export +17=Exec +19=Recent Files +20=Recent Scripts +// View +101=View +103=WFrame +105=HLine +107=Shading +109=ZoomAll +111=ZoomIn +113=ZoomOut +115=Top +117=Front +119=Right +121=Back +123=Left +125=Bottom +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Grid +136=SetView perpendicular to current Grid +137=CurveDir +139=Analyze +141=GetDist +// Grid +201=Grid +203=Top +205=Front +207=Right +209=Back +211=Left +213=Bottom +215=View +216=Set Grid perpendicular to View +217=Elevat +218=Set Grid Elevation +219=Origin +220=Set Grid Origin +221=Rotate +222=Rotate Grid
3D Rotate Grid (Shift) +223=3 Points +224=Set Grid from 3 Points +225=Perp +226=Set Grid Perpendicular to Object +227=Object +228=Set Grid from Object +// Draw +301=Draw +303=Point +304=Point
Vector (Shift)
Frame (Ctrl) +305=Line 2P +306=Line : 2 Points
Line : 2 Points with Continue (Ctrl) +307=LineSDL +308=Line : Start, Direction, Length
Line : Start, Direction Vector, Length (Shift) +309=Circle +310=Circle : Center, Point
Circle : Center, Diameter (Shift) +311=Fillet +312=Fillet : Radius
Chamfer : Dist (Shift) +313=Arc CSE +314=Arc : Center, Start, End +315=Arc 3P +316=Arc : 3 Points +317=Arc SDE +318=Arc : Start, Direction, End
Arc : Start, Direction Vector, End (Shift)
Arc : Start, Direction, End with Continue (Ctrl) +319=Rect 2P +320=Rectangle : 2 Points +321=Polygon +322=Polygon : Radius or Apothem
Polygon : Side with 2 Points (Shift) +323=Text +324=Text
Advanced Text (Shift) +399=Continue : 'L' with line, 'A' with arc +// Construct +401=Construct +403=Plane +404=Surface : between planar curves
Flat Region (Shift) +405=Extrude +406=Surface : curve extrusion +407=Revolve +408=Surface : curve revolution +409=Screw +410=Surface : curve screwing +411=Ruled +412=Surface : ruled between 2 curves +413=Merge +414=Merge Surfaces +415=Flip +416=Flip Surface Outside +417=Explode +418=Explode Surfaces or Flat Regions +419=Swept +420=Surface :sweeping a curve along another +// Edit +501=Edit +503=Delete +504=Delete Objects +505=Layer +506=Change Object Layer to Current +507=Color +508=Change Color
Remove Color (Shift)
Change Trasparency (Ctrl) +509=Invert +510=Invert Curve +511=Trim/Ext +512=Trim or Extend Curve +513=Break +514=Break Curve
Split Curve in Pieces (Shift) +515=Join +516=Join Curves
Join Curves making a Copy (Shift)
Merge Curves in Composite (Ctrl) +517=Explode +518=Explode Text or Curve in Components +519=Thick +520=Set Curve Thickness and Extrusion +521=Start +522=Change Closed Curve Start Point +// Transform +601=Transform +603=Move +604=Object Move +605=Rotate +606=Object Rotate
3D Object Rotate (Shift) +607=Mirror +608=Object Mirror
3D Object Mirror (Shift) +609=Scale +610=Object Scale
3D Object Scale (Shift) +611=Offset +612=Curve Offset +// Special +701=Special +703=Flat Parts +704=Insert DXF or NGE flat parts +705=Compo +706=Insert parametric components +// Scene : Entity selection Menu +1001=Select All +1003=Deselect All +1005=Select Window +1007=Select Part +1009=Select Layer +1011=Select Path +1013=Select Full Path +1015=Select Entity +1016=Select All Visible +// Scene : Point selection Menu + Statusbar +1101=Sketch Point +1102=Sketch Point +1103=Grid Point +1104=Grid Point +1105=End Point +1106=End Point +1107=Mid Point +1108=Mid Point +1109=Center Point +1110=Center +1111=Centroid +1112=Centroid +1113=Near Point +1114=Near Point +1115=Intersection Point +1116=Inters Point +1117=Tangent Point +1118=Tang Point +1119=Perpendicular Point +1120=Perp Point +1121=Min.Distance Point +1122=MinDist Point +1123=Exclude Surfaces +// Scene : Other Menu +1201=Drag Off +1203=Drag On +// Scene : Others +1301=Dist= +// Controller +2001=Copy (V) +2002=Error +2003=Warning +2051=The Point must be different from previous +2052=The Points must be not aligned +2053=Zero or Negative Values not allowed +2054=Two Zero or Negative Values not allowed +2055=At least one Entity is not scalable +2056=Distance too big +2057=Curve not flat (in its plane) +// Controller : Draw +2101= +// Controller : Construct +2201= +// Controller : Modify +2301= +// Controller : Transform +2401=COPY +2402=MOVE +2403=Insert Base Point +2404=Insert Target Point +2406=ROTATE +2407=Insert Center +2408=Insert Base Point +2409=Insert Angle or Rotation Point +2411=ROTATE 3D +2412=Insert First Point on Axis +2413=Insert Second Point on Axis +2414=Insert Base Point +2415=Insert Angle or Rotation Point +2416=MIRROR +2417=Insert First Point +2418=Insert Second Point +2421=MIRROR 3D +2422=Insert First Point +2423=Insert Second Point +2424=Insert Third Point +2426=SCALE +2427=Insert Center +2428=Insert Factor +2431=SCALE 3D +2432=Insert Center +2433=Insert Factors +2436=OFFSET +2437=Insert Distance +2438=Fillet +2439=Chamfer +2440=Extend +// ----- EgtCAM5 ----- +5001=DRAW +5002=MACHINING +5003=Tool Db +5004=Machining Db +5005=Options +5006=Tool Db +5007=Mach Db +5008=Machine Options +5009=SetUp Db +5010=SetUp Db +5020=Machining Table Db +//Top CommandBar +5101=New +5102=Open
Open recent File (Right button) +5103=Save +5104=Save as +5105=Insert +5106=Import +5107=Export +5108=Exec Script
Exec recent Script (Right button) +5109=Options +5110=Can't find support address. +5111=Save current file before sending feedback? +5112=Send a feedback to {0} with the {1} directory attached. +5113=Feedback +5114=Feedback mail ready. +// Draw Panel +5150=Extract Free Edges of Surfaces and Flat Regions +5151=Join Surfaces and Flat Regions +5152=Subtract Surfaces and Flat Regions
Cut Surface with Reverse Surface (Shift) +5153=Intersect Surfaces and Flat Regions
Cut Surface with Surface (Shift) +5154=Points, Curves and Faces from Surfaces Intersection +5155=Linear Dimension
Aligned Dimension (Shift) +5156=Circle 3 Points +5157=Extract Edges of Surface Faces and Flat Regions Parts +5158=Extract Face from Surface +5159=Arc Flip
Arc Explementary (Shift) +5160=Modify Shape +5161=Add Point
Modify in Arc (Shift)
Close Curve Composite (Ctrl) +5162=Remove Point
Modify in Line (Shift)
Open Curve Composite (Ctrl) +5163=Approx Curve
Approx Curve with Lines (Shift) +5201=Point
Vector (Shift)
Frame (Ctrl) +5202=Line 2 Points
Line 2 Points with Continue (Ctrl) +5203=Line Point Direction Length
Line Point Direction vector Length (Shift) +5204=Circle Center Point +5205=Circle Center Diameter +5206=Arc Center Start End points +5207=Arc 3 Points +5208=Arc Start point Direction End point
Arc Start point Direction vector End point (Shift)
Arc Start point Direction End point with Continue (Ctrl) +5209=Fillet +5210=Chamfer +5211=Rectangle 2 Points +5212=Polygon +5213=Polygon Side +5214=Text
Advanced Text (Shift) +5215=Plane from boundary curves
Flat Region (Shift) +5216=Extrude +5217=Revolve +5218=Screw +5219=Ruled +5220=Merge Surfaces +5221=Explode Surfaces and Flat Regions +5222=Invert Surface and Flat Regions +5223=Delete +5224=Change Layer
Change Layer with Transformations (Shift) +5225=Change Transparency +5226=Reset Color +5227=Change Color +5228=Invert Curve +5229=Change closed Curve Start point +5230=Trim or Extend Curve +5231=Break Curve +5232=Split Curve +5233=Join Curves
Join Curves making a Copy (Shift)
Merge Curves in Composite (Ctrl) +5234=Explode Curves and Texts +5235=Thick and Extrusion Curve +5236=Move +5237=Rotate +5238=Rotate 3D +5239=Mirror +5240=Mirror 3D +5241=Scale +5242=Scale 3D +5243=Offset +5244=2D Draw +5245=3D Draw +5246=Modify +5247=Transform +5248=Swept (Section, Guide) +5249=Edit Text +// Grid View Panel +5251=Wireframe +5252=Hidden Lines +5253=Shading +5254=Zoom All +5255=Zoom In +5256=Zoom Out +5257=Top View +5258=Front View +5259=Left View +5260=Back View +5261=Right View +5262=SW Isometric View +5263=SE Isometric View +5264=NE Isometric View +5265=NW Isometric View +5266=Show Curve Direction +5267=Analyze +5268=Distance +5269=Top Grid +5270=Front Grid +5271=Right Grid +5272=Back Grid +5273=Left Grid +5274=Bottom Grid +5275=Grid From View +5276=Grid Elevation +5277=Grid Origin +5278=Grid Rotation
Grid 3D Rotation (Shift) +5279=Grid From 3 Points +5280=Grid Perpendicular to Curve +5281=Grid From Object +5282=View From Grid +5283=Zoom Selection +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=END +5302=Outstroke +5303=Tool direction unreachable +5304=Error +5305=ERROR +5306=Error in generation! +5307=Simulation +5308=One step +5309=Play/Pause +5310=Stop/Home +5311=PAUSE +5312=STOP +5313=Can't exit now. Stop the Simulation or wait until the end of it! +5314=HOME +5315=WARNING +5316=Virtual Milling +5317=Error in estimates calculation! +5318=Estimation file missing +5319=Collision! +5320=INFORMATION +5330=GENERATE +5331=The project must be saved before generated. Save it ? +5332=Generation completed successfully +5333=The license does not allow NC Generation +5340=Estimations +5341=Total time +5342=Total length +5343=Details +5344=Estimations details +// Draw Option +5351=Properties +5352=New Part +5353=New Layer +5354=Color +5355=Drawings Parameters +5356=Select +5357=Deselect +5358=Name +5359=Info +5360=Relocate +5361=Copy +5362=Delete +5363=Save +5364=Show +5365=Ok +5366=Delete Confirm +5367=Workpiece, do you want to delete it? +// Operation +5401=Operations +5402=Operation Parameters +5403=Apply Machining +5404=New Mach +5405=New Disp +5406=Delete +5407=Generic +5408=Move Up +5409=Move Down +5410=Update +5411=Update completed successfully +5412=New Machinings +5413=Tool Preview +5414=Next +5415=Prev +5416=Duplicate +5417=Copy to Db +5418=Machining name in Db +5419=Machining adding failed +5420=Rename +5421=Name can not start with "Disp" +5422=Name already used. +5423=Machining cannot be applied due to the following reasons: +// Disposition +5431=Ok +5432= +5433=New +5434=Remove +5435=Length +5436=Width +5437=Height +5438=Position +// Disposition Errors +5461=SCRIPT EXECUTION ERROR +5462=Error executing automatic disposition script +5463=Error executing machining init script +5464=Error executing machining exit script +// Mach Group +5501=Are you sure you want to reset the Machining Group ? +5502=Are you sure you want to delete the Machining Group ? +5551=There are no Machining Groups :
select the parts to insert and
repeat the command to create the first one. +5552=Do you want to create a new Machining Group
with the selected parts? +// Tools Db Page +6001=Drillbit +6002=Sawblade +6003=Mill +6004=Mortise +6005=Compo +6006=Long drill +6007=Flat saw +6008=No tip mill +6009=Chisel +6010=WaterJet +6051=Compensation +6052=Exit +6053=Type +6054=Coolant +6055=Corner Radius +6056=Diameter +6057=Total Diameter +6058=Feed +6059=End Feed +6060=Start Feed +6061=Tip Feed +6062=Length +6063=Total Length +6064=Max Material +6065=Longitudinal Offset +6066=Radial Offset +6067=RPM +6068=Side Angle +6069=Max RPM +6070=Thick +6071=Max Absorption +6072=Min Feed +6073=Draw +6074=Head +6075=Name +6076=Notes +6077=Tool Changer Position +6078=Position +6079=Distance +6080=Overtable +// Tools Errors +6100=Save the modified tool? +6101=SAVE +6102=File has to be .nge +6103=File does not exist or is not Nge type +6104=ToolMaker does not exist for this kind of tool +6105=Impossible creating tool with this parameter +6106=MaxMat value must be greater than 0 +6107=MaxMat value must be less than Len +6108=Thick value must be greater than 0 +6109=Diam value must be greater than 0 +6110=Len value must be greater than 0 +6111=RPM value must be less than MaxRPM +6112=Invalid Name +6113=Length value must be less than Total Length +6114=Length value must be greater than Max Material +6115=Total Length must be greater than 0 +6116=Total Length must be greater than Length +6117=Max Material must be less than 1/3 Diameter +6118=Diameter must be less than Total Diameter +6119=Diameter must be greater than 3 times Max Material +6120=Total Diameter must be greater than 0 +6121=Length too small with toolholder +6122=Are you sure you want to delete +6123=? +6124=DELETE +6125=SetUp configuration file not found! +6126=Error +6127=Head value must be set +6128=Exit value must be set +6129=Invalid tool, correct or delete it before exit Tool Db. +6130=Impossible reloading Tool database. If the machine dir is on a server, verify the connection is active. +6131=Thick value must be different than 0 +6132=Side Angle value must be smaller than 90 +6133=Side Angle value must be bigger than -90 +6134=Total Length must be greater than Length + Thick +6135=Corner Radius value is too big +6136=Thick value is too small for insert radius +6137=Calculated Diameter must be less than Total Diameter +6138=Calculated Diameter is less than 0 +6139=Calculated Diameter is less or equal than 0 +6140=MaxMat value must be greater than Corner Radius +6141=Calculated MaxMat must be >= 0 +6142=Corner Radius must not exceed half Thick +6143=Save tool +6144=Tool modified! All tools must be saved before changing activations. Save tool {0}? +6145=Position already occupied! +6146=Position not defined! +// Machinings Db Page +6201=Drilling +6202=Sawing +6203=Milling +6204=Pocketing +6205=Mortising +6206=Sawroughing +6207=Sawfinishing +6208=Gen Machining +6209=Chiseling +6210=Surface Roughing +6211=Surface Finishing +6212=WaterJet +6251=Invert +6252=Leave Tab +6253=Type +6254=Work Side +6255=Head Side +6256=Lead In +6257=Link +6258=Lead Out +6259=Curve Use +6260=Step Type +6261=Sub Type +6262=Lead Link Type +6263=RPM +6264=Feed +6265=Start Feed +6266=End Feed +6267=Tip Feed +6268=Radial Offset +6269=Longitudinal Offset +6270=Depth +6271=Side Angle +6272=Approximation +6273=Start Safety Length +6274=Start Slow Length +6275=End Slow Length +6276=Throu Add Length +6277=Step +6278=Return Position +6279=Length +6280=Distance +6281=Height +6282=Angle +6283=L.In Tangent Distance +6284=L.In Perp. Distance +6285=L.In Elevation +6286=L.In Comp. Length +6287=L.Out Tangent Distance +6288=L.Out Perp. Distance +6289=L.Out Elevation +6290=L.Out Comp. Length +6291=Start Add. Length +6292=End Add. Length +6293=Step External Arc +6294=Step Internal Arc +6295=Side Step +6296=Vertical Feed +6297=Name +6298=Tool +6299=Depth +6300=Notes +6301=Overlap +6302=Offset +6303=Sub Type +6304=SCC +6305=None +6306=Standard +6307=Opposite +6308=AuxDir X+ +6309=AuxDir X- +6310=AuxDir Y+ +6311=AuxDir Y- +6312=AuxDir Z+ +6313=AuxDir Z- +6314=Nearest AuxDir +6315=Farthest AuxDir +6320=Center +6321=Left +6322=Right +6323=Extend +6324=Standard +6325=Strict +6326=Out +6327=Extend Central +6328=Extend Out +6329=None +6330=Linear +6331=Tangent +6332=Glide +6333=Helix +6334=Extend Prev +6335=Extend Next +6336=Extend Both +6337=As Lead In +6338=Skip +6339=Approx +6340=Convex +6341=Keep +6342=ZigZag +6343=Oneway +6344=Spiral +6345=To And From +6346=Along +6347=Across +6348=Spiral In +6349=Spiral Out +6350=Advanced +6351=Invert tool direction +6352=Face machining +6353=Not defined +6354= Parallel +6355= Orthogonal +6356= Orthog. Up +6357=Down +6358=Top +6359=Front +6360=Back +6361=Left +6362=Right +6363=Contour +6364=Suggested Angles +6365=Blocked Axis +6366=Max count +6367=Min count +// Machining errors +6370=Save the modified machining? +6371=SAVE +6372=Invalid name +6373=Characters \ / : * ? " < > | are not allowed +6374=Are you sure you want to delete +6375=? +6376=DELETE +6377=Impossible reloading Machining database. If the machine dir is on a server, verify the connection is active. +6378=Oscillation +6379=Amplitude +6380=Ramp Length +6381=Flat Length +// Machining Option Page +6401=Safe Z +6402=Split Arcs +6403=Never +6404=Gen plane +6405=No XY plane +6406=Always +6407=Default Setup +6408=Safe Z bottom aggregate +6409=Holes tolerance +// SetUp Window +6451=SetUp +6452=Apply +6453=Save +6454=Retrieves +6455=Auto +6456=Apply current setup before exit? +6457=New +// SetUp Errors +6471=Error +6472=Warning +6473=Can't find tool +6474=in Tool Database. +6475=The tool's default position is not valid. +6476=Tools not setup because their default position is alredy occupied: +6477=SetUp configuration file doesn't exist! +6478=SetUp configuration use a head that doesn't exist on the machine! +6479=Error loading default setup +// Option Page +6501=Current language +6502=The new language will take effect after restart. +6503=Curves +6504=Surfaces +6505=Curves & Surfaces +6506=Selecting geometry +6507=New machining is the last one +6508=Use disposition script +6509=Measure Unit +6510=View top color +6511=View bottom color +6512=Default color +6513=Geometric tolerance +6514=Generic +6515=CAD +6516=CAM +6517=Grid color +6518=Smoothed surfaces +6519=Import +6520=DXF +6521=STL +6522=Images +6523=Export +6524=Image +6525=Width (pixel) +6526=Height (pixel) +6527=Update Machine +6528="{0}" machine already exists,
what do you want to do ? +6529=File {0} does not contain a machine. +6530=The machine "{0}" has been successfully updated. +6531=Replace +6532=Update +6533=Cancel +6534=Warning +6535=The update of the "{0}" machine failed. +6536=Thick lines +6537=Extra line length +6538=Arrow length +6539=Text distance +6540=Measuring unit +6541=Decimal +6542=Font +6543=Text height +6544=Dimension +6545=Current unit +6546=Other +6547=Measuring unit +6548=Scale factor +6549=Export Current Machine +6550=Select the folder where you want to save the machine +6551=The export of the "{0}" machine failed. +6552=The machine "{0}" has been successfully exported. +6553=Update Licence +// Heads +6601=Vertical +6602=Horizontal +6603=2 exit aggr. +6604=3 exit aggr. +6605=4 exit aggr. +6606=3 axis head +6607=4 axis head +6608=5 axis head +6609=Shuttle 1 +6610=Shuttle 2 +6611=Carousel +6612=Gang drill +6613=Multi chisel +6614=Bottom aggr. +6615=5 axis saw +6616=Chainsaw +6617=1 exit aggr. +6618=Probe head +6619=Floating 360deg +6620=2nd 5 axis head +6621=Horizontal drill +6622=Mortiser +6623=2nd 5 axis saw +6624=1 exit tilt. aggr. +6625=Extruder +6799= +// StatusBar +6801=Machines dir not found. EgtCAM5 wil be run in CAD-ONLY mode. +// Doors +8001=Create new MTable +8002=Save MTable +8003=Save MTable As +8004=Delete MTable +8005=Save MTable file +8006=Are you sure to delete this MTable? +8007=Save the modified MTable? +8008=Active Machines List +8009=Machine Name +8010=Nc Generate +8011=Make Raw +8012=On +8013=Geometry Name +8014=Operation +8015=MId +8016=Shift +8017=Machining Type +8018=Machining 1 +8019=Machining 2 +8020=Machining 3 +8021=Add Machine +8022=Remove Machine +8023=Add Machining +8024=Remove Machining +8025=CURR +8026=Set active MTable +8027=GId +8028=Property +8029=Machining +8030=Join +// Door errors +8101=Error +8102=Error running Ddf file +8103=Warning +8104=MTable dir path not found +8105=MTable dir not exist +8106=Missing configuration files in MTable dir +8107=Unknown error +8108=This MTable is currently the active one. +8109=You can't delete it. +8110=Are you sure you want to delete the selected machining? +8111=DELETE +8112=Are you sure you want to delete the selected machine? +8113=Can't find {0} machine dir. If the machine dir is on a server, verify the connection is active. +8114=Try to reload the machine? +8115=Can't find {0} dir. If the Doors dir is on a server, verify the connection is active. +8116=Try to reload Doors dir? +8117=Execution error (see log file) +// GunStock +8201=New Part +8202=Gunstock new part +8203=Modify Part +8204=Gunstock modify part +8205=Gunstock parameters +8206=File name +8207=Description +8208=Ok +8209=Cancel +8210=must have a value. +8211=The value has to be between +8212=and +8213=Rawpart dimensions +// GunStock errors +8251=Error +8252=Error running Gunstock environment +8253=Error reading model file +8254=Error writing part file +// ----- Beams & Walls ----- +9000=Beam machining tables +9001=On +9002=Name +9003=Type +9004=Add +9005=Delete +9006=Save +9007=Save modifications? +9008=Error +9009=Impossible to open Beam Machining Editor.
Can't find config files. +9010=Wall machining tables +9011=Impossible to open Wall Machining Editor.
Can't find config files. +// ----- Errors ----- +10001=Error +10002=Error on new file +10003=Error opening file +10004=Error saving file +10005=File type unknown +10006=Error importing file +10007=Error exporting file +10008=Error loading or creating Machining Group +10009=Missing file +// Missing Key Window +10101=Error +10102=Missing Protection Key. +10103=Insert Dongle and restart the program. +10104=Ok +10105=Program without licence. +10106=Load Licence and restart the program. +10107=Run GetMachineId and send results to supplier. +// Numeric virtual keyboard +10201=Wrong Expression +// ----- MessageBox ----- +15001=Error +15002=Warning +15003=Information +15010=Internal error (see log file) +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Wrong Expression +// EgtCalculatorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Canc +20043=YES +20044=NO +// ----- EgtWPFLib5 ----- +// EgtFileDialog +30001=Save +30002=Cancel +30003=alredy exists. +30004=Do you want to replace it? +30005=File name: +30006=Open +30007=ERROR +30008=Name can't be empty! +30009=WARNING +30010=File Name +30011=Folder Name +// Top CommandBar +30501=New +30502=Open +30503=Save +30504=Save as +30505=Insert +30506=Import +30507=Export +30508=Exec +30509=Options +30510=Can't find support address. +30511=Save current file before sending feedback? +30512=Send a feedback to {0} with the {1} directory attached. +30513=Feedback +30514=Feedback mail ready. +// Grid View Panel +30801=Wireframe +30802=Hidden Lines +30803=Shading +30804=Zoom All +30805=Zoom In +30806=Zoom Out +30807=Top View +30808=Front View +30809=Left View +30810=Back View +30811=Right View +30812=SW Isometric View +30813=SE Isometric View +30814=NE Isometric View +30815=NW Isometric View +30816=Show Curve Direction +30817=Analyze +30818=Distance +30819=Top Grid +30820=Front Grid +30821=Right Grid +30822=Back Grid +30823=Left Grid +30824=Bottom Grid +30825=Grid From View +30826=Grid Elevation +30827=Grid Origin +30828=Grid Rotation +30829=Grid From 3 Points +30830=Grid Perpendicular to Curve +30831=Grid From Object +30832=View From Grid +// MachGroupPanel +30901=New Mach Group +30902=Name: +30903=Machine: +// ToolDbWindow +31001=Drillbit +31002=Sawblade +31003=Mill +31004=Mortise +31005=Compo +31006=Long drill +31007=Flat saw +31008=No tip mill +31009=Chisel +31010=Waterjet +31051=Compensation +31052=Exit +31053=Type +31054=Coolant +31055=Corner Radius +31056=Diameter +31057=Total Diameter +31058=Feed +31059=End Feed +31060=Start Feed +31061=Tip Feed +31062=Length +31063=Total Length +31064=Max Material +31065=Longitudinal Offset +31066=Radial Offset +31067=RPM +31068=Side Angle +31069=Max RPM +31070=Thick +31071=Max Absorption +31072=Min Feed +31073=Draw +31074=Head +31075=Name +31076=Notes +31077=Tool Changer Position +31078=Position +31079=Drilling +31080=Cutting edge +// ToolDb Errors +31100=Save the modified tool? +31101=SAVE +31102=File has to be .nge +31103=File does not exist or is not Nge type +31104=ToolMaker does not exist for this kind of tool +31105=Impossible creating tool with this parameter +31106=MaxMat value must be greater than 0 +31107=MaxMat value must be less than Len +31108=Thick value must be greater than 0 +31109=Diam value must be greater than 0 +31110=Len value must be greater than 0 +31111=RPM value must be less than MaxRPM +31112=Invalid Name +31113=Length value must be less than Total Length +31114=Length value must be greater than Max Material +31115=Total Length must be greater than 0 +31116=Total Length must be greater than Length +31117=Max Material must be less than {0} +31118=Diameter must be less than Total Diameter +31119=Diameter must be greater than 3 times Max Material +31120=Total Diameter must be greater than 0 +31121=Length too small with toolholder +31122=Are you sure you want to delete +31123=? +31124=DELETE +31125=SetUp configuration file not found! +31126=Error +31127=Head value must be set +31128=Exit value must be set +31129=Invalid tool, correct or delete it before exit Tool Db. +31130=Impossible reloading Tool database. If the machine dir is on a server, verify the connection is active. +31131=Thick value must be different than 0 +31132=Side Angle value must be smaller than 90 +31133=Side Angle value must be bigger than -90 +31134=Total Length must be greater than Length + Thick +31135=Corner Radius value is too big +31136=Thick value is too small for insert radius +31137=Calculated Diameter must be less than Total Diameter +31138=Calculated Diameter is less than 0 +31139=Calculated Diameter is less or equal than 0 +31140=MaxMat value must be greater than Corner Radius +31141=Calculated MaxMat must be >= than 0 +31142=Cutting edge must be greater than 0 +31143=Cutting edge must be less than Len +// ImportExportToolWindow +31161=Import +31162=Export +31163=Tools +31164=Tool already existing in DB. Overwrite? +31165=Tool will be imported with the name followed by "_imp" +31166=The following Tools have been imported succesfully: +31167=Reset +// MachiningDbWindow +31201=Drilling +31202=Sawing +31203=Milling +31204=Pocketing +31205=Mortising +31206=Sawroughing +31207=Sawfinishing +31208=Gen Machining +31209=Chiseling +31210=Waterjetting +31211=Surffinishing +31251=Invert +31252=Leave Tab +31253=Type +31254=Work Side +31255=Head Side +31256=Lead In +31257=Link +31258=Lead Out +31259=Curve Use +31260=Step Type +31261=Sub Type +31262=Lead Link Type +31263=RPM +31264=Feed +31265=Start Feed +31266=End Feed +31267=Tip Feed +31268=Radial Offset +31269=Longitudinal Offset +31270=Depth +31271=Side Angle +31272=Approximation +31273=Start Safety Length +31274=Start Slow Length +31275=End Slow Length +31276=Throu Add Length +31277=Step +31278=Return Position +31279=Length +31280=Height +31281=Angle +31282=Distance +31283=Tangent Distance +31284=Perp. Distance +31285=Elevation +31286=Comp. Length +31287=Min count +31288=Max count +31291=Add. Length +31293=Step External Arc +31294=Step Internal Arc +31295=Side Step +31296=Vertical Feed +31297=Name +31298=Tool +31299=Depth +31300=Notes +31301=Overlap +31302=Offset +31303=Sub Type +31304=SCC +31305=None +31306=Standard +31307=Opposite +31308=AuxDir X+ +31309=AuxDir X- +31310=AuxDir Y+ +31311=AuxDir Y- +31312=AuxDir Z+ +31313=AuxDir Z- +31314=Nearest AuxDir +31315=Farthest AuxDir +31320=Center +31321=Left +31322=Right +31323=Extend +31324=Standard +31325=Strict +31326=Out +31327=Extend Central +31328=Extend Out +31329=None +31330=Linear +31331=Tangent +31332=Glide +31333=Helix +31334=Extend Prev +31335=Extend Next +31336=Extend Both +31337=As Lead In +31338=Skip +31339=Approx +31340=Convex +31341=Keep +31342=ZigZag +31343=Oneway +31344=Spiral +31345=To And From +31346=Along +31347=Across +31348=Spiral In +31349=Spiral Out +31350=Advanced +31351=Invert tool direction +31352=Face machining +31353=Not defined +31354= Parallel +31355= Orthogonal +31356= Orthog. Up +31357=Down +31358=Top +31359=Front +31360=Back +31361=Left +31362=Right +31363=Contour +31364=Suggested Angles +31365=Blocked Axis +31366=Last backward feed +31367=Backward step +31368=Tilted step +31369=Tilted back step +31370=Forward angle +31371=Probing +31372=Min dist. points +31373=Max dist. points +31374=External +31375=Internal +31376=Slowdown len. +31377=Slowdown % +31378=Lead in hole +31379=Radius +31380=LP turns +31381=HP turns +31382=Oscillation +31383=Amplitude +31384=Ramp Length +31385=Flat Length +31386=Generic +31387=Advanced +31388=Tang+Perp +31389=Perp+Tang +//MachiningTreeView +31391=Standard +31392=Slowdown +31393=Loop +31394=Enable +31395=Add Length +31396=Start +31397=End +31398=System notes +31399=Epicycles radius +31400=Epicycles distance +// MachiningDb Errors +31401=Save the modified machining? +31402=SAVE +31403=Invalid name +31404=Characters \ / : * ? " < > | are not allowed +31405=Are you sure you want to delete +31406=? +31407=DELETE +31408=Impossible reloading Machining database. If the machine dir is on a server, verify the connection is active. +31409=Machine material not recognized +31410=Invalid machining, correct or delete it before exiting. +31411=Length must be positive +31412=Distance must be positive +31413=Height must be positive +31414=Angle must be between {0}° and {1}° +31415=Max count must be null or positive +31416=Max count must be equal or greater than Min +31417=Min count must be null or positive +31418=Min count must be equal or less than Max +31419=Enabling {0} will disable {1}. Continue? +// ImportExportMachiningWindow +31450=Import +31451=Export +31452=Machinings +31453=Machining already existing in DB. Overwrite? +31454=Machining will be imported with the name followed by "_imp" +31455=The following Machinings have been imported succesfully: +31456=Reset +// SetUp Window +31501=SetUp +31502=Apply +31503=Archive +31504=Retrieves +31505=Auto +31506=Apply current setup before exit? +// SetUp Errors +31551=Error +31552=Warning +31553=Can't find tool +31554=in Tool Database. +31555=The tool's default position is not valid. +31556=Tools not setup because their default position is alredy occupied: +31557=SetUp configuration file doesn't exist! +31558=SetUp configuration use a head that doesn't exist on the machine! +31559=Error loading default setup +// Simulation +31601=Complete simulation +31602=Outstroke +31603=Tool direction unreachable +31604=Error +31605=ERROR +31606=Error in generation! +31607=Simulation +31608=One step at a time +31609=Play/Pause +31610=Stop/Home +31611=Pause +31612=Stopped simulation +31613=Can't exit now. Stop the Simulation or wait until the end of it! +31614=WARNING +31615=Estimation file missing +31616=Estimation details +//MachiningDbWindow/ToolDbWindow buttons +31701=New +31702=Save +31703=Remove +31704=Edit +//Db Waterjet +31751=Waterjet Db +31752=Thickness +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=Do you want to save edits? +// ----- EgtDOORCreator ----- +//General +50001=Width +50002=Height +50003=Thickness +50004=Swing +50005=Lock edge +50006=Hinge edge +50007=Top +50008=Bottom +50009=Type +50010=Corner +50011=Extension +50012=Side +50013=Offset wide side +50014=Back set +50015=Top to center +50016=Bottom rail +50017=Lock stile +50018=Offset from center +50019=Point to pocket +50020=Pocket length +50021=Pocket offset narrow side +50022=Point to arm +50023=Arm length +50024=CenterHung +50025=Offset +50026=Offset intermediate +50027=Radius +50028=Top rail +50029=Position +50030=Length +50031=Template +50032=Up +50033=Down +50034=Shape +50035=Hinge +50036=Top to top application +50037=Center from top application +50038=Center from top lock +50039=Depth +50040=General +50041=Center +50042=Thru +50043=Face to center line application +50044=Edge Type +50045=Over Material +50046=Send Feedback +50047=Weight +50048=Angle +50049=Face +50050=Secure +50051=Keyway +50052=Brand +50053=Folder +50054=Main Folder +50055=Jamb +50056=Light Up +50057=Light Lock +50058=Light Bottom +50059=Light Hinge +50060=Thickness Head +50061=Overlap Hinge +50062=Overlap Lock +50063=Overlap Top +50064=Delta T +50065=Exterior +50066=Number of Doors +50067=Jambs and Doors +50068=Order +50069=Disposition +50070=Customer +50071=Inv. Lock prof. +//Compo Name +50072=Flush Bolt +50073=Flush Pull +50074=Hinge +50075=Lock +50076=Louver Cut Out +50077=Mail Slot +50078=Over Head +50079=Pivot +50080=Roller Latch +50081=Stops And Closer +50082=Strike +50083=Edge pull +50084=Peep hole +50085=Light cut out +50086=Groove +50087=Rabbet +50088=EPT +50089=Raceway +50090=Face Decoration +//error messages +50100=Directory not founded +50101=Error +50102=Failed reading DDF file. Missing needed parameter {0}. +50103=Failed reading value +50104=Failed reading DDF file row # +50105=Row +50106=Invalid value in +50107=Empty file. +50108=You can not add a compo if there is not a door! +50109=Do you want to save this file ({0}) ? +50110=Question +50111=Add new door +50112=Remove door +50113=New Door +50114=File name already exists in the current directory ({0}). +50115=Caution +50116=Do you want to delete this file ({0}.ddf)? +50117=Confirm deleting ({0})?. +50118=Information +50119=Error in reading messages. There is no match with the number {0}. +50120=Error reading name {0} in {1}. Expected numeric match. +50121=Error reading {0} param in {1} compo: do not exist. +50122=Error in {0} param in {1} compo. +50123=Error reading {0} param in {1} compo: do not exist list. +50124=Error reading {0} param in {1} compo: {2}. +50125=Error in {0} param in {1} compo: do not exist value. +50126=Delete +50127=Error in EgtLoadMessages +50128=You can not save a file if there is not a door! +50129=Error in Project scene creation +50130=Error in reading: line {0}. +50131=Error in reading {0}: line {1}. Expected ':' after the name. +50132=Error in reading {0}: line {1}. Expected 'template' or 'shape'. +50133={0} has not been created. +50134=Error reading 'Template' in file {0}\{1}. Expetcted name. +50135=Error reading 'Template' in file {0}\{1}. File {0}\{2} .lua does not exist. +50136=Error in reading {0}: line {1}. It does not exist in the list of components in file 'Default.ini'. +50137=Error in reading {0}: line {1}. It is not a member of the list. +50138=This param will be initialized by default. +50139=Error in reading: line {0}. Expected {1}. +50140=All missing params will be initialized by default. +50141=Invalid expression in {0}. +50142=Remove compo +50143=Invalid expression. +50144=Warning +50145=Impossible to create the current door. +50146=Do you want to open a template? +50147=Error expression in {0}. {1} does not match anything. +50148=Invalid value. +50149=Caution: Weight is setted in OptionPage. Do you want to remove? +50150=Caution: Weight is setted in DDF. Do you want to add? +50151={0} is not a member of the current list of EdgeType. Check Bevel in option page. +50152=Do you want to save this file ({0})? +50153=Caution. Weight is setted in the current door. Do you want to remove? +50154=It is the bevel of the current door. Do You want to proced? +50155=Impossible to create a template if there is not a door! +50156=Error in reading ddf: door is not completed or ddf has been slpitted by '---' bad. +50157=Script Lua ( {0}\{1} )has not been found. +50158=Bevel {0} can not be acceptable in Jamb. +50159=Missing parameter in ddf! +50160=File {0} in directory {1} has not been found. +50161=parameter +50162=In file {0} param 'Default' must be numeric. +50163=Error in reading General Assembly in DDF +50164=In General Assembly: +50165=CompoDir not found : +50166=Jamb compo does not exist +50167=Empty Line +50168=No matching param +50169=Door disposition has been modify. +50170=Incongruity between the bevel, it has been resolved by default. +50171=In file StdTempate.ini is missing numeric param in [Type]. +50172=File does not exist. +50173=Definition type is not correct: +50174=Missing name of the new template! +50175=The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=Error in copying: {0} +50177=Do you want to save the current changes? +50179=Doors Compo Default.ini not found in {0} . +50180=Warning : {0} does not exist. +50181=Error in creating the print image +50182=Error executing print +50183=Some Doors could use this hardware, do you want to proceed deleting? +50184=Impossible to delete Hardware if there is no Hardware selected! +50185=Impossible to duplicate Hardware if there is no Hardware selected! +50186=Project must be saved before copying +50187=Do you want to copy all files ? {0} (No to copy only the current file) +50188=Export to machine +50189=Machine Directory not found +50190=Error in copying: {0} +50191=Impossible to copy a door if there is not a door! +50192=Impossible to export to machine a door if there is not a door! +50193=Impossible to print a door if there is not a door! +50194=Properties has been deleted +50195=The current ddf configuration ({0}) is different from the current program configuration ({1}).{2}To load the current ddf configuration you have to restart the program, do you want it? +50196=Configuration ddf ({0}) does not exist! +50197=Top Arch has been modified because of configuration. +50198=Bevel on lock edge would be inverted. +//Option +50200=Unit measure +50201=General +50202=LockEdgeOverMaterial +50203=HingeEdgeOverMaterial +50204=TopOverMaterial +50205=BottomOverMaterial +50206=Open Window +50207=Last Project +50208=Empty +50209=Option Page +50210=StartUp +50211=Unit measure new door. +50212=Directory Project +50213=Option Start +50214=Current Directory +50215=Edge Type +50216=Over Material +50217=Browse +50218=Close +50219=Bevel +50220=Bevel Up +50221=Bevel Down +50222=Door disposition in machining +50223=Save as template +50224=Matching +50225=Brand +50226=File +50227=Template +50228=Enable template +50229=Enable Order +50230=Open template door. +50231=Open window order. +50232=Directory Template +//Scene +50301=Refresh +50302=Add New Door +50303=Remove Door +50304=New Project +50305=Help +50306=Directory Machine +50307=Machine +50308=Door +50309=Wide Side Down (BU) +50310=Wide Side Up (BD) +50311=Resize +50312=Design +50313=Save as pdf +//Launcher +50400=Launcher +50401=New Project +50402=Open Project +50403=Open Last Project +50404=New Project +50405=New Hardware +50406=Elevation +50407=Project +50408=PO +50409=Line +50410=Save +50411=Print +50412=Cancel +50413=Hardware +50414=Dimensioning +50415=Duplicate +50416=Export to machine +50417=New Template +50418=Dimension +50419=New Directory +50420=Create Assembly +50421=Reload Directories +50422=Save As +50423=Reload Compo on Jamb +//Error messages +50501=Error reading {0} param in {1} compo: incomplete definition (look at StdTemplate.ini). +50502=Error reading {0} param in {1} compo: no matching (look at StdTemplate.ini and GeometryNameList.ini). +50503=Do you want to save? +50504=File name contains empty spaces, do you want to rename file deleting empty spaces? +50505=DDF is not an assembly, there are only: {0}, do you want to save? +50506=Impossible to find the first door (DO_1)! +50507=The swing is not a member of the swing list of single door. +50508=The swing of left door is not a member of the swing list of left door. +50509=The swing of right door is not a member of the swing list of right door. +50510=The swing of left door is on the right door and viceverse. +50511=The swing of left door is not a member of the swing list of left door. +50512=The swing of right door is not a member of the swing list of right door. +50513=Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=The swing are absolutly wrong! +50515=The first door is not realy the first, check the ddf. +50516=The current ddf contains {0} jambs. +50517=The current ddf does not contains doors! +50518=The current ddf is not an assembly. +50519=Impossible to open a ddf with no doors. +50520=The current ddf is an assembly. +50521=The current ddf is a jamb: {0}. +50522=The profile {0} is not a member of the {1} profile list. +50523=Missing profile on {0}. +50524={0} file open by another EgtDOORCreator {1}. +50525={0} file open by another EgtDOORCreator {1}. +50526=Directory {0} already exists! Do you want to overwrite it? +50527=Impossible to overwrite {0} +50528=Impossible to save the door out of the project! +50530=Property {0} does not exist in the list of {1}. Look at file "../Compo/Default.ini". +50531=The current material {0} does not exist in the list of material. Look at file "../Compo/Default.ini". +50532=Missing list of material at file "../Compo/Default.ini". +50533=Impossible to load more than one property at time. +50534=Property {0} does not exist in the list. Look at file "../Compo/Default.ini". +50535=Impossible to delete a project if there is not a project! +50536=Do you want to delete entire project? ( All doors will be deleted!) +50537=Do you want to delete subdirectory {0} ? ( All doors will be deleted!) +50538=Impossible to vreate a template door if there is not a door! +50539=Do you want to change project? +50540=The current ddf is a part of a frame, do you want to save? +50541={0} in reading {1}. +50542={0}: Directory does not exist! +50543=It has been renamed file: {0}, {1}. +50544=It has been created new file: {0}, {1}. +50545=It has been deleted file: {0}, {1}. +50546=Enable single door. +50547=Project +50548=The new configuration will take effect after restart. +50549=File {0} exist, but it is not in the correct Directory! +50550=Every componente on jambs will be relocated, do you want to continue +50551=The current parameters have been modified: +50552=Do you want to overwrite? +50553= has not been created. +50554=Parameter {0} is already deinfed in geometry {1}. +50555=Impossible to save. +50556=File has nge extension. +50557=Error in deleting file: {0} +50558=Impossible to import a different hardware! +50559=Open File Dialog +50560=The hardware part has not been generated correctly. +50561=Directory already exists +50562=Folder {0} does not exist. Check in OptionPage. +50563=Compo {0} does not exist. +50564=In group {0} at paramater {1} does not exist: {2} +50565=Brand {0} has not been found in HardwareManager. +50566=Template {0} has not been found in HardwareManager. +50567=Error in executing EgtCam5. +50568=Error in definition {0} in file GeometryNameList.ini . +50569=Error in definition {0} in file StdTemplate.ini . +50570=Nothing has been selected. +//Added General messages +50701=Lines +50702=Rectangle +50703=None +50704=Radius +50705=Angle +50706=Pos_x +50707=Top Arc +50708=Top Angle +50709=Properties +50710=Material +50711=Mach. +50712=HardwarePart +50713=Assemby +50714=Total Dimension +50715=Depth +50716=Overlap Bottom +50717=Thickness Bottom +50718=Depth Bottom +50719=Delta Bottom +50720=GoToAssembly +50721=New Geometry +50722=Geometry Name +50723=Type Hardware +50724=Parameter +50725=Part Dimension +50726=Apply +50727=Frame +50728=Refresh Directory +50729=General +50730=Report +50731=Opposite face +// ----- EgtBEAMEditor ------ +60951=Cut +60952=Longitudinal Cut +60953=Double Cut +60954=Ridge or Valley Cut +60955=Saw Cut +60956=Slot +60957=Front Slot +60958=Birds Mouth +60959=Hip or Valley Rafter Notch +60960=Ridge Lap +60961=Lap Joint +60962=Notch/Rabbet +60963=Block House Half Lap, Stairs Riser Dado +60964=Seathing Cut +60965=French Ridge Lap +60966=Chamfer +60967=Block House Half Lap +60968=Block House Front +60969=Pocket +60970=Drilling +60971=Tenon +60972=Mortise +60973=Mortise Front +60974=House +60975=House Mortise +60976=Dovetail Tenon +60977=Dovetail Mortise +60978=Dovetail Mortise Front +60979=Marking/Labeling +60980=Text +60981=Simple Scarf +60982=Scarf Joint +60983=Step Joint +60984=Step Joint Notch +60985=Planing +60986=Profile Front +60987=Profile Head concave +60988=Profile Head convex +60989=Profile Head cambered +60990=Round Arch +60991=Profile Head +60992=Sphere +60993=Triangle Cut +60994=Tyrolean Dovetail +60995=Dovetail +60996=Free Contour +60997=Outline +60998=Aperture +61001=Distance from beam start to the reference point +61002=Distance from the reference edge to the reference point +61003=Distance from the reference side to the reference point (orthogonal) +61004=Angle between cut edge and reference edge +61005=Inclination between face and reference side +61008=Limit of the 2 ends, binary code +61009=Inclination to the reference side +61010=Depth: If P11 is zero, then the face of the cut dispreads to the neigbour-sides or opposite-side to referenceside +61011=Length: If P12 and P04 equal to zero, the processing is performed along the whole component length +61012=Angle in face at start +61013=Angle in face at end +61015=Distance from the reference point to the reference edge +61016=Angle between the first cutting edge and the reference edge +61017=Inclination of the first cutting towards the reference side +61018=Angle between the second cutting edge and the reference edge +61019=Inclination of the second cutting towards the reference side +61023=Inclination between the first face and the reference side +61024=Inclination between the second face and the reference side +61025=Depth +61027=Angle in face at reference edge at start +61028=Angle in face at reference edge at end +61029=Angle in face in opposite to reference edge at start +61030=Angle in face in opposite to reference edge at end +61033=Displacement to the reference side +61036=Angle to the reference edge in the cut face +61037=Depth, orthogonal to the reference side +61038=Length +61041=Distance to the reference point orthogonal to the reference side P03 = 0: Slot on one of the 4 sides of the component. P03 > 0: Slot on one of the 2 front sides of the component +61042=Limit of the 6 faces of the slot, binary code +61043=Angle to the reference edge in the reference side +61045=Interior angle at reference point +61046=Interior angle at opposite of reference point +61047=Addition to P09 +61048=Depth orthogonal to the reference side +61049=Length +61050=Thickness +61051=Displacement of the entrance edge at reference point +61052=Displacement of the entrance edge at opposite of reference point +61055=Distance to the reference point orthogonal to the reference side +61056=Limit of the 6 faces of the Frotn Slot, binary code +61059=Angle between the longitudinal axis of the slot and the reference side +61060=Depth +61061=Length +61062=Width +61065=Location of P09/P10, if P09>0 and P10>0. If P04=-1, then the location must be defined on the machineside +61066=P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole. +61067=Angle to the reference edge in the reference area +61068=Inclination between face 1 and reference side +61069=Inclination between face 2 and reference side +61070=First cut angle of the counterpart. If P09 is zero, the limit face beside face 1 is parallel to component side. +61071=First cut inclination of the counterpart. If P10 is zero, the limit face beside face 1 is parallel to component side. +61072=Depth 1 orthogonal to reference side +61073=Depth 2 orthogonal to reference side +61074=Grooving depth in the transverse direction of the component. If P13 is zero, then its value must be calculated:P13=WRS-P02 +61075=Height Counterpart. Zero means: no limit. Measurement orthogonal to face 1 (P07). +61076=Width Counterpart. Zero means: no limit. Measurement orthogonal to face 2 (P08). +61079=P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole +61080=Angle notch 1 to the reference edge in the reference area +61081=Angle notch 2 to the opposite reference edge in the reference area +61082=Inclination between base area of notches and reference side +61083=Depth orthogonal to reference side +61084=Width of notch 1. If this value is equal 0, then the notch is not limited. +61085=Width of notch 2. If this value is equal 0, then the notch is not limited. +61087=0: Reference point on referene edge. 1: Reference point on the opposite edge +61088=Angle to the reference edge in the reference side +61089=Depth of Half Lap +61090=Width of Half Lap +61091=Drill hole diameter +61094=Displacement to the reference side +61095=Limit of the 6 faces of the lap, binary code +61096=Angle to the reference edge in the reference side +61098=Angle between edge and reference side in face +61099=Angle in the floor face +61100=Angle between base face and one face of lap +61101=Distance (orthogonal) from reference side to point below reference point +61102=Length +61103=Chamfer angle +61104=Grooving depth (length of the lapped scarf in transverse direction). If P14 is zero, then its value must be calculated: P14=WRS-P02 +61107=Limit of the 6 faces of the notch/rabbet, binary code +61108=Notch/Rabbet depth +61109=Notch/Rabbet length +61110=Notch/Rabbet width +61113=Depth of the Half Lap on the reference side +61114=Depth of the Half Lap opposite of the reference side +61115=Length of the Half Lap / Dado +61117=Depth of Seathing Cut +61118=Length of Seathing Cut +61120=0: Reference point on reference edge; 1: Reference point on the opposite edge +61121=Angle to the reference edge in the reference side +61122=Drill hole diameter +61124=Input of edge(s) to be beveled, binary code: Bit 0=edge 1 ; Bit 1=edge 2; Bit 2=edge 3; Bit 3=edge 4. Example: P04=9: edge 1+4; P04=3: edge 1+2 +61125=Depth +61126=Length: If P12 is equal to zero, the processing is performed along the whole component length. +61127=Shape for bevel exit: 0 = orthogonal, 1 = at 45 deg, 2 = round; +61129=Depth orthogonal to reference side of the lap 2 and 4. If P03 is zero, then its value must be calculated: P03=HRS +61130=0:all laps are symmetric to each other; 1:lap on reference edge moved to start beam, lap in opposite of reference edge moved to end beam; 2: lap on reference edge moved to end beam, lap in opposite of reference edge moved to start beam; +61131=P05=1: drilhole for drop rod, P05=0: no drillhole. The machines defines place and direction of the drillhole. +61132=lap 1: Depth +61133=lap 1: Length +61134=lap 2: Depth +61135=lap 2: Length +61136=lap 3: Depth +61137=lap 3: Length +61138=lap 4: Depth +61139=lap 4: Length +61140=Distance from end of arc orthogonal to the reference side +61141=Radius of arc +61142=Distance reference point to center of arc +61143=Which arc (A, B,C or D) is to produced, binary code +61145=0:only one lap on reference side; 1:one lap on reference side and one on the opposite side +61146=Angle to the reference edge in the reference side +61147=Depth at reference point +61148=Depth opposite to the reference point +61149=Depth at reference edge +61150=Length +61153=Limit of the 6 faces of the pocket, binary code +61154=Rotation angle around the local z-axis of the cuboid +61155=Rotation angle around the local y-axis of the cuboid, rotated with P06 +61156=Rotation angle around the local x-axis of the cuboid, rotated with P06 and P07 +61157=Internal angle at the reference point +61158=Depth of reference point orthogonal to reference side +61159=Length of Half Lap +61160=Width of Half Lap +61163=Distance from the reference face to the reference point. P03 = 0:Drilling on one of the 4 sides of the component. P03 <> 0:Drilling on one of the 2 front sides of the component. +61164=P03 = 0:Angle to the reference edge in the reference side. P03 <> 0:Angle in the front side. +61165=Inclination between drilling and reference side. P03 = 0: Inclination between drilling and reference side. P03 > 0: Inclination between drilling and front side +61166=Depth, orthogonal to reference side or front side. +61167=Drill hole diameter +61170=Rounding +61171=Chamfer +61174=Angle between axis of the tenon and reference side +61175=Radius for P04=4 +61176=Tenon height +61177=Tenon width +61178=Margin on the reference side +61179=Margin opposite the reference side +61182=Displacement to the reference side +61183=Rounding +61184=Angle between axis and reference edge +61185=Inclination between strut and reference side +61186=Inclination of hole side walls towards reference side +61187=Radius for P04=4 +61188=Mortise depth +61189=Mortise width +61190=Height of strut +61191=Margin on the reference point +61192=Margin opposite the reference point +61193=Inclination of hole front side towards reference side +61196=Rounding +61199=Angle between axis of the tenon and reference side +61200=Radius for P04=4 +61201=Mortise depth +61202=Mortise width +61203=Margin on the reference side +61204=Margin opposite the reference side +61205=Processident of the associated tenon or dovetail tenon +61206=Processident of the associated mortise or dovetail mortise +61209=0:with rounding at the bottom; 1:without rounding, unbounded +61210=Angle between edge and reference edge +61212=Angle between axis of the tenon and reference side +61213=Middle flattening +61214=Angle of cone +61215=Tenon height +61216=Diameter of the curve: If P12 < 0, then the radius must be defined on the machineside. +61217=Margin on the reference side +61218=Margin opposite the reference side +61221=Displacement to the reference side +61222=0:with rounding at the bottom; 1:without rounding, unbounded +61223=0:with elongation; 1:with pocket +61224=Angle between axis and reference edge +61225=Inclination between strut and reference side +61226=Middle flattening +61227=Angle of cone +61228=Mortise depth +61229=Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61230=Height of strut +61231=Margin on the reference point +61232=Margin opposite the reference point +61235=Displacement to the front side +61236=0=with rounding at the bottom; 1=without rounding, unbounded +61237=0=with elongation; 1=with pocket +61240=Angle between axis of the tenon and reference side +61241=Middle flattening +61242=Angle of cone +61243=Mortise depth +61244=Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61245=Margin on the reference side +61246=Margin opposite the reference side +61249=Position and alignment of the text. P04 = 0 if there is no text. +61250=Angle between axis and reference edge. If P06 equals 180°, then a horizontal line is defined, P12 defines the length of the line. +61251=Interior angle. If P07 equals zero, 2 single markings have to be produced. +61252=Width of quadrangle. If P11 equals zero, there is only a single marking. +61253=Height of quadrangle. If P12 equals zero, marking is limited by the edge opposite to the reference edge. +61254=Height of text. If P13 equals zero, the machine determines the text height. +61255=Text (String max. 256 characters) +61258=Angle between axis and reference edge +61259=Alignment vertical. 0 = bottom, 1=middle, 2=top +61260=Alignment horizontal. 0 = left, 1=middle, 2=right +61261=Alignment in case of a multiline text. 0 = left-aligned, 1=centered, 2=right-aligned. A new line must be defined with this 2 letters: \n +61262=Letters standard or horizontal placed. 0 = standard, 1=letters horizontal placed +61263=Height of text. If P13 equals zero, the machine determines the text height. +61266=Depth at the reference side +61267=Depth at the opposite of reference side +61268=Length of the overlap +61269=Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61270=Drilling 2 diameter. Placed at 2/3 P13 +61272=Angle of inclination of the lapped scarf base +61273=Shape of the lapped scarf or classic data identification: 1:when cutting orthogonal to reference side; -1:when cutting orthogonal to base side; 0:classic definition, P10 and P12 are not used +61274=Length of the lapped scarf base +61275=Depth of the lapped scarf base +61276=Depth of the lapped scarf base orthogonal to reference side +61277=Length +61278=Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61279=Drilling 2 diameter. Placed at 2/3 P13 +61281=Type of heel notch:0=normal; 1=tapered +61282=Inclination strut +61283=Depth step joint +61284=Depth heel notch +61285=Height tenon. Which implementation (A or B) is used depends on the machine +61286=Width tenon +61289=Type of heel notch: 0=normal; 1=tapered +61290=Inclination between strut and reference side +61291=Width of the notch +61292=Depth step joint +61293=Depth heel notch +61294=Height of strut +61295=Depth of mortise. Which implementation (A or B) is used depends on the machine +61296=Width of mortise +61298=Specification of side(s) to be planed; binary coded +61299=Planing depth +61300=Length of the area to be planed +61303=Rotation angle of the first curve of the profile +61304=Rotation angle of the profile towards the reference edge +61305=Offset angle +61306=Radius of the first curve +61307=Radius of the second curve +61309=Radius +61310=Depth +61311=Displacement +61312=Depth +61313=Displacement +61315=Radius +61316=Depth +61317=Displacement +61318=Depth +61319=Displacement +61321=Profile length +61322=Depth at the reference point +61323=Maximum depth of profile +61324=Minimum depth of profile +61325=Depth at the profile end +61326=Premill: 0=round; 1=angular +61328=Depth of the arch segment +61329=Length of the arch segment +61331=Type of arc (convex, concave), binary coded. See table below. +61332=Length of lap 1 +61333=Depth of lap 1 +61334=Displacement arc 1 +61335=Horizontal length arc 1 +61336=Vertical length arc 1 +61337=Camber arc 2 +61338=Length of lap 2 +61339=Depth of lap 2 +61340=Displacement arc 2 +61341=Horizontal length arc 2 +61342=Vertical length arc 2 +61343=Camber arc 2 +61344=Length of lap 3 +61345=Depth of lap 3 +61348=Distance from the reference side to the reference point +61349=Radius +61350=Start offset +61351=Length +61354=Distance from the reference side to the reference point +61355=Normal vector 1: Length of X-component +61356=Normal vector 1: Length of Y-component +61357=Normal vector 1: Length of Z-component +61358=Normal vector 2: Length of X-component +61359=Normal vector 2: Length of Y-component +61360=Normal vector 2: Length of Z-component +61362=Distance between "inside" an side of part +61363=Distance orthogonal to the reference side +61364=0:"inside" at reference edge, 1:"inside" at opposite of reference edge +61365=0:Without rebate or mitre, -1:With mitre, >0:With rebate +61366=Angle to the reference edge in the reference side +61367=Width +61368=Depth +61369=Inclination +61370=Height +61371=Radius +61372=Length of tool (part of arc) +61373=0:Angular corner joint, 1:Straight T-wall connection +61374=Length +61375=0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61377=Distance between "inside" an side of part +61378=Distance orthogonal to the reference side +61379=0:"inside" at reference edge, 1:"inside" at oppostite of reference edge +61380=0:Without rebate or mitre, -1:with mitre, >0:with rebate +61381=Inclination +61382=Depth 1 +61383=Depth 2 +61384=0:European Dovetail, 1:American Dovetail +61385=Length +61386=0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61387=Depth +61388=Mode: 0=contour only, 1=countersink completely. Only for closed contours. +61389=Contour type +61390=Parameter depends on contour type(P13) +61391=Parameter depends on the contour type(P13) +61400=Reference point on referene edge +61401=Reference point on the opposite edge +61402=Reference point on referene edge +61403=Reference point on the opposite edge +61404=orthogonal +61405=at 45 deg +61406=round +61407=all laps are symmetric to each other +61408=lap on reference edge moved to end beam. lap in opposite of reference edge moved to start beam +61409=lap on reference edge moved to start beam. lap in opposite of reference edge moved to end beam +61410=only one lap on reference side +61411=one lap on reference side and one on the opposite side +61412=with rounding at the bottom +61413=without rounding, unbounded +61414=with elongation +61415=with pocket +61416=bottom +61417=middle +61418=top +61419=left +61420=right +61421=left-aligned +61422=centered +61423=right-aligned +61424=standard +61425=letters horizontal placed +61426=when cutting orthogonal to reference side +61427=when cutting orthogonal to base side +61428=classic definition, P10 and P12 are not used +61429=normal +61430=tapered +61431=round +61432=angular +61433="inside" at reference edge +61434="inside" at opposite of reference edge +61435=Angular corner joint +61436=Straight T-wall connection +61437=Processing on the reference side and opposite the reference side +61438=Processing only on the reference side +61439=Processing only opposite the reference side +61440=European Dovetail +61441=American Dovetail +// ---Custom Parameter (Q) +61451=Chamfer depth +61452=0=Default; 1=Longitudinal machining with saw blade +61453=Wood thickness for processing support with Q02 +61454=0=Centered Leadin 1=Inside Leadin +61455=0=Default; 1=Machine with mill side +61456=0=Default; 1=Use saw blade +61457=0=Default; 1=Only chamfer +61458=0=Default; 1=Max depth +61459=0=Default; 1=Chipper; 2=Chipper side; 3=Mill; 4=Mill side +61460=0=Default; 1=Machine outline with smallest diameter mill; 2=Corner cleaning +61461=0=Default; 1=Max radius permitted on closed pockets +61462=Tool diameter for Q05 +61463=Tool diameter for Q07 +61464=0=Rounded corner; 1=Drill on corner; 2=Sharp corner +61465=Drill diameter when P05=1 +61466=0=Default; 1=Roughing with saw blade +61467=Anti-splint: 0=No; 1=With saw blade; 2=With mill +61468=Increase pocket size +61469=Clean corners: 0=No; 1=With conical mill after manual removal of scraps; 2=With small conical mill; 3=With groove +61470=0=Default; 1=Outline only ; 2=Drill or Pocket +61471=0=Default; 1=Machine from only one side +61472=Increase/decrease P01 value for drills in tenons +61473=0=Chip breaker drilling; 1=Chip discharge drilling +61474=Chamfer depth when P05=1 +61475=Decrease tenon depth +61476=Decrease tenon width +61477=Decrease tenon height +61478=Decrease tenon depth +61479=Increase/decrease tenon shape +61480=Increase/decrease tenon height +61481=Increase mortise depth +61483=Machining depth +61484=Increase P10 dimensions +61485=0=Default; 1=Chipper +61486=Decrease P14 length +61487=Decrease P15 width +61488=Overmaterial for finishing +61489=Number of chamfer corrugation parts on the length +61490=0=Default; 1=Disable step milling +61491=0=Default; 1=Enable top chamfer +61492=0=Default; 1=Top chamfer with blade +61493=Wood thickness for processing support +61494=Enable anti-splint +61495=Anti-splint depth +61496=Max elevation (0=Default, >10=By value) +61497=0=Default; 1=Saw blade +61498=0=Default; 1=Disable tool length check +61499=0=Default; 1=Saw on top face 2=Saw on sides and below; 3=Saw on closed faces; 4=Saw on sides and below on closed faces +61500=0=Default; 1=Saw on top face 2=Saw on sides and below; 3=Saw on closed faces; 4=Saw on sides and below on closed faces +61501=0=Default; 1=Machining with horizontal mill if above or below (disable blade) +61502=0=Default; 1=Use chipper if below +61503=0=Centered Leadin and Leadout 1=Inside Leadin and leadout +61504=0=Default; 1=Machine with mill side like blade; 2=Machine with mill side like blade only on top faces +61505=0=Default; 1=Machine like LongCut +61506=0=Default; 1=Machine with mill +// ----- EgtBEAMWALL - BTLParam ----- +61601=???SN +61602=Enable +61603=Description +61604=L +61605=W +61606=H +61607=Material +61608=Required +61609=In production +61610=Done +61611=Rotate +61612=Group +61613=Unit Time +61614=Parameter +61615=Value +61616=Min +61617=Max +61618=Single member number +61619=Assembly number +61620=Order number +61621=Designation +61622=Annotation +61623=Subgroup/Storey +61624=Group +61625=Package +61626=Material +61627=Timber grade +61628=Quality grade +61629=Count +61630=Colour +61631=Transparency +61632=Planing length +61633=Start offset +61634=End offset +61635=Transformation: Origin +61636=Transformation: X-axis dir. vect. +61637=Transformation: Y-axis dir. vect. +61638=Camber: Reference side +61639=Camber: P01,P02,P03,P04 +61640=Part offset: ref. side fix clamp +61641=Part offset: P11,P12,P13,P14 +61642=Processing quality +61643=Recess +61644=Storey type +61645=Element number +61646=Layer +61647=Module number +61648=USERATTRIBUTE +61649=Comment +61650=Grain direction: X,Y,Z +61651=Grain direction: Align +61652=Reference side +61653=Reference side: Align +61654=Alignment: Location +61655=Alignment: Endtype +61656=Material type: Group +61657=Material type: Specification +61658=AUTOMATIC +61659=VISIBLE +61660=FAST +61661=MANUAL +61662=CEILING +61663=ROOF +61664=WALL +61665=inactiv +61666=BR +61667=TR +61668=BA +61669=TA +61670=HC +61671=VC +61672=AC +61673=R +61674=A +61675=D +61676=Batten +61677=Cladding +61678=Massive timber +61679=Membrane +61680=Gypsum Board +61681=Gypsum Fibre +61682=Insulation +61683=Sheet Component +61684=Facade Panel +61685=Profiled Panel +61686=Plaster +61687=Reference side 1 +61688=Reference side 2 +61689=Reference side 3 +61690=Reference side 4 +61691=UID +61692=Project number +61693=Project name +61694=Project part +61695=GUID +61696=Listname +61697=Customer +61698=Architect +61699=Editor name +61700=Delivery date +61701=Export date +61702=Export time +61703=Export release +61704=Language +61705=Range +61706=Computername +61707=User name +61708=Path & name of CAD-File +61709=Path & name of BTL-File +61710=STANDARD +61711=EXTENDED +61712=Vol unit +61713=Vol tot +61714=Time unit +61715=Time tot +61716=Total parts number +61717=Total volume +61718=Total time +61719=Total estimed time +61720=Remaining time +61721=Rawpart counter +61722=BTL part counter +61723=Added part counter +61724=Part in rawpart counter +61725=Done part counter +61726=Quantity +61727=Print PDF +//Warehouse +61751=Current S +61752=Current L +61753=StartOffset +61754=Kerf +61755=Offset +61756=S Parameters +61757=L Parameters +61758=New Value: +61759=W +61760=L +61761=Confirm +61762=Save +61763=Cancel +61764=Error +61765=Input value already present +61766=Input value not correct +61767=Input pair already present +61768=One or more input values not correct +61769=Attention +61770=Selected parameter is equivalent to current L/S. Are you sure you want to remove it? +61771=SectionXMaterial +61772=Alias +61773=Values +61774=Quantity +61775=Min thickness +61776=Max thickness +61777=Increment Max thickness of the last range before adding a new range +// +61801=Custom +61802=Default +61803=L +61804=T +61805=Process +61806=Section time +61807=Part time +61808=Name +61809=PDN +61810=DO +61811=X position +61812=Y position +61813=Added +61814=Done +61815=ID +61816=Start offset +61817=% Used +61818=Waste +61819=BTL File Name +61820=List Name +61821=Export Date +61822=Creation Date +61823=Delete +61824=Face +61825=Group +61826=Modify +61827=Save +61828=Cancel +61829=Nesting +61830=Viewer +61831=Optimizer +61832=Configuration +61833=Optimize +61834=Update BTL +61835=Go to optimization +61836=Filter type +61837=Search +61838=Export project +61839=Import project +61840=Import BTL +61841=Copy to Clipboard +61842=DisplayIndex +61843=Column name +61844=CanUserReorder +61845=CanUserResize +61846=CanUserSort +61847=IsReadOnly +61848=Visible +61849=Variable Path +61850=Type +// +61851=This part modification will cause the removal of the part from {0} raw parts. Do you want to proceed anyway? +61852=Impossible create feature with this values +61853=Impossible create part with this values +61854=Impossible create bar with this values +61855=Impossible create wall with this values +61856=Value outside minimum and maximum +61857=Impossible to insert a quantity inferior to the number of parts already in rawparts! +61858=Impossible to modify these values +61859=Error in machine parameter writing +61860=Save machine parameters modification? +61861=Save default values modification? +61862=Changing type second path will be deleted. Do you want to proceed? +61863=To produce part number reached: +61864= from BTL; +61865= added. Do you want to add another one? +61866=Selected part has different section from selected bar. Impossible to add. +61867=Selected part lenght is more then the selected bar lenght. Impossible to add. +61868=Selected part has different height from selected wall. Impossibl to add. +61869=Error in macro file execution! +61870=Impossible create a Macro without selecting a Feature or with empty name +61871=File not found! +61872=Impossibie deleting current project +61873=Impossibile deleting the project because already linked to an optimization +61874=Impossibile deleting the project because some parts are already sent to production +61875=Do you want to save the project modifications? +61876=Impossible creating a new file! +61877=Save project modification before continuing? +61878=Impossible proceeding with a new unsaved project! +61879=Type of current machine is both Beam and Wall. Select the type you want to set the project to: +61880=Select one of the available machines and/or types. Otherwise cancel the project import. +61881=The opened project type is not compatible with the current machine type +61882=Do you want to save the modifications to the DataGrid columns? +61883=The columnn specified as "{0}" in the "{1}" table in the datagrid columns ini file was not found in the program +61884=Select the machine you want to associate to the project: +61885=The machine linked to the opening project cannot be found among the available machines +61886=Machine +61887=Impossible creating the inserted rawparts quantity +61888=How many copies of the rawpart do you want to create? +61889=Long Drill Area +61890=Min Rule +61891=Can't send feedback from Optimizer if there is no open Prod +61892=Can't proceed with an unsaved project! Please save before updating it. +// +61900=Change parameter +61901=Verify +61902=Simulate +61903=New raw part +61904=Add to raw part +61905=Copy part +61906=Add part +61907=Remove part +61908=Copy feature +61909=Create macro +61910=Add feature +61911=Remove feature +61912=Produce rawpart +61913=Produce all rawpart +61914=Copy rawpart +61915=Remove rawpart +61916=Reorder parts +61917=Move up part +61918=Move down part +61919=Remove part +61920=Warehouse +61921=Add project to optimization +61922=Go to project +61923=Statistics +61924=Reset +61925=Show all parts +61926=Show solid +61927=Show building +61928=Verify all +61929=Can't change machine because the Proj is already linked to a Prod +61930=Inputs +61931=Outputs +61932=Calculate Flip & Rotation +61933=Unlock Flip +61934=Unlock Rotation +61935=Length +61936=Width +61937=Offset +61938=Kerf +61939=Edit +61940=Reset +61941=Choose machine +61942=BTL file already imported and optimized. Do you want to import it again? +61943=BTL file already imported. Do you want to overwrite it? +61944=Shift parts +61945=Shift direction +61946=Shift length +61947=Parts can't be shifted outside the raw part +61948=The inserted shift value is not valid +61949=Search & Filter +61950=Parameter Type +61951=Parameter Value +61952=R +61953=A +61954=P +61955=D +61956=All +61957=Filtered +61958=Update +61959=Append +61960=Check the parts you would like to add to update BTL +61961=Change material +61962=Project material +61963=Warehouse material +61964=Standard +61965=From BTL +61966=Save +61967=Do NOT save +61968=Waiting for optimizer save +61969=Cancel +// +62500=Supervisor +62501=Channel +62502=OPMode +62503=Produce All +62504=Done RawPart +62505=Reset RawPart +62506=Delete RawPart +62507=Print Label +62508=Done Part +62509=Resume started processing? +// Loading +63000=Project opening +63001=Loading project geometries +63002=Loading machining groups +63003=Loading production data +63004=Optimization opening +63005=Loading parts +63006=Loading graphics +63007=Project saving +63008=BTL file importing +63009=Reading BTL file +63010=Project exporting +63011=Loading environment +63012=Saving geometry +63013=Saving data on Db +63014=Modifying parameters +63015=Part viewer opening +63016=Adding export info +63017=Exporting... +63018=Project importing +63019=Loading project +63020=Creating imported project +63021=Modifying materials +// ----- FromLua ----- +65001=Rawpart ({0} x {1} x {2}) bigger then machine maximum rawpart ({3} x {4} x {5}) +// ----- OmagCUT ----- +// General +90001=CURRENT MACHINING +90002=DIRECT CUTS +90003=CAD CUTS +90004=FRAMES +90005=MACHINE +90006=OPTIONS +// Current Machining +90101= +// Direct Cuts +90201=Manual move +90202=Single cut +90203=Multiple cuts +90204=Grid cuts +90205=MTH +90206=Leveling cuts +90207=Saw test +90208=Saw probe +90209=Copy template +90210=Acquire P1 +90211=Acquire P2 +90212=Laser +90213=Depth +90214=Length +90215=Direction +90216=Side angle +90217=Number +90218=Dimension +90219=Number X +90220=Dimension X +90221=Number Y +90222=Dimension Y +90223=Spindle side cut +90224=Saw +90225=Draw +90226=Width +90227=Overlap +90228=Offset +90229=C Axis Lock +90230=Execute +90231=Polishing +90232=Saw thickness +90241=Saw probing +90242=Probing in progress... +90243=Probing succesfully completed +90244=Error in saw probing +90245=New template name +90246=Probing canceled by user +90250=Line +90251=Arc +90252=Remove +90253=Close +90254=Save +90255=Test +90256=Test work position +90257=Testing work position... +90258=Single drill +// Cad Cuts +90301=Simulate +90302=Execute +90303=New +90304=Load +90305=Save +90306=Save as +90307=New project name +90308=CSV +90309=Vein Match +90310=Export +90311=Tool +90312=Machining +90313=Photo camera failed +90314=Error in NC program generation +90315=Error in NC program transmission +90316=Not connected to the machine +90317=NC program transmitted +90318=NC program refused by machine +90319=NC program already sent, resend ? +90320=Different machine +90321=Reduced some machinings to avoid interference +90322=Missing tools : +90323=Background photo taken +90324=Contour recognition failed +90325=Error saving statistics +90326=Confirm restart from phase {0} ? +90327=New Ruined Parts +90328=Parts Area : +90329=To be Produced : +90330=NC program already sent, new slab ? +// NestPage +90331=Insert part +90332=Park part +90333=Remove part +90334=Select all +90335=Deselect all +90336=Reset +90337=One or more parts with non-compatible thickness, material or finish +90338=Rotation beyond the limits +90339=Rotation impossible +90340=Automatic nesting in progress +// SplitPage +90341=On/Off +90342=All On +90343=All Off +90344=Extend/Reduce +90345=Start Ext/Red +90346=End Ext/Red +90347=Start Cnt/Out +90348=All Starts Out +90349=All Starts Center +90350=Automatic computation failed +90351=Saw too big for vacuum use +90352=End Cnt/Out +90353=All End Out +90354=All End Center +90355=All Extend +90356=All Reduce +90357=Modify +90358=Auto +90359=Restart +// MoveRawPart +90361=Remove +90362=Part too small : can not be moved +90363=Selected position already occupied +90364=Part too havy : can not be moved +90365=Part beyond strokes : can not be moved +// SplitPage 2 +90371=Pause On/Off +90372=Pause +90373=Start Modif. +90374=End Modif. +90375=Elongation +90376=Invert +// DrawPage +90381=Part Count +90382=Measure +90383=Side angles +90384=Mark Top +90385=Parametric Draw +90386=Select a contour +90387=No editable sides +90388=Name +90389=Trf Data +90390=Order Code +90391=Order Description +90392=Material Code +90393=Surface Code +90394=Thickness +90395=Select one or more holes +90396=Part Code +90397=Engrave +90398=Csv Data +90399=All machinings updated +90400=Top Edge +// Component +// Massimo 17 caratteri senza immagine e massimo 12 con l'immagine +90401=Triangle +90402=Rectangle +90403=Trapezium +90404=Quadrilateral +90405=Winder +90406=Sill +90407=Kitchen top +90408=Vanity top +90409=Others +90410=2Sides 1Ang +90411=3Sides +90412=Isosceles +90413=Right +90414=Scalene +90415=Scalene +90416=4Sides 1Ang +90417=3Sides 2Ang +90418=3Sides 2Diag +90419=4Sides 1Diag +90420=4Sides 3Diag +90421=4Sides 3Ang +90422=4Sides 3Ang +90423=Right Angle +90424=Chamfered Right Angle +90425=Aligned Angle +90426=Chamfered Aligned Angle +90427=Part A +90428=Part B +90429=Angle +90430=Chamfered Angle +90431=Ellipse +90432=Oval +90433=Arc +90434=Arc LHF +90435=Arc LLH +90436=Arc LLF +90437=Rounded Rectangle +90438=Convex +90439=Hole +90440=2 Holes +90441=3 Holes +90442=Arc RHa +90443=Polygon +90444=Bottom Hole +90445=Dxf +90446=Recess +90447=Internal Features +90448=Add +90449=Remove +90450=Confirm +// Import +90451=Use layers +90452=Use regions +90453=Reset +90454=mm +90455=inch +90456=Use closed curves +90457=Side angle +90458=Drip +90459=Angle +90460=Offset +90461=Depth +90462=Shortening +90463=DXF import +90464=Drill bottom +90465=Number +90466=Offset2 +90467=Order +90468=List +90469=Name +// Component 2 +90470=Recess engravings +90471=Engravings +90472=TriangleCH +90473=TriangleRT +90474=TrapeziumRtA +90475=3Sides 2Ang +90476=Nuova soglia +// FastGrid +90480=Order name +90481=N. slab +90482=Last slab +90483=Piece type +90484=Insert pieces +90485=Confirm order +// Open +90491=Invalid project +90492=Project with collisions. To load disable whole cuts guard. +// RawPart +90499=Undefined Raw part +90500=Rotation +90501=Rectangle +90502=By points +90503=Length +90504=Width +90505=Thickness +90506=Offset X +90507=Offset Y +90508=Kerf +90509=Material +90510=Damaged area +90511=New +90512=Erase +90513=Points +90514=Add +90515=Remove +90516=Max length = +90517=Max width = +90518=Negative thickness not allowed +90519=Min X offset = +90520=Min Y offset = +90521=Min kerf = +90522=Max kerf = +90523=Raw probe +90524=Ok +90525=Raw probing +90526=Probing in progress... +90527=Probing succesfully completed +90528=Error in raw probing +90529=From draw +90530=From laser +90531=Close +90532=Error in laser point acquisition +90533=Outline +90534=Saw too big for probing +90535=From photo +//ChooseMachining +90536=Choose sawing +90537=Choose auxiliary machining +90538=Choose drilling +90539=Choose milling +90540=None +90541=Drilling +90542=Milling +90543=Both +90544=Choose Current Machining +90545=Choose waterjet +90546=Waterjet Cut +90547=Error in the position or size of the raw +90548=Max X offset = +90549=Max Y offset = +90550=Choose pocketoing +// Simulation +90551=Complete simulation +90552=Outstroke +90553=Tool direction unreachable +90554=Error +90555=ERROR +90556=Error in generation! +90557=Simulation +90558=One step at a time +90559=Play/Pause +90560=Stop/Home +90561=Pause +90562=Stopped simulation +90563=Mach view +90564=Home +90565=Time +90566=Length +90567=Parts Area +90568=Usage +90569=Estimations +90570=Details +// FrameCut +90601=Along X +90602=Along Y +90603=Remove +90604=Roughing +90605=Finishing +90606=Side finishing +90607=Mirror +90608=Top clearance +90609=Side clearance +90610=Trim start +90611=Trim end +90612=Single cut +90613=Arc +90614=Guide +90615=Section +90616=Guide +90617=Rad +90618=Ang +90619=Error : radius smaller then section width +90620=Error : frame creation failed +90621=X clearance +90622=Y clearance +90623=Opposite Side +// Machine +90701=Msg_Ita.xpi +90705=Machine data +90706=Tool DB +90707=Machining DB +90708=Machine +90709=Statistics +90715=New +90716=New +90717=Save +90718=Delete +//ToolsDb +//param +90719=Tool holder length +90720=Core +90721=Name +90722=Position +90723=Head +90724=Exit +90725=Speed +90726=Standard +90727=Maximum +90728=Feed +90729=Standard +90730=Tip +90731=Lead in +90732=Lead out +90733=Coolant +90734=Compensation +90735=Over material +90736=Longitudinal +90737=Radial +90738=Max power +90739=Min feed +90740=Max depth +90741=Length +90742=Diameter +90743=Thickness +90744=Cutter +90745=Notes +90746=Serial Number +90747=Code +90748=Supplier +90749=End Life +//tools families +90751=Sawblade +90752=Drillbit +90753=Mill +90754=Cupwheel +90755=Waterjet +90756=Polishingwheel +//Tool Setup +90759=Default tool position already occupied +//MachiningsDb +//param +90761=Name +90762=Depth +90763=Side angle +90764=Invert +90765=Step type +90766=Mach. side +90767=Head side +90768=Start position +90769=Lead in +90770=Link +90771=Lead out +90772=Use curve +90773=Tolerance +90774=Depth step +90775=Standard +90776=Depth step +90777=Inner arc +90778=Outer arc +90779=Slowing length +90780=Starting +90781=Ending +90782=Additional depth +90783=Return position +90784=Tool +90785=Min thickness +90786=Max thickness +90787=Step +90788=Down +90789=Side +90790=Vertical +//machinings families +90791=Sawing +90792=Drilling +90793=Milling +90794=Saw Roughing +90795=Saw Finishing +90796=Pocketing +90797=Waterjet +//ComboBox Param +90801=No +90802=Inner +90803=Outer +90804=Both +90821=Center +90822=Left +90823=Right +90824=Centered +90825=Inner +90826=Outer +90827=Cent. Extended +90828=Outer Extended +90829=Prev Extended +90830=Next Extended +90831=Booth Extended +90832=Centered +90833=Inner +90834=Outer +90835=Skip +90836=Approximate +90837=Convex +90838=Zig Zag +90839=One way +90840=Back and forth +90841=Keep +90842=None +90843=Standard +90844=Slowdown +90845=Loop +90846=Linear +90847=Tangent +90848=Glide +90849=Helix +90850=As lead in +// param2 +90861=Side +90862=Tilted +90863=Tilted back +90864=Forward +90865=Backward +90866=Last backward +90867=Forward angle +90868=Probing +90869=Min dist. points +90870=Max dist. points +90871=External +90872=Internal +90873=Slowdown len. +90874=Slowdown % +90875=Lead in hole +90876=Radius +90877=LP turns +90878=HP turns +90879=Enable +90880=Corners +// Barcode +90881=Barcode +90882=Block +90883=Number +90884=Slab data +// param3 +90890=Dist. tang. +90891=Dist. perp. +90892=Dist. tang. +90893=Dist. perp. +90894=Leadin ceramic +90895=Length +90896=Step +90897=Last cut +90898=Side angle cuts +// Alarms +90900=Current Waterjet +90901=Current sawblade +90902=Auxiliary tool +90903=Current drillbit +90904=Current mill +90905=Safe Z +90906=Cut safety +90907=Corner safety +90908=Whole cuts guard +90909=Holes offset +90910=Holes overlap +90911=Holes toler. +90912=NC Errors List +90913=Materials +90914=Add +90915=Remove +90916=Current tools +90917=Holes parameters +90918=Ext arc min R +90919=Machine parameters +90920=None +90921=Drillbit +90922=Mill +90923=Both +90924=Int arc max A +90925=Saw parameter +90926=Single hole in corner +90927=Direct cuts +90928=Final home +90929=Millings parameters +90930=Always on sinks +90931=Nesting +90932=Aligned +90933=Setup +90934=New +90935=Delete +90936=Overtable height +90937=Camera +90938=Background +90939=Threshold +90940=Tolerance +90941=Washing +90942=Confirm deletion of selected material ? +90943=Default Setup +90944=Always on corners +90945=Select tool to probe +90946=Cuts Feed start/end +90947=Length +90948=Slowdown% +90949=Shortening +90950=Probing +//Machine +90951=Start +90952=Stop +90953=Reset +90954=Auto +90955=Single +90956=MDI +90957=Manual +90958=Home +90959=Download +90960=Upload +90961=Activate +90962=Delete +90963=MDI Confirm +90964=CN Mode +90965=Machine Commands +90966=MDI string +90967=Part program transfer +90968=Do you want to change table? +// Options +90981=Language +90982=The new language will take effect after restart. +90983=Units of measure +90984=View rotation +90985=Side angle +90986=Same value +90987=Multiple values +90988=Direct insertion of parts +90989=Parametrics and DXF +90990=CSV +90991=Fast grid +90992=Enable standard pieces creation +90993=Text color +90994=Slab Dxf +90995=Slab Layer +90996=Parts Layer +90997=Scrap Layer +90998=Std Thick +90999=ColorToSideAng +91000=Enable +91001=Tolerance +91002=Heel +91003=Side angle +91004=Feedback +91005=Themes +91006=Engrave from color +91007=Depth +91008=Width +91009=Start program +91010=Select start mode +91011=Recent project +91012=Last opening +91013=Last project +91014=New project +91015=Open folder +91016=Show window +//Alarms2 +91051=Machinings +91052=Sawing +91053=Drilling +91054=Milling +91055=DripSawing +91056=DripDrilling +91057=WaterJet +91058=Waterjet parameters +91059=Automatic +91060=Aligned and Guillotine +91061=Engraving parameters +91062=Use Mill +91063=Depth +91064=Width +91065=Precut exit +91066=Guillotine +91067=Add pause +91068=Frame +91069=Pocketing +91070=Current cupwheel +//Statistics +91071=Day Production +91072=Week Production +91073=Project +91074=Parts Area +91075=Cuts Area +91076=Day +91077=Week +91078=Reset +91079=To Produce Area +//Lucidature +91089=Offset +91090=Polishing DB +91091=Polishings +91092=Move +91093=Count +91094=LeadIn/LeadOut +91095=Height +91096=Tools +91097=Length +91098=Up +91099=Down +91100=Load +//EgtMsgBox +91101=Save changes to current project ? +91102=Save changes to current tool ? +91103=Save changes to current machining ? +91104=Already used name +91105=There are collisions, some pieces will be parked. Continue ? +91106=Another file with same name alredy exists? Overwrite it? +91107=NC CONNECTION +91108=Try to connect... +91109=Connection failed +91110=Succesfully connected +91111=Table to use ? +91112=Also delete parts from CSV list ? +91113=Parts not removed because free +91114= or from other Csv lists +91115=Error +91116=Option Production line not enabled +91117=Error copying file for OmagVIEW +91118=Retain parked parts ? +91119=Error in ruined parts management +91120=Characters \ / : * ? " < > | are not allowed +91121=Are you sure you want to delete selected pieces? +91122=Warning +91123=Table +91124=???Salvare la lucidatura corrente? +91125=Do you want to save current modified? +91126=Export +91127=Import +91128=DB WaterJet +91129=Origin from laser +91130=Start program? +// CSV +91201=Open +91202=Insert +91203=New +91204=Remove +91205=Error saving CSV file, continue anyway ? +91206=Error reading CSV file +// OmagVIEW +91301=All Good +91302=Good Part +91303=Ruined Part +91304=Print Label +91305=Confirm +91306=Print +// OmagOFFICE +// OptionPanel +91401=RawPart +91402=Disposition +91403=Work +91404=Simulation +// MachiningDbWindow +91451=Material +91452=Min Thickness +91453=MaxThickness +// Errori di stampa +91461=Error connection printer +91462=Error formatting data +91463=Error during print +91464=No selection +// TopCommandBar +91501=Save project is mandatory before export +91502=Select export directory +91503=Error in export +91504=Export completed successfully +91505=Export to machine +91506=DXF export +// Rawpart +91551=Error loading photo +91552=Import photo +// VeinMatching +91601=Export +91602=Show Info +91603=Edit +91604=Verify +91605=Magnetic +91606=Part not selectable in this situation +91607=Part not selectable because belonging to non-current workgroup : +91608=Dxf parts BoundingBox too big for VeinMatching +// Generic +91651=Ok +91652=Cancel +91653=A° +91654=H +91655=Start +91656=End +// ----- OmagPHOTO ----- +// General +92001=Db not found! +92002=Unable starting the program +// OptionPanel +92051=Save +92052=Add +92053=Cancel +92054=Remove +92055=Are you sure you want to delete current slab? +92056=Label +92057=Label Arrow +92058=Browse +92059=Print +92060=Select +// Slab +92071=Id +92072=Image name +92073=State +92074=Project assigned to +92075=Warehouse position +92076=Date +92101=Name already used +92102=Name is mandatory +92103=Image is mandatory +// SearchPanel +92151=Search +92152=Thickness tolerance +92153=Start date +92154=End date +92155=Reset +//Messaggi +92200=???Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=Warning +92202=???Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=???Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=???Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// General +101001=Import BTL +101002=Draw +101003=Place +101004=Options +// ImportPage +101101 +// DrawPage +101201=Wall +101202=Door +101203=Window +101204=Add +101205=Cancel +101206=Apply +101207=Remove +101208=Spacer +// PlacePage +101301=Generate +101302=Trasmit +101303=Place wall +101304=Add +101305=Park +101306=Remove +101307=Layer thickness +101308=Table count on top +101309=Add failed +101310=Generation successful +101311=Generation error +101312=Transmission exec successful +101313=Transmission exec error +101314=Transmission successfully completed +101315=Transmission failed +101316=All gantries disabled +101317=Generation file missing +// OptionsPage +101401=Machine options +101402=Glueing parameters +101403=X Extra Raw +101404=Y Extra Raw +101405=Extra glue +101406=Plank parameters +101407=Plank width +101408=Table count in a layer +101409=Gantries activation +101410=Glue gantry +101411=Plank gantry +101421=Software options +101422=Language selection +101423=The new language will take effect after restart +101424=Saved project number +101425=Place planks on doors and windows +101426=Advance opening glue +101427=Advance closing glue +// OpenPage +101501=Invalid project +// ----- End ----- diff --git a/ProgramData/EgtBeamWall/Config/EgalTechEsp.txt b/ProgramData/EgtBeamWall/Config/EgalTechEsp.txt new file mode 100644 index 0000000..23f5c8e --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/EgalTechEsp.txt @@ -0,0 +1,3319 @@ +// File dei messaggi EgalTech Spagnolo 2022/05/02 +0=ESP +// File +1=File +3=Nuovo +5=Apri +6=Apri
File recenti (Shift) +7=Inserisci +9=Salva +11=Copia +13=Importa +15=Esporta +17=Esegui +19=File Recenti +20=Script Recenti +// Vista +101=Vista +103=Linee +105=Bordi +107=Solidi +109=ZoomAll +111=ZoomIn +113=ZoomOut +115=Sopra +117=Fronte +119=Destra +121=Dietro +123=Sinistra +125=Sotto +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Griglia +136=Imposta Vista perpendicolare alla Griglia corrente +137=DirCurve +139=Analisi +141=Distanza +// Griglia +201=Griglia +203=Sopra +205=Fronte +207=Destra +209=Dietro +211=Sinistra +213=Sotto +215=Vista +216=Imposta Griglia perpendicolare alla direzione di Vista +217=Elevaz +218=Imposta Elevazione della Griglia +219=Origine +220=Imposta Origine della Griglia +221=Ruota +222=Ruota Griglia
Ruota Griglia in 3d (Shift) +223=3 Punti +224=Imposta Griglia da 3 Punti +225=Perp +226=Imposta Griglia Perpendicolare a Oggetto +227=Oggetto +228=Imposta Griglia da Oggetto +// Disegna +301=Disegna +303=Punto +304=Punto
Vettore (Shift)
Riferimento (Ctrl) +305=Lin 2P +306=Linea : 2 Punti
Linea : 2 punti con Continuazione (Ctrl) +307=Lin PDL +308=Linea : Punto iniziale, Direzione, Lunghezza
Linea : Punto iniziale, Vettore direzione, Lunghezza (Shift) +309=Circ +310=Circonferenza : Centro, Punto
Circonferenza : Centro, Diametro (Shift) +311=Racc +312=Raccordo : Raggio
Smusso : Dist (Shift) +313=Arco CIF +314=Arco : Centro, Punto iniziale, Punto finale +315=Arco 3P +316=Arco : 3 Punti +317=Arc IDF +318=Arco : Punto iniziale, Direzione, Punto finale
Arco : Punto iniziale, Vettore direzione, Punto finale (Shift)
Arco : Punto iniziale, Direzione, Punto finale con Continuazione (Ctrl) +319=Rett 2P +320=Rettangolo : 2 Punti +321=Poligono +322=Poligono : Raggio o Apotema
Poligono : Lato con 2 Punti (Shift) +323=Testo +324=Testo
Testo Avanzato (Shift) +399=Continuazione : 'L' con linea, 'A' con arco +// Costruisci +401=Costruisci +403=Piano +404=Superficie : piano contornato da una o più curve
Regione piana (Shift) +405=Estrudi +406=Superficie : da estrusione di una o più curve +407=Ruota +408=Superficie : da rotazione di una curva +409=Avvita +410=Superficie : da rototraslazione di una curva +411=Rigata +412=Superficie : rigata tra 2 curve +413=Combina +414=Combina una o più Superfici +415=Inverti +416=Inverte l'esterno di una o più Superfici +417=Esplodi +418=Esplodi Superfici o Regioni Piane +419=Swept +420=Superficie : da spostamento di una curva lungo un'altra +// Modifica +501=Modifica +503=Cancella +504=Cancella gli Oggetti +505=Layer +506=Porta gli Oggetti nel Layer corrente +507=Colore +508=Cambia Colore
Rimuovi Colore specifico (Shift)
Cambia Trasparenza (Ctrl) +509=Inverti +510=Inverti Curva +511=Trim/Est +512=Taglia o Estendi Curva +513=Spezza +514=Spezza Curva
Dividi Curva in Parti (Shift) +515=Unisci +516=Unisci Curve
Unisci Curve creando una Copia (Shift)
Fondi Curve nella Composita (Ctrl) +517=Esplodi +518=Explodi Testi o Curve in Componenti +519=Spess +520=Imposta Spessore e direzione di Estrusione su una o più Curve +521=Inizio +522=Cambia Inizio di Curva Chiusa +// Trasforma +601=Trasforma +603=Muovi +604=Muovi uno o più Oggetti +605=Ruota +606=Ruota uno o più Oggetti
Ruota uno o più Oggetti in 3D (Shift) +607=Specch +608=Specchia uno o più Oggetti
Specchia uno o più Oggetti in 3D (Shift) +609=Scala +610=Scala uno o più Oggetti
Scala uno o più Oggetti in 3D (Shift) +611=Offset +612=Offset di una Curva +// Special +701=Special +703=Pezzi 2d +704=Inserisci Pezzi Piani da DXF o NGE +705=Compo +706=Inserisci Componenti Parametrici +// Scene : Menù Selezione Entità +1001=Seleccionar todo +1003=Deseleccionar todo +1005=Seleccionar con ventana +1007=Seleccionar pieza +1009=Seleccionar capa +1011=Seleccionar ruta +1013=Seleccionar ruta completa +1015=Seleccionar entidad +1016=Seleccionar todo visible +// Scene : Menù Punto notevole +1101=Punto Sketch +1102=Punto Sketch +1103=Punto Rejilla +1104=Punto de cuadrícula +1105=Punto Final +1106=Punto Final +1107=Punto Medio +1108=Punto Medio +1109=Centro +1110=Centro +1111=Centro de Gravedad +1112=Centro de Gravedad +1113=Punto Cercano +1114=Punto Cercano +1115=Intersección +1116=Intersección +1117=Punto de Tangencia +1118=Punto Tang +1119=Punto Perpendicular +1120=Punto Perp +1121=Punto a Distancia Mínima +1122=Punto MinDist +1123=Excluir Superficies +// Scene : Menù Varie +1201=Disattiva Trascinamento +1203=Attiva Trascinamento +// Scene : Varie +1301=Dist= +// Controller +2001=Copia (V) +2002=Errore +2003=Allarme +2051=Il Punto deve essere diverso dal precedente +2052=I Punti devono essere non allineati +2053=Valori Nulli o Negativi non sono ammessi +2054=Valori Negativi o Due Valori Nulli non sono ammessi +2055=Almeno una Entità non è scalabile +2056=Distanza troppo grande +2057=Curva non piatta (nel suo piano) +// Controller : Disegna +2101= +// Controller : Costruisci +2201= +// Controller : Modifica +2301= +// Controller : Trasforma +2401=COPIA +2402=MUOVI +2403=Inserisci Punto Base +2404=Inserisci Punto Destinazione +2406=RUOTA +2407=Inserisci Centro +2408=Inserisci Punto Base +2409=Inserisci Angolo o Punto +2411=RUOTA 3D +2412=Inserisci Primo Punto Asse +2413=Inserisci Secondo Punto Asse +2414=Inserisci Punto Base +2415=Inserisci Angolo o Punto +2416=SPECCHIA +2417=Inserisci Primo Punto +2418=Inserisci Secondo Punto +2421=SPECCHIA 3D +2422=Inserisci Primo Punto +2423=Inserisci Secondo Punto +2424=Inserisci Terzo Punto +2426=SCALA +2427=Inserisci Centro +2428=Inserisci Coefficiente +2431=SCALA 3D +2432=Inserisci Centro +2433=Inserisci Coefficienti +2436=OFFSET +2437=Inserisci Distanza +2438=Raccordo +2439=Smusso +2440=Estendi +// ----- EgtCAM5 ----- +5001=DIBUJA +5002=TRABAJA +5003=Db Herramientas +5004=Db Trabajos +5005=Opciones +5006=Db Herr. +5007=Db Trab. +5008=Opciones Maquina +5009=Db Equip. +5010=Db Equipado +5020=Tablas Trabajos +//Top CommandBar +5101=Nuevo +5102=Abrir
Abrir archivos recientes (clic derecho) +5103=Gravar +5104=Gravar como +5105=Insertar +5106=Importar +5107=Exportar +5108=Ejecutar guión
Ejecutar guión reciente (tecla derecha) +5109=Opciones +5110=Dirección de correo electrónico de soporte no encontrada. +5111=¿Guardar el proyecto actual antes de enviar comentarios? +5112=Enviar comentarios a {0} con la carpeta {1} adjunta. +5113=Comentarios (Feedback) +5114=Correo de comentarios listo. +//Draw Panel +5150=Extraer bordes libres de superficies y regiones planas +5151=Combinar superficies y regiones planas +5152=Restar superficies y regiones planas
Taglia Superficie con Superficie Inversa (Shift) +5153=Intersecar superficies y regiones planas
Taglia Superficie con Superficie (Shift) +5154=Puntos, curvas y caras de intersección entre superficies +5155=Dimensión lineal
Dimensión alineada (Shift) +5156=Círculo 3 Puntos +5157=Extraer bordes de caras de superficies y partes de regiones planas +5158=Extraer cara de superficie +5159=Arco Invertido
Arco Esplementare (Shift) +5160=???Modifica forma +5161=???Aggiungi Punto
Trasforma in Arco (Shift)
Chiudi Curva Composita (Ctrl) +5162=???Rimuovi Punto
Trasforma in Retta (Shift)
Apri Curva Composita (Ctrl) +5163=???Approssima Curva
Approssima Curva con Linee (Shift) +5201=Punto
Vector (Shift)
Referencia (Ctrl) +5202=Línea de 2 puntos
Línea de 2 puntos con continuación (Ctrl) +5203=Línea Punto, Dirección y Longitud
Línea Punto, Dirección Vectorial y Longitud (Shift) +5204=Círculo Centro Punto +5205=Círculo Centro Diámetro +5206=Arco Centro Puntos de inicio y fin +5207=Arco 3 Puntos +5208=Arco Punto y Dirección de Inicio, Punto de Fin
Arco Punto y Dirección Vectorial de inicio, Punto de Fin (Shift)
Arco Punto y Dirección de Inicio, Punto de Fin con continuación (Ctrl) +5209=Conexión +5210=Bisel +5211=Rectángulo de 2 puntos +5212=Polígono +5213=Polígono desde el lado +5214=Texto
Texto avanzado (Shift) +5215=Plano delineado
Región plana (Shift) +5216=Extrusión +5217=Revolución +5218=Atornillar +5219=Rigata +5220=Fusionar superficies +5221=Explotar superficies y regiones planas +5222=Invertir superficies y regiones planas +5223=Eliminar +5224=Cambiar capa
Cambiar capa con transformaciones (Shift) +5225=Cambiar transparencia +5226=Cancelar color +5227=Cambiar color +5228=Curva inversa +5229=Cambiar el punto inicial de la curva cerrada +5230=Extender o acortar curva +5231=Interruptor de curva +5232=Curva de división +5233=Combinar curvas
Combinar curvas creando una copia (Shift)
Fusionar curvas en Composita (Ctrl) +5234=Explotar curvas y textos +5235=Espesor y extrusión curva +5236=Moverse +5237=Rotar +5238=Rueda 3D +5239=Espejo +5240=Espejo 3D +5241=Escalera +5242=Escala 3D +5243=Offset +5244=Dibujo 2D +5245=Dibujo 3D +5246=Cambiar +5247=Transformar +5248=Barrido (Sección, Guía) +5249=Editar texto +// Grid View Panel +5251=Wireframe +5252=Líneas ocultas +5253=Sombra +5254=Zoom todo +5255=Acercar +5256=Alejar +5257=Vista desde arriba +5258=Vista frontal +5259=Vista desde la izquierda +5260=Vista desde atrás +5261=Vista desde la derecha +5262=Vista isométrica desde SW +5263=Vista isométrica desde el SE +5264=Vista isométrica desde NE +5265=Vista isométrica desde el NO +5266=Mostrar dirección de curva +5267=Analizar +5268=Distancia +5269=Cuadrícula desde arriba +5270=Cuadrícula frontal +5271=cuadrícula derecha +5272=Cuadrícula desde atrás +5273=Cuadrícula izquierda +5274=Cuadrícula desde abajo +5275=Ver cuadrícula +5276=Elevación de la cuadrícula +5277=Origen de cuadrícula +5278=Rueda de Cuadrícula
Rueda de Cuadrícula 3d (Shift) +5279=Cuadrícula de 3 puntos +5280=Cuadrícula perpendicular curvada +5281=Cuadrícula de objeto +5282=Vista desde la cuadrícula +5283=Selección de zoom +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=FIN +5302=Extra corsa +5303=Dirección de herramienta inalcanzable +5304=Error +5305=ERROR +5306=¡Error en la generación! +5307=Simulación +5308=Un paso a la vez +5309=Reproducir / Pausa +5310=Parar / Inicio +5311=PAUSA +5312=PARAR +5313=Imposible salir ahora. ¡Primero pare la simulación o espere a que termine! +5314=INICIO +5315=ADVERTENCIA +5316=Fresado virtual +5317=¡Error al calcular las estimaciones! +5318=Archivo de estimación no encontrado +5319=¡Colisión! +5320=INFORMACIÓN +5330=GENERAR +5331=El proyecto debe guardarse antes de la generación NC. ¿Desea hacerlo? +5332=Generado con éxito +5333=La licencia no permite la generación CN +5340=Estimado +5341=Tiempo total +5342=longitud total +5343=Detalles +5344=Estimaciones detalladas +// Draw Option +5351=Propiedades +5352=Nueva pieza +5353=Nueva capa +5354=Color +5355=Parámetros de dibujo +5356=Seleccionar +5357=Desmarcar +5358=Nombre +5359=Información +5360=Mover +5361=Copiar +5362=Eliminar +5363=Guardar +5364=Mostrar +5365=Confirmación +5366=Cancelación de confirmación +5367=Pieza de trabajo, ¿quieres eliminarla de todos modos? +// Operation +5401=Operaciones +5402=Parámetros de operación +5403=Aplicar procesamiento +5404=Nuevo Trab +5405=Nueva Disp +5406=Eliminar +5407=Genérico +5408=ascender +5409=abajo +5410=Actualizar +5411=Actualización completada con éxito +5412=Nuevo procesamiento +5413=Vista herramienta +5414=adelante +5415=Atrás +5416=Duplicado +5417=Copiar a Db +5418=Procesando nombre en el Db +5419=Error en la inserción del trabajo +5420=Cambiar nombre +5421=El nombre no puede comenzar con "Disp" +5422=Nombre ya usado +5423=???La lavorazione non può essere applicata per i seguenti motivi: +// Disposition +5431=Ok +5432= +5433=Nuevo +5434=Eliminar +5435=Longitud +5436=Ancho +5437=Altura +5438=Posición +// Mach & Disposition Errors +5461=ERROR DE EJECUCIÓN DE SCRIPT +5462=Error al ejecutar el script de disposición automática +5463=Error al ejecutar el script de inicio de mecanizado +5464=Error al ejecutar el script de mecanizado final +// Mach Group +5501=¿Está seguro de que desea limpiar el grupo de procesamiento? +5502=¿Está seguro de que desea cancelar el Grupo de procesamiento? +5551=No hay grupos de mecanizado:
seleccione las piezas a insertar y
repita el comando para crear el primero +5552=¿Desea crear un nuevo grupo de trabajo
con las piezas seleccionadas? +// Tools Db Page +6001=Broca +6002=Cuchilla +6003=Cortador +6004=Mortaja +6005=Compuesto +6006=Broca larga +6007=Cuchilla plana +6008=Cortador sin punta +6009=Cincel +6010=WaterJet +6051=Corrección +6052=Salida +6053=Tipo +6054=Refrigerante +6055=Radio de la esquina +6056=Diámetro +6057=Diámetro total +6058=Progreso +6059=Progreso final +6060=Progreso inicial +6061=Progreso de pico +6062=Longitud +6063=Longitud total +6064=Agudo +6065=Desplaz. longitudinal +6066=Desplaz. radial +6067=Rotación +6068=ángulo lateral +6069=Rotación máxima +6070=Espesor +6071=Absorción máxima +6072=Avance mínima +6073=Diseño +6074=Motor +6075=Nombre +6076=Notas +6077=Pos.herramienta +6078=Posición +6079=Distancia +6080=???Overtable +// Tools Errors +6100=¿Guardar la herramienta modificada? +6101=GUARDAR +6102=El archivo debe ser .nge +6103=El archivo no existe o no es del tipo Nge +6104=No hay ToolMaker para este tipo de herramienta +6105=La herramienta no se puede crear con estos parámetros +6106=El agudo debe ser mayor que 0 +6107=El agudo debe ser menor que el pulmón +6108=El grosor debe ser mayor que 0 +6109=El diámetro debe ser mayor que 0 +6110=La longitud debe ser mayor que 0 +6111=La rotación debe ser menor que la rotación máxima +6112=Nombre inválido +6113=La longitud debe ser menor que la Longitud total +6114=La longitud debe ser mayor que el Agudo +6115=La longitud total debe ser mayor que 0 +6116=La longitud total debe ser mayor que la longitud +6117=El agudo debe ser inferior a 1/3 del diámetro +6118=El diámetro debe ser menor que el diámetro total +6119=El diámetro debe ser mayor que 3 veces el agudo +6120=El diámetro total debe ser mayor que 0 +6121=Longitud demasiado pequeña con el portaherramientas +6122=¿Está seguro de que desea eliminar la herramienta? +6123=? +6124=CLARO +6125=¡No se encontró el archivo de configuración de instalación! +6126=Error +6127=Establecer el tipo de cabeza. +6128=Establecer el tipo de salida. +6129=Herramienta no válida, corríjala o elimínela antes de salir de la base de datos de herramientas. +6130=No se puede volver a cargar la base de datos de herramientas. Si la carpeta de máquinas está en un servidor, verifique que la conexión esté activa. +6131=El grosor debe ser diferente de 0 +6132=El ángulo lateral debe ser inferior a 90 +6133=El ángulo lateral debe ser mayor que -90 +6134=La longitud total debe ser mayor que la longitud + grosor +6135=El radio de la esquina es demasiado grande. +6136=El grosor es demasiado pequeño en comparación con el radio de la esquina +6137=El diámetro resultante excede el diámetro total +6138=El diámetro resultante es menor que 0 +6139=El diámetro de la varilla resultante es menor o igual a 0 +6140=El agudo debe ser mayor que el radio de la esquina +6141=El agudo resultante debe ser> = 0 +6142=El radio de la esquina no debe exceder la mitad del grosor +6143=Guardar herramienta +6144=¡Herramienta modificada! Todas las herramientas deben guardarse antes de cambiar las activaciones. ¿Guardar herramienta {0}? +6145=¡Posición ya ocupada! +6146=¡Posición no definida! +// Machinings Db Page +6201=Taladrar +6202=Corte con disco +6203=Mecanizado +6204=Vaciar +6205=Ranurado +6206=Desbaste con disco +6207=Acabado con disco +6208=Trab.generico +6209=Cincelado +6210=Desbaste de superficies +6211=Acabado superficial +6212=WaterJet +6251=Invertir +6252=TAB +6253=Tipo +6254=Lado de trabajo +6255=Lado de la cabeza +6256=Ataque +6257=Conexión +6258=Salir +6259=Usando curvas +6260=Tipo de paso +6261=Subtipo +6262=Tipo de aproximación +6263=Velocidad +6264=Progreso +6265=Alimentación inicial +6266=Alimentación final +6267=Avance del cabezal +6268=Desplaz. radial +6269=Desplaz. longitud. +6270=Hundimiento +6271=Ángulo de flanco +6272=Aproximación +6273=Dist. la seguridad +6274=Longitud ralentizado inicial +6275=Longitud ralentizado el final +6276=Longitud passante adj. +6277=Paso +6278=Posición de retorno +6279=Longitud +6280=Distancia +6281=Altura +6282=Esquina +6283=Dist. ataque tangente +6284=Dist. para p. ataque +6285=Elevación del ataque +6286=Long. corre. ataque +6287=Dist. salida tangente +6288=Dist. para p. salida +6289=Elevación de salida +6290=Long. correg. salida +6291=Long. añadir. ataque +6292=Long. añadir. salida +6293=Paso en arco exterior +6294=Paso en arco interior +6295=Paso lateral +6296=Progreso vertical +6297=Nombre +6298=Herramienta +6299=Hundimiento +6300=Notas +6301=Superposición +6302=Desplazamiento +6303=Subtipo +6304=SCC +6305=Ninguno +6306=Estándar +6307=Opuesto +6308=AuxDir derecha +6309=AuxDir Izquierda +6310=AuxDir detrás +6311=AuxDir delantero +6312=AuxDir arriba +6313=AuxDir abajo +6314=AuxDir más cercano +6315=AuxDir más lejos +6320=Centro +6321=Izquierda +6322=Derecha +6323=Ampliar +6324=Estándar +6325=Interna +6326=Externo +6327=Extendido centrado +6328=externo extendido +6329=Ninguno +6330=Lineal +6331=Tangente +6332=Persecución +6333=Hélice +6334=Ampliar anterior +6335=Ampliar siguiente +6336=Extender ambos +6337=Como ataque +6338=Saltar +6339=Aproximado +6340=convexo +6341=Mantener +6342=ZigZag +6343=Unidireccional +6344=Espiral +6345=Ir y volver +6346=Longitudinal +6347=transversal +6348=Espiral en +6349=Espiral hacia fuera +6350=Avanzado +6351=Dir. inversa herr. +6352=Mecanizado de caras +6353=Indefinido +6354=Paralelo +6355=Ortogonal +6356=Orthog. Arriba +6357=Abajo +6358=Arriba +6359=Frente +6360=Detrás +6361=Izquierda +6362=Derecha +6363=Esquema +6364=Ángulos sugeridos +6365=Eje bloqueado +6366=Máximo no +6367=Número mínimo +// Machining errors +6370=¿Guardar el mecanizado modificado? +6371=GUARDAR +6372=Nombre inválido +6373=Los personajes \ /: *? "<> | no están permitidos +6374=¿Está seguro de que desea eliminar? +6375=? +6376=BORRAR +6377=No se puede volver a cargar la base de datos del trabajo. Si la carpeta de máquinas está en un servidor, verifique que la conexión esté activa. +6378=Oscilación +6379=Ancho +6380=Longitud rampa +6381=Longitud. cresta +// Machining Option Page +6401=Z de Seguridad +6402=División del arco +6403=Nunca +6404=Plan genérico +6405=Plano distinto de XY +6406=Siempre +6407=Configuración predeterminada +6408=Retorno de seguridad desde abajo +6409=Tolerancia del agujero +// SetUp Window +6451=Config. +6452=Aplicar +6453=Guardar +6454=Recuperar +6455=Automático +6456=¿Aplicar las herramientas actuales antes de salir? +6457=???New +// SetUp Errors +6471=Error +6472=Advertencia +6473=No se pudo encontrar la herramienta +6474=en el DB de herramientas. +6475=La posición predeterminada de la herramienta no es válida. +6476=La posición de herramienta predeterminada ya está ocupada. +6477=¡El archivo de configuración no existe! +6478=¡La herramienta utiliza un cabezal que no existe en la máquina! +6479=Error al cargar la configuración +// Option Page +6501=Idioma actual +6502=El nuevo idioma serà actualizado desde el pròximo inicio del programa. +6503=Curvas +6504=Superficies +6505=Curvas y superficies +6506=Geometría seleccionable +6507=Agregar el nuevo mecanizado al final +6508=Usar script de disposición +6509=Unidad de medida +6510=Color de la vista de arriba +6511=Color de la vista inferior +6512=Color predeterminado +6513=Tolerancia geométrica +6514=General +6515=CAD +6516=CAM +6517=Color de la cuadrícula +6518=Superficie biselada +6519=Importar +6520=DXF +6521=STL +6522=Imágenes +6523=Exportar +6524=Imagen +6525=Ancho (píxeles) +6526=Altura (píxeles) +6527=Actualización de la máquina +6528=La máquina "{0}" ya está, ¿qué quieres hacer? +6529=El archivo {0} no contiene una máquina. +6530=La máquina "{0}" se ha actualizado correctamente. +6531=Soporte +6532=Actualización +6533=Cancelar +6534=Aviso +6535=El usuario de la máquina "{0}" ha fallado. +6536=Líneas gruesas +6537=Longitud extra de referencia +6538=Longitud de la flecha +6539=Distancia de texto +6540=Unidad de medida +6541=Decimales +6542=Fuente +6543=Altura del texto +6544=Dimensionamiento +6545=Unidad actual +6546=Otro +6547=Unidad de medida +6548=Factor de escala +6549=Exportar máquina actual +6550=???Select the folder where you want to save the machine +6551=???The exportation of the "{0}" machine failed. +6552=???The machine "{0}" has been successfully exported. +6553=???Update Licence +// Heads +6601=???Verticale +6602=???Orizzontale +6603=???Aggr. 2 uscite +6604=???Aggr. 3 uscite +6605=???Aggr. 4 uscite +6606=???Testa 3 assi +6607=???Testa 4 assi +6608=???Testa 5 assi +6609=???Navetta 1 +6610=???Navetta 2 +6611=???Multi rotante +6612=???Gr. a forare +6613=???Multi scalp. +6614=???Rinvio sotto +6615=???Lama 5 assi +6616=???Sega a catena +6617=???Aggr. 1 uscite +6618=???Testa tastatura +6619=???Flottante 360° +6620=???Seconda Testa 5 assi +6621=???Foratore orizzontale +6622=???Mortasatrice +6623=???Seconda Lama 5 assi +6624=???Aggr. 1 uscita tilt. +6625=???Estrusore +6799= +// StatusBar +6801=Direttorio Machines non trovato. EgtCAM5 funzionerà in modo solo CAD. +// Doors +8001=Crea nuova MTable +8002=Salva MTable +8003=Salva MTable Come +8004=Elimina MTable +8005=Salva file MTable +8006=Sei sicuro di voler cancellare questa MTable? +8007=Salva la MTable modificata? +8008=Lista delle macchine attive +8009=Nome della macchina +8010=Genera Cn +8011=Aggiorna grezzo +8012=On +8013=Nome Geometria +8014=Operazione +8015=MId +8016=Spost. +8017=Tipo Lavorazione +8018=Lavorazione 1 +8019=Lavorazione 2 +8020=Lavorazione 3 +8021=Aggiungi Macchina +8022=Elimina Macchina +8023=Aggiungi Lavorazione +8024=Elimina Lavorazione +8025=CORR +8026=Imposta MTable corrente +8027=GId +8028=Proprietà +8029=Lavorazione +8030=Unisci +// Door errors +8101=Errore +8102=Errore nell'esecuzione del file Ddf +8103=Avvertimento +8104=Path della cartella MTable non trovata +8105=La cartella MTable non esiste +8106=Mancano i file di configurazione nella cartella MTable +8107=Errore sconosciuto +8108=Questa è la MTable correntemente attiva. +8109=Non può essere cancellata. +8110=Sei sicuro di voler cancellare la lavorazione selezionata? +8111=CANCELLA +8112=Sei sicuro di voler cancellare la macchina selezionata? +8113=Impossibile trovare la cartella delle macchine {0}. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +8114=Provare a ricaricare la macchina? +8115=Impossibile trovare la cartella {0}. Se la cartella Doors è su un server, verificare che la connessione sia attiva. +8116=Provare a ricaricare la cartella Doors? +8117=Errore di esecuzione (guarda il file di log) +// GunStock +8201=Nuovo pezzo +8202=Gunstock Nuovo Pezzo +8203=Mod pezzo +8204=Gunstock Modifica Pezzo +8205=Parametri calcio +8206=Nome file +8207=Descrizione +8208=Ok +8209=Cancella +8210=deve avere un valore. +8211=Il valore deve essere compreso tra +8212=e +8213=Dimensioni del grezzo +// GunStock errors +8251=Errore +8252=Errore nel lancio dell'ambiente Gunstock +8253=Errore nella lettura del file Modello +8254=Errore nella scrittura del file Pezzo +// ----- Beams ----- +9000=Tabla de mecanizado de vigas +9001=Activado +9002=Nombre +9003=Tipo +9004=Agregar +9005=Eliminar +9006=Guardar +9007=¿Quiere guardar sus cambios? +9008=Error +9009=No se puede abrir el editor de características de la viga.
Faltan archivos de configuración. +9010=Tablas de procesamiento de paredes +9011=No se pudo abrir el Editor de características del muro.
Faltan archivos de configuración. +// ----- Errori ----- +10001=Error +10002=Error enla creaciòn de un nuevo file +10003=Error en el abrir el file +10004=Error en el salvar el file +10005=Tipo de file desconocido +10006=Error en importar el file +10007=Error en exportar el file +10008=Error cargando o creando el Grupo de trabajo +10009=No existe el file +// Missing Key Window +10101=Error ! +10102=Llave no presente. +10103=Introducirla y reiniciar el programa. +10104=Ok +10105=Programa sin licencia. +10106=Cárgalo y reinicia el programa. +10107=Ejecuta GetMachineId y envia los resultados al proveedor.. +// Numeric virtual keyboard +10201=Expresión equivocada +// ----- MessageBox ----- +15001=???Errore +15002=???Avviso +15003=???Informazione +15010=???Errore interno (guarda log file) +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Expresiòn errada +// EgtCalculadorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Canc +20043=SI +20044=NO +// ----- EgtWPFLib5 ----- +// EgtSaveFileDialog +30001=Salvar +30002=Anular +30003=ya existe. +30004=reemplazarlo? +30005=Nombre file: +30006=Abrir +30007=ERROR +30008=El nombre no puede estar vacio! +30009=ATENCION +30010=Nombre File +30011=Nombre Carpeta +// Top CommandBar +30501=Nuevo +30502=Abrir +30503=Salvar +30504=Salva como +30505=Introducir +30506=Importar +30507=Exportar +30508=Ejecutar +30509=Opciones +30510=Direcciòn de correo electronico de soporte no encontrado +30511=Salvar el proyecto actual antes de enviar el feedback +30512=Enviar el feedback a {0} con adjunto la carpeta {1} +30513=Feedback +30514=Correo de feedback listo +// Grid View Panel +30801=Wireframe +30802=Lineas Escondidas +30803=Sombreado +30804=Zoom All +30805=Zoom In +30806=Zoom Out +30807=Vista desde arriba +30808=Vista de Frente +30809=Vista de izquierda +30810=Vista desde atràs +30811=Vista de Derecha +30812=Vista Isometrica de SW +30813=Vista Isometrica de SE +30814=Vista Isometrica de NE +30815=Vista Isometrica de NW +30816=Muestra Direcciòne Curvas +30817=Analiza +30818=Distancia +30819=Rejilla desde arriba +30820=Rejilla de Frente +30821=Rejilla de Derecha +30822=Rejilla desde Atràs +30823=Rejilla de Izquierda +30824=Rejilla desde Abajo +30825=Rejilla de Vista +30826=Elevaciòn Rejilla +30827=Origen Rejilla +30828=Girar Rejilla +30829=Rejilla de 3 Puntos +30830=Rejilla Perpenticular a Curva +30831=Rejilla de Objeto +30832=Vista de Rejilla +// MachGroupPanel +30901=Nuevo grupo de trabajo +30902=Nombre: +30903=Màquina: +// ToolDbWindow +31001=Broca +31002=Cuchilla +31003=Cortador +31004=Mortaja +31005=Compuesto +31006=Broca larga +31007=Cuchilla plana +31008=Taladro sin fin +31009=Cincel +31010=Chorro de agua +31051=Corrector +31052=Salida +31053=Tipo +31054=Refrigerante +31055=Radio de la esquina +31056=Diámetro +31057=Diámetro total +31058=Progreso +31059=Progreso Final +31060=Progreso Inicial +31061=Progreso de pico +31062=longitud +31063=longitud total +31064=Material máximo +31065=Desplaz. long. +31066=Desplaz. radial +31067=Rotación +31068=Angulo de Lado +31069=Rotaciòn Màxima +31070=Espesor +31071=Absorción máxima +31072=Progreso mínima +31073=Diseño +31074=Cabezal +31075=Nombre +31076=Notas +31077=Posic. Cambio Herramienta +31078=Posiciòn +31079=Perforación +31080=Agudo +// ToolDb Errors +31100=¿Guardar la herramienta modificada? +31101=GUARDAR +31102=El archivo debe ser .nge +31103=El archivo no existe o no es del tipo Nge +31104=No hay ToolMaker para este tipo de herramienta +31105=Imposible crear la herramienta con estos parametros +31106=El Agudo tiene que ser mayor de 0 +31107=El Agudo tiene que ser menor de Len +31108=El espesor tiene que ser mayor de 0 +31109=El Diàmetro tiene que ser mayor de 0 +31110=La longitud debe ser mayor que 0 +31111=La rotación debe ser menor que la rotación máxima +31112=Nombre no vàlido +31113=La longitud debe ser menor que la longitud total. +31114=La longitud debe ser mayor que el máximo del material. +31115=La longitud total debe ser mayor que 0 +31116=La longitud total debe ser mayor que la longitud +31117=El Agudo debe ser inferior a {0} +31118=El diámetro debe ser menor que el diámetro total. +31119=El diámetro debe ser superior a 3 veces el máximo del material. +31120=El diámetro total debe ser mayor que 0 +31121=Longitud demasiado pequeña con portaherramientas +31122=¿Estás seguro de que deseas eliminar la herramienta? +31123=? +31124=BORRAR +31125=Archivo de configuración de instalación no encontrado! +31126=Error +31127=Configurar el tipo de cabeza. +31128=Configurar el tipo de salida. +31129=Herramienta no vàlida, corrijala o eliminela antes de salir del Db Herramientas. +31130=Imposible recargar el database herramientas. Si la carpeta de máquinas está en un servidor, verifique que la conexión esté activa. +31131=El espesor debe ser diferente de 0 +31132=El ángulo lateral debe ser inferior a 90 +31133=El ángulo lateral debe ser mayor que -90 +31134=La longitud total debe ser mayor que longitud + espesor +31135=El radio corner tiene un valor demasiado grande. +31136=El grosor tiene un valor demasiado pequeño en comparación con el radio Corner +31137=El diámetro resultante excede el diámetro total +31138=El diámetro resultante es menor que 0 +31139=El diámetro del vástago resultante es menor o igual que 0 +31140=El Agudo debe ser mayor que el radio Corner +31141=El Agudo resultante debe ser >= 0 +31142=El agudo debe ser mayor que 0 +31143=El agudo debe ser menor que Len +// ImportExportToolWindow +31161=???Import +31162=???Export +31163=???Tools +31164=???Tool already existing in DB. Overwrite? +31165=???Tool will be imported with the name followed by "_imp" +31166=???The following Tools have been imported succesfully: +31167=Reset +// MachiningDbWindow +31201=perforación +31202=Corte de la cuchilla +31203=fresado +31204=Vaciar +31205=Ranurado +31206=Desbaste con cuchilla +31207=Terminar con cuchilla +31208=Procesamiento genérico +31209=cincelado +31210=Chorro de agua +31211=???Surffinishing +31251=invertido +31252=Salir de la pestaña +31253=Tipo +31254=Lado de trabajo +31255=Lado del cabezal +31256=Ataque +31257=Conexión +31258=Salida +31259=Usa curvas +31260=Tipo de paso +31261=subtipo +31262=Tipo de aproximación +31263=Rotación +31264=Progreso +31265=Progreso inicial +31266=Progreso final +31267=Progreso pico +31268=Despl. radial +31269=Despl. longit. +31270=Hundimiento +31271=Angulo de lado +31272=Aproximación +31273=Dist. de seguridad +31274=Long. ralent. inicial +31275=Long. ralent. final +31276=Long. pasador adic. +31277=Paso +31278=Posición de retorno +31279=Longitud +31280=Altura +31281=Ángulo +31282=Distancia +31283=Dist. tangente +31284=Dist. perp. +31285=Elevación +31286=Longitud. Corrección. +31287=Número mínimo +31288=Número máximo +31291=Longitud. Suplem. +31293=pisar el arco externo +31294=pisar el arco interno +31295=Paso a un lado +31296=Progreso vertical +31297=Nombre +31298=Herramienta +31299=Profundidad +31300=Notas +31301=Superposición +31302=OFFSET +31303=Subtipo +31304=SCC +31305=Ninguno +31306=Estándar +31307=Opuesto +31308=AuxDir derecha +31309=AuxDir izquierda +31310=AuxDir detrás +31311=AuxDir Delantero +31312=AuxDir arriba +31313=AuxDir debajo +31314=AuxDir màs cercano +31315=AuxDir màs lejano +31320=Centro +31321=Izquierda +31322=Derecha +31323=Extender +31324=Estándar +31325=Dentro +31326=Fuera +31327=Centrado extendido +31328=Extendido externo +31329=Ninguno +31330=Linear +31331=Tangente +31332=Persecución +31333=Hélice +31334=Extender anterior +31335=Extender siguiente +31336=Extender ambos +31337=Como ataque +31338=saltar +31339=aproximado +31340=Convexo +31341=Mantiene +31342=ZigZag +31343=Una via +31344=Espiral +31345=Va y regresa +31346=Longitudinal +31347=Transversal +31348=Espiral en +31349=Espiral fuera +31350=Avanzados +31351=Dirección inversa her. +31352=Mecanizado frontal +31353=No definido +31354=Paralelo +31355=Ortogonal +31356=Ortog. arriba +31357=Debajo +31358=Arriba +31359=Delante +31360=Atràz +31361=Izquierda +31362=Derecha +31363=Contorno +31364=Angulos Sugeridos +31365=Eje Blocado +31366=Retroalimentar último +31367=Retroceder +31368=Paso inclinado +31369=Paso hacia atrás inclinado +31370=inclinación hacia adelante +31371=Sondeo +31372=Min dist. puntos +31373=Dist. Máx. puntos +31374=Exterior +31375=Interior +31376=Longitud. rall. +31377=DECELERACIÓN. % +31378=Agujero de ataque +31379=Radio +31380=Número. vueltas en LP +31381=Número. revoluciones en HP +31382=Oscilación +31383=ancho +31384=Longitud. rampa +31385=Longitud. cresta +31386=Genérico +31387=Avanzado +31388=Tang+Perp +31389=Perp+Tang +//MachiningTreeView +31391=Normal +31392=Ralentiza +31393=Anillo +31394=Habilitar +31395=???Add Length +31396=???Start +31397=???End +31398=???System notes +31399=???Epicycles radius +31400=???Epicycles distance +// MachiningDb Errors +31401=¿Guardar el mecanizado modificado? +31402=GUARDAR +31403=Nombre inválido +31404=Los caracteres \ /: *? "<> | no están permitidos +31405=¿Está seguro de que desea eliminar? +31406=? +31407=BORRAR +31408=Imposible recargar database laboraciones. Si la carpeta de máquinas está en un servidor, verifique que la conexión esté activa. +31409=???Machine material not recognized +31410=???Lavorazione non valida, correggerla o cancellarla prima di uscire. +31411=???La Lunghezza deve essere positiva +31412=???La Distanza deve essere positiva +31413=???L'Altezza deve essere positiva +31414=???L'Angolo deve essere compreso tra {0}° e {1}° +31415=???N° massimo deve essere nullo o positivo +31416=???N° massimo deve essere maggiore o uguale al minimo +31417=???N° minimo deve essere nullo o positivo +31418=???N° minimo deve essere minore o uguale al massimo +31419=???L'abilitazione di {0} disabiliterà {1}. Procedere? +// ImportExportMachiningWindow +31450=???Import +31451=???Export +31452=???Machinings +31453=???Machining already existing in DB. Overwrite? +31454=???Machining will be imported with the name followed by "_imp" +31455=???The following Machinings have been imported succesfully: +31456=???Reset +// Ventana de configuración +31501=Configuración +31502=Aplicar +31503=Archivar +31504=Recuperar +31505=Auto +31506=¿Aplicar el equipo actual antes de partir? +// SetUp Errores +31551=Error +31552=Aviso +31553=No se pudo encontrar la herramienta +31554=en el DB herramientas. +31555=La posición predeterminada de la herramienta no es válida. +31556=La posición predeterminada de la herramienta ya está ocupada. +31557=¡El archivo de configuración no existe! +31558=¡Las herramientas utilizan un cabezal que no existe en la máquina! +31559=Error al cargar la configuración +// Simulaciòn +31601=Simulaciòn completada +31602=Carrera extra +31603=Dirección de herramienta inalcanzable +31604=Error +31605=ERROR +31606=¡Error en la generación! +31607=Simulaciòn +31608=Un paso a la vez +31609=Reproducir / Pausa +31610=Detener / Inicio +31611=Pausa +31612=Simulación detenida +31613=Imposible salir ahora. ¡Primero pare la simulación o espere a que termine! +31614=ADVERTENCIA +31615=Archivo de estimaciones no encontrado +31616=Estimaciones detalladas +//MachiningDbWindow/ToolDbWindow buttons +31701=Nuevo +31702=Guardar +31703=Eliminar +31704=???Edit +//Db Waterjet +31751=???Waterjet Db +31752=???Thickness +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=???Do you want to save edits? +// ----- EgtDOORCreator ----- +//General +50001=Larghezza +50002=Altezza +50003=Spessore +50004=???Swing +50005=Lato-serratura +50006=Lato-cerniera +50007=???Top +50008=Fondo +50009=Tipo +50010=Angolo +50011=???Extension +50012=Lato +50013=???Offset wide side +50014=Margine +50015=???Top to center application +50016=Traverso basso +50017=???Lock stile +50018=???Offset from center +50019=???Point to pocket +50020=???Pocket length +50021=???Pocket offset narrow side +50022=???Point to arm +50023=???Arm length +50024=???CenterHung +50025=Traslato +50026=Intermedio traslato +50027=Raggio +50028=Traverso alto +50029=Posizione +50030=Lunghezza +50031=Modello +50032=???Up +50033=???Down +50034=???Shape +50035=Cerniera +50036=???Top to top application +50037=???Center from top application +50038=???Center from top lock +50039=Profondità +50040=Generale +50041=Centro +50042=???Thru +50043=???Face to center line application +50044=Tipo di spigolo +50045=Sovramateriale +50046=Invia Feedback +50047=Peso +50048=???Angle +50049=???Face +50050=???Secure +50051=???Keyway +50052=???Brand +50053=???Folder +50054=???Main Folder +50055=???Jamb +50056=???Light Up +50057=???Light Lock +50058=???Light Bottom +50059=???Light Hinge +50060=???Thickness Head +50061=???Overlap Hinge +50062=???Overlap Lock +50063=???Overlap Top +50064=???Delta T +50065=???Exterior +50066=???Number of Doors +50067=???Jambs and Doors +50068=Ordine +50069=Disposizione +50070=Cliente +50071=Inverti profilo serratura +//Compo Name +50072=Catenaci +50073=Maniglia di superficie +50074=Cerniera +50075=Serratura +50076=Passaggio animali +50077=Buca delle lettere +50078=Ferramenta lato superiore +50079=Cerniera perno +50080=Fermo rullo +50081=???Stops And Closer +50082=Piastrina di battuta +50083=Maniglia incassata tirare +50084=Spioncino +50085=Sfinestratura +50086=Gole +50087=Ribassi +50088=???Ept +50089=???Raceway +50090=Decorazioni +//error messages +50100=Direttorio non trovato +50101=Errore +50102=Fallita lettura del file ddf. Manca un parametro fondamentale {0}. +50103=Fallita lettura valore. +50104=Fallita lettura nella riga del file ddf +50105=Riga +50106=Valore non accettabile in +50107=File vuoto. +50108=Impossibile aggiunegere la componente. Inserire una porta! +50109=Vuoi salvare questo file ({0}) ? +50110=Domanda +50111=Aggiungi nuova porta +50112=Rimuovi porta +50113=Nuova Porta +50114=Il nome del file già esiste nel direttorio corrente ({0}). +50115=Attenzione +50116=Vuoi cancellare questo file ({0}.ddf) ? +50117=Confermi la cancellazione ({0}.ddf) ? +50118=Informazione +50119=Errore nella lettura dei messaggi. Non esiste corrispondenza con il numero {0}. +50120=Errore nella lettura del nome {0} in {1}. Attesa una corrispondenza numerica. +50121=Errore nella lettura {0} nel parametro {1} della componente: non esiste. +50122=Errore nel parametro {0} della componente {1} della componente. +50123=Errore nella lettura {0} nel parametro {1} della componente: non esiste la lista. +50124=Errore nella lettura {0} nel parametro {1} della componente: {2}. +50125=Errore nel parametro {0} della componente {1} della componente: non esiste il valore. +50126=Elimina +50127=Errore in EgtLoadMessages +50128=Impossibile salvare un file se non esiste una porta! +50129=Errore nella creazione della scena. +50130=Errore nella lettura della riga {0}. +50131=Errore in lettura {0}: riga {1}. Atteso ':' dopo il nome. +50132=Errore in lettura {0}: riga {1}. Atteso 'template' o 'shape'. +50133={0} non è stato creato. +50134=Errore nella lettura di 'Template' nel file {0}\{1}. Atteso nome. +50135=Errore nella lettura di 'Template' nel file {0}\{1}. File {0}\{2} .lua non esiste. +50136=Errore nella lettura {0}: riga {1}. Non esite la componente nel file 'Default.ini'. +50137=Errore nella lettura {0}: riga {1}. Non è un memebro della lista. +50138=Questo parametro sarà inizializzato di default. +50139=Errore in lettura: riga {0}. Atteso {1}. +50140=Tutti i parametri mancanti saranno inizializzati di default. +50141=Espressione non valida in {0}. +50142=Rimuovi componente +50143=Espressione non valida +50144=Avvertenza +50145=Impossibile creare la porta corrente. +50146=Vuoi aprire un modello? +50147=Errore nell'espressione {0}. {1} non associa nulla. +50148=Valore non valido. +50149=Attenzione: il peso è selezionato nella pagine delle impostazioni. Vuoi disabilitarlo? +50150=Attenzione: il peso è un parametro del file .ddf. Vuoi aggiungerlo alle impostazioni? +50151={0} Non appartiene alla lista degli spigoli. Seleziona il Bevel nella pagina delle impostazioni. +50152=Vuoi salvare questo file ({0})? +50153=Attenzioni: il peso è un parametro della porta corrente. Vuoi rimuoverlo dalla porta? +50154=Questo bevel è selezionato nella porta corrente. Vuoi procedere? +50155=Impossibile creare un modello se non esite una porta! +50156=???Errore nella lettura ddf: la porta non è completa o il ddf è stato separato male da '---'. +50157=???Script Lua ( {0}\{1} )has not been found. +50158=???Bevel {0} can not be acceptable in Jamb. +50159=??? Missing parameter in ddf! +50160=Il file {0} nel direttorio {1} non esite. +50161=???parameter +50162=???In file {0} param 'Default' must be numeric. +50163=???Error in reading General Assembly in DDF +50164=???In General Assembly: +50165=???CompoDir not found : +50166=???Jamb compo does not exist +50167=???Empty Line +50168=???No matching param +50169=???Door disposition has been modify. +50170=???Incongruity between the bevel, it has been resolved by default. +50171=???In file StdTempate.ini is missing numeric param in [Type]. +50172=???File does not exist. +50173=???Definition type is not correct: +50174=???Missing name of the new template! +50175=???The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=???Error in copying: {0} +50177=???Do you want to save the current changes? +50179=Il file Default.ini non esiste nella cartella {0} . +50180=Attenzione : {0} non esiste. +50181=Errore nella stampa dell'immagine. +50182=Errore nell'esecuzione della stampa +50183=Alcune porte potrebbero usare questa ferramenta, confermi l'eliminazione? +50184=???Impossible to delete Hardware if there is no Hardware selected! +50185=???Impossible to duplicate Hardware if there is no Hardware selected! +50186=Il progetto deve essere salvato prima di essere copiato. +50187=Vuoi copiare tutti i files ? {0} (No: per copiare solo il file corrente) +50188=Esporta in macchina +50189=Direttorio macchina non trovato +50190=Errore durante la copia: {0} +50191=Non c'è alcuna porta, impossibile copiare +50192=Non c'è alcuna porta, impossibile esportare verso la macchina +50193=Non c'è alcuna porta, impossibile stampare +50194=Le proprietà sono state cancellate +50195=La configurazione del ddf corrente ({0}) è differente dalla configurazione del programma ({1}).{2}Per caricare la configurazione del ddf corrente devi rilanciare il programma, vuoi farlo? +50196=La configurazione del ddf ({0}) non esiste! +50197=Porta ad arco modificata perchè la configurazioe non la pravede. +50198=Il profilo sul lato serratura dovrebbe essere invertito. +//Option +50200=Unità di misura +50201=Generale +50202=???LockEdgeOverMaterial +50203=???HingeEdgeOverMaterial +50204=???TopOverMaterial +50205=???BottomOverMaterial +50206=Apri finestra +50207=Ultimo progetto +50208=Vuoto +50209=Pagina delle opzioni +50210=Avvio programma +50211=Unità di misura nuova porta. +50212=???Directory Project +50213=Impostazione di avvio +50214=???Current Directory +50215=???Edge Type +50216=???Over Material +50217=???Browse +50218=Chiudi +50219=???Bevel +50220=???Bevel Up +50221=???Bevel Down +50222=Posizionamento porta in lavorazione. +50223=Salva come modello +50224=Associazione +50225=Marca +50226=Modello +50227=???Template +50228=???Enable template +50229=???Enable Order +50230=???Open template door. +50231=???Open window order. +50232=???Directory Template +//Scene +50301=Aggiorna +50302=Aggiungi Nuova Porta +50303=Rimuovi Porta +50304=Nuovo Progetto +50305=???Help +50306=Direttorio Macchina +50307=Macchina +50308=Anta +50309=???Wide Side Down (BU) +50310=???Wide Side Up (BD) +50311=???Resize +50312=???Design +50313=???Save as pdf +//Launcher +50400=???Launcher +50401=Apri Nuovo Progetto +50402=Apri Progetto +50403=Apri Ultimo Progetto +50404=Nuovo Progetto +50405=Nuova Ferramenta +50406=???Elevation +50407=???Project +50408=???PO +50409=???Line +50410=Salva +50411=Stampa +50412=Annulla +50413=Ferramenta +50414=???Dimensioning +50415=???Duplica +50416=???Esporta in macchina +50417=???New Template +50418=???Dimension +50419=Nuovo Direttorio +50420=Ricalcola posizione Hardware +50421=Aggiorna +50422=???Save As +50423=???Reaload Compo on Jamb +//Error (continue) +50501=Errore nella lettura del parametro {0 nel componente {1} : definizione incompleta (controlla StdTemplate.ini). +50502=Errore nella lettura del parametro {0 nel componente {1} : nessuna associazione (controlla StdTemplate.ini e GeometryNameList.ini). +50503=Vuoi salvare? +50504=Il nome del file contiene spazi vuoti agli estremi, vuoi eliminarli ? +50505=Il DDF non è un assemblato, le parti resenti sono: {0}, vuoi salvare? +50506=Impossibile trovare la prima anta! +50507=???The swing is not a member of the swing list of single door. +50508=???The swing of left door is not a member of the swing list of left door. +50509=???The swing of right door is not a member of the swing list of right door. +50510=???The swing of left door is on the right door and viceverse. +50511=???The swing of left door is not a member of the swing list of left door. +50512=???The swing of right door is not a member of the swing list of right door. +50513=???Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=???The swing are absolutly wrong! +50515=???The first door is not realy the first, check the ddf. +50516=???The current ddf contains {0} jambs. +50517=???The current ddf does not contains doors! +50518=???The current ddf is not an assembly. +50519=???Impossible to open a ddf with no doors. +50520=???The current ddf is an assembly. +50521=???Il ddf corrente è un pezzo del telaio: {0}. +50522=???The profile {0} is not a member of the {1} profile list. +50523=???Manca il profile sul lato {0}. +50524=???{0} file aperto da un altro EgtDOORCreator {1}. +50525=???{0} file open by another EgtDOORCreator {1}. +50526=???Il direttorio {0} già esiste! Vuoi sovrascriverlo? +50527=???Impossibile sovrascrivere {0} +50528=???Impossibile salvare il file fuori dal progetto corrente! +50530=???Property {0} does not exist in the list of {1}. Look at file "../Compo/Default.ini". +50531=???The current material {0} does not exist in the list of material. Look at file "../Compo/Default.ini". +50532=???Missing list of material at file "../Compo/Default.ini". +50533=???Impossible to load more than one property at time. +50534=???Property {0} does not exist in the list. Look at file "../Compo/Default.ini". +50535=???Impossible to delete a project if there is not a project! +50536=???Do you want to delete entire project? +50537=???Do you want to delete subdirectory {0} ? +50538=???Impossible to vreate a template door if there is not a door! +50539=???Do you want to change project? ( All doors will be deleted!) +50540=???The current ddf is a part of a frame, do you want to save? +50541=???{0} in reading {1}. +50542=???{0}: Directory does not exist! +50543=???It has been renamed file: {0}, {1}. +50544=???It has been created new file: {0}, {1}. +50545=???It has been deleted file: {0}, {1}. +50546=???Enable single door. +50547=???Project +50548=???The new configuration will take effect after restart. +50549=???File {0} exist, but it is not in the correct Directory! +50550=???Every componente on jambs will be relocated, do you want to continue +50551=???The current parameters have been modified: +50552=???Do you want to overwrite? +50553=??? has not been created. +50554=???Parameter {0} is already deinfed in geometry {1}. +50555=???Impossible to save. +50556=???File has nge extension. +50557=???Error in deleting file: {0} +50558=???Impossible to import a different hardware! +50559=???Open File Dialog +50560=???The hardware part has not been generated correctly. +50561=???Directory already exists +50562=???Folder {0} does not exist. Check in OptionPage. +50563=???Compo {0} does not exist. +50564=???In group {0} at paramater {1} does not exist: {2} +50565=???Brand {0} has not been found in HardwareManager. +50566=???Template {0} has not been found in HardwareManager. +50567=???Error in executing EgtCam5. +50568=???Error in definition {0} in file GeometryNameList.ini . +50569=???Error in definition {0} in file StdTemplate.ini . +50570=???Nothing has been selected. +//Added General messages +50701=???Lines +50702=???Rectangle +50703=???None +50704=???Radius +50705=???Angle +50706=???Pos_x +50707=???Top Arc +50708=???Top Angle +50709=???Properties +50710=???Material +50711=???Mach. +50712=???HardwarePart +50713=???Assemby +50714=???Total Dimension +50715=???Depth +50716=???Overlap Bottom +50717=???Thickness Bottom +50718=???Depth Bottom +50719=???Delta Bottom +50720=???GoToAssembly +50721=???New Geometry +50722=???Geometry Name +50723=???Type Hardware +50724=???Parameter +50725=???Part Dimension +50726=???Apply +50727=???Frame +50728=???Refresh Directory +50729=???General +50730=???Report +50731=???Opposite face +// ----- EgtBEAMEditor ------ +60951=???Cut +60952=???Longitudinal Cut +60953=???Double Cut +60954=???Ridge or Valley Cut +60955=???Saw Cut +60956=???Slot +60957=???Front Slot +60958=???Birds Mouth +60959=???Hip or Valley Rafter Notch +60960=???Ridge Lap +60961=???Lap Joint +60962=???Notch/Rabbet +60963=???Block House Half Lap, Stairs Riser Dado +60964=???Seathing Cut +60965=???French Ridge Lap +60966=???Chamfer +60967=???Block House Half Lap +60968=???Block House Front +60969=???Pocket +60970=???Drilling +60971=???Tenon +60972=???Mortise +60973=???Mortise Front +60974=???House +60975=???House Mortise +60976=???Dovetail Tenon +60977=???Dovetail Mortise +60978=???Dovetail Mortise Front +60979=???Marking/Labeling +60980=???Text +60981=???Simple Scarf +60982=???Scarf Joint +60983=???Step Joint +60984=???Step Joint Notch +60985=???Planing +60986=???Profile Front +60987=???Profile Head concave +60988=???Profile Head convex +60989=???Profile Head cambered +60990=???Round Arch +60991=???Profile Head +60992=???Sphere +60993=???Triangle Cut +60994=???Tyrolean Dovetail +60995=???Dovetail +60996=???Free Contour +60997=???Outline +60998=???Aperture +61001=???Distance from beam start to the reference point +61002=???Distance from the reference edge to the reference point +61003=???Distance from the reference side to the reference point (orthogonal) +61004=???Angle between cut edge and reference edge +61005=???Inclination between face and reference side +61008=???Limit of the 2 ends, binary code +61009=???Inclination to the reference side +61010=???Depth: If P11 is zero, then the face of the cut dispreads to the neigbour-sides or opposite-side to referenceside +61011=???Length: If P12 and P04 equal to zero, the processing is performed along the whole component length +61012=???Angle in face at start +61013=???Angle in face at end +61015=???Distance from the reference point to the reference edge +61016=???Angle between the first cutting edge and the reference edge +61017=???Inclination of the first cutting towards the reference side +61018=???Angle between the second cutting edge and the reference edge +61019=???Inclination of the second cutting towards the reference side +61023=???Inclination between the first face and the reference side +61024=???Inclination between the second face and the reference side +61025=???Depth +61027=???Angle in face at reference edge at start +61028=???Angle in face at reference edge at end +61029=???Angle in face in opposite to reference edge at start +61030=???Angle in face in opposite to reference edge at end +61033=???Displacement to the reference side +61036=???Angle to the reference edge in the cut face +61037=???Depth, orthogonal to the reference side +61038=???Length +61041=???Distance to the reference point orthogonal to the reference side P03 = 0: Slot on one of the 4 sides of the component. P03 > 0: Slot on one of the 2 front sides of the component +61042=???Limit of the 6 faces of the slot, binary code +61043=???Angle to the reference edge in the reference side +61045=???Interior angle at reference point +61046=???Interior angle at opposite of reference point +61047=???Addition to P09 +61048=???Depth orthogonal to the reference side +61049=???Length +61050=???Thickness +61051=???Displacement of the entrance edge at reference point +61052=???Displacement of the entrance edge at opposite of reference point +61055=???Distance to the reference point orthogonal to the reference side +61056=???Limit of the 6 faces of the Frotn Slot, binary code +61059=???Angle between the longitudinal axis of the slot and the reference side +61060=???Depth +61061=???Length +61062=???Width +61065=???Location of P09/P10, if P09>0 and P10>0. If P04=-1, then the location must be defined on the machineside +61066=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole. +61067=???Angle to the reference edge in the reference area +61068=???Inclination between face 1 and reference side +61069=???Inclination between face 2 and reference side +61070=???First cut angle of the counterpart. If P09 is zero, the limit face beside face 1 is parallel to component side. +61071=???First cut inclination of the counterpart. If P10 is zero, the limit face beside face 1 is parallel to component side. +61072=???Depth 1 orthogonal to reference side +61073=???Depth 2 orthogonal to reference side +61074=???Grooving depth in the transverse direction of the component. If P13 is zero, then its value must be calculated:P13=WRS-P02 +61075=???Height Counterpart. Zero means: no limit. Measurement orthogonal to face 1 (P07). +61076=???Width Counterpart. Zero means: no limit. Measurement orthogonal to face 2 (P08). +61079=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole +61080=???Angle notch 1 to the reference edge in the reference area +61081=???Angle notch 2 to the opposite reference edge in the reference area +61082=???Inclination between base area of notches and reference side +61083=???Depth orthogonal to reference side +61084=???Width of notch 1. If this value is equal 0, then the notch is not limited. +61085=???Width of notch 2. If this value is equal 0, then the notch is not limited. +61087=???0: Reference point on referene edge. 1: Reference point on the opposite edge +61088=???Angle to the reference edge in the reference side +61089=???Depth of Half Lap +61090=???Width of Half Lap +61091=???Drill hole diameter +61094=???Displacement to the reference side +61095=???Limit of the 6 faces of the lap, binary code +61096=???Angle to the reference edge in the reference side +61098=???Angle between edge and reference side in face +61099=???Angle in the floor face +61100=???Angle between base face and one face of lap +61101=???Distance (orthogonal) from reference side to point below reference point +61102=???Length +61103=???Chamfer angle +61104=???Grooving depth (length of the lapped scarf in transverse direction). If P14 is zero, then its value must be calculated: P14=WRS-P02 +61107=???Limit of the 6 faces of the notch/rabbet, binary code +61108=???Notch/Rabbet depth +61109=???Notch/Rabbet length +61110=???Notch/Rabbet width +61113=???Depth of the Half Lap on the reference side +61114=???Depth of the Half Lap opposite of the reference side +61115=???Length of the Half Lap / Dado +61117=???Depth of Seathing Cut +61118=???Length of Seathing Cut +61120=???0: Reference point on reference edge; 1: Reference point on the opposite edge +61121=???Angle to the reference edge in the reference side +61122=???Drill hole diameter +61124=???Input of edge(s) to be beveled, binary code: Bit 0=edge 1 ; Bit 1=edge 2; Bit 2=edge 3; Bit 3=edge 4. Example: P04=9: edge 1+4; P04=3: edge 1+2 +61125=???Depth +61126=???Length: If P12 is equal to zero, the processing is performed along the whole component length. +61127=???Shape for bevel exit: 0 = orthogonal, 1 = at 45 deg, 2 = round; +61129=???Depth orthogonal to reference side of the lap 2 and 4. If P03 is zero, then its value must be calculated: P03=HRS +61130=???0:all laps are symmetric to each other; 1:lap on reference edge moved to start beam, lap in opposite of reference edge moved to end beam; 2: lap on reference edge moved to end beam, lap in opposite of reference edge moved to start beam; +61131=???P05=1: drilhole for drop rod, P05=0: no drillhole. The machines defines place and direction of the drillhole. +61132=???lap 1: Depth +61133=???lap 1: Length +61134=???lap 2: Depth +61135=???lap 2: Length +61136=???lap 3: Depth +61137=???lap 3: Length +61138=???lap 4: Depth +61139=???lap 4: Length +61140=???Distance from end of arc orthogonal to the reference side +61141=???Radius of arc +61142=???Distance reference point to center of arc +61143=???Which arc (A, B,C or D) is to produced, binary code +61145=???0:only one lap on reference side; 1:one lap on reference side and one on the opposite side +61146=???Angle to the reference edge in the reference side +61147=???Depth at reference point +61148=???Depth opposite to the reference point +61149=???Depth at reference edge +61150=???Length +61153=???Limit of the 6 faces of the pocket, binary code +61154=???Rotation angle around the local z-axis of the cuboid +61155=???Rotation angle around the local y-axis of the cuboid, rotated with P06 +61156=???Rotation angle around the local x-axis of the cuboid, rotated with P06 and P07 +61157=???Internal angle at the reference point +61158=???Depth of reference point orthogonal to reference side +61159=???Length of Half Lap +61160=???Width of Half Lap +61163=???Distance from the reference face to the reference point. P03 = 0:Drilling on one of the 4 sides of the component. P03 <> 0:Drilling on one of the 2 front sides of the component. +61164=???P03 = 0:Angle to the reference edge in the reference side. P03 <> 0:Angle in the front side. +61165=???Inclination between drilling and reference side. P03 = 0: Inclination between drilling and reference side. P03 > 0: Inclination between drilling and front side +61166=???Depth, orthogonal to reference side or front side. +61167=???Drill hole diameter +61170=???Rounding +61171=???Chamfer +61174=???Angle between axis of the tenon and reference side +61175=???Radius for P04=4 +61176=???Tenon height +61177=???Tenon width +61178=???Margin on the reference side +61179=???Margin opposite the reference side +61182=???Displacement to the reference side +61183=???Rounding +61184=???Angle between axis and reference edge +61185=???Inclination between strut and reference side +61186=???Inclination of hole side walls towards reference side +61187=???Radius for P04=4 +61188=???Mortise depth +61189=???Mortise width +61190=???Height of strut +61191=???Margin on the reference point +61192=???Margin opposite the reference point +61193=???Inclination of hole front side towards reference side +61196=???Rounding +61199=???Angle between axis of the tenon and reference side +61200=???Radius for P04=4 +61201=???Mortise depth +61202=???Mortise width +61203=???Margin on the reference side +61204=???Margin opposite the reference side +61205=???Processident of the associated tenon or dovetail tenon +61206=???Processident of the associated mortise or dovetail mortise +61209=???0:with rounding at the bottom; 1:without rounding, unbounded +61210=???Angle between edge and reference edge +61212=???Angle between axis of the tenon and reference side +61213=???Middle flattening +61214=???Angle of cone +61215=???Tenon height +61216=???Diameter of the curve: If P12 < 0, then the radius must be defined on the machineside. +61217=???Margin on the reference side +61218=???Margin opposite the reference side +61221=???Displacement to the reference side +61222=???0:with rounding at the bottom; 1:without rounding, unbounded +61223=???0:with elongation; 1:with pocket +61224=???Angle between axis and reference edge +61225=???Inclination between strut and reference side +61226=???Middle flattening +61227=???Angle of cone +61228=???Mortise depth +61229=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61230=???Height of strut +61231=???Margin on the reference point +61232=???Margin opposite the reference point +61235=???Displacement to the front side +61236=???0=with rounding at the bottom; 1=without rounding, unbounded +61237=???0=with elongation; 1=with pocket +61240=???Angle between axis of the tenon and reference side +61241=???Middle flattening +61242=???Angle of cone +61243=???Mortise depth +61244=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61245=???Margin on the reference side +61246=???Margin opposite the reference side +61249=???Position and alignment of the text. P04 = 0 if there is no text. +61250=???Angle between axis and reference edge. If P06 equals 180°, then a horizontal line is defined, P12 defines the length of the line. +61251=???Interior angle. If P07 equals zero, 2 single markings have to be produced. +61252=???Width of quadrangle. If P11 equals zero, there is only a single marking. +61253=???Height of quadrangle. If P12 equals zero, marking is limited by the edge opposite to the reference edge. +61254=???Height of text. If P13 equals zero, the machine determines the text height. +61255=???Text (String max. 256 characters) +61258=???Angle between axis and reference edge +61259=???Alignment vertical. 0 = bottom, 1=middle, 2=top +61260=???Alignment horizontal. 0 = left, 1=middle, 2=right +61261=???Alignment in case of a multiline text. 0 = left-aligned, 1=centered, 2=right-aligned. A new line must be defined with this 2 letters: \n +61262=???Letters standard or horizontal placed. 0 = standard, 1=letters horizontal placed +61263=???Height of text. If P13 equals zero, the machine determines the text height. +61266=???Depth at the reference side +61267=???Depth at the opposite of reference side +61268=???Length of the overlap +61269=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61270=???Drilling 2 diameter. Placed at 2/3 P13 +61272=???Angle of inclination of the lapped scarf base +61273=???Shape of the lapped scarf or classic data identification: 1:when cutting orthogonal to reference side; -1:when cutting orthogonal to base side; 0:classic definition, P10 and P12 are not used +61274=???Length of the lapped scarf base +61275=???Depth of the lapped scarf base +61276=???Depth of the lapped scarf base orthogonal to reference side +61277=???Length +61278=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61279=???Drilling 2 diameter. Placed at 2/3 P13 +61281=???Type of heel notch:0=normal; 1=tapered +61282=???Inclination strut +61283=???Depth step joint +61284=???Depth heel notch +61285=???Height tenon. Which implementation (A or B) is used depends on the machine +61286=???Width tenon +61289=???Type of heel notch: 0=normal; 1=tapered +61290=???Inclination between strut and reference side +61291=???Width of the notch +61292=???Depth step joint +61293=???Depth heel notch +61294=???Height of strut +61295=???Depth of mortise. Which implementation (A or B) is used depends on the machine +61296=???Width of mortise +61298=???Specification of side(s) to be planed; binary coded +61299=???Planing depth +61300=???Length of the area to be planed +61303=???Rotation angle of the first curve of the profile +61304=???Rotation angle of the profile towards the reference edge +61305=???Offset angle +61306=???Radius of the first curve +61307=???Radius of the second curve +61309=???Radius +61310=???Depth +61311=???Displacement +61312=???Depth +61313=???Displacement +61315=???Radius +61316=???Depth +61317=???Displacement +61318=???Depth +61319=???Displacement +61321=???Profile length +61322=???Depth at the reference point +61323=???Maximum depth of profile +61324=???Minimum depth of profile +61325=???Depth at the profile end +61326=???Premill: 0=round; 1=angular +61328=???Depth of the arch segment +61329=???Length of the arch segment +61331=???Type of arc (convex, concave), binary coded. See table below. +61332=???Length of lap 1 +61333=???Depth of lap 1 +61334=???Displacement arc 1 +61335=???Horizontal length arc 1 +61336=???Vertical length arc 1 +61337=???Camber arc 2 +61338=???Length of lap 2 +61339=???Depth of lap 2 +61340=???Displacement arc 2 +61341=???Horizontal length arc 2 +61342=???Vertical length arc 2 +61343=???Camber arc 2 +61344=???Length of lap 3 +61345=???Depth of lap 3 +61348=???Distance from the reference side to the reference point +61349=???Radius +61350=???Start offset +61351=???Length +61354=???Distance from the reference side to the reference point +61355=???Normal vector 1: Length of X-component +61356=???Normal vector 1: Length of Y-component +61357=???Normal vector 1: Length of Z-component +61358=???Normal vector 2: Length of X-component +61359=???Normal vector 2: Length of Y-component +61360=???Normal vector 2: Length of Z-component +61362=???Distance between "inside" an side of part +61363=???Distance orthogonal to the reference side +61364=???0:"inside" at reference edge, 1:"inside" at opposite of reference edge +61365=???0:Without rebate or mitre, -1:With mitre, >0:With rebate +61366=???Angle to the reference edge in the reference side +61367=???Width +61368=???Depth +61369=???Inclination +61370=???Height +61371=???Radius +61372=???Length of tool (part of arc) +61373=???0:Angular corner joint, 1:Straight T-wall connection +61374=???Length +61375=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61377=???Distance between "inside" an side of part +61378=???Distance orthogonal to the reference side +61379=???0:"inside" at reference edge, 1:"inside" at oppostite of reference edge +61380=???0:Without rebate or mitre, -1:with mitre, >0:with rebate +61381=???Inclination +61382=???Depth 1 +61383=???Depth 2 +61384=???0:European Dovetail, 1:American Dovetail +61385=???Length +61386=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61387=???Depth +61388=???Mode: 0=contour only, 1=countersink completely. Only for closed contours. +61389=???Contour type +61390=???Parameter depends on contour type(P13) +61391=???Parameter depends on the contour type(P13) +61400=???Reference point on referene edge +61401=???Reference point on the opposite edge +61402=???Reference point on referene edge +61403=???Reference point on the opposite edge +61404=???orthogonal +61405=???at 45 deg +61406=???round +61407=???all laps are symmetric to each other +61408=???lap on reference edge moved to end beam. lap in opposite of reference edge moved to start beam +61409=???lap on reference edge moved to start beam. lap in opposite of reference edge moved to end beam +61410=???only one lap on reference side +61411=???one lap on reference side and one on the opposite side +61412=???with rounding at the bottom +61413=???without rounding, unbounded +61414=???with elongation +61415=???with pocket +61416=???bottom +61417=???middle +61418=???top +61419=???left +61420=???right +61421=???left-aligned +61422=???centered +61423=???right-aligned +61424=???standard +61425=???letters horizontal placed +61426=???when cutting orthogonal to reference side +61427=???when cutting orthogonal to base side +61428=???classic definition, P10 and P12 are not used +61429=???normal +61430=???tapered +61431=???round +61432=???angular +61433=???"inside" at reference edge +61434=???"inside" at opposite of reference edge +61435=???Angular corner joint +61436=???Straight T-wall connection +61437=???Processing on the reference side and opposite the reference side +61438=???Processing only on the reference side +61439=???Processing only opposite the reference side +61440=???European Dovetail +61441=???American Dovetail +// ---Custom Parameter (Q) +61451=???Profondità smusso +61452=???0=Automatico; 1=Ciclo longitudinale con lama +61453=???Spessore testimone centrale per ciclo Q02 +61454=???0=Attacco centrato; 1=Attacco interno +61455=???0=Automatico; 1=Lavorazione con fresa di lato +61456=???1=Forza Lama; 0=Automatico +61457=???1=Solo smusso +61458=???0=Automatico; 1=Massima profondità +61459=???0=Automatico; 1=Truciolatore; 2=Truciolatore di lato; 3=Fresa; 4=Fresa di lato +61460=???0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +61461=???0=Automatico; 1=Massimo raggio ammesso su tasche non passanti +61462=???Diametro utensile per Q05 +61463=???Diametro utensile per Q07 +61464=???0=Raggio su spigolo; 1=Foro su spigolo; 2=Spigolo vivo +61465=???Diametro foro quando P05=1 +61466=???0=Automatico; 1=Sgrossatura con lama +61467=???Antischeggia: 0=No; 1=Con lama; 2=Con fresa +61468=???Aumenta dimensioni tasca +61469=???Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico +61470=???0=Automatico; 1=Solo contorno ; 2=Drill or Pocket +61471=???0=Automatico; 1=Lavoro da un lato solo +61472=???Incrementare/decrementare valore P01 per fori nei tenoni +61473=???0=Foratura rompi truciolo; 1=Foratura scarico truciolo +61474=???Profondità smusso quando P05=1 +61475=???Riduzione profondità tenone +61476=???Riduzione larghezza tenone +61477=???Riduzione altezza tenone +61478=???Riduzione profondità tenone +61479=???Ridurre/Allargare sagoma tenone +61480=???Ridurre/Allargare altezza tenone +61481=???aumenta profondità mortasa +61483=???Profondità di lavoro +61484=???Aumenta dimensioni P10 +61485=???0=Automatico; 1=Truciolatore +61486=???Riduzione lunghezza P14 +61487=???Riduzione larghezza P15 +61488=???Sovramateriale finitura +61489=???Numero divisioni ondulazioni dello smusso sulla lunghezza +61490=???1=Disabilita fresatura gradini +61491=???1=Attiva smusso superiore +61492=???1=Smusso superiore con lama +61493=???Spessore legno per supporto lavorazione +61494=???Attiva antischeggia +61495=???Profondità antischeggia +61496=???Massima elevazione (0=Automatico, >10=Manuale) +61497=???0=Automatico; 1=Lama +61498=???0=Automatico; 1=Disabilita controllo lunghezza fresa +61499=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61500=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61501=???0=Automatico 1=Lavorazione con fresa orizzontale se sopra o sotto (disabilita lama) +61502=???0=Automatico 1=Usa truciolatore se sotto +61503=???0=Attacco e uscita centrati 1=Attacco e uscita interni +61504=???0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +61505=???0=Automatico; 1=Lavora come Taglio Longitudinale +61506=???0=Automatico; 1=Lavorazione con fresa +// ----- EgtBEAMWALL - BTLParam ----- +61601=???SN +61602=???Abilita +61603=???Descrizione +61604=L +61605=W +61606=H +61607=???Material +61608=???Richiesti +61609=???In produzione +61610=???Prodotti +61611=???Ruotare +61612=???Group +61613=???Unit Time +61614=???Parametro +61615=???Valore +61616=???Minimo +61617=???Massimo +61618=???Single member number +61619=???Assembly number +61620=???Order number +61621=???Designation +61622=???Annotation +61623=???Subgroup/Storey +61624=???Group +61625=???Package +61626=???Material +61627=???Timber grade +61628=???Quality grade +61629=???Count +61630=???Colour +61631=???Transparency +61632=???Planing length +61633=???Start offset +61634=???End offset +61635=???Transformation: Origin +61636=???Transformation: X-axis dir. vect. +61637=???Transformation: Y-axis dir. vect. +61638=???Camber: Reference side +61639=???Camber: P01,P02,P03,P04 +61640=???Part offset: ref. side fix clamp +61641=???Part offset: P11,P12,P13,P14 +61642=???Processing quality +61643=???Recess +61644=???Storey type +61645=???Element number +61646=???Layer +61647=???Module number +61648=???USERATTRIBUTE +61649=???Comment +61650=???Grain direction: X,Y,Z +61651=???Grain direction: Align +61652=???Reference side +61653=???Reference side: Align +61654=???Alignment: Location +61655=???Alignment: Endtype +61656=???Material type: Group +61657=???Material type: Specification +61658=???AUTOMATIC +61659=???VISIBLE +61660=???FAST +61661=???MANUAL +61662=???CEILING +61663=???ROOF +61664=???WALL +61665=???inactiv +61666=???BR +61667=???TR +61668=???BA +61669=???TA +61670=???HC +61671=???VC +61672=???AC +61673=???R +61674=???A +61675=???D +61676=???Batten +61677=???Cladding +61678=???Massive timber +61679=???Membrane +61680=???Gypsum Board +61681=???Gypsum Fibre +61682=???Insulation +61683=???Sheet Component +61684=???Facade Panel +61685=???Profiled Panel +61686=???Plaster +61687=???Reference side 1 +61688=???Reference side 2 +61689=???Reference side 3 +61690=???Reference side 4 +61691=???UID +61692=???Project number +61693=???Project name +61694=???Project part +61695=???GUID +61696=???Listname +61697=???Customer +61698=???Architect +61699=???Editor name +61700=???Delivery date +61701=???Export date +61702=???Export time +61703=???Export release +61704=???Language +61705=???Range +61706=???Computername +61707=???User name +61708=???Path & name of CAD-File +61709=???Path & name of BTL-File +61710=???STANDARD +61711=???EXTENDED +61712=???Vol unit +61713=???Vol tot +61714=???Time unit +61715=???Time tot +61716=???Total parts number +61717=???Total volume +61718=???Total time +61719=???Total estimed time +61720=???Remaining time +61721=???Rawpart counter +61722=???BTL part counter +61723=???Added part counter +61724=???Part in rawpart counter +61725=???Done part counter +61726=???Quantity +61727=???Print PDF +//Ware???house +61751=???Current S +61752=???Current L +61753=???StartOffset +61754=???Kerf +61755=???Offset +61756=???S Parameters +61757=???L Parameters +61758=???New Value: +61759=???W +61760=???L +61761=???Confirm +61762=???Save +61763=???Cancel +61764=???Error +61765=???Input value already present +61766=???Input value not correct +61767=???Input pair already present +61768=???One or more input values not correct +61769=???Attention +61770=???Selected parameter is equivalent to current L/S. Are you sure you want to remove it? +61771=???SectionXMaterial +61772=???Alias +61773=???Values +61774=???Quantity +61775=???Min thickness +61776=???Max thickness +61777=???Increment Max thickness of the last range before adding a new range +// +61801=???Custom +61802=???Default +61803=???L +61804=???T +61805=???Process +61806=???Section time +61807=???Part time +61808=???Name +61809=???PDN +61810=???DO +61811=???X position +61812=???Y position +61813=???Added +61814=???Done +61815=???ID +61816=???Start offset +61817=???% Used +61818=???Waste +61819=???BTL File Name +61820=???List Name +61821=???Export Date +61822=???Creation Date +61823=???Delete +61824=???Face +61825=???Group +61826=???Modify +61827=???Save +61828=???Cancel +61829=???Nesting +61830=???Viewer +61831=???Optimizer +61832=???Configuration +61833=???Optimize +61834=???Update BTL +61835=???Go to optimization +61836=???Filter type +61837=???Search +61838=???Export project +61839=???Import project +61840=???Import BTL +61841=???Copy to Clipboard +61842=???DisplayIndex +61843=???Column name +61844=???CanUserReorder +61845=???CanUserResize +61846=???CanUserSort +61847=???IsReadOnly +61848=???Visible +61849=???Variable Path +61850=???Type +// +61851=???This part modification will cause the removal of the part from {0} raw parts. Do you want to proceed anyway? +61852=???Impossible create feature with this values +61853=???Impossible create part with this values +61854=???Impossible create bar with this values +61855=???Impossible create wall with this values +61856=???Value outside minimum and maximum +61857=???Impossible to insert a quantity inferior to the number of parts already in rawparts! +61858=???Impossible to modify these values +61859=???Error in machine parameter writing +61860=???Save machine parameters modification? +61861=???Save default values modification? +61862=???Changing type second path will be deleted. Do you want to proceed? +61863=???To produce part number reached: +61864=??? from BTL; +61865=??? added. Do you want to add another one? +61866=???Selected part has different section from selected bar. Impossible to add. +61867=???Selected part lenght is more then the selected bar lenght. Impossible to add. +61868=???Selected part has different height from selected wall. Impossibl to add. +61869=???Error in macro file execution! +61870=???Impossible create a Macro without selecting a Feature or with empty name +61871=???File not found! +61872=???Impossibie deleting current project +61873=???Impossibile deleting the project because already linked to an optimization +61874=???Impossibile deleting the project because some parts are already sent to production +61875=???Do you want to save the project modifications? +61876=???Impossible creating a new file! +61877=???Save project modification before continuing? +61878=???Impossible proceding with a new unsaved project! +61879=???Type of current machine is both Beam and Wall. Select the type you want to set the project to: +61880=???Select one of the available machines and/or types. Otherwise cancel the project import. +61881=???The opened project type is not compatible with the current machine type +61882=???Do you want to save the modifications to the DataGrid columns? +61883=???The columnn specified as "{0}" in the "{1}" table in the datagrid columns ini file was not found in the program +61884=???Select the machine you want to associate to the project: +61885=???The machine linked to the opening project cannot be found among the available machines +61886=???Machine +61887=???Impossible creating the inserted rawparts quantity +61888=???How many copies of the rawpart do you want to create? +61889=???Long Drill Area +61890=???Min Rule +61891=???Can't send feedback from Optimizer if there is no open Prod +61892=???Can't proceed with an unsaved project! Please save before updating it. +// +61900=???Change paramter +61901=???Verify +61902=???Simulate +61903=???New raw part +61904=???Add to raw part +61905=???Copy part +61906=???Add part +61907=???Remove part +61908=???Copy feature +61909=???Create macro +61910=???Add feature +61911=???Remove feature +61912=???Produce rawpart +61913=???Produce all rawpart +61914=???Copy rawpart +61915=???Remove rawpart +61916=???Reorder parts +61917=???Move up part +61918=???Move down part +61919=???Remove part +61920=???Warehouse +61921=???Add project to optimization +61922=???Go to project +61923=???Statistics +61924=???Reset +61925=???Show all parts +61926=???Show solid +61927=???Show building +61928=???Verify all +61929=???Can't change machine because the Proj is already linked to a Prod +61930=???Inputs +61931=???Outputs +61932=???Calculate Flip & Rotation +61933=???Unlock Flip +61934=???Unlock Rotation +61935=???Length +61936=???Width +61937=???Offset +61938=???Kerf +61939=???Edit +61940=???Reset +61941=???Choose machine +61942=???BTL file already imported and optimized. Do you want to import it again? +61943=???BTL file already imported. Do you want to overwrite it? +61944=???Shift parts +61945=???Shift direction +61946=???Shift length +61947=???Parts can't be shifted outside the raw part +61948=???The inserted shift value is not valid +61949=???Search & Filter +61950=???Parameter Type +61951=???Parameter Value +61952=???R +61953=???A +61954=???P +61955=???D +61956=???All +61957=???Filtered +61958=???Update +61959=???Append +61960=???Check the parts you would like to add to update BTL +61961=???Change material +61962=???Project material +61963=???Warehouse material +61964=???Standard +61965=???From BTL +61966=???Save +61967=???Do NOT save +61968=???Waiting for optimizer save +61969=???Cancel + +// +62500=???Supervisor +62501=???Channel +62502=???OPMode +62503=???Produce All +62504=???Done RawPart +62505=???Reset RawPart +62506=???Delete RawPart +62507=???Print Label +62508=???Done Part +62509=???Resume started processing? +// Loading +63000=???Project opening +63001=???Loading project geometries +63002=???Loading machining groups +63003=???Loading production data +63004=???Optimization opening +63005=???Loading parts +63006=???Loading graphics +63007=???Project saving +63008=???BTL file importing +63009=???Reading BTL file +63010=???Project exporting +63011=???Loading environment +63012=???Saving geometry +63013=???Saving data on Db +63014=???Modifying parameters +63015=???Part viewer opening +63016=???Adding export info +63017=???Exporting... +63018=???Project importing +63019=???Loading project +63020=???Creating imported project +63021=???Modifying materials +// ----- FromLua ----- +65001= +// ----- OmagCUT ----- +// General +90001=TRABAJO EN CURSO +90002=CORTES LINEALES +90003=CORTES CAD +90004=MARCOS +90005=MAQUINA +90006=OPCIONES +//Trabajo en progreso +90101= +// DirectCut +90201=Movimiento manual +90202=Corte singolo +90203=Corte multiple +90204=Corte rejilla +90205=MTH +90206=Alisado +90207=Test disco +90208=Palpador disco +90209=Copia molde +90210=Adquirir P1 +90211=Adquirir P2 +90212=Laser +90213=Profundidad +90214=Longitud +90215=Direcciòn +90216=Inclinaciòn +90217=Nùmero +90218=Dimensiones +90219=Nùmero X +90220=Dimensiones X +90221=Nùmero Y +90222=Dimensiones Y +90223=Corte lado motor +90224=Disco +90225=Diseño +90226=Ancho +90227=Superposiciòn +90228=Offset +90229=Bloquea el eje C +90230=Ejecuta +90231=???Lucidatura +90232=Espesor disco +90241=Palpaciòn disco +90242=Palpaciòn en curso... +90243=Palpaciòn completada con èxito +90244=Errore en tastatura disco +90245=Nuevo nombre del molde +90246=???Tastatura interrotta dall'utente +90250=Linea +90251=Arco +90252=Remueve +90253=Cierra +90254=Guardar +90255=???Test +90256=???Verifica posizione taglio +90257=???Verifica posizione in corso... +90258=???Single drill +// CadCut +90301=Simula +90302=Ejecuta +90303=Nuevo +90304=Carga +90305=Guardar +90306=Guardar como +90307=Nuevo nombre del proyecto +90308=CSV +90309=Vein Match +90310=Exporta +90311=Herramienta +90312=Elaboraciòn +90313=Fotografia no lograda +90314=Error en la generaciòn del programa CN +90315=Error en la transmisiòn del programa CN +90316=No conectado a la màquina +90317=Programa CN transmitido +90318=La màquina no acepta el programa CN +90319=Programa ya transmitido, quieres retransmitirlo ? +90320=Màquina diferente +90321=Reducidas algunas elaboraciones para evitar interferencias +90322=Faltan las herramientas : +90323=???Fotografia di sfondo eseguita +90324=???Riconoscimento contorno non riuscito +90325=???Errore nel salvataggio delle statistiche +90326=Confirmas Restart desde fase {0} ? +90327=Nuevas Piezas dañadas +90328=Area pezas : +90329=???Da Produrre : +90330=Programa ya transmitido, nueva losa ? +// NestPage +90331=Introducir pieza +90332=Aparcar pieza +90333=Eliminar pieza +90334=Selecionar todo +90335=Deselecionar todo +90336=Reset +90337=???Uno o più pezzi con spessore, materiale o finitura non compatibili +90338=???Rotazione oltre i limiti +90339=???Rotazione impossibile +90340=???Nesting Automatico in corso +// Pagina Dividida +90341=On/Off +90342=Todos On +90343=Todos Off +90344=Alarga/Acorta +90345=Inicio Alar/Acor +90346=Final Alar/Acor +90347=Inicio Centro/Fuera +90348=Inicio Todos Fuera +90349=Inicio Todos Centro +90350=Càlculo automàtico no exitoso +90351=Disco demasiado grande para utilizar ventosa +90352=Fin Centro/Afuera +90353=Fin Todos Afuera +90354=Fin Todos Centro +90355=Estira Todos +90356=Acorta Todos +90357=Modif. +90358=Auto +90359=Restart +// MoveRawPart +90361=Remueve +90362=Pieza demasiado pequeña : no se puede mover +90363=Posición seleccionada ya ocupada +90364=???Part too havy : can not be moved +90365=???Part beyond strokes : can not be moved +// SplitPage 2 +90371=Pausa On/Off +90372=Pausa +90373=Modif inicio +90374=Modif fine +90375=Elongación +90376=Revertir +// DrawPage +90381=Nùmero piezas +90382=Medidas +90383=Inclinaciones +90384=Indica Lado Arriba +90385=???Disegno Parametrico +90386=Seleccionar un contorno +90387=No hay lados editables +90388=Nombre +90389=???Dati Trf +90390=???Codice ordine +90391=???Descrizione ordine +90392=???Codice materiale +90393=???Codice superficie +90394=???Spessore +90395=???Seleziona uno o più fori +90396=???Codice pezzo +90397=Tallar +90398=???Dati Csv +90399=Todos los mecanizados actualizados +90400=???Filo Top +// Component +// Màximo 30 caracteres sin imagenes y màximo 20 con la imagen +90401=Triangulo +90402=Rectangulo +90403=Trapecio +90404=Cuadrilatero +90405=Piedoca +90406=Limite +90407=Piano Cocina +90408=Piano Baño +90409=Otros +90410=Triangulo2L +90411=Triangulo3L +90412=Isòsceles +90413=Rectangulo +90414=Escaleno +90415=Escaleno +90416=4Lados 1Ang +90417=3Lados 2Ang +90418=3Lados 2Diag +90419=4Lados 1Diag +90420=4Lados 3Diag +90421=4Lados 3Ang +90422=4Lados 3Ang +90423=Angulo Recto +90424=Angulo Recto Desafilado +90425=Angulo Alineado +90426=Angulo Alin. Desafilado +90427=Parte A +90428=Parte B +90429=Angulo +90430=Angulo Desafilado +90431=Elipse +90432=Oval +90433=Arco +90434=Arco LHF +90435=Arco LLH +90436=Arco LLF +90437=Rectangolo redondeado +90438=Convexo +90439=Agujero +90440=???2 Fori +90441=3 Agujeros +90442=Arco RHa +90443=Polygon +90444=???Foro da sotto +90445=Dxf +90446=Rebaje +90447=Componentes interiores +90448=Agrega +90449=Remueve +90450=Confirmación +// Import +90451=Usa layer +90452=Usa regiones +90453=Reset +90454=mm +90455=inch +90456=Usa curvas cerradas +90457=Inclinaciòn +90458=Tallar de debajo +90459=Ángulo +90460=Compensar +90461=Hundimiento +90462=Acortamiento +90463=Importa DXF +90464=Fora de debajo +90465=???Numero +90466=Compensar2 +90467=???Ordine +90468=???Distinta +90469=???Nome +// Component 2 +90470=Grabados Rebaje +90471=Grabados +90472=TriánguloCH +90473=TriánguloRT +90474=TrapecioRtA +90475=3Lados 2Ang +90476=???Nuova soglia +// FastGrid +90480=???Nome ordine +90481=???N° Lastra +90482=???Ultima lastra +90483=???Tipo pezzo +90484=???Inserisci pezzi +90485=???Conferma ordine +// Abierto +90491=Proyecto no vàlido +90492=Proyecto con interferencias. Para cargarlo desactiva respecto cortes completos. +// RawPart +90499=Bruto indefinido +90500=Rotación +90501=Rectangulo +90502=Para puntos +90503=Longitud +90504=Ancho +90505=Espesor +90506=Offset X +90507=Offset Y +90508=Kerf +90509=Material +90510=Zona aruinada +90511=Nuevo +90512=Borrar +90513=Puntos +90514=Agregar +90515=Borrar +90516=Màxima longitud = +90517=Màximo Ancho = +90518=No se admiten alturas negativas +90519=Minimo offset X = +90520=Minimo offset Y = +90521=Minimo kerf = +90522=Màximo kerf = +90523=Sondeo en bruto +90524=???Conferma +90525=Sondear en bruto +90526=Sondeo en curso... +90527=Sondeo completado con èxito +90528=Error en el sondeo en bruto +90529=Del diseño +90530=Del laser +90531=Cierra +90532=Error en la adquisiciòn del punto +90533=Contorno +90534=Disco demasiado grande para sondeo +90535=Da fotografia +//ChooseMachining +90536=Seleccionar el mecanizado de la disco +90537=Seleccionar el mecanizado secundario +90538=Seleccionar la perforaciòn +90539=Seleccionar el fresado +90540=Ninguna +90541=Taladrar +90542=Fresado +90543=Ambas +90544=Elegir trabajos +90545=Seleccionar el chorro de agua +90546=Corte por chorro de agua +90547=Error en la psicion o dimenson del material +90548=Maximo offset X = +90549=Maximo offset Y = +90550=???Scegliere la svuotatura +// Simulaciòn +90551=Simulaciòn completada +90552=Extracarrera +90553=Dirección de la herramienta inalcanzable +90554=Error +90555=ERROR +90556=Error al generar! +90557=Simulacion +90558=Un paso a la vez +90559=Play/Pausa +90560=Stop/Home +90561=Pausa +90562=Simulacion interumpida +90563=Vista maquina +90564=Home +90565=Tiempo +90566=Longitud +90567=Area pezas +90568=Utilizo +90569=Estimado +90570=Detalle +// FrameCut +90601=Largo X +90602=Largo Y +90603=Remueve +90604=Desbaste +90605=Acabado +90606=Espatulatur +90607=Espeja +90608=Dist.desde arriba +90609=Dist.desde princ. +90610=Acorta el inicio +90611=Acorta el final +90612=Corte único +90613=Arco +90614=Guia +90615=Sección +90616=Guia +90617=Rad +90618=Ang +90619=Error : radio más pequeño que el ancho de la sección. +90620=Error : la creación del marco falló +90621=Distancia X +90622=Distancia Y +90623=Lado contrario +// Màquinas +90701=Msg_Ita.xpi +90705=Datos màquina +90706=DB herramientas +90707=DB trabajos +90708=Màquina +90709=???Statistics +90715=Nuevo +90716=Nueva +90717=Salva +90718=Elimina +//ToolsDb +//param +90719=???Lunghezza portautensili +90720=???Anima +90721=Nombre +90722=Posiciòn +90723=Cabezal +90724=Salida +90725=Rotaciòn +90726=Normal +90727=Màxima +90728=Progreso +90729=Progreso +90730=Cabezal +90731=Entrada +90732=Salida +90733=Agua +90734=Corrector +90735=Supramaterial +90736=Longitudinal +90737=Radial +90738=Max absorciòn. +90739=Feed minima +90740=Max affond. +90741=Longitud +90742=Diàmetro +90743=Espesor +90744=Filo cortante +90745=Notas +90746=Numero de Serie +90747=Código +90748=Proveedor +90749=Fin de servicio +//tools families +90751=Disco +90752=Agujero +90753=Cortador +90754=???Mola da scasso +90755=Chorro de agua +90756=???Mola lucidante +//Tool Setup +90759=???Posizione utensile predefinita già occupata +//MachiningsDb +//param +90761=Nombre +90762=Profundidad +90763=Angulo de deslizamiento +90764=Invertir +90765=Tipo de paso +90766=Lado de trabajo +90767=Lado cabezal +90768=Posiciòn inicio +90769=Ataque +90770=Entrada +90771=Salida +90772=Utiliza curvas +90773=Tolerancia +90774=Paso de hundimiento +90775=Normal +90776=Paso de hundimiento +90777=Interno arcos +90778=Externo arcos +90779=Longitud de desaceleración +90780=Inicial +90781=Final +90782=Profundidad adicional +90783=Posiciòn de retorno +90784=Herramienta +90785=Espesor minimo +90786=Espesor màximo +90787=Paso +90788=En hundida +90789=De lado +90790=En vertical +//machinings families +90791=Corte +90792=Perforar +90793=Fresado +90794=Desbaste con disco +90795=Acabado con disco +90796=???Svuotatura +90797=???Waterjet +//ComboBox Param +90801=No +90802=Interior +90803=Exterior +90804=Ambas +90821=Centro +90822=Izquierda +90823=Derecha +90824=Centrado +90825=Interior +90826=Exterior +90827=Extendido centrado +90828=Extendido exterior +90829=Extendido anterior +90830=Extendido siguiente +90831=Extendido ambos +90832=Centrada +90833=Interior +90834=Exterior +90835=Salta +90836=Aproximar +90837=Convexo +90838=Zig Zag +90839=Una via +90840=Adelante y atràs +90841=Trabaja +90842=Ninguno +90843=???Normale +90844=???Rallenta +90845=???Anello +90846=???Lineare +90847=???Tangente +90848=???Inseguimento +90849=???Elica +90850=???Come attacco +// param2 +90861=Espatular +90862=Inclinado +90863=Incl. retorno +90864=Ida +90865=Retorno +90866=Último retorno +90867=???Inclinazione in avanti +90868=???Tastatura +90869=???Min dist. punti +90870=???Max dist. punti +90871=???Esterni +90872=???Interni +90873=???Lungh. rall. +90874=???Rallentam. % +90875=???Foro di attacco +90876=???Raggio +90877=???Num. giri in LP +90878=???Num. giri in HP +90879=???Abilitazione +90880=???Angoli +// Barcode +90881=Código de barras +90882=???Blocco +90883=???Numero +90884=???Dati lastra +// param3 +90890=???Dist. tang. +90891=???Dist. perp. +90892=???Dist. tang. +90893=???Dist. perp. +90894=???Ataque cerámico +90895=???Longitud +90896=???Paso +90897=???Last cut +90898=???Side angle cuts +// Alarms +90900=Chorro de agua actual +90901=Disco actual +90902=Herramienta auxiliar +90903=Agujero actual +90904=Fresa actual +90905=Z seguridad +90906=Seguridad cortes +90907=Seguridad esquinas +90908=Cumple con los cortes completos +90909=Offset agujeros +90910=Superposición agujeros +90911=Tolerancia agujeros +90912=Lista errores CN +90913=Materiales +90914=Agrega +90915=Remueve +90916=Herramientas actuales +90917=Parametros agujeros +90918=Rmin arcos ext. +90919=Parametros màquina +90920=Ninguno +90921=Agujero +90922=Fresa +90923=Ambos +90924=Amax arcos int. +90925=Parametros disco +90926=Un solo agujero en angùlo +90927=Cortes directos +90928=Inicio definitiva +90929=Parametros fresado +90930=Siempre sobre interiores +90931=Nesting +90932=Alineado +90933=Cargar herram. +90934=Nuevo +90935=Eliminar +90936=Altura sobremesa +90937=Recuadro Foto +90938=Fondo +90939=Margen +90940=Tolerancia +90941=Seco +90942=Confirmar la cancelación del material seleccionado? +90943=Setup di default +90944=Siempre en angùlo +90945=Seleccione la herramienta +90946=Cortes Progreso inicio/fin +90947=Longitud +90948=Reducc.% +90949=Acortar +90950=???Tastatura +//Machine +90951=Start +90952=Stop +90953=Reset +90954=Auto +90955=Single +90956=MDI +90957=Manual +90958=Home +90959=Download +90960=Upload +90961=Activate +90962=Delete +90963=MDI Confirm +90964=Modalidad CN +90965=controles de la máquina +90966=Cadena MDI +90967=Transferimiento part program +90968=???Do you want to change table? +// Options +90981=Idioma +90982=El nuevo idioma serà actualizado desde el pròximo inicio del programa. +90983=Unidad de medida +90984=Rotaciòn visiòn +90985=???Angolo inclinato +90986=???Un solo valore +90987=???Più valori +90988=???Inserimento diretto dei pezzi +90989=???Parametrici e DXF +90990=???CSV +90991=???Fast grid +90992=Permitir la creación de piezas estándar +90993=???Colore testo +90994=???Slab Dxf +90995=???Slab Layer +90996=???Parts Layer +90997=???Scrap Layer +90998=???Std Thick +90999=???ColorToSideAng +91000=???Enable +91001=???Tolerance +91002=???Heel +91003=???Side Angle +91004=???Feedback +91005=???Themes +91006=???Engrave from color +91007=???Depth +91008=???Width +91009=???Start program +91010=???Select start mode +91011=???Recent project +91012=???Last opening +91013=???Last project +91014=???New project +91015=???Open folder +91016=???Show window +//Alarms2 +91051=Trabajos +91052=Corte +91053=Perforar +91054=Fresado +91055=???DripSawing +91056=???DripDrilling +91057=WaterJet +91058=Parametros waterjet +91059=Automático +91060=Alineado y Guillotina +91061=Parámetros de grabado +91062=Con cortador +91063=Profundidad +91064=Anchura +91065=Salir precortado +91066=Guillotina +91067=Insertar pausa +91068=Marcos +91069=Vaciando +91070=???Scasso corrente +//Statistics +91071=???Day Production +91072=???Week Production +91073=???Project +91074=???Parts Area +91075=???Cuts Area +91076=???Day +91077=???Week +91078=???Reset +91079=???To Produce Area +//Lucidature +91089=???Offset +91090=???DB Lucidature +91091=???Lucidature +91092=???Movimento +91093=???Ripetizioni +91094=???Attacco/Uscita +91095=???Altezza +91096=???Lista utensili +91097=???Lunghezza +91098=↑ +91099=↓ +91100=???Precarico +//EgtMsgBox +91101=Salvar el proyecto actual? +91102=Salvar la herramienta actual? +91103=Salvar el trabajo actual? +91104=Nombre gya utilizado +91105=Hay interferencia, se pueden aparcar algunas piezas. ¿Quieres continuar? +91106=Ya existe un archivo con ese nombre. Sobreescribirlo? +91107=CONEXION AL CN +91108=Conexiòn en curso... +91109=Conexiòn no obtenida +91110=Conexiòn obtenida +91111=Mesa para usar ? +91112=Quieres borrar tambien las piezas provenientes de la lista Csv ? +91113=Piezas no se remueve porque esta libre +91114= o de otras listas Csv +91115=Error +91116=Opciòn Linea de producciòn no habilitada +91117=Error en copia archibo por OmagVIEW +91118=Conservo las pieza en estacionamiento? +91119=Error en la gestiòn dei pezzi rovinati +91120=???I caratteri \ / : * ? " < > | non sono permessi +91121=???Sei sicuro di voler cancellare i pezzi selezionati? +91122=???Attenzione +91123=Mesa +91124=???Salvare la lucidatura corrente? +91125=???Salvare le modifiche correnti? +91126=???Export +91127=???Import +91128=???DB WaterJet +91129=???Origine da laser +91130=???Start program? +// CSV +91201=Abrir +91202=Ingresar +91203=Nuevo +91204=Remuove +91205=???Errore nel salvataggio del file CSV, vuoi continuare lo stesso ? +91206=???Errore nella lettura del file CSV +// OmagVIEW +91301=Todos Validos +91302=Pieza Valida +91303=Pieza dañada +91304=Imprimir Etiqueta +91305=Confirmacòn +91306=???Stampa +// OmagOFFICE +// OptionPanel +91401=Crudo +91402=Disponer +91403=Trabajo +91404=Simula +// MachiningDbWindow +91451=Material +91452=Espesor mìnimo +91453=Espesor màxsimo +// Errori di stampa +91461=???Error connection printer +91462=???Error formatting data +91463=???Error during print +91464=???No selection +// TopCommandBar +91501=Es necesario salvar el proyecto antes de exportarlo +91502=Seleccionar el directorio de exportación +91503=Error en la exportación +91504=Exportación completada con éxito +91505=???Esporta in macchina +91506=???Esporta DXF +// Rawpart +91551=Error en el cargar la fotografia +91552=Importa fotografia +// VeinMatching +91601=Exporta +91602=Muestra Info +91603=Modificaciòn +91604=Comprobar +91605=Magnètica +91606=Pieza no seleccionable en esta situación +91607=Pieza no seleccionable porque pertenece a un grupo de trabajo no actual : +91608=???Ingombro dei pezzi DXF troppo grande per VeinMatching +// Generic +91651=Ok +91652=Cancelar +91653=A° +91654=T +91655=Comienzo +91656=Final +// ----- OmagPHOTO ----- +// General +92001=???Db non trovato! +92002=???Unable starting the program +// OptionPanel +92051=???Salva +92052=???Aggiungi +92053=???Annulla +92054=???Elimina +92055=???Sei sicuro di voler cancellare la lastra corrente? +92056=???Etichetta +92057=???Etichetta Freccia +92058=???Sfoglia +92059=???Stampa +92060=???Seleziona +// Slab +92071=???Id +92072=???Nome immagine +92073=???Stato +92074=???Progetto assegnato +92075=???Posizione in magazzino +92076=???Data +92101=???Nome già utilizzato +92102=???Il nome è obbligatorio +92103=???L'immagine è obbligatoria +// SearchPanel +92151=???Cerca +92152=???Tolleranza spessore +92153=???Data d'inizio +92154=???Data di fine +92155=???Reset +//Messaggi +92200=???Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=???Avviso +92202=???Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=???Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=???Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// General +101001=Importar BTL +101002=Diseña +101003=Posicionar +101004=Opciones +// ImportPage +101101 +// DrawPage +101201=Pared +101202=Puerta +101203=Ventana +101204=Agregar +101205=Anular +101206=Aplicar +101207=Eliminar +101208=Distanciador +// PlacePage +101301=General +101302=Transmitir +101303=Posicionamiento pared +101304=Introducir +101305=Estacionar +101306=Eliminar +101307=Espesor estratos +101308=Nùmero tablas encima +101309=Introducciòn no lograda +101310=Generaciòn lograda +101311=Error en generaciòn +101312=Lanzammiento transmisiòn con èxito +101313=Error en lanzamiento transmisiòn +101314=Transmisiòn completada con exito +101315=Transmisiòn no lograda +101316=Puentes todos discapacitados +101317=Archibo de Generaciòn faltante +// OptionsPage +101401=Opzioni macchina +101402=Caracteristicas vinculaciòn +101403=Extra bruto en X +101404=Extra bruto en Y +101405=Extra pegamento +101406=Caracteristicas mesa +101407=Ancho de la mesa +101408=N° tablas en un plano +101409=Activaciòn puentes +101410=Puente pegamento +101411=Puente tablas +101421=Opciones software +101422=Seleccionar Idioma +101423=El nuevo idioma estarà vigente al partir del pròximo inicio del programa +101424=Nùmero proyectos por salvar +101425=Posicionar tablas sobre puertas y ventanas +101426=Anticipada apertura pegamento +101427=Anticipado cierre pegamento +// OpenPage +101501=Proyecto no vàlido +// ----- End ----- diff --git a/ProgramData/EgtBeamWall/Config/EgalTechFra.txt b/ProgramData/EgtBeamWall/Config/EgalTechFra.txt new file mode 100644 index 0000000..583c960 --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/EgalTechFra.txt @@ -0,0 +1,3319 @@ +// File dei messaggi EgalTech Francese 2022/05/02 +0=FRA +// File +1=Fichier +3=Nouveau +5=Ouvrir +6=Ouvrir
un fichier récent (Shift) +7=Insérer +9=Sauvegarder +11=Copier +13=Importer +15=Exporter +17=Executer +19=Fichiers récents +20=Script récents +// Vista +101=Vue +103=Lignes +105=Bords +107=Solides +109=Zoom tout +111=Zoom plus +113=Zoom moins +115=Dessus +117=Face +119=Droite +121=Arrière +123=Gauche +125=Dessous +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Grille +136=Régler vue perpendiculaire à la grille actuelle +137=Dircourbes +139=Analyse +141=Distance +// Griglia +201=Grille +203=Dessus +205=Face +207=Droite +209=Arrière +211=Gauche +213=Dessous +215=Vue +216=Régler la grille perpendiculaire à la direction de Vue +217=Elévation +218=Régler élévation de la Grille +219=Origine +220=Régler Origine de la Grille +221=Pivoter +222=Pivoter Grille
Pivoter en 3d Grille (Shift) +223=3 Points +224=Régler Grille avec 3 Points +225=Perp +226=Régler la grille perpendiculaire à Objet +227=Objet +228=Régler Grille par Objet +// Disegna +301=Dessiner +303=Point +304=Point
Vecteur (Shift)
Référence (Ctrl) +305=Lin 2P +306=Ligne : 2 Points
Ligne : 2 Points avec Continuation (Ctrl) +307=Lin PDL +308=Ligne : Point initial, Direction, Longueur
Ligne : Point initial, Vecteur direction, Longueur (Shift) +309=Circ +310=Circonférence : Centre, Point
Circonférence : Centre, Diamètre (Shift) +311=Chan +312=Chanfrein : Rayon
Chanfrein : Dist (Shift) +313=Arc CIF +314=Arc : Centre, Point initial, Point final +315=Arc 3P +316=Arc : 3 Points +317=Arc IDF +318=Arc : Point initial, Direction, Point final
Arc : Point initial, Vecteur direction, Point final (Shift)
Arc : Point initial, Direction, Point final avec Continuation (Ctrl) +319=Rect 2P +320=Rectangle : 2 Points +321=Polygone +322=Polygone : Rayon ou Apothème
Polygone : Côté avec 2 Points (Shift) +323=Texte +324=Texte
Texte Avancée (Shift) +399=Continuation : 'L' avec ligne, 'A' avec arc +// Costruisci +401=Construire +403=Plan +404=Surface : plan entouré par une ou plusieurs courbes
Région plate (Shift) +405=Extruder +406=Surface : da extrusion de une ou plusieurs courbes +407=Pivoter +408=Surface : da rotation de une courbe +409=Hélice +410=Surface : da rototraslation de une courbe +411=Rainurée +412=Surface : Rainurée entre 2 courbes +413=Combiner +414=Combiner une ou plus Surfaces +415=Inverser +416=Inverser l'extérieur de une ou plusieurs Surfaces +417=Exploser +418=Exploser Surfaces ou Régions Planes +419=Balayée +420=Surface : balayer une courbe le long d'une autre +// Modifica +501=Modifier +503=Effacer +504=Effacer les Objects +505=Layer +506=Porter les Objects dans le Layer courant +507=Couleur +508=Changer Couleur
Supprimer Couleur spécifique (Shift)
Changer Transparence (Ctrl) +509=Inverser +510=Inverser Courbe +511=Trim/Est +512=Couper ou Prolonger Courbe +513=Couper +514=Couper Courbe
Diviser Courbe en Parties (Shift) +515=Joindre +516=Joindre Courbes
Joindre Courbes créant une Copie (Shift)
Fusionner les courbes dans la Composite (Ctrl) +517=Exploser +518=Exploser Texte ou Courbes en Composants +519=épaisseur +520=Régler épaisseur et direction de Extrusion sur une ou plusieurs courbes +521=Début +522=Changer Début de une Courbe fermée +// Trasforma +601=Transformer +603=Déplacer +604=Déplacer un ou plusieurs Objects +605=Pivoter +606=Pivoter un ou plusieurs Objects
Pivoter un ou plusieurs Objects en 3D (Shift) +607=Miroir +608=Miroir un ou plusieurs Objects
Miroir un ou plusieurs Objects en 3D (Shift) +609=Échelle +610=Échelle de un ou plusieurs Objects
échelle de un ou plusieurs Objects en 3D (Shift) +611=Offset +612=Offset de une Courbe +// Special +701=Special +703=Pièces 2d +704=Insérer Pièces Plans da DXF ou NGE +705=Compo +706=Insérer Composants Paramétriques +// Scene : Menù Selezione Entità +1001=Sélectionner Tout +1003=Desélectionner Tout +1005=Sélectionner avec Fenêtre +1007=Sélectionner Pièce +1009=Sélectionner Layer +1011=Sélectionner Parcours +1013=Sélectionner Parcours Complet +1015=Sélectionner Entité +1016=Sélectionner Tout Visible +// Scene : Menù Punto notevole +1101=Point Sketch +1102=Point Sketch +1103=Point Grille +1104=Point Grille +1105=Point Final +1106=Point Final +1107=Point Médian +1108=Point Médian +1109=Centre +1110=Centre +1111=Barycentre +1112=Barycentre +1113=Point Près +1114=Point Près +1115=Intersection +1116=Intersection +1117=Point Tangent +1118=Point Tang +1119=Point Perpendiculaire +1120=Point Perp +1121=Point à Distance minimum +1122=Point MinDist +1123=Exclure Surfaces +// Scene : Menù Varie +1201=Désactiver Glissement +1203=Activer Glissement +// Scene : Varie +1301=Dist= +// Controller +2001=Copier (V) +2002=Erreur +2003=Alarme +2051=Le Point doit être différente de le précédent +2052=Les points doivent être pas alignés +2053=Valeurs Nulles ou Négatives ne sont pas valides +2054=Valeurs Négatives ou Deux Valeurs Nulles ne sont pas valides +2055=Au moins une Entité est non modifiable +2056=Distance trop gros +2057=Courbe pas plate (dans son plan) +// Controller : Disegna +2101= +// Controller : Costruisci +2201= +// Controller : Modifica +2301= +// Controller : Trasforma +2401=Copier +2402=Déplacer +2403=Insérer Point Base +2404=Insérer Point Destination +2406=PIVOTER +2407=Insérer Centre +2408=Insérer Point Base +2409=Insérer Angle ou Point +2411=PIVOTER 3D +2412=Insérer Premier Point Axe +2413=Insérer Deuxième Point Axe +2414=Insérer Point Base +2415=Insérer Angle ou Point +2416=MIROIR +2417=Insérer Premier Point +2418=Insérer Deuxième Point +2421=MIROIR 3D +2422=Insérer Premier Point +2423=Insérer Deuxième Point +2424=Insérer Troisième Point +2426=ÉCHELLE +2427=Insérer Centre +2428=Insérer Coefficient +2431=ÉCHELLE 3D +2432=Insérer Centre +2433=Insérer Coefficients +2436=OFFSET +2437=Insérer Distance +2438=Raccord +2439=Chanfrein +2440=Étendre +// ----- EgtCAM5 ----- +5001=DESSINER +5002=USINER +5003=Outils +5004=Usinages +5005=Options +5006=BD Outils +5007=BD Usin. +5008=Options de la Machine +5009=???SetUp Db +5010=???SetUp Db +5020=Tables des Usinages +//Top CommandBar +5101=Nouveau +5102=Ouvrir
Ouvrir un fichier récent (Bouton droit) +5103=Sauvegarder +5104=Sauvegarder comme +5105=Insérer +5106=Importer +5107=Exporter +5108=Executer script
Executer un script récent (Bouton droit) +5109=Options +5110=???Mail di supporto non trovata. +5111=???Salvare il progetto corrente prima di mandare il feedback? +5112=???Mandare il feedback a {0} con allegata la cartella {1}. +5113=???Feedback +5114=???Mail di feedback pronta. +//Draw Panel +5150=Extraire les Bords libres des Surfaces et Régions plates +5151=Joindre Surfaces et Régions plates +5152=Soustraire Surfaces et Régions plates
Couper Surface avec Surface inversé (Shift) +5153=Intersecter Surfaces et Régions plates
Couper Surface avec Surface (Shift) +5154=Points, Courbes et Faces d'Intersection entre Surfaces +5155=Dimension Linéaire
Dimension Alignée (Shift) +5156=Circonférence 3 Points +5157=Extraire les Bords des Faces des Surfaces et des Régions plates +5158=Extraire Face de Surface +5159=Arc Renversé
Arc Explémentaire (Shift) +5160=Modifier la forme +5161=Ajouter un Point
Modifier en Arc (Shift)
Fermer la Courbe Composite (Ctrl) +5162=Supprimer un Point
Modifier en Ligne (Shift)
Ouvrir la Courbe Composite (Ctrl) +5163=Approximer Courbe
Approximer Courbes avec Lignes (Shift) +5201=Point
Vecteur (Shift)
Référence (Ctrl) +5202=Ligne 2 Points
Ligne 2 Points avec Continuation (Ctrl) +5203=Ligne Point initial Direction Longueur
Ligne Point initial Vecteur direction Longueur (Shift) +5204=Circonférence Centre Point +5205=Circonférence Centre Diamètre +5206=Arc Centre Point initial Point final +5207=Arc 3 Points +5208=Arc Point initial Direction Point final
Arc Point initial Vecteur direction Point final (Shift)
Arc Point initial Direction Point final avec Continuation (Ctrl) +5209=Arrondi +5210=Chanfrein +5211=Rectangle 2 Points +5212=Polygone Centre et Rayon ou Apothème +5213=Polygone Côté avec 2 Points +5214=Texte
Texte Avancée (Shift) +5215=Plan entouré par une ou plusieurs courbes
Région plate (Shift) +5216=Extruder +5217=Pivoter +5218=Hélice +5219=Rainurée +5220=Comibiner des Surfaces +5221=Exploser des Surfaces et des Régions Planes +5222=Renverser des Surfaces et des Régions Planes +5223=Effacer +5224=Changer Couche
Changer Couche avec Transformations (Shift) +5225=Changer Transparence +5226=Supprimer Couleur spécifique +5227=Changer Couleur +5228=Inverser Courbe +5229=Changer Début d'une Courbe fermée +5230=Couper ou Prolonger Courbe +5231=Couper Courbe +5232=Diviser Courbe en Parties +5233=Joindre Courbes
Joindre Courbes créant une Copie (Shift)
Fusionner les courbes dans la Composite (Ctrl) +5234=Exploser Courbes ou Textes en Composants +5235=Épaisseur et Extrusion des Courbes +5236=Déplacer +5237=Pivoter +5238=Pivoter en 3D +5239=Miroir +5240=Miroir en 3D +5241=Échelle +5242=Échelle en 3D +5243=Offset +5244=Dessin 2D +5245=Dessin 3D +5246=Modification +5247=Transformation +5248=Swept (Section, Guide) +5249=Modifier Texte +// Grid View Panel +5251=Lignes +5252=Bords +5253=Solids +5254=Zoom Tout +5255=Zoom Plus +5256=Zoom Moins +5257=Vue de Dessus +5258=Vue de Face +5259=Vue de Gauche +5260=Vue d'Arrière +5261=Vue de Droite +5262=Vue Iso de SO +5263=Vue Iso de SE +5264=Vue Iso de NE +5265=Vue Iso de NO +5266=Direction des Courbes +5267=Analyser +5268=Mesurer la distance +5269=Grille par Dessus +5270=Grille par Face +5271=Grille par Droite +5272=Grille par Arrière +5273=Grille par Gauche +5274=Grille par Dessous +5275=Grille perpendiculaire à la direction de Vue +5276=Élévation de la Grille +5277=Origine de la Grille +5278=Pivoter Grille
Pivoter Grille en 3d (Shift) +5279=Grille par 3 Points +5280=Grille perpendiculaire à Courbe +5281=Grille par Object +5282=Vue perpendiculaire à la Grille +5283=Zoom Sélection +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=FIN +5302=Surcourse +5303=Direction de l'outil inaccessible +5304=Erreur +5305=ERREUR +5306=Erreur dans la génération! +5307=Simulation +5308=Une étape à la fois +5309=Play/Pause +5310=Stop/Home +5311=PAUSE +5312=STOP +5313=Impossible d'arrêter maintenant. Arrêtez d'abord la simulation ou attendez qu'elle se termine! +5314=HOME +5315=AVERTISSEMENT +5316=Virtual Milling +5317=Erreur dans le calcul des estimations! +5318=Fichier d'estimations manquant +5319=Collision! +5320=INFORMATION +5330=GÉNÉRER +5331=Le projet doit être enregistré avant la génération CN. Voulez-vous le faire? +5332=Généré avec succès +5333=La licence n'autorise pas la génération CN +5340=Estimations +5341=Temps total +5342=Longueur totale +5343=Détails +5344=Estimations détaillées +// Draw Option +5351=Propriété +5352=Nouv. Pièce +5353=Nouv. Couche +5354=Couleur +5355=Paramètres de dessin +5356=Sélectionner +5357=Desélectionner +5358=Nom +5359=Info +5360=Transférer +5361=Copiér +5362=Effacer +5363=Sauvegarder +5364=Visualiser +5365=Confirmer +5366=Confirmation de la Suppression +5367=Pièce à usiner, voulez-vous la supprimer? +// Operation +5401=Liste des opérations +5402=Paramètres de l'opération +5403=Appliquer Usinage +5404=Nouveau Usinage +5405=Nouveau Dispo +5406=Effacer +5407=Générique +5408=Dépl. haut +5409=Dépl. bas +5410=Actualiser +5411=Actualisation terminée avec succès +5412=Liste des Nouveaux Usinages +5413=Aperçu de l'Outil +5414=Suivant +5415=Précédent +5416=Dupliquer +5417=Copier dans la bibliothèque +5418=Nom de l'usinage dans la bibliothèque +5419=Insertion de l'usinage pas réussi +5420=Renommer +5421=Le nom ne peut pas commencer par "Disp" +5422=Nom déjà utilisé +5423=L'usinage ne peut pas être appliqué pour les raisons suivantes: +// Disposition +5431=Ok +5432= +5433=Nouvelle +5434=Supprimer +5435=Longueur +5436=Largeur +5437=Hauteur +5438=Position +// Disposition Errors +5461=ERREUR DE EXECUTION SCRIPT +5462=Erreur dans l'exécution du script automatic pour la disposition +5463=Erreur dans l'exécution du script de début usinages +5464=Erreur dans l'exécution du script de fin usinages +// Mach Group +5501=Voulez-vous vraiment vider le Groupe d'Usinage? +5502=Voulez-vous vraiment supprimer le Groupe d'Usinage? +5551=Il n'y a aucun Groupe d'Usinage :
sélectionnez les pièces à insérer et
répétez la commande pour créer le premier +5552=Voulez-vous créer un nouveau Groupe d'Usinage?
avec les pièces sélectionnées ? +// Tools Db Page +6001=Foret +6002=Scie +6003=Fraise +6004=Mortaise +6005=Composite +6006=Long foret +6007=Scie plat +6008=Fraise de côté +6009=Chiseau +6010=Jet d'eau +6051=Compensation +6052=Sortie +6053=Type +6054=Réfrigérant +6055=Rayon de Coin +6056=Diamètre +6057=Diamètre Total +6058=Vitesse +6059=Vitesse Finale +6060=Vitesse Initiale +6061=Vitesse de Pointe +6062=Longueur +6063=Longueur Totale +6064=Matériau Maximum +6065=Décalage longitudinal +6066=Décalage radial +6067=Rotation +6068=Angle latéral +6069=Rotation maximale +6070=Épaisseur +6071=Absorption maximale +6072=Vitesse minimum +6073=Dessin +6074=Tête +6075=Nom +6076=Notes +6077=Pos. Change Outil +6078=Position +6079=Distance +6080=???Overtable +// Tools Errors +6100=Enregistrer l'outil modifié? +6101=ENREGISTRER +6102=Le fichier doit être .nge +6103=Le fichier n'existe pas ou n'est pas de type Nge +6104=Il n'y a pas de ToolMaker pour ce type d'outil +6105=L'outil ne peut pas être créé avec ces paramètres +6106=Le Matériau Maximum doit être supérieur à 0 +6107=Le Matériau Maximum doit être inférieur à Long +6108=L'Épaisseur doit être supérieure à 0 +6109=Le Diamètre doit être supérieur à 0 +6110=La Longueur doit être supérieure à 0 +6111=La Vitesse doit être inférieure à la Vitesse maximale +6112=Nom non valide +6113=La Longueur doit être inférieure à la Longueur Totale +6114=La Longueur doit être supérieure au Matériau Maximum +6115=La Longueur Totale doit être supérieure à 0 +6116=La Longueur Totale doit être supérieure à la Longueur +6117=Le Matériau Maximum doit être inférieur à 1/3 du Diamètre +6118=Le Diamètre doit être inférieur au Diamètre Total +6119=Le Diamètre doit être supérieur à 3 fois le Matériau Maximum +6120=Le Diamètre Total doit être supérieur à 0 +6121=Longueur trop petite avec porte-outil +6122=Voulez-vous vraiment effacer l'outil +6123=? +6124=EFFACER +6125=Fichier de configuration d'outillage pas trouvé! +6126=Erreur +6127=Définir le type de tête. +6128=Définir le type de sortie. +6129=L'outil n'est pas valide, corrigez-le ou supprimez-le avant de quitter la base de données d'outils. +6130=Impossible de recharger la base de données d'outils. Si le dossier machines se trouve sur un serveur, vérifiez que la connexion est active. +6131=L'Épaisseur doit être différente de 0 +6132=L'Angle Latéral doit être inférieur à 90 +6133=L'Angle Latéral doit être supérieur à -90 +6134=La Longueur Totale doit être supérieure à la Longueur + l'Épaisseur +6135=Le Rayon du Coin a une valeur trop grande +6136=L'Épaisseur est trop petite par rapport au Rayon de Coin +6137=Le Diamètre résultant dépasse le Diamètre Total +6138=Le Diamètre résultant est inférieur à 0 +6139=Le Diamètre de tige résultant est inférieur ou égal à 0 +6140=Le Matériau Maximum doit être supérieur au Rayon de Coin +6141=Le Matériau résultant Maximum doit être >= 0 +6142=Le Rayon des Coins ne doit pas dépasser la moitié de l'Épaisseur +6143=Enregistrer outil +6144=Outil modifié! Tous les outils doivent être enregistrés avant de modifier les activations. Enregistrer outil {0}? +6145=Position déjà occupé! +6146=Position non définie! +// Machinings Db Page +6201=Perçage +6202=Sciage +6203=Fraisage +6204=Vidage +6205=Mortaisage +6206=Dégrossissage avec scie +6207=Finition avec scie +6208=Usinage générique +6209=Ciselure +6210=Dégrossissage surfaces +6211=Finition surfaces +6212=Jet d'eau +6251=???Invert +6252=???Leave Tab +6253=???Type +6254=???Work Side +6255=???Head Side +6256=???Lead In +6257=???External Link Type +6258=???Lead Out +6259=???Curve Use +6260=???Step Type +6261=???Sub Type +6262=???Lead Link Type +6263=???Speed +6264=???Feed +6265=???Start Feed +6266=???End Feed +6267=???Tip Feed +6268=???Radial Offset +6269=???Longitudinal Offset +6270=???Depth +6271=???Side Angle +6272=???Approximation +6273=???Start Safety Length +6274=???Start Slow Length +6275=???End Slow Length +6276=???Throu Add Length +6277=???Step +6278=???Return Position +6279=???Length +6280=???Distance +6281=???Height +6282=???Angle +6283=???L.In Tangent Distance +6284=???L.In Perp. Distance +6285=???L.In Elevation +6286=???L.In Comp. Length +6287=???L.Out Tangent Distance +6288=???L.Out Perp. Distance +6289=???L.Out Elevation +6290=???L.Out Comp. Length +6291=???Start Add. Length +6292=???End Add. Length +6293=???Step External Arc +6294=???Step Internal Arc +6295=???Side Step +6296=???Vertical Feed +6297=???Name +6298=???Tool +6299=???Depth +6300=???Notes +6301=???Overlap +6302=???Offset +6303=???Sub Type +6304=???SCC +6305=Aucun +6306=Standard +6307=Contraire +6308=AuxDir X+ +6309=AuxDir X- +6310=AuxDir Y+ +6311=AuxDir Y- +6312=AuxDir Z+ +6313=AuxDir Z- +6314=Le plus proche de AuxDir +6315=Le plus loin de AuxDir +6320=???Center +6321=???Left +6322=???Right +6323=???External +6324=???Standard +6325=???Strict +6326=???Out +6327=???External Central +6328=???External Out +6329=???None +6330=???Linear +6331=???Tangent +6332=???Glide +6333=???Helix +6334=???External Prev +6335=???External Next +6336=???External Both +6337=???As Li +6338=???Skip +6339=???Approx +6340=???Convex +6341=???Keep +6342=???Zigzag +6343=???Oneway +6344=???Spiral +6345=???To And From +6346=???Along +6347=???Across +6348=???Spiral In +6349=???Spiral Out +6350=???Avanzati +6351=???Inverti direz. utensile +6352=???Lavorazione faccia +6353=???Non definito +6354=??? Parallelo +6355=??? Ortogonale +6356=??? Ortog. Su +6357=???Sotto +6358=???Sopra +6359=???Davanti +6360=???Dietro +6361=???Sinistra +6362=???Destra +6363=???Contorno +6364=???Angoli Suggeriti +6365=???Asse Bloccato +6366=Nombre max +6367=Nombre min +// Machining errors +6370=Enregistrer l'usinage modifié? +6371=SAUVEGARDER +6372=Nom invalide +6373=Les caractères \ / : * ? " < > | ne sont pas permis +6374=Êtes-vous sûr de vouloir annuler +6375=? +6376=EFFACER +6377=Impossible de recharger la base de données des usinages. Si le dossier est sur un serveur, vérifiez que la connexion est active. +6378=Oscillation +6379=Amplitude d'oscill. +6380=Long. rampe d'oscill. +6381=Long. crête d'oscill. +// Machining Option Page +6401=Z de sécurité +6402=Couper les arcs +6403=Jamais +6404=Plan générique +6405=Plan autre que XY +6406=Toujours +6407=Outillage par défaut +6408=Sécurité renvoi d'en bas +6409=Tolérance trous +// SetUp Window +6451=Outillage +6452=Actualiser +6453=Sauvegarder +6454=Ouvrir +6455=Auto +6456=Actualiser l'outillage courant avant de sortir? +6457=???New +// SetUp Errors +6471=Erreur +6472=Avis +6473=Outil pas trouvé +6474=dans le DB des outils. +6475=La position de l'outil par défaut est invalide. +6476=La position de l'outil par défaut est déjà occupée. +6477=Le fichier de configuration n'existe pas! +6478=L'outillage utilise une tête qui n'existe pas sur la machine! +6479=Erreur de chargement de l'outillage +// Option Page +6501=Langue actuelle +6502=La nouvelle langue sera mise à jour à partir du prochain démarrage du programme. +6503=Courbes +6504=Surfaces +6505=Courbes et Surfaces +6506=Géométrie sélectionnable +6507=Ajouter le nouveau usinage à la fin +6508=Utiliser le script de disposition +6509=Unité de mesure +6510=Couleur en haut de la vue +6511=Couleur en bas de la vue +6512=Couleur par défaut +6513=Tolérance géométrique +6514=Générale +6515=CAO +6516=FAO +6517=Couleur de la grille +6518=Surfaces lissées +6519=Importer +6520=DXF +6521=STL +6522=Images +6523=Exportation +6524=Image +6525=Largeur (pixel) +6526=Hauteur (pixel) +6527=Mettre à jour machine +6528=La machine "{0}" existe déjà,
que veux-tu faire? +6529=Le fichier {0} ne contient pas une machine. +6530=La machine "{0}" a été mise à jour avec succès. +6531=Remplacer +6532=Mettre à jour +6533=Annuler +6534=Avis +6535=La mise à jour de la machine "{0}" a échoué. +6536=Lignes épaisses +6537=Longueur supplémentaire de ligne +6538=Longueur de la flèche +6539=Distance du texte +6540=Unité de mesure +6541=Décimal +6542=Caractère +6543=Hauteur du texte +6544=Dimension +6545=Unité actuelle +6546=Autre +6547=Unité de mesure +6548=Facteur d'échelle +6549=Exporter la machine actuelle +6550=Sélectionner le dossier où enregistrer la machine +6551=L'exportation de la machine "{0}" a échoué. +6552=La machine "{0}" a été exportée avec succès. +6553=Nouvelle Licence +// Heads +6601=Tête vertical +6602=Tête horizontal +6603=Agrégat 2 sorties +6604=Agrégat 3 sorties +6605=Agrégat 4 sorties +6606=Tête 3 axes +6607=Tête 4 axes +6608=Tête 5 axes +6609=Navette 1 +6610=Navette 2 +6611=Carousel +6612=Perceuse Multiple +6613=Multi ciseau +6614=Agrégat d'en bas +6615=Scie 5 axes +6616=Scie à chaîne +6617=Agrégat 1 sortie +6618=Tête de palpage +6619=Flottante 360° +6620=Second Tête 5 axes +6621=Perceuse Horizontal +6622=Mortaiseuse +6623=Second Scie 5 axes +6624=Agrégat 1 sortie tilt. +6625=Extrudeuse +6799= +// StatusBar +6801=???Direttorio Machines non trovato. EgtCAM5 funzionerà in modo solo CAD. +// Doors +8001=???Crea nuova MTable +8002=???Salva MTable +8003=???Salva MTable Come +8004=???Elimina MTable +8005=???Salva file MTable +8006=???Sei sicuro di voler cancellare questa MTable? +8007=???Salva la MTable modificata? +8008=???Lista delle macchine attive +8009=???Nome della macchina +8010=???Genera Cn +8011=???Aggiorna grezzo +8012=???On +8013=???Nome Geometria +8014=???Operazione +8015=???MId +8016=???Spost. +8017=???Tipo Lavorazione +8018=???Lavorazione 1 +8019=???Lavorazione 2 +8020=???Lavorazione 3 +8021=???Aggiungi Macchina +8022=???Elimina Macchina +8023=???Aggiungi Lavorazione +8024=???Elimina Lavorazione +8025=???CORR +8026=???Imposta MTable corrente +8027=???GId +8028=???Proprietà +8029=???Lavorazione +8030=???Unisci +// Door errors +8101=???Errore +8102=???Errore nell'esecuzione del file Ddf +8103=???Attenzione +8104=???Path della cartella MTable non trovata +8105=???La cartella MTable non esiste +8106=???Mancano i file di configurazione nella cartella MTable +8107=???Errore sconosciuto +8108=???Questa è la MTable correntemente attiva. +8109=???Non può essere cancellata. +8110=???Sei sicuro di voler cancellare la lavorazione selezionata? +8111=???CANCELLA +8112=???Sei sicuro di voler cancellare la macchina selezionata? +8113=???Impossibile trovare la cartella delle macchine {0}. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +8114=???Provare a ricaricare la macchina? +8115=???Impossibile trovare la cartella {0}. Se la cartella Doors è su un server, verificare che la connessione sia attiva. +8116=???Provare a ricaricare la cartella Doors? +8117=???Errore di esecuzione (guarda il file di log) +// GunStock +8201=???Nuovo pezzo +8202=???Gunstock Nuovo Pezzo +8203=???Mod pezzo +8204=???Gunstock Modifica Pezzo +8205=???Parametri calcio +8206=???Nome file +8207=???Descrizione +8208=???Ok +8209=???Cancella +8210=???deve avere un valore. +8211=???Il valore deve essere compreso tra +8212=???e +8213=???Dimensioni del grezzo +// GunStock errors +8251=Erreur +8252=???Errore nel lancio dell'ambiente Gunstock +8253=???Errore nella lettura del file Modello +8254=???Errore nella scrittura del file Pezzo +// ----- Beams & Walls ----- +9000=Table des usinages des poutres +9001=On +9002=Nom +9003=Type +9004=Ajouter +9005=Effacer +9006=Sauver +9007=Enregistrer les modifications apportées? +9008=Erreur +9009=Impossible d'ouvrir l'éditeur des usinages des poutres.
Il n'y a pas les fichiers de configuration. +9010=Table des usinages des parois +9011=Impossible d'ouvrir l'éditeur des usinages des parois.
Il n'y a pas les fichiers de configuration. +// ----- Errors ----- +10001=???Error +10002=???Error on new file +10003=???Error opening file +10004=???Error saving file +10005=???File type unknown +10006=???Error importing file +10007=???Error exporting file +10008=???Error loading or creating Machining Group +10009=???Missing file +// Missing Key Window +10101=Erreur ! +10102=Key pas présent. +10103=Insérer-le et redémarrer le programme. +10104=Ok +10105=Programme sans permis. +10106=Insérer-le et redémarrer le programme. +10107=Exécutez GetMachineId et envoyez les résultats au fournisseur. +// Numeric virtual keyboard +10201=Expression incorrect +// ----- MessageBox ----- +15001=Erreur +15002=Alerte +15003=Information +15010=Erreur inconnue +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Expression incorrect +// EgtCalculatorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Canc +20043=OUI +20044=NO +// ----- EgtWPFLib5 ----- +// EgtSaveFileDialog +30001=Sauvegarder +30002=Annuler +30003=existe déjà. +30004=Le remplacer? +30005=Nom du fichier: +30006=Ouvrir +30007=ERREUR +30008=Le nom ne peut pas être vide! +30009=ALERTE +30010=Nom du fichier +30011=Nom du répertoire +// Top CommandBar +30501=Nouveau +30502=Ouvrir +30503=Sauvegarder +30504=Sauvegarder sous +30505=Insérer +30506=Importer +30507=Exporter +30508=Executer +30509=Options +30510=Adresse e-mail du support introuvable. +30511=Enregistrer le projet en cours avant d'envoyer le feedback? +30512=Envoyer le feedback à {0} avec le répertoire attaché {1}. +30513=Feedback +30514=E-mail du feedback prête. +// Grid View Panel +30801=???Wireframe +30802=???Linee Nascoste +30803=???Ombreggiatura +30804=???Zoom All +30805=???Zoom In +30806=???Zoom Out +30807=???Vista da Sopra +30808=???Vista di Fronte +30809=???Vista da Sinistra +30810=???Vista da Dietro +30811=???Vista da Destra +30812=???Vista Isometrica da SW +30813=???Vista Isometrica da SE +30814=???Vista Isometrica da NE +30815=???Vista Isometrica da NW +30816=???Mostra Direzione Curve +30817=???Analizza +30818=???Distanza +30819=???Griglia da Sopra +30820=???Griglia di Fronte +30821=???Griglia da Destra +30822=???Griglia da Dietro +30823=???Griglia da Sinistra +30824=???Griglia da Sotto +30825=???Griglia da Vista +30826=???Elevazione Griglia +30827=???Origine Griglia +30828=???Ruota Griglia +30829=???Griglia da 3 Punti +30830=???Griglia Perpendicolare a Curva +30831=???Griglia da Oggetto +30832=???Vista da Griglia +// MachGroupPanel +30901=Nouveau Groupe d'Usinage +30902=Nom: +30903=Machine: +// ToolDbWindow +31001=Foret +31002=Scie +31003=Fraise +31004=Mortaise +31005=Composite +31006=Long foret +31007=Scie plat +31008=Fraise de côté +31009=Chiseau +31010=Jet d'eau +31051=Compensation +31052=Sortie +31053=Type +31054=Réfrigérant +31055=Rayon de Coin +31056=Diamètre +31057=Diamètre Total +31058=Vitesse +31059=Vitesse Finale +31060=Vitesse Initiale +31061=Vitesse de Pointe +31062=Longueur +31063=Longueur Totale +31064=Matériau Maximum +31065=Décalage longitudinal +31066=Décalage radial +31067=Rotation +31068=Angle latéral +31069=Rotation maximale +31070=Épaisseur +31071=Absorption maximale +31072=Vitesse minimum +31073=Dessin +31074=Tête +31075=Nom +31076=Notes +31077=Pos. Change Outil +31078=Position +31079=Perçage +31080=Tranchant +// ToolDb Errors +31100=Enregistrer l'outil modifié? +31101=ENREGISTRER +31102=Le fichier doit être .nge +31103=Le fichier n'existe pas ou n'est pas de type Nge +31104=Il n'y a pas de ToolMaker pour ce type d'outil +31105=L'outil ne peut pas être créé avec ces paramètres +31106=Le Matériau Maximum doit être supérieur à 0 +31107=Le Matériau Maximum doit être inférieur à Long +31108=L'Épaisseur doit être supérieure à 0 +31109=Le Diamètre doit être supérieur à 0 +31110=La Longueur doit être supérieure à 0 +31111=La Vitesse doit être inférieure à la Vitesse maximale +31112=Nom non valide +31113=La Longueur doit être inférieure à la Longueur Totale +31114=La Longueur doit être supérieure au Matériau Maximum +31115=La Longueur Totale doit être supérieure à 0 +31116=La Longueur Totale doit être supérieure à la Longueur +31117=Le Matériau Maximum doit être inférieur à {0} +31118=Le Diamètre doit être inférieur au Diamètre Total +31119=Le Diamètre doit être supérieur à 3 fois le Matériau Maximum +31120=Le Diamètre Total doit être supérieur à 0 +31121=Longueur trop petite avec porte-outil +31122=Voulez-vous vraiment effacer l'outil +31123=? +31124=EFFACER +31125=Fichier de configuration d'outillage pas trouvé! +31126=Erreur +31127=Définir le type de tête. +31128=Définir le type de sortie. +31129=L'outil n'est pas valide, corrigez-le ou supprimez-le avant de quitter la base de données d'outils. +31130=Impossible de recharger la base de données d'outils. Si le dossier machines se trouve sur un serveur, vérifiez que la connexion est active. +31131=L'Épaisseur doit être différente de 0 +31132=L'Angle Latéral doit être inférieur à 90 +31133=L'Angle Latéral doit être supérieur à -90 +31134=La Longueur Totale doit être supérieure à la Longueur + l'Épaisseur +31135=Le Rayon du Coin a une valeur trop grande +31136=L'Épaisseur est trop petite par rapport au Rayon de Coin +31137=Le Diamètre résultant dépasse le Diamètre Total +31138=Le Diamètre résultant est inférieur à 0 +31139=Le Diamètre de tige résultant est inférieur ou égal à 0 +31140=Le Matériau Maximum doit être supérieur au Rayon de Coin +31141=Le Matériau résultant Maximum doit être >= 0 +31142=Le Tranchant doit être supérieur à 0 +31143=Le Tranchant doit être inférieur à Long +// ImportExportToolWindow +31161=Importer +31162=Exporter +31163=Outils +31164=Outil déjà existant dans la base de données. Ecraser? +31165=L'outil sera importé avec le nom suivi de "_imp" +31166=Les outils suivants ont été importés avec succès: +31167=Reset +// MachiningDbWindow +31201=Perçage +31202=Coupe de la lame +31203=Fraisage +31204=Vidage +31205=Sciage à chaîne +31206=Ebauche avec lame +31207=Finition avec lame +31208=Usinage générique +31209=???Scalpellatura +31210=???Waterjetting +31211=???Surffinishing +31251=Inverser +31252=Laisser onglets +31253=Type +31254=Côté de travail +31255=Côté de la tête +31256=Entrée +31257=Connexion +31258=Sortie +31259=Utilisation des courbes +31260=Type de marche +31261=Sous-type +31262=Type d'approche +31263=Rotation +31264=Vitesse +31265=Vitesse Initiale +31266=Vitesse Finale +31267=Vitesse de Pointe +31268=Décalage radial +31269=Décalage longitudinal +31270=Profondeur +31271=Inclinaison latéral +31272=Approximation +31273=Dist. sécurité +31274=Long. ralentiss. initial +31275=Long. ralentiss. final +31276=Long. ajoutée au trou +31277=Pas +31278=Position de retour +31279=Longueur +31280=Hauteur +31281=Angle +31282=Distance +31283=Dist. tangente +31284=Dist. perp. +31285=Élévation +31286=Long. Correction +31287=Nombre min +31288=Nombre max +31291=Longueur Additionnel +31293=Pas sur extérieur arc +31294=Pas sur inxtérieur arc +31295=Pas de côté +31296=Avance verticale +31297=Nom +31298=Outil +31299=Profondeur +31300=Notes +31301=Superposition +31302=Décalage +31303=Sous-type +31304=SCC +31305=Aucun +31306=Standard +31307=Opposé +31308=AuxDir Droit +31309=AuxDir Gauche +31310=AuxDir Derrière +31311=AuxDir Front +31312=AuxDir Sur +31313=AuxDir Sous +31314=AuxDir Plus Proche +31315=AuxDir Plus Éloigné +31320=Centre +31321=Gauche +31322=Droite +31323=Étendre +31324=Standard +31325=Intérieur +31326=Extérieur +31327=Étendu centré +31328=Étendu externe +31329=Aucun +31330=Linéaire +31331=Tangente +31332=Poursuite +31333=Hélice +31334=Étendre le précédent +31335=Prolonger ensuite +31336=Étendre les deux +31337=Même qu'entrée +31338=Éviter +31339=Approximer +31340=Convexe +31341=Garder +31342=ZigZag +31343=Aller simple +31344=Spirale +31345=Aller-retour +31346=Longitudinal +31347=Transversal +31348=Spirale vers l'intérieur +31349=Spirale vers l'éxtérieur +31350=Avancés +31351=Inverser Outil +31352=Usinage de faces +31353=Non défini +31354=Parallèle +31355=Orthogonal +31356=Ortog. vers haut +31357=Sous +31358=Sur +31359=Avant +31360=Derrière +31361=Gauche +31362=Droite +31363=Contour +31364=Angles suggérés +31365=Axe verrouillé +31366=???Last backward feed +31367=???Backward step +31368=???Tilted step +31369=???Tilted back step +31370=Inclinaison vers l'avant +31371=Palpage +31372=Dist. min. points +31373=Dist. max. points +31374=Extérieur +31375=Intérieur +31376=Longueur. ralentir. +31377=DÉCÉLÉRATION. % +31378=Trou d'attaque +31379=Rayon +31380=???Num. giri in LP +31381=???Num. giri in HP +31382=Oscillation +31383=Amplitude +31384=???Lungh. rampa +31385=???Lungh. cresta +31386=Génériques +31387=Avancés +31388=Tang+Perp +31389=Perp+Tang +//MachiningTreeView +31391=Normal +31392=Ralentir +31393=Anneau +31394=Activation +31395=???Add Length +31396=???Start +31397=???End +31398=???System notes +31399=???Epicycles radius +31400=???Epicycles distance +// MachiningDb Errors +31401=Enregistrer l'usinage modifié? +31402=ENREGISTRER +31403=Nom invalide +31404=Les caractères \ /: *? "<> | ne sont pas autorisés +31405=Êtes-vous sûr de vouloir annuler? +31406=???? +31407=SUPPRIMER +31408=Impossible de recharger la base de données d'usinage. Si le dossier machines se trouve sur un serveur, vérifiez que la connexion est active. +31409=Matériau de la machine non reconnu +31410=L'usinage n'est pas valide, corrigez-le ou supprimez-le avant de quitter. +31411=La longueur doit être positive +31412=La distance doit être positive +31413=La hauteur doit être positive +31414=L'angle doit être compris entre {0} ° et {1} ° +31415=Le nombre maximum doit être nul ou positif +31416=Le nombre maximum doit être supérieur ou égal au minimum +31417=Le nombre minimum doit être nul ou positif +31418=Le nombre minimum doit être inférieur ou égal au maximum +31419=L'activation de {0} désactivera {1}. Procéder? +// ImportExportMachiningWindow +31450=???Import +31451=???Export +31452=???Machinings +31453=???Machining already existing in DB. Overwrite? +31454=???Machining will be imported with the name followed by "_imp" +31455=???The following Machinings have been imported succesfully: +31456=???Reset +// SetUp Window +31501=Outillage +31502=Appliquer +31503=Enregistrer +31504=Récupérer +31505=Auto +31506=Appliquer l'outillage actuel avant de sortir? +// SetUp Errors +31551=Erreur +31552=Avertissement +31553=L'outil est introuvable +31554=Dans le DB d'outils. +31555=La position d'outil par défaut n'est pas valide. +31556=La position d'outil par défaut est déjà occupée. +31557=Le fichier de configuration n'existe pas! +31558=L'outillage utilise une tête qui n'existe pas sur la machine! +31559=Erreur lors du chargement de l'outillage +// Simulation +31601=Simulation achevé +31602=Surcourse +31603=Direction de l'outil inaccessible +31604=Erreur +31605=ERREUR +31606=Erreur de génération! +31607=Simulation +31608=Un pas à la fois +31609=Aller/Pause +31610=Arrêt/Accueil +31611=Pause +31612=Simulation arrêtée +31613=Impossible de quitter maintenant. Arrêtez d'abord la simulation ou attendez qu'elle se termine! +31614=AVERTISSEMENT +31615=Fichier d'estimation introuvable +31616=Estimations détaillées +//MachiningDbWindow/ToolDbWindow buttons +31701=Nouveau +31702=Enregistrer +31703=Effacer +31704=???Edit +//Db Waterjet +31751=???Waterjet Db +31752=???Thickness +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=???Do you want to save edits? +// ----- EgtDOORCreator ----- +//General +50001=???Width +50002=???Height +50003=???Thickness +50004=???Swing +50005=???Lockedge +50006=???Hingeedge +50007=???Top +50008=???Bottom +50009=???Type +50010=???Corner +50011=???Extension +50012=???Side +50013=???Offset wide side +50014=???Back set +50015=???Top to center application +50016=???Bottom rail +50017=???Lock stile +50018=???Offset from center +50019=???Point to pocket +50020=???Pocket length +50021=???Pocket offset narrow side +50022=???Point to arm +50023=???Arm length +50024=???CenterHung +50025=???Offset +50026=???Offset intermediate +50027=???Radius +50028=???Top rail +50029=???Position +50030=???Lenght +50031=???Template +50032=???Up +50033=???Down +50034=???Shape +50035=???Hinge +50036=???Top to top application +50037=???Center from top application +50038=???Center from top lock +50039=???Depth +50040=???General +50041=???Center +50042=???Thru +50043=???Face to center line application +50044=???Edge Type +50045=???Over Material +50046=???Send Feedback +50047=???Weight +50048=???Angle +50049=???Face +50050=???Secure +50051=???Keyway +50052=???Brand +50053=???Folder +50054=???Main Folder +50055=???Jamb +50056=???Light Up +50057=???Light Lock +50058=???Light Bottom +50059=???Light Hinge +50060=???Thickness Head +50061=???Overlap Hinge +50062=???Overlap Lock +50063=???Overlap Top +50064=???Delta T +50065=???Exterior +50066=???Number of Doors +50067=???Jambs and Doors +50068=???Order +50069=???Disposition +50070=???Customer +50071=???Invert bevel on Lock +//Compo Name +50072=???Flush Bolt +50073=???Flush Pull +50074=???Hinge +50075=???Lock +50076=???Louver Cut Out +50077=???Mail Slot +50078=???Over Head +50079=???Pivot +50080=???Roller Latch +50081=???Stops And Closer +50082=???Strike +50083=???Edge pull +50084=???Viewer +50085=???Vision cut out +50086=???Grove +50087=???Rabbet +50088=???Ept +50089=???Raceway +50090=???Face Decoration +//error messages +50100=???Directory not founded +50101=???Error +50102=???Failed reading DDF file. Missing incumbent parameter {0}. +50103=???Failed reading value +50104=???Failed reading DDF file's row +50105=???Row +50106=???Invalid value in +50107=???Empty file. +50108=???You can not add a compo if there is not a dorr! +50109=???Do you want to save this file ({0}) ? +50110=???Question +50111=???Add new door +50112=???Remove door +50113=???New Door +50114=???File name already exists in the current directory ({0}). +50115=???Caution +50116=???Do you want to delete this file ({0}.ddf)? +50117=???Confirm deleting ({0})?. +50118=???Information +50119=???Error in reading messages. There is no match with the number {0}. +50120=???Error reading name {0} in {1}. Expected numeric match. +50121=???Error reading {0} param in {1} compo: do not exist. +50122=???Error in {0} param in {1} compo. +50123=???Error reading {0} param in {1} compo: do not exist list. +50124=???Error reading {0} param in {1} compo: {2}. +50125=???Error in {0} param in {1} compo: do not exist value. +50126=???Delete +50127=???Error in EgtLoadMessages +50128=???You can not save a file if there is not a door! +50129=???Error in Project scene creation +50130=???Error in reading: line {0}. +50131=???Error in reading {0}: line {1}. Expected ':' after the name. +50132=???Error in reading {0}: line {1}. Expected 'template' or 'shape'. +50133=???{0} has not been created. +50134=???Error reading 'Template' in file {0}\{1}. Expetcted name. +50135=???Error reading 'Template' in file {0}\{1}. File {0}\{2} .lua does not exist. +50136=???Error in reading {0}: line {1}. It does not exist in the list of components in file 'Default.ini'. +50137=???Error in reading {0}: line {1}. It is not a member of the list. +50138=???This param will be initialized by default. +50139=???Error in reading: line {0}. Expected {1}. +50140=???All missing params will be initialized by default. +50141=???Invalid expression in {0}. +50142=???Remove compo +50143=???Invalid expression. +50144=???Warning +50145=???Impossible to create the current door. +50146=???Do you want to open a template? +50147=???Error expression in {0}. {1} does not match anything. +50148=???Invalid value.ù +50149=???Caution: Weight is setted in OptionPage. Do you want to remove? +50150=???Caution: Weight is setted in DDF. Do you want to add? +50151=???{0} is not a member of the current list of EdgeType. Check Bevel in option page. +50152=???Do you want to save this file ({0})? +50153=???Caution. Weight is setted in the current door. Do you want to remove? +50154=???It is the bevel of the current door. Do You want to proced? +50155=???Impossible to create a template if there is not a door! +50156=???Errore nella lettura ddf: la porta non è completa o il ddf è stato separato male da '---'. +50157=???Script Lua ( {0}\{1} )has not been found. +50158=???Bevel {0} can not be acceptable in Jamb. +50159=??? Missing parameter in ddf! +50160=???File {0} in directory {1} has not been found. +50161=???parameter +50162=???In file {0} param 'Default' must be numeric. +50163=???Error in reading General Assembly in DDF +50164=???In General Assembly: +50165=???CompoDir not found : +50166=???Jamb compo does not exist +50167=???Empty Line +50168=???No matching param +50169=???Door disposition has been modify. +50170=???Incongruity between the bevel, it has been resolved by default. +50171=???In file StdTempate.ini is missing numeric param in [Type]. +50172=???File does not exist. +50173=???Definition type is not correct: +50174=???Missing name of the new template! +50175=???The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=???Error in copying: {0} +50177=???Do you want to save the current changes? +50179=???Doors Compo Default.ini not found in {0} . +50180=???Warning : {0} does not exist. +50181=???Error in creating the print image +50182=???Error executing print +50183=???Some Doors could use this hardware, do you want to proceed deleting? +50184=???Impossible to delete Hardware if there is no Hardware selected! +50185=???Impossible to duplicate Hardware if there is no Hardware selected! +50186=???Project must be saved before copying +50187=???Do you want to copy all files ? {0} (No to copy only the current file) +50188=???Export to machine +50189=???Machine Directory not found +50190=???Error in copying: {0} +50191=???Impossible to copy a door if there is not a door! +50192=???Impossible to export to machine a door if there is not a door! +50193=???Impossible to print a door if there is not a door! +50194=???Properties has been deleted +50195=???The current ddf configuration ({0}) is different from the current program configuration ({1}).{2}To load the current ddf configuration you have to restart the program, do you want it? +50196=???Configuration ddf ({0}) does not exist! +50197=???Top Arch has been modified because of configuration. +50198=???Bevel on lock edge would be inverted. +//Option +50200=???Unit measure +50201=???General +50202=???LockEdgeOverMaterial +50203=???HingeEdgeOverMaterial +50204=???TopOverMaterial +50205=???BottomOverMaterial +50206=???Open Window +50207=???Last Project +50208=???Empty +50209=???Option Page +50210=???StartUp +50211=???Unit measure new door. +50212=???Directory Project +50213=???Option Start +50214=???Current Directory +50215=???Edge Type +50216=???Over Material +50217=???Browse +50218=???Close +50219=???Bevel +50220=???Bevel Up +50221=???Bevel Down +50222=???Door positioning in machining +50223=???Save as template +50224=???Matching +50225=???Brand +50226=???File +50227=???Template +50228=???Enable template +50229=???Enable Order +50230=???Open template door. +50231=???Open window order. +50232=???Directory Template +//Scene +50301=???Refresh +50302=???Add New Door +50303=???Remuve Door +50304=???New Project +50305=???Help +50306=???Directory Machine +50307=???Machine +50308=???Door +50309=???Wide Side Down (BU) +50310=???Wide Side Up (BD) +50311=???Resize +50312=???Design +50313=???Save as pdf +//Launcher +50400=???Launcher +50401=???Open New Project +50402=???Open Project +50403=???Open Last Project +50404=???New Project +50405=???New Hardware +50406=???Elevation +50407=???Project +50408=???PO +50409=???Line +50410=Sauvegarder +50411=???Print +50412=Annuler +50413=???Hardware +50414=???Dimensioning +50415=???Duplicate +50416=???Export to machine +50417=???New Template +50418=???Dimension +50419=???New Directory +50420=???Create Assembly +50421=???Relaod Directory +50422=???Save As +50423=???Reaload Compo on Jamb +//Error messages +50501=???Error reading {0} param in {1} compo: incomplete definition (look at StdTemplate.ini). +50502=???Error reading {0} param in {1} compo: no matching (look at StdTemplate.ini and GeometryNameList.ini). +50503=???Do you want to save? +50504=???File name contains empty spaces, do you want to rename file deleting empty spaces? +50505=???DDF is not an assembly, there are only: {0}, do you want to save? +50506=???Impossible to find the first door (DO_1)! +50507=???The swing is not a member of the swing list of single door. +50508=???The swing of left door is not a member of the swing list of left door. +50509=???The swing of right door is not a member of the swing list of right door. +50510=???The swing of left door is on the right door and viceverse. +50511=???The swing of left door is not a member of the swing list of left door. +50512=???The swing of right door is not a member of the swing list of right door. +50513=???Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=???The swing are absolutly wrong! +50515=???The first door is not realy the first, check the ddf. +50516=???The current ddf contains {0} jambs. +50517=???The current ddf does not contains doors! +50518=???The current ddf is not an assembly. +50519=???Impossible to open a ddf with no doors. +50520=???The current ddf is an assembly. +50521=???The current ddf is a jamb: {0}. +50522=???The profile {0} is not a member of the {1} profile list. +50523=???Missing profile on {0}. +50524=???{0} file open by another EgtDOORCreator {1}. +50525=???{0} file open by another EgtDOORCreator {1}. +50526=???Directory {0} already exists! Do you want to overwrite it? +50527=???Impossible to overwrite {0} +50528=???Impossible to save the door out of the project! +50530=???Property {0} does not exist in the list of {1}. Look at file "../Compo/Default.ini". +50531=???The current material {0} does not exist in the list of material. Look at file "../Compo/Default.ini". +50532=???Missing list of material at file "../Compo/Default.ini". +50533=???Impossible to load more than one property at time. +50534=???Property {0} does not exist in the list. Look at file "../Compo/Default.ini". +50535=???Impossible to delete a project if there is not a project! +50536=???Do you want to delete entire project? +50537=???Do you want to delete subdirectory {0} ? +50538=???Impossible to vreate a template door if there is not a door! +50539=???Do you want to change project? ( All doors will be deleted!) +50540=???The current ddf is a part of a frame, do you want to save? +50541=???{0} in reading {1}. +50542=???{0}: Directory does not exist! +50543=???It has been renamed file: {0}, {1}. +50544=???It has been created new file: {0}, {1}. +50545=???It has been deleted file: {0}, {1}. +50546=???Enable single door. +50547=???Project +50548=???The new configuration will take effect after restart. +50549=???File {0} exist, but it is not in the correct Directory! +50550=???Every componente on jambs will be relocated, do you want to continue +50551=???The current parameters have been modified: +50552=???Do you want to overwrite? +50553=??? has not been created. +50554=???Parameter {0} is already deinfed in geometry {1}. +50555=???Impossible to save. +50556=???File has nge extension. +50557=???Error in deleting file: {0} +50558=???Impossible to import a different hardware! +50559=???Open File Dialog +50560=???The hardware part has not been generated correctly. +50561=???Directory already exists +50562=???Folder {0} does not exist. Check in OptionPage. +50563=???Compo {0} does not exist. +50564=???In group {0} at paramater {1} does not exist: {2} +50565=???Brand {0} has not been found in HardwareManager. +50566=???Template {0} has not been found in HardwareManager. +50567=???Error in executing EgtCam5. +50568=???Error in definition {0} in file GeometryNameList.ini . +50569=???Error in definition {0} in file StdTemplate.ini . +50570=???Nothing has been selected. +//Added General messages +50701=???Lines +50702=???Rectangle +50703=???None +50704=???Radius +50705=???Angle +50706=???Pos_x +50707=???Top Arc +50708=???Top Angle +50709=???Properties +50710=???Material +50711=???Mach. +50712=???HardwarePart +50713=???Assemby +50714=???Total Dimension +50715=???Depth +50716=???Overlap Bottom +50717=???Thickness Bottom +50718=???Depth Bottom +50719=???Delta Bottom +50720=???GoToAssembly +50721=???New Geometry +50722=???Geometry Name +50723=???Type Hardware +50724=???Parameter +50725=???Part Dimension +50726=???Apply +50727=???Frame +50728=???Refresh Directory +50729=???General +50730=???Report +50731=???Opposite face +// ----- EgtBEAMEditor ------ +60951=???Cut +60952=???Longitudinal Cut +60953=???Double Cut +60954=???Ridge or Valley Cut +60955=???Saw Cut +60956=???Slot +60957=???Front Slot +60958=???Birds Mouth +60959=???Hip or Valley Rafter Notch +60960=???Ridge Lap +60961=???Lap Joint +60962=???Notch/Rabbet +60963=???Block House Half Lap, Stairs Riser Dado +60964=???Seathing Cut +60965=???French Ridge Lap +60966=???Chamfer +60967=???Block House Half Lap +60968=???Block House Front +60969=???Pocket +60970=???Drilling +60971=???Tenon +60972=???Mortise +60973=???Mortise Front +60974=???House +60975=???House Mortise +60976=???Dovetail Tenon +60977=???Dovetail Mortise +60978=???Dovetail Mortise Front +60979=???Marking/Labeling +60980=???Text +60981=???Simple Scarf +60982=???Scarf Joint +60983=???Step Joint +60984=???Step Joint Notch +60985=???Planing +60986=???Profile Front +60987=???Profile Head concave +60988=???Profile Head convex +60989=???Profile Head cambered +60990=???Round Arch +60991=???Profile Head +60992=???Sphere +60993=???Triangle Cut +60994=???Tyrolean Dovetail +60995=???Dovetail +60996=???Free Contour +60997=???Outline +60998=???Aperture +61001=???Distance from beam start to the reference point +61002=???Distance from the reference edge to the reference point +61003=???Distance from the reference side to the reference point (orthogonal) +61004=???Angle between cut edge and reference edge +61005=???Inclination between face and reference side +61008=???Limit of the 2 ends, binary code +61009=???Inclination to the reference side +61010=???Depth: If P11 is zero, then the face of the cut dispreads to the neigbour-sides or opposite-side to referenceside +61011=???Length: If P12 and P04 equal to zero, the processing is performed along the whole component length +61012=???Angle in face at start +61013=???Angle in face at end +61015=???Distance from the reference point to the reference edge +61016=???Angle between the first cutting edge and the reference edge +61017=???Inclination of the first cutting towards the reference side +61018=???Angle between the second cutting edge and the reference edge +61019=???Inclination of the second cutting towards the reference side +61023=???Inclination between the first face and the reference side +61024=???Inclination between the second face and the reference side +61025=???Depth +61027=???Angle in face at reference edge at start +61028=???Angle in face at reference edge at end +61029=???Angle in face in opposite to reference edge at start +61030=???Angle in face in opposite to reference edge at end +61033=???Displacement to the reference side +61036=???Angle to the reference edge in the cut face +61037=???Depth, orthogonal to the reference side +61038=???Length +61041=???Distance to the reference point orthogonal to the reference side P03 = 0: Slot on one of the 4 sides of the component. P03 > 0: Slot on one of the 2 front sides of the component +61042=???Limit of the 6 faces of the slot, binary code +61043=???Angle to the reference edge in the reference side +61045=???Interior angle at reference point +61046=???Interior angle at opposite of reference point +61047=???Addition to P09 +61048=???Depth orthogonal to the reference side +61049=???Length +61050=???Thickness +61051=???Displacement of the entrance edge at reference point +61052=???Displacement of the entrance edge at opposite of reference point +61055=???Distance to the reference point orthogonal to the reference side +61056=???Limit of the 6 faces of the Frotn Slot, binary code +61059=???Angle between the longitudinal axis of the slot and the reference side +61060=???Depth +61061=???Length +61062=???Width +61065=???Location of P09/P10, if P09>0 and P10>0. If P04=-1, then the location must be defined on the machineside +61066=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole. +61067=???Angle to the reference edge in the reference area +61068=???Inclination between face 1 and reference side +61069=???Inclination between face 2 and reference side +61070=???First cut angle of the counterpart. If P09 is zero, the limit face beside face 1 is parallel to component side. +61071=???First cut inclination of the counterpart. If P10 is zero, the limit face beside face 1 is parallel to component side. +61072=???Depth 1 orthogonal to reference side +61073=???Depth 2 orthogonal to reference side +61074=???Grooving depth in the transverse direction of the component. If P13 is zero, then its value must be calculated:P13=WRS-P02 +61075=???Height Counterpart. Zero means: no limit. Measurement orthogonal to face 1 (P07). +61076=???Width Counterpart. Zero means: no limit. Measurement orthogonal to face 2 (P08). +61079=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole +61080=???Angle notch 1 to the reference edge in the reference area +61081=???Angle notch 2 to the opposite reference edge in the reference area +61082=???Inclination between base area of notches and reference side +61083=???Depth orthogonal to reference side +61084=???Width of notch 1. If this value is equal 0, then the notch is not limited. +61085=???Width of notch 2. If this value is equal 0, then the notch is not limited. +61087=???0: Reference point on referene edge. 1: Reference point on the opposite edge +61088=???Angle to the reference edge in the reference side +61089=???Depth of Half Lap +61090=???Width of Half Lap +61091=???Drill hole diameter +61094=???Displacement to the reference side +61095=???Limit of the 6 faces of the lap, binary code +61096=???Angle to the reference edge in the reference side +61098=???Angle between edge and reference side in face +61099=???Angle in the floor face +61100=???Angle between base face and one face of lap +61101=???Distance (orthogonal) from reference side to point below reference point +61102=???Length +61103=???Chamfer angle +61104=???Grooving depth (length of the lapped scarf in transverse direction). If P14 is zero, then its value must be calculated: P14=WRS-P02 +61107=???Limit of the 6 faces of the notch/rabbet, binary code +61108=???Notch/Rabbet depth +61109=???Notch/Rabbet length +61110=???Notch/Rabbet width +61113=???Depth of the Half Lap on the reference side +61114=???Depth of the Half Lap opposite of the reference side +61115=???Length of the Half Lap / Dado +61117=???Depth of Seathing Cut +61118=???Length of Seathing Cut +61120=???0: Reference point on reference edge; 1: Reference point on the opposite edge +61121=???Angle to the reference edge in the reference side +61122=???Drill hole diameter +61124=???Input of edge(s) to be beveled, binary code: Bit 0=edge 1 ; Bit 1=edge 2; Bit 2=edge 3; Bit 3=edge 4. Example: P04=9: edge 1+4; P04=3: edge 1+2 +61125=???Depth +61126=???Length: If P12 is equal to zero, the processing is performed along the whole component length. +61127=???Shape for bevel exit: 0 = orthogonal, 1 = at 45 deg, 2 = round; +61129=???Depth orthogonal to reference side of the lap 2 and 4. If P03 is zero, then its value must be calculated: P03=HRS +61130=???0:all laps are symmetric to each other; 1:lap on reference edge moved to start beam, lap in opposite of reference edge moved to end beam; 2: lap on reference edge moved to end beam, lap in opposite of reference edge moved to start beam; +61131=???P05=1: drilhole for drop rod, P05=0: no drillhole. The machines defines place and direction of the drillhole. +61132=???lap 1: Depth +61133=???lap 1: Length +61134=???lap 2: Depth +61135=???lap 2: Length +61136=???lap 3: Depth +61137=???lap 3: Length +61138=???lap 4: Depth +61139=???lap 4: Length +61140=???Distance from end of arc orthogonal to the reference side +61141=???Radius of arc +61142=???Distance reference point to center of arc +61143=???Which arc (A, B,C or D) is to produced, binary code +61145=???0:only one lap on reference side; 1:one lap on reference side and one on the opposite side +61146=???Angle to the reference edge in the reference side +61147=???Depth at reference point +61148=???Depth opposite to the reference point +61149=???Depth at reference edge +61150=???Length +61153=???Limit of the 6 faces of the pocket, binary code +61154=???Rotation angle around the local z-axis of the cuboid +61155=???Rotation angle around the local y-axis of the cuboid, rotated with P06 +61156=???Rotation angle around the local x-axis of the cuboid, rotated with P06 and P07 +61157=???Internal angle at the reference point +61158=???Depth of reference point orthogonal to reference side +61159=???Length of Half Lap +61160=???Width of Half Lap +61163=???Distance from the reference face to the reference point. P03 = 0:Drilling on one of the 4 sides of the component. P03 <> 0:Drilling on one of the 2 front sides of the component. +61164=???P03 = 0:Angle to the reference edge in the reference side. P03 <> 0:Angle in the front side. +61165=???Inclination between drilling and reference side. P03 = 0: Inclination between drilling and reference side. P03 > 0: Inclination between drilling and front side +61166=???Depth, orthogonal to reference side or front side. +61167=???Drill hole diameter +61170=???Rounding +61171=???Chamfer +61174=???Angle between axis of the tenon and reference side +61175=???Radius for P04=4 +61176=???Tenon height +61177=???Tenon width +61178=???Margin on the reference side +61179=???Margin opposite the reference side +61182=???Displacement to the reference side +61183=???Rounding +61184=???Angle between axis and reference edge +61185=???Inclination between strut and reference side +61186=???Inclination of hole side walls towards reference side +61187=???Radius for P04=4 +61188=???Mortise depth +61189=???Mortise width +61190=???Height of strut +61191=???Margin on the reference point +61192=???Margin opposite the reference point +61193=???Inclination of hole front side towards reference side +61196=???Rounding +61199=???Angle between axis of the tenon and reference side +61200=???Radius for P04=4 +61201=???Mortise depth +61202=???Mortise width +61203=???Margin on the reference side +61204=???Margin opposite the reference side +61205=???Processident of the associated tenon or dovetail tenon +61206=???Processident of the associated mortise or dovetail mortise +61209=???0:with rounding at the bottom; 1:without rounding, unbounded +61210=???Angle between edge and reference edge +61212=???Angle between axis of the tenon and reference side +61213=???Middle flattening +61214=???Angle of cone +61215=???Tenon height +61216=???Diameter of the curve: If P12 < 0, then the radius must be defined on the machineside. +61217=???Margin on the reference side +61218=???Margin opposite the reference side +61221=???Displacement to the reference side +61222=???0:with rounding at the bottom; 1:without rounding, unbounded +61223=???0:with elongation; 1:with pocket +61224=???Angle between axis and reference edge +61225=???Inclination between strut and reference side +61226=???Middle flattening +61227=???Angle of cone +61228=???Mortise depth +61229=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61230=???Height of strut +61231=???Margin on the reference point +61232=???Margin opposite the reference point +61235=???Displacement to the front side +61236=???0=with rounding at the bottom; 1=without rounding, unbounded +61237=???0=with elongation; 1=with pocket +61240=???Angle between axis of the tenon and reference side +61241=???Middle flattening +61242=???Angle of cone +61243=???Mortise depth +61244=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61245=???Margin on the reference side +61246=???Margin opposite the reference side +61249=???Position and alignment of the text. P04 = 0 if there is no text. +61250=???Angle between axis and reference edge. If P06 equals 180°, then a horizontal line is defined, P12 defines the length of the line. +61251=???Interior angle. If P07 equals zero, 2 single markings have to be produced. +61252=???Width of quadrangle. If P11 equals zero, there is only a single marking. +61253=???Height of quadrangle. If P12 equals zero, marking is limited by the edge opposite to the reference edge. +61254=???Height of text. If P13 equals zero, the machine determines the text height. +61255=???Text (String max. 256 characters) +61258=???Angle between axis and reference edge +61259=???Alignment vertical. 0 = bottom, 1=middle, 2=top +61260=???Alignment horizontal. 0 = left, 1=middle, 2=right +61261=???Alignment in case of a multiline text. 0 = left-aligned, 1=centered, 2=right-aligned. A new line must be defined with this 2 letters: \n +61262=???Letters standard or horizontal placed. 0 = standard, 1=letters horizontal placed +61263=???Height of text. If P13 equals zero, the machine determines the text height. +61266=???Depth at the reference side +61267=???Depth at the opposite of reference side +61268=???Length of the overlap +61269=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61270=???Drilling 2 diameter. Placed at 2/3 P13 +61272=???Angle of inclination of the lapped scarf base +61273=???Shape of the lapped scarf or classic data identification: 1:when cutting orthogonal to reference side; -1:when cutting orthogonal to base side; 0:classic definition, P10 and P12 are not used +61274=???Length of the lapped scarf base +61275=???Depth of the lapped scarf base +61276=???Depth of the lapped scarf base orthogonal to reference side +61277=???Length +61278=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61279=???Drilling 2 diameter. Placed at 2/3 P13 +61281=???Type of heel notch:0=normal; 1=tapered +61282=???Inclination strut +61283=???Depth step joint +61284=???Depth heel notch +61285=???Height tenon. Which implementation (A or B) is used depends on the machine +61286=???Width tenon +61289=???Type of heel notch: 0=normal; 1=tapered +61290=???Inclination between strut and reference side +61291=???Width of the notch +61292=???Depth step joint +61293=???Depth heel notch +61294=???Height of strut +61295=???Depth of mortise. Which implementation (A or B) is used depends on the machine +61296=???Width of mortise +61298=???Specification of side(s) to be planed; binary coded +61299=???Planing depth +61300=???Length of the area to be planed +61303=???Rotation angle of the first curve of the profile +61304=???Rotation angle of the profile towards the reference edge +61305=???Offset angle +61306=???Radius of the first curve +61307=???Radius of the second curve +61309=???Radius +61310=???Depth +61311=???Displacement +61312=???Depth +61313=???Displacement +61315=???Radius +61316=???Depth +61317=???Displacement +61318=???Depth +61319=???Displacement +61321=???Profile length +61322=???Depth at the reference point +61323=???Maximum depth of profile +61324=???Minimum depth of profile +61325=???Depth at the profile end +61326=???Premill: 0=round; 1=angular +61328=???Depth of the arch segment +61329=???Length of the arch segment +61331=???Type of arc (convex, concave), binary coded. See table below. +61332=???Length of lap 1 +61333=???Depth of lap 1 +61334=???Displacement arc 1 +61335=???Horizontal length arc 1 +61336=???Vertical length arc 1 +61337=???Camber arc 2 +61338=???Length of lap 2 +61339=???Depth of lap 2 +61340=???Displacement arc 2 +61341=???Horizontal length arc 2 +61342=???Vertical length arc 2 +61343=???Camber arc 2 +61344=???Length of lap 3 +61345=???Depth of lap 3 +61348=???Distance from the reference side to the reference point +61349=???Radius +61350=???Start offset +61351=???Length +61354=???Distance from the reference side to the reference point +61355=???Normal vector 1: Length of X-component +61356=???Normal vector 1: Length of Y-component +61357=???Normal vector 1: Length of Z-component +61358=???Normal vector 2: Length of X-component +61359=???Normal vector 2: Length of Y-component +61360=???Normal vector 2: Length of Z-component +61362=???Distance between "inside" an side of part +61363=???Distance orthogonal to the reference side +61364=???0:"inside" at reference edge, 1:"inside" at opposite of reference edge +61365=???0:Without rebate or mitre, -1:With mitre, >0:With rebate +61366=???Angle to the reference edge in the reference side +61367=???Width +61368=???Depth +61369=???Inclination +61370=???Height +61371=???Radius +61372=???Length of tool (part of arc) +61373=???0:Angular corner joint, 1:Straight T-wall connection +61374=???Length +61375=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61377=???Distance between "inside" an side of part +61378=???Distance orthogonal to the reference side +61379=???0:"inside" at reference edge, 1:"inside" at oppostite of reference edge +61380=???0:Without rebate or mitre, -1:with mitre, >0:with rebate +61381=???Inclination +61382=???Depth 1 +61383=???Depth 2 +61384=???0:European Dovetail, 1:American Dovetail +61385=???Length +61386=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61387=???Depth +61388=???Mode: 0=contour only, 1=countersink completely. Only for closed contours. +61389=???Contour type +61390=???Parameter depends on contour type(P13) +61391=???Parameter depends on the contour type(P13) +61400=???Reference point on referene edge +61401=???Reference point on the opposite edge +61402=???Reference point on referene edge +61403=???Reference point on the opposite edge +61404=???orthogonal +61405=???at 45 deg +61406=???round +61407=???all laps are symmetric to each other +61408=???lap on reference edge moved to end beam. lap in opposite of reference edge moved to start beam +61409=???lap on reference edge moved to start beam. lap in opposite of reference edge moved to end beam +61410=???only one lap on reference side +61411=???one lap on reference side and one on the opposite side +61412=???with rounding at the bottom +61413=???without rounding, unbounded +61414=???with elongation +61415=???with pocket +61416=???bottom +61417=???middle +61418=???top +61419=???left +61420=???right +61421=???left-aligned +61422=???centered +61423=???right-aligned +61424=???standard +61425=???letters horizontal placed +61426=???when cutting orthogonal to reference side +61427=???when cutting orthogonal to base side +61428=???classic definition, P10 and P12 are not used +61429=???normal +61430=???tapered +61431=???round +61432=???angular +61433=???"inside" at reference edge +61434=???"inside" at opposite of reference edge +61435=???Angular corner joint +61436=???Straight T-wall connection +61437=???Processing on the reference side and opposite the reference side +61438=???Processing only on the reference side +61439=???Processing only opposite the reference side +61440=???European Dovetail +61441=???American Dovetail +// ---Custom Parameter (Q) +61451=???Profondità smusso +61452=???0=Automatico; 1=Ciclo longitudinale con lama +61453=???Spessore testimone centrale per ciclo Q02 +61454=???0=Attacco centrato; 1=Attacco interno +61455=???0=Automatico; 1=Lavorazione con fresa di lato +61456=???1=Forza Lama; 0=Automatico +61457=???1=Solo smusso +61458=???0=Automatico; 1=Massima profondità +61459=???0=Automatico; 1=Truciolatore; 2=Truciolatore di lato; 3=Fresa; 4=Fresa di lato +61460=???0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +61461=???0=Automatico; 1=Massimo raggio ammesso su tasche non passanti +61462=???Diametro utensile per Q05 +61463=???Diametro utensile per Q07 +61464=???0=Raggio su spigolo; 1=Foro su spigolo; 2=Spigolo vivo +61465=???Diametro foro quando P05=1 +61466=???0=Automatico; 1=Sgrossatura con lama +61467=???Antischeggia: 0=No; 1=Con lama; 2=Con fresa +61468=???Aumenta dimensioni tasca +61469=???Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico +61470=???0=Automatico; 1=Solo contorno ; 2=Drill or Pocket +61471=???0=Automatico; 1=Lavoro da un lato solo +61472=???Incrementare/decrementare valore P01 per fori nei tenoni +61473=???0=Foratura rompi truciolo; 1=Foratura scarico truciolo +61474=???Profondità smusso quando P05=1 +61475=???Riduzione profondità tenone +61476=???Riduzione larghezza tenone +61477=???Riduzione altezza tenone +61478=???Riduzione profondità tenone +61479=???Ridurre/Allargare sagoma tenone +61480=???Ridurre/Allargare altezza tenone +61481=???aumenta profondità mortasa +61483=???Profondità di lavoro +61484=???Aumenta dimensioni P10 +61485=???0=Automatico; 1=Truciolatore +61486=???Riduzione lunghezza P14 +61487=???Riduzione larghezza P15 +61488=???Sovramateriale finitura +61489=???Numero divisioni ondulazioni dello smusso sulla lunghezza +61490=???1=Disabilita fresatura gradini +61491=???1=Attiva smusso superiore +61492=???1=Smusso superiore con lama +61493=???Spessore legno per supporto lavorazione +61494=???Attiva antischeggia +61495=???Profondità antischeggia +61496=???Massima elevazione (0=Automatico, >10=Manuale) +61497=???0=Automatico; 1=Lama +61498=???0=Automatico; 1=Disabilita controllo lunghezza fresa +61499=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61500=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61501=???0=Automatico 1=Lavorazione con fresa orizzontale se sopra o sotto (disabilita lama) +61502=???0=Automatico 1=Usa truciolatore se sotto +61503=???0=Attacco e uscita centrati 1=Attacco e uscita interni +61504=???0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +61505=???0=Automatico; 1=Lavora come Taglio Longitudinale +61506=???0=Automatico; 1=Lavorazione con fresa +// ----- EgtBEAMWALL - BTLParam ----- +61601=???SN +61602=???Abilita +61603=???Descrizione +61604=L +61605=W +61606=H +61607=???Material +61608=???Richiesti +61609=???In produzione +61610=???Prodotti +61611=???Ruotare +61612=???Group +61613=???Unit Time +61614=???Parametro +61615=???Valore +61616=???Minimo +61617=???Massimo +61618=???Single member number +61619=???Assembly number +61620=???Order number +61621=???Designation +61622=???Annotation +61623=???Subgroup/Storey +61624=???Group +61625=???Package +61626=???Material +61627=???Timber grade +61628=???Quality grade +61629=???Count +61630=???Colour +61631=???Transparency +61632=???Planing length +61633=???Start offset +61634=???End offset +61635=???Transformation: Origin +61636=???Transformation: X-axis dir. vect. +61637=???Transformation: Y-axis dir. vect. +61638=???Camber: Reference side +61639=???Camber: P01,P02,P03,P04 +61640=???Part offset: ref. side fix clamp +61641=???Part offset: P11,P12,P13,P14 +61642=???Processing quality +61643=???Recess +61644=???Storey type +61645=???Element number +61646=???Layer +61647=???Module number +61648=???USERATTRIBUTE +61649=???Comment +61650=???Grain direction: X,Y,Z +61651=???Grain direction: Align +61652=???Reference side +61653=???Reference side: Align +61654=???Alignment: Location +61655=???Alignment: Endtype +61656=???Material type: Group +61657=???Material type: Specification +61658=???AUTOMATIC +61659=???VISIBLE +61660=???FAST +61661=???MANUAL +61662=???CEILING +61663=???ROOF +61664=???WALL +61665=???inactiv +61666=???BR +61667=???TR +61668=???BA +61669=???TA +61670=???HC +61671=???VC +61672=???AC +61673=???R +61674=???A +61675=???D +61676=???Batten +61677=???Cladding +61678=???Massive timber +61679=???Membrane +61680=???Gypsum Board +61681=???Gypsum Fibre +61682=???Insulation +61683=???Sheet Component +61684=???Facade Panel +61685=???Profiled Panel +61686=???Plaster +61687=???Reference side 1 +61688=???Reference side 2 +61689=???Reference side 3 +61690=???Reference side 4 +61691=???UID +61692=???Project number +61693=???Project name +61694=???Project part +61695=???GUID +61696=???Listname +61697=???Customer +61698=???Architect +61699=???Editor name +61700=???Delivery date +61701=???Export date +61702=???Export time +61703=???Export release +61704=???Language +61705=???Range +61706=???Computername +61707=???User name +61708=???Path & name of CAD-File +61709=???Path & name of BTL-File +61710=???STANDARD +61711=???EXTENDED +61712=???Vol unit +61713=???Vol tot +61714=???Time unit +61715=???Time tot +61716=???Total parts number +61717=???Total volume +61718=???Total time +61719=???Total estimed time +61720=???Remaining time +61721=???Rawpart counter +61722=???BTL part counter +61723=???Added part counter +61724=???Part in rawpart counter +61725=???Done part counter +61726=???Quantity +61727=???Print PDF +//Ware???house +61751=???Current S +61752=???Current L +61753=???StartOffset +61754=???Kerf +61755=???Offset +61756=???S Parameters +61757=???L Parameters +61758=???New Value: +61759=???W +61760=???L +61761=???Confirm +61762=???Save +61763=???Cancel +61764=???Error +61765=???Input value already present +61766=???Input value not correct +61767=???Input pair already present +61768=???One or more input values not correct +61769=???Attention +61770=???Selected parameter is equivalent to current L/S. Are you sure you want to remove it? +61771=???SectionXMaterial +61772=???Alias +61773=???Values +61774=???Quantity +61775=???Min thickness +61776=???Max thickness +61777=???Increment Max thickness of the last range before adding a new range +// +61801=???Custom +61802=???Default +61803=???L +61804=???T +61805=???Process +61806=???Section time +61807=???Part time +61808=???Name +61809=???PDN +61810=???DO +61811=???X position +61812=???Y position +61813=???Added +61814=???Done +61815=???ID +61816=???Start offset +61817=???% Used +61818=???Waste +61819=???BTL File Name +61820=???List Name +61821=???Export Date +61822=???Creation Date +61823=???Delete +61824=???Face +61825=???Group +61826=???Modify +61827=???Save +61828=???Cancel +61829=???Nesting +61830=???Viewer +61831=???Optimizer +61832=???Configuration +61833=???Optimize +61834=???Update BTL +61835=???Go to optimization +61836=???Filter type +61837=???Search +61838=???Export project +61839=???Import project +61840=???Import BTL +61841=???Copy to Clipboard +61842=???DisplayIndex +61843=???Column name +61844=???CanUserReorder +61845=???CanUserResize +61846=???CanUserSort +61847=???IsReadOnly +61848=???Visible +61849=???Variable Path +61850=???Type +// +61851=???This part modification will cause the removal of the part from {0} raw parts. Do you want to proceed anyway? +61852=???Impossible create feature with this values +61853=???Impossible create part with this values +61854=???Impossible create bar with this values +61855=???Impossible create wall with this values +61856=???Value outside minimum and maximum +61857=???Impossible to insert a quantity inferior to the number of parts already in rawparts! +61858=???Impossible to modify these values +61859=???Error in machine parameter writing +61860=???Save machine parameters modification? +61861=???Save default values modification? +61862=???Changing type second path will be deleted. Do you want to proceed? +61863=???To produce part number reached: +61864=??? from BTL; +61865=??? added. Do you want to add another one? +61866=???Selected part has different section from selected bar. Impossible to add. +61867=???Selected part lenght is more then the selected bar lenght. Impossible to add. +61868=???Selected part has different height from selected wall. Impossibl to add. +61869=???Error in macro file execution! +61870=???Impossible create a Macro without selecting a Feature or with empty name +61871=???File not found! +61872=???Impossibie deleting current project +61873=???Impossibile deleting the project because already linked to an optimization +61874=???Impossibile deleting the project because some parts are already sent to production +61875=???Do you want to save the project modifications? +61876=???Impossible creating a new file! +61877=???Save project modification before continuing? +61878=???Impossible proceding with a new unsaved project! +61879=???Type of current machine is both Beam and Wall. Select the type you want to set the project to: +61880=???Select one of the available machines and/or types. Otherwise cancel the project import. +61881=???The opened project type is not compatible with the current machine type +61882=???Do you want to save the modifications to the DataGrid columns? +61883=???The columnn specified as "{0}" in the "{1}" table in the datagrid columns ini file was not found in the program +61884=???Select the machine you want to associate to the project: +61885=???The machine linked to the opening project cannot be found among the available machines +61886=???Machine +61887=???Impossible creating the inserted rawparts quantity +61888=???How many copies of the rawpart do you want to create? +61889=???Long Drill Area +61890=???Min Rule +61891=???Can't send feedback from Optimizer if there is no open Prod +61892=???Can't proceed with an unsaved project! Please save before updating it. +// +61900=???Change paramter +61901=???Verify +61902=???Simulate +61903=???New raw part +61904=???Add to raw part +61905=???Copy part +61906=???Add part +61907=???Remove part +61908=???Copy feature +61909=???Create macro +61910=???Add feature +61911=???Remove feature +61912=???Produce rawpart +61913=???Produce all rawpart +61914=???Copy rawpart +61915=???Remove rawpart +61916=???Reorder parts +61917=???Move up part +61918=???Move down part +61919=???Remove part +61920=???Warehouse +61921=???Add project to optimization +61922=???Go to project +61923=???Statistics +61924=???Reset +61925=???Show all parts +61926=???Show solid +61927=???Show building +61928=???Verify all +61929=???Can't change machine because the Proj is already linked to a Prod +61930=???Inputs +61931=???Outputs +61932=???Calculate Flip & Rotation +61933=???Unlock Flip +61934=???Unlock Rotation +61935=???Length +61936=???Width +61937=???Offset +61938=???Kerf +61939=???Edit +61940=???Reset +61941=???Choose machine +61942=???BTL file already imported and optimized. Do you want to import it again? +61943=???BTL file already imported. Do you want to overwrite it? +61944=???Shift parts +61945=???Shift direction +61946=???Shift length +61947=???Parts can't be shifted outside the raw part +61948=???The inserted shift value is not valid +61949=???Search & Filter +61950=???Parameter Type +61951=???Parameter Value +61952=???R +61953=???A +61954=???P +61955=???D +61956=???All +61957=???Filtered +61958=???Update +61959=???Append +61960=???Check the parts you would like to add to update BTL +61961=???Change material +61962=???Project material +61963=???Warehouse material +61964=???Standard +61965=???From BTL +61966=???Save +61967=???Do NOT save +61968=???Waiting for optimizer save +61969=???Cancel + +// +62500=???Supervisor +62501=???Channel +62502=???OPMode +62503=???Produce All +62504=???Done RawPart +62505=???Reset RawPart +62506=???Delete RawPart +62507=???Print Label +62508=???Done Part +62509=???Resume started processing? +// Loading +63000=???Project opening +63001=???Loading project geometries +63002=???Loading machining groups +63003=???Loading production data +63004=???Optimization opening +63005=???Loading parts +63006=???Loading graphics +63007=???Project saving +63008=???BTL file importing +63009=???Reading BTL file +63010=???Project exporting +63011=???Loading environment +63012=???Saving geometry +63013=???Saving data on Db +63014=???Modifying parameters +63015=???Part viewer opening +63016=???Adding export info +63017=???Exporting... +63018=???Project importing +63019=???Loading project +63020=???Creating imported project +63021=???Modifying materials +// ----- FromLua ----- +65001= +// ----- OmagCUT ----- +// General +90001=Travail en cours +90002=Coupes Directs +90003=Coupes Cad +90004=Cadres +90005=Machine +90006=Options +// WorkInProgress +90101= +// DirectCut +90201=Mouvement manuel +90202=Coupe unique +90203=Coupe multiple +90204=Coupe de quadrillage +90205=MTH +90206=Planage +90207=Test lame +90208=Palpage lame +90209=Copier gabarit +90210=Prendre P1 +90211=Prendre P2 +90212=Laser +90213=Enfoncement +90214=Longueur +90215=Direction +90216=Inclinaison +90217=Nombre +90218=Dimensions +90219=Nombre X +90220=Dimensions X +90221=Nombre Y +90222=Dimensions Y +90223=Coupes côté broche +90224=Lame +90225=Dessin +90226=Largeur +90227=Superposition +90228=Offset +90229=Bloquer l'axe C +90230=Usiner +90231=Polissage +90232=Épaisseur lame +90241=Palpage lame +90242=Palpage en cours... +90243=Palpage réussi +90244=Erreur en palpage lame +90245=Nouveau nome du gabarit +90246=Palpage interrompue par l'utilisateur +90250=Ligne +90251=Arc +90252=Effacer +90253=Fermer +90254=Sauvgarder +90255=???Test +90256=???Verifica posizione taglio +90257=???Verifica posizione in corso... +90258=???Single drill +// CadCut +90301=Simuler +90302=Usiner +90303=Nouv. +90304=Ouvrir +90305=Enreg. +90306=Enreg. sous +90307=Nouveau nom de fichier +90308=CSV +90309=Vein Match +90310=Export +90311=Outil +90312=Usinage +90313=Photographie pas réussie +90314=Erreur dans la création du programme CN +90315=Erreur dans la transmission du programme CN +90316=Non connecté à la machine +90317=Transmission du programme CN réussie +90318=Programme CN refusé par la machine +90319=Programme CN déjà transmis, à renvoyer ? +90320=Machine différente +90321=Réduction des usinage pour éviter les interférences +90322=Outils manquants : +90323=Photographie de fond réalisée +90324=Reconnaissance contour pas réussi +90325=Erreur lors de l'enregistrement des statistiques +90326=Confirmer le redémarrage de la phase {0} ? +90327=Insérées de nouvelles pièces ruinées +90328=Surface des pièces : +90329=À produire : +90330=Programme CN déjà transmis, nouvelle dalle ? +// NestPage +90331=Insérer Pièce +90332=Stationn. Pièce +90333=Supprimer Pièce +90334=Sélectionn. Tout +90335=Desél. Tout +90336=Reset +90337=Une ou plusieurs pièces avec épaisseur, matériau ou finition non compatible +90338=Rotation au-delà des limites +90339=Rotation impossible +90340=Imbrication automatique en cours +// SplitPage +90341=On/Off +90342=Tous On +90343=Tous Off +90344=Allong/Raccour +90345=Début All/Racc +90346=Fin All/Racc +90347=Début Centre/Ext +90348=Débuts Tous Ext +90349=Débuts Tous Centre +90350=Calcul automatique impossible +90351=Scie trop grand pour utiliser ventouse +90352=Fin Centre/Ext +90353=Fin Tous Ext +90354=Fin Tous Centre +90355=Tous Allong +90356=Tous Raccour +90357=Modif. +90358=Auto +90359=Restart +// MoveRawPart +90361=Enlever +90362=Pièce trop petite : déplacement impossible +90363=Poste sélectionné déjà occupé +90364=???Part too havy : can not be moved +90365=???Part beyond strokes : can not be moved +// SplitPage 2 +90371=Pause On/Off +90372=Pause +90373=Début Modif. +90374=Fin Modif. +90375=Elongation +90376=Inverser +// DrawPage +90381=Nombre de Pièces +90382=Dimensions +90383=Inclinations +90384=Marquer en haut +90385=Dessin paramétrique +90386=Sélectionner un contour +90387=Pas de côtés éditables +90388=Nombre +90389=Données Trf +90390=Code de la commande +90391=Description de la commande +90392=Code du matériel +90393=Code de la surface +90394=Épaisseur +90395=Sélectionner un ou plusieurs trous +90396=Code de la pièce +90397=Graver +90398=Données Csv +90399=Tous les usinages mis à jour +90400=???Filo Top +// Component +// Massimo 17 caratteri senza immagine e massimo 12 avec l'immagine +90401=Triangle +90402=Rectangle +90403=Trapeze +90404=Quadrilatère +90405=Pied d'oie +90406=Seuil +90407=Plat Cuisine +90408=Plat Toilette +90409=Autres +90410=Triangle2C +90411=Triangle3C +90412=Isocèle +90413=Rectangle +90414=Scalène +90415=Scalène +90416=4Côtés 1Ang +90417=3Côtés 2Ang +90418=3Côtés 2Diag +90419=4Côtés 1Diag +90420=4Côtés 3Diag +90421=4Côtés 3Ang +90422=4Côtés 3Ang +90423=Angle droit +90424=Angle droit avec chanfrein +90425=Angle aligné +90426=Angle aligné avec chanfrein +90427=Partie A +90428=Partie B +90429=Angle +90430=Angle avec chanfrein +90431=Ellipse +90432=Ovale +90433=Arc +90434=Arc LHF +90435=Arc LLH +90436=Arc LLF +90437=Rectangle arrondi +90438=En dôme +90439=Trou +90440=2 Trous +90441=3 Trous +90442=Arc RHa +90443=Polygone +90444=Trou d'en bas +90445=Dxf +90446=Creux +90447=Composants internes +90448=Ajouter +90449=Supprimer +90450=???Confirm +// Import +90451=User Layers +90452=User Regions +90453=Reset +90454=mm +90455=inch +90456=User curves fermées +90457=Inclination +90458=Goutte +90459=Angle +90460=Décalage +90461=Enfoncement +90462=Raccourcissement +90463=???DXF import +90464=???Drill bottom +90465=Nombre +90466=Décalage2 +90467=Commande +90468=Liste +90469=Nom +// Component 2 +90470=Gravures Creux +90471=Gravures +90472=TriangleCH +90473=TriangleRT +90474=TrapèzeRtA +90475=3Côtés 2Ang +90476=???Nuova soglia +// FastGrid +90480=Nom de la commande +90481=Nombre de dalles +90482=Dernière dalle +90483=Type de pièce +90484=Insérer pièces +90485=Confirmer la commande +// Open +90491=Fichier non valide +90492=Fichier avec interférences. Pour le charger, désactiver les coupes pleines. +// RawPart +90499=Blanc non défini +90500=Rotation +90501=Rectangle +90502=Par points +90503=Longueur +90504=Largeur +90505=Épaisseur +90506=Offset X +90507=Offset Y +90508=Kerf +90509=Matériel +90510=Région ruiné +90511=Nouveau +90512=Effacer +90513=Points +90514=Ajouter +90515=Supprimer +90516=Longueur maximale = +90517=Largeur maximale = +90518=Hauteurs négatives pas autorisés +90519=Décalage minimum X = +90520=Décalage minimum Y = +90521=Kerf minimum = +90522=Kerf maximale = +90523=Palper blanc +90524=Confirmer +90525=Palpage blanc +90526=Palpage en cours... +90527=Palpage réussi +90528=Erreur en palpage +90529=Du dessin +90530=Du laser +90531=Fermer +90532=Erreur en acquisition du point +90533=Contour +90534=Scie trop grand pour palpage +90535=Par photo +//ChooseMachining +90536=Choisir l'usinage avec lame +90537=Choisir le deuxième usinage +90538=Choisir le perçage +90539=Choisir le fraisage +90540=Aucun +90541=Perçage +90542=Fraisage +90543=Les deux +90544=Choix des usinages actuels +90545=Choisir le jet d'eau +90546=Jet d'eau +90547=Erreur dans la position ou les mesures du brut +90548=Décalage maximale X = +90549=Décalage maximale Y = +90550=???Scegliere la svuotatura +// Simulation +90551=Simulation achevé +90552=Surcourse +90553=Direction de l'outil inaccessible +90554=Erreur +90555=ERREUR +90556=Erreur dans la génération! +90557=Simulation +90558=Une seule étape +90559=???Play/Pause +90560=???Stop/Home +90561=Pause +90562=Simulation interrompue +90563=Vue machine +90564=???Home +90565=Temps +90566=Longueur +90567=Surface utile +90568=Utilisation +90569=Estimations +90570=Détails +// FrameCut +90601=Le long de X +90602=Le long de Y +90603=Enlever +90604=Dégrossissage +90605=Finition +90606=Finition latéral +90607=Miroir +90608=Espace supér. +90609=Espace latéral +90610=Racc. début +90611=Raccourcir fin +90612=Coupe unique +90613=Arc +90614=Guide +90615=Section +90616=Guide +90617=Rad +90618=Ang +90619=Attention: rayon inférieur à la largeur de la section +90620=Erreur : création du cadre pas réussie +90621=Espace X +90622=Espace Y +90623=Coté opposé +// Machine +90701=Msg_Fra.xpi +90705=Données de la machine +90706=Outils +90707=Usinages +90708=Machine +90709=???Statistiche +90715=Nouveau +90716=Nouveau +90717=Sauvegarder +90718=Effacer +//ToolsDb +//param +90719=Longueur du porte-outil +90720=Noyau +90721=Nome +90722=Position +90723=Tête +90724=Exit +90725=Rotation +90726=Normale +90727=Maximale +90728=Vitesse +90729=Avance +90730=Tête +90731=Entrée +90732=Sortie +90733=Eau +90734=Correcteur +90735=Surépaisseur +90736=Longitudinal +90737=Radial +90738=Puissance max. +90739=Vitesse min. +90740=Enfoncement maximal +90741=Longueur +90742=Diamètre +90743=Epaisseur +90744=Tranchant +90745=Notes +90746=Numéro matricule +90747=Code +90748=Fournisseur +90749=Fin du service +//tools families +90751=Lame +90752=Foret +90753=Fraise +90754=Meule +90755=Jet d'eau +90756=Meule polissage +//Tool Setup +90759=Position d'outil par défaut déjà occupée +//MachiningsDb +//param +90761=Nome +90762=Enfoncement +90763=Angle d'inclinaison +90764=Inverser +90765=Step +90766=Côté de travail +90767=Côté de la tête +90768=Position de départ +90769=Entrée +90770=Liaison +90771=Sortie +90772=Utiliser curbes +90773=Tolérance +90774=Pas d'enfoncemet +90775=Normal +90776=Pas d'enfoncemet +90777=Intérieur d'arcs +90778=Extérieur d'arcs +90779=Longueur de ralentissement +90780=Initial +90781=Final +90782=Enfoncement supplémentaire +90783=Position de retour +90784=Outil +90785=Epaisseur minimum +90786=Epaisseur maximum +90787=Pas +90788=Vers le bas +90789=De côté +90790=Vertical +//machinings families +90791=Coupe +90792=Perçage +90793=Fraisage +90794=Dégrossissage avec scie +90795=Finition avec scie +90796=Fraisage de poches +90797=Jet d'eau +//ComboBox Param +90801=No +90802=Interne +90803=Externe +90804=les deux +90821=Centre +90822=Gauche +90823=Droit +90824=Centré +90825=Interne +90826=Externe +90827=Etendu centré +90828=Etendu externe +90829=Etendu précédent +90830=Etendu suivant +90831=Etendu les deux +90832=Centrée +90833=Interne +90834=Externe +90835=Ignorer +90836=Approximatif +90837=Convex +90838=Zig Zag +90839=Une manière +90840=Avant et arrière +90841=Usiner +90842=Aucun +90843=Standard +90844=Ralentir +90845=Boucle +90846=???Linear +90847=???Tangent +90848=???Glide +90849=???Helix +90850=???As lead in +// param 2 +90861=De côté +90862=Penché +90863=Penché à l'arrière +90864=En avant +90865=À l'arrière +90866=Dernier arrière +90867=Angle vers l'avant +90868=Palpage +90869=Min dist. points +90870=Max dist. points +90871=Externe +90872=Interne +90873=Long. ralent. +90874=Ralentissment % +90875=Trou d'entrée +90876=Rayon +90877=Tours LP +90878=Tours HP +90879=Permettre +90880=Coins +// Barcode +90881=Code-barres +90882=Bloc +90883=Nombre +90884=Données de dalle +// param3 +90890=Dist. tang. +90891=Dist. perp. +90892=Dist. tang. +90893=Dist. perp. +90894=Entrée céramique +90895=Longueur +90896=Pas +90897=???Last cut +90898=???Side angle cuts +// Alarms +90900=Jet d'eau courant +90901=Lame courante +90902=Deuxième outil +90903=Foret courant +90904=Fraise courante +90905=Z sûr +90906=Sécur. coupes +90907=Sécur. angles +90908=Observer les coupes pleines +90909=Décal. trous +90910=Superp. trous +90911=Tolérance +90912=Liste erreurs CN +90913=Materiaux +90914=Ajouter +90915=Effacer +90916=Outils actuels +90917=Paramètres trous +90918=R min arcs ext. +90919=Paramètres machine +90920=Aucun +90921=Foret +90922=Fraise +90923=Les deux +90924=A max arcs int. +90925=Paramètres lame +90926=Un seul trou dans coin +90927=Coupes directs +90928=Home à la fin +90929=Paramètres fraisages +90930=Toujours sur les intérieurs +90931=Nesting +90932=Aligné +90933=Outillage +90934=Nouveau +90935=Supprimer +90936=Hauteur table supplémentaire +90937=Contour de Photo +90938=Fonde +90939=Seuil +90940=Tolérance +90941=Lavage +90942=Confirmer l'annulation du matériel sélectionné? +90943=Outillage par défaut +90944=Toujours dans les coins +90945=Sélectionner l'outil à palper +90946=Coupes Feed start/end +90947=Longueur +90948=Réduction% +90949=Diminution +90950=Palpage +//Machine +90951=Start +90952=Stop +90953=Reset +90954=Auto +90955=Single +90956=MDI +90957=Manual +90958=Home +90959=Download +90960=Upload +90961=Activate +90962=Delete +90963=MDI Confirm +90964=Modalité CN +90965=Commandes de la machine +90966=Caractères MDI +90967=Transfert programme pièce +90968=???Do you want to change table? +// Options +90981=Sélection du langage +90982=Le nouveau langage deviendra courant au prochain démarrage du programme +90983=Unité de mesure +90984=Rotation de la vue +90985=Angle d'inclinaison +90986=Une valeur +90987=Plus de valeurs +90988=Insertion directe des pièces +90989=Paramétrés et DXF +90990=CSV +90991=Fast grid +90992=Permetter la création de pièces standard +90993=???Colore testo +90994=???Slab Dxf +90995=???Slab Layer +90996=???Parts Layer +90997=???Scrap Layer +90998=???Std Thick +90999=???ColorToSideAng +91000=???Enable +91001=???Tolerance +91002=???Heel +91003=???Side Angle +91004=???Feedback +91005=???Themes +91006=???Engrave from color +91007=???Depth +91008=???Width +91009=???Start program +91010=???Select start mode +91011=???Recent project +91012=???Last opening +91013=???Last project +91014=???New project +91015=???Open folder +91016=???Show window +//Alarms2 +91051=Usinages +91052=Sciage +91053=Perçage +91054=Fraisage +91055=???DripSawing +91056=???DripDrilling +91057=Jet d'eau +91058=Paramètres jet d'eau +91059=Automatique +91060=Aligné et Guillotine +91061=Paramètres de gravure +91062=Avec fraise +91063=Profondeur +91064=Largeur +91065=Sortie prédécoupée +91066=Guillotine +91067=Insérer une pause +91068=Cadres +91069=Vidage +91070=???Scasso corrente +//Statistics +91071=???Produzione del giorno +91072=???Produzione della settimana +91073=???Progetto +91074=???Area Pezzi +91075=???Area Tagli +91076=???Giorno +91077=???Settimana +91078=???Reset +91079=???Area da Tagliare +//Lucidature +91089=???Offset +91090=Polissages +91091=Polissages +91092=Mouvement +91093=Nombre +91094=Entrée/Sortie +91095=Hauteur +91096=Liste d'outils +91097=Longueur +91098=↑ +91099=↓ +91100=Charge +//EgtMsgBox +91101=Sauvegarder le fichier actuel? +91102=Sauvegarder l'outil actuel? +91103=Sauvegarder l'usinage actuel? +91104=Nom déjà utilisé +91105=Il ya des interferences, des pièces seront en stationnement. Voulez continuer? +91106=Un fichier de ce nom existe déjà. Ecraser? +91107=CONNEXION AU CN +91108=Connexion en cours... +91109=Connexion pas réussie +91110=Connexion réussie +91111=Table à utiliser ? +91112=Supprimer aussi les pièces des listes CSV ? +91113=Pièce pas supprimés parce que libres +91114= ou d'autres listes Csv +91115=Erreur +91116=Option Ligne de production pas activé +91117=Erreur dans la copie des fichiers pour OmagVIEW +91118=Garder les pièces stationnés ? +91119=Erreur avec pièces ruinées +91120=???I caratteri \ / : * ? " < > | non sono permessi +91121=Voulez-vous vraiment supprimer les parties sélectionnées ? +91122=Alerte +91123=Table +91124=???Salvare la lucidatura corrente? +91125=???Salvare le modifiche correnti? +91126=???Export +91127=???Import +91128=???DB WaterJet +91129=???Origine da laser +91130=???Start program? +// CSV +91201=Ouvrir +91202=Insérer +91203=Nouveau +91204=Retirer +91205=Erreur d'enregistrement du fichier CSV, continuer de toute façon ? +91206=Erreur de lecture du fichier CSV +// OmagVIEW +91301=Toutes Bonnes +91302=Partie Bonne +91303=Partie Ruinée +91304=Imprimer Etiquette +91305=Confirmer +91306=Imprimer +// OmagOFFICE +// OptionPanel +91401=Brut +91402=Disposer +91403=Usiner +91404=Simuler +// MachiningDbWindow +91451=???Materiale +91452=???Spessore minimo +91453=???Spessore massimo +// Errori di stampa +91461=???Error connection printer +91462=???Error formatting data +91463=???Error during print +91464=???No selection +// TopCommandBar +91501=Vous devez enregistrer votre projet avant l'exportation +91502=Sélectionnez le répertoire export +91503=Erreur in export +91504=Export terminé avec succès +91505=Exporter à la machine +91506=Exporter DXF +// Rawpart +91551=Erreur pendant le chargement de la photo +91552=???Importa fotografia +// VeinMatching +91601=Export +91602=Afficher Info +91603=Modifier +91604=Vérifier +91605=Magnétique +91606=Pièce non sélectionnable dans cette situation +91607=Pièce non sélectionnable car appartenant à un groupe de travail non actuel : +91608=Empreinte des pièces DXF trop grande pour VeinMatching +// Generic +91651=???Ok +91652=???Annulla +91653=A° +91654=T +91655=Démarrer +91656=Finir +// ----- OmagPHOTO ----- +// General +92001=???Db non trovato! +92002=???Unable starting the program +// OptionPanel +92051=Enregistrer +92052=Ajouter +92053=Annuler +92054=Effacer +92055=???Sei sicuro di voler cancellare la lastra corrente? +92056=???Etichetta +92057=???Etichetta Freccia +92058=???Sfoglia +92059=???Stampa +92060=???Seleziona +// Slab +92071=Id +92072=Nom de l'image +92073=État +92074=Attaché à un projet +92075=Position en magazine +92076=Date +92101=Nom déjà utilisé +92102=Le nom est obligatoire +92103=L'image est obligatoire +// SearchPanel +92151=Rechercher +92152=Tolérance d'épaisseur +92153=Date de début +92154=Date de fin +92155=???Reset +//Messaggi +92200=???Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=???Avviso +92202=???Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=???Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=???Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// General +101001=Importer BTL +101002=Dessiner +101003=Positionner +101004=Options +// ImportPage +101101 +// DrawPage +101201=Mur +101202=Port +101203=Fenêtre +101204=Ajouter +101205=Annuler +101206=Appliquer +101207=Supprimer +101208=Espaceur +// PlacePage +101301=Générer +101302=Transmettre +101303=Positionnement mur +101304=Insérer +101305=Stationner +101306=Supprimer +101307=Epaisseur couches +101308=N. planches au sommet +101309=Insertion impossible +101310=Succès génération +101311=Erreur en génération +101312=Succès en exec transmission +101313=Erreur en exec transmission +101314=Transmission réussie +101315=Transmission pas réussie +101316=Portiques tous désactivé +101317=Fichier de Génération non trouvé +// OptionsPage +101401=Options machine +101402=Caractéristiques collage +101403=Extra brut en X +101404=Extra brut en Y +101405=Extra colle +101406=Caractéristiques bois +101407=Largeur planche +101408=N. planches dans un plane +101409=Activation portiques +101410=Portique colle +101411=Portique bois +101421=Options du logiciel +101422=Sélection du langage +101423=Le nouveau langage deviendra courant au prochain démarrage du programme +101424=Nombre de projets à sauvegarder +101425=Placer planches sur portes et fenêtres +101426=Avance ouverture colle +101427=Avance fermeture colle +// OpenPage +101501=Projet non valide +// ----- End ----- diff --git a/ProgramData/EgtBeamWall/Config/EgalTechIta.txt b/ProgramData/EgtBeamWall/Config/EgalTechIta.txt new file mode 100644 index 0000000..42a4ef3 --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/EgalTechIta.txt @@ -0,0 +1,3318 @@ +// File dei messaggi EgalTech Italiano 2022/05/02 +0=ITA +// File +1=File +3=Nuovo +5=Apri +6=Apri
File recenti (Shift) +7=Inserisci +9=Salva +11=Copia +13=Importa +15=Esporta +17=Esegui +19=File Recenti +20=Script Recenti +// Vista +101=Vista +103=Linee +105=Bordi +107=Solidi +109=ZoomAll +111=ZoomIn +113=ZoomOut +115=Sopra +117=Fronte +119=Destra +121=Dietro +123=Sinistra +125=Sotto +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Griglia +136=Imposta Vista perpendicolare alla Griglia corrente +137=DirCurve +139=Analisi +141=Distanza +// Griglia +201=Griglia +203=Sopra +205=Fronte +207=Destra +209=Dietro +211=Sinistra +213=Sotto +215=Vista +216=Imposta Griglia perpendicolare alla direzione di Vista +217=Elevaz +218=Imposta Elevazione della Griglia +219=Origine +220=Imposta Origine della Griglia +221=Ruota +222=Ruota Griglia
Ruota Griglia in 3d (Shift) +223=3 Punti +224=Imposta Griglia da 3 Punti +225=Perp +226=Imposta Griglia Perpendicolare a Oggetto +227=Oggetto +228=Imposta Griglia da Oggetto +// Disegna +301=Disegna +303=Punto +304=Punto
Vettore (Shift)
Riferimento (Ctrl) +305=Lin 2P +306=Linea : 2 Punti
Linea : 2 punti con Continuazione (Ctrl) +307=Lin PDL +308=Linea : Punto iniziale, Direzione, Lunghezza
Linea : Punto iniziale, Vettore direzione, Lunghezza (Shift) +309=Circ +310=Circonferenza : Centro, Punto
Circonferenza : Centro, Diametro (Shift) +311=Racc +312=Raccordo : Raggio
Smusso : Dist (Shift) +313=Arco CIF +314=Arco : Centro, Punto iniziale, Punto finale +315=Arco 3P +316=Arco : 3 Punti +317=Arc IDF +318=Arco : Punto iniziale, Direzione, Punto finale
Arco : Punto iniziale, Vettore direzione, Punto finale (Shift)
Arco : Punto iniziale, Direzione, Punto finale con Continuazione (Ctrl) +319=Rett 2P +320=Rettangolo : 2 Punti +321=Poligono +322=Poligono : Raggio o Apotema
Poligono : Lato con 2 Punti (Shift) +323=Testo +324=Testo
Testo Avanzato (Shift) +399=Continuazione : 'L' con linea, 'A' con arco +// Costruisci +401=Costruisci +403=Piano +404=Superficie : piano contornato da una o più curve
Regione piana (Shift) +405=Estrudi +406=Superficie : da estrusione di una o più curve +407=Ruota +408=Superficie : da rotazione di una curva +409=Avvita +410=Superficie : da rototraslazione di una curva +411=Rigata +412=Superficie : rigata tra 2 curve +413=Combina +414=Combina una o più Superfici +415=Inverti +416=Inverte l'esterno di una o più Superfici +417=Esplodi +418=Esplodi Superfici o Regioni Piane +419=Swept +420=Superficie : da spostamento di una curva lungo un'altra +// Modifica +501=Modifica +503=Cancella +504=Cancella gli Oggetti +505=Layer +506=Porta gli Oggetti nel Layer corrente +507=Colore +508=Cambia Colore
Rimuovi Colore specifico (Shift)
Cambia Trasparenza (Ctrl) +509=Inverti +510=Inverti Curva +511=Trim/Est +512=Taglia o Estendi Curva +513=Spezza +514=Spezza Curva
Dividi Curva in Parti (Shift) +515=Unisci +516=Unisci Curve
Unisci Curve creando una Copia (Shift)
Fondi Curve nella Composita (Ctrl) +517=Esplodi +518=Explodi Testi o Curve in Componenti +519=Spess +520=Imposta Spessore e direzione di Estrusione su una o più Curve +521=Inizio +522=Cambia Inizio di Curva Chiusa +// Trasforma +601=Trasforma +603=Muovi +604=Muovi uno o più Oggetti +605=Ruota +606=Ruota uno o più Oggetti
Ruota uno o più Oggetti in 3D (Shift) +607=Specch +608=Specchia uno o più Oggetti
Specchia uno o più Oggetti in 3D (Shift) +609=Scala +610=Scala uno o più Oggetti
Scala uno o più Oggetti in 3D (Shift) +611=Offset +612=Offset di una Curva +// Special +701=Special +703=Pezzi 2d +704=Inserisci Pezzi Piani da DXF o NGE +705=Compo +706=Inserisci Componenti Parametrici +// Scene : Menù Selezione Entità +1001=Seleziona Tutto +1003=Deseleziona Tutto +1005=Seleziona con Finestra +1007=Seleziona Pezzo +1009=Seleziona Layer +1011=Seleziona Percorso +1013=Seleziona Percorso Completo +1015=Seleziona Entità +1016=Seleziona Tutti i Visibili +// Scene : Menù Punto notevole +1101=Punto Sketch +1102=Punto Sketch +1103=Punto Griglia +1104=Punto Griglia +1105=Punto Finale +1106=Punto Finale +1107=Punto Medio +1108=Punto Medio +1109=Centro +1110=Centro +1111=Baricentro +1112=Baricentro +1113=Punto Vicino +1114=Punto Vicino +1115=Intersezione +1116=Intersezione +1117=Punto Tangente +1118=Punto Tang +1119=Punto Perpendicolare +1120=Punto Perp +1121=Punto a Minima Distanza +1122=Punto MinDist +1123=Escludi Superfici +// Scene : Menù Varie +1201=Disattiva Trascinamento +1203=Attiva Trascinamento +// Scene : Varie +1301=Dist= +// Controller +2001=Copia (V) +2002=Errore +2003=Allarme +2051=Il Punto deve essere diverso dal precedente +2052=I Punti devono essere non allineati +2053=Valori Nulli o Negativi non sono ammessi +2054=Valori Negativi o Due Valori Nulli non sono ammessi +2055=Almeno una Entità non è scalabile +2056=Distanza troppo grande +2057=Curva non piatta (nel suo piano) +// Controller : Disegna +2101= +// Controller : Costruisci +2201= +// Controller : Modifica +2301= +// Controller : Trasforma +2401=COPIA +2402=MUOVI +2403=Inserisci Punto Base +2404=Inserisci Punto Destinazione +2406=RUOTA +2407=Inserisci Centro +2408=Inserisci Punto Base +2409=Inserisci Angolo o Punto +2411=RUOTA 3D +2412=Inserisci Primo Punto Asse +2413=Inserisci Secondo Punto Asse +2414=Inserisci Punto Base +2415=Inserisci Angolo o Punto +2416=SPECCHIA +2417=Inserisci Primo Punto +2418=Inserisci Secondo Punto +2421=SPECCHIA 3D +2422=Inserisci Primo Punto +2423=Inserisci Secondo Punto +2424=Inserisci Terzo Punto +2426=SCALA +2427=Inserisci Centro +2428=Inserisci Coefficiente +2431=SCALA 3D +2432=Inserisci Centro +2433=Inserisci Coefficienti +2436=OFFSET +2437=Inserisci Distanza +2438=Raccordo +2439=Smusso +2440=Estendi +// ----- EgtCAM5 ----- +5001=DISEGNA +5002=LAVORA +5003=Db Utensili +5004=Db Lavorazioni +5005=Opzioni +5006=Db Ut. +5007=Db Lav. +5008=Opzioni Macchina +5009=Db Att. +5010=Db Attrezzaggio +5020=Tabelle Lavorazioni +//Top CommandBar +5101=Nuovo +5102=Apri
Apri File recenti (Tasto Destro) +5103=Salva +5104=Salva come +5105=Inserisci +5106=Importa +5107=Esporta +5108=Esegui Script
Esegui Script recenti (Tasto Destro) +5109=Opzioni +5110=Indirizzo mail di supporto non trovato. +5111=Salvare il progetto corrente prima di mandare il feedback? +5112=Mandare il feedback a {0} con allegata la cartella {1}. +5113=Feedback +5114=Mail di feedback pronta. +// Draw Panel +5150=Estrai Bordi Liberi di Superfici e Regioni Piane +5151=Unisci Superfici e Regioni Piane +5152=Sottrai Superfici e Regioni Piane
Taglia Superficie con Superficie Inversa (Shift) +5153=Interseca Superfici e Regioni Piane
Taglia Superficie con Superficie (Shift) +5154=Punti, Curve e Facce di Intersezione Tra Superfici +5155=Quota Lineare
Quota Allineata (Shift) +5156=Cerchio 3 Punti +5157=Estrai Bordi di Facce di Superfici e di Parti di Regioni Piane +5158=Estrai Faccia da Superficie +5159=Arco Capovolto
Arco Esplementare (Shift) +5160=Modifica forma +5161=Aggiungi Punto
Trasforma in Arco (Shift)
Chiudi Curva Composita (Ctrl) +5162=Rimuovi Punto
Trasforma in Retta (Shift)
Apri Curva Composita (Ctrl) +5163=Approssima Curva
Approssima Curva con Linee (Shift) +5201=Punto
Vettore (Shift)
Riferimento (Ctrl) +5202=Linea 2 Punti
Linea 2 Punti con Continuazione (Ctrl) +5203=Linea Punto Direzione Lunghezza
Linea Punto Vettore Direzione Lunghezza (Shift) +5204=Cerchio Centro Punto +5205=Cerchio Centro Diametro +5206=Arco Centro Punti Inizio e Fine +5207=Arco 3 Punti +5208=Arco Punto e Direzione Inizio Punto Fine
Arco Punto e Vettore Direzione Inizio Punto Fine (Shift)
Arco Punto e Direzione Inizio Punto Fine con Continuazione (Ctrl) +5209=Raccordo +5210=Smusso +5211=Rettangolo 2 Punti +5212=Poligono +5213=Poligono da Lato +5214=Testo
Testo Avanzato (Shift) +5215=Piano contornato
Regione piana (Shift) +5216=Estrusione +5217=Rivoluzione +5218=Avvitamento +5219=Rigata +5220=Unisci Superfici +5221=Esplodi Superfici e Regioni Piane +5222=Inverti Superfici e Regioni Piane +5223=Cancella +5224=Cambia Layer
Cambia Layer con Trasformazioni (Shift) +5225=Cambia Trasparenza +5226=Annulla Colore +5227=Cambia Colore +5228=Inverti Curva +5229=Cambia Punto Iniziale di Curva Chiusa +5230=Estendi o Accorcia Curva +5231=Spezza Curva +5232=Dividi Curva +5233=Unisci Curve
Unisci Curve creando una Copia (Shift)
Fondi Curve nella Composita (Ctrl) +5234=Esplodi Curve e Testi +5235=Spessore e Estrusione Curva +5236=Muovi +5237=Ruota +5238=Ruota 3D +5239=Specchia +5240=Specchia 3D +5241=Scala +5242=Scala 3D +5243=Offset +5244=Disegno 2D +5245=Disegno 3D +5246=Modifica +5247=Trasforma +5248=Swept (Sezione, Guida) +5249=Modifica Testo +// Grid View Panel +5251=Wireframe +5252=Linee Nascoste +5253=Ombreggiatura +5254=Zoom All +5255=Zoom In +5256=Zoom Out +5257=Vista da Sopra +5258=Vista di Fronte +5259=Vista da Sinistra +5260=Vista da Dietro +5261=Vista da Destra +5262=Vista Isometrica da SW +5263=Vista Isometrica da SE +5264=Vista Isometrica da NE +5265=Vista Isometrica da NW +5266=Mostra Direzione Curve +5267=Analizza +5268=Distanza +5269=Griglia da Sopra +5270=Griglia di Fronte +5271=Griglia da Destra +5272=Griglia da Dietro +5273=Griglia da Sinistra +5274=Griglia da Sotto +5275=Griglia da Vista +5276=Elevazione Griglia +5277=Origine Griglia +5278=Ruota Griglia
Ruota Griglia in 3d (Shift) +5279=Griglia da 3 Punti +5280=Griglia Perpendicolare a Curva +5281=Griglia da Oggetto +5282=Vista da Griglia +5283=Zoom Selezione +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=END +5302=Extra corsa +5303=Direzione utensile irraggiungibile +5304=Errore +5305=ERRORE +5306=Errore in generazione! +5307=Simulazione +5308=Un passo alla volta +5309=Play/Pausa +5310=Stop/Home +5311=PAUSA +5312=STOP +5313=Impossibile uscire ora. Prima fermare la simulazione o aspettarne la fine! +5314=HOME +5315=AVVERTIMENTO +5316=Virtual Milling +5317=Errore nel calcolo delle stime! +5318=File delle stime non trovato +5319=Collisione! +5320=INFORMAZIONE +5330=GENERA +5331=Il progetto deve essere salvato prima della generazione CN. Vuoi farlo ? +5332=Generato con successo +5333=La licenza non permette la Generazione CN +5340=Stime +5341=Tempo totale +5342=Lunghezza totale +5343=Dettagli +5344=Stime dettagliate +// Draw Option +5351=Proprietà +5352=Nuovo Pezzo +5353=Nuovo Layer +5354=Colore +5355=Parametri di disegno +5356=Seleziona +5357=Deseleziona +5358=Nome +5359=Info +5360=Sposta +5361=Copia +5362=Elimina +5363=Salva +5364=Mostra +5365=Conferma +5366=Conferma Cancellazione +5367=Pezzo in lavorazione, vuoi cancellarlo lo stesso ? +// Operation +5401=Operazioni +5402=Parametri Operazione +5403=Applica Lavorazione +5404=Nuova Lav +5405=Nuova Disp +5406=Cancella +5407=Generici +5408=Sposta su +5409=Sposta giù +5410=Aggiorna +5411=Aggiornamento completato con successo +5412=Nuove Lavorazioni +5413=Anteprima Utensile +5414=Avanti +5415=Indietro +5416=Duplica +5417=Copia nel Db +5418=Nome lavorazione nel Db +5419=Inserimento lavorazione non riuscito +5420=Rinomina +5421=Il nome non può iniziare con "Disp" +5422=Nome già utilizzato +5423=La lavorazione non può essere applicata per i seguenti motivi: +// Disposition +5431=Ok +5432= +5433=Nuovo +5434=Rimuovi +5435=Lunghezza +5436=Larghezza +5437=Altezza +5438=Posizione +// Mach & Disposition Errors +5461=ERRORE DI ESECUZIONE SCRIPT +5462=Errore nella esecuzione dello script automatico di disposizione +5463=Errore nella esecuzione dello script di inizio lavorazioni +5464=Errore nella esecuzione dello script di fine lavorazioni +// Mach Group +5501=Sicuro di voler pulire il Gruppo di Lavorazione? +5502=Sicuro di voler cancellare il Gruppo di Lavorazione? +5551=Non ci sono Gruppi di Lavorazione :
selezionare i pezzi da inserire e
ripetere il comando per creare il primo +5552=Vuoi creare un nuovo Gruppo di Lavoro
con i pezzi selezionati ? +// Tools Db Page +6001=Punta +6002=Lama +6003=Fresa +6004=Mortasatrice +6005=Composito +6006=Punta lunga +6007=Lama piatta +6008=Fresa senza punta +6009=Scalpello +6010=WaterJet +6051=Correttore +6052=Uscita +6053=Tipo +6054=Refrigerante +6055=Raggio Corner +6056=Diametro +6057=Diametro Totale +6058=Avanzamento +6059=Avanzamento Finale +6060=Avanzamento Iniziale +6061=Avanzamento di Punta +6062=Lunghezza +6063=Lunghezza totale +6064=Massimo Materiale +6065=Offset Longitudinale +6066=Offset Radiale +6067=Rotazione +6068=Angolo di Lato +6069=Rotazione Massima +6070=Spessore +6071=Assorbimento Massimo +6072=Avanzamento Minimo +6073=Disegno +6074=Testa +6075=Nome +6076=Note +6077=Posiz. Cambio Utensile +6078=Posizione +6079=Distanza +6080=Sovratavola +// Tools Errors +6100=Salvare l'utensile modificato ? +6101=SALVA +6102=Il file deve essere .nge +6103=Il file non esiste o non è di tipo Nge +6104=Non esiste il ToolMaker per questo tipo di utensile +6105=Impossibile creare l'utensile con questi parametri +6106=Il Massimo Materiale deve essere maggiore di 0 +6107=Il Massimo Materiale deve essere minore di Lung +6108=Lo Spessore deve essere maggiore di 0 +6109=Il Diametro deve essere maggiore di 0 +6110=La Lunghezza deve essere maggiore di 0 +6111=La Rotazione deve essere minore della Rotazione Massima +6112=Nome non valido +6113=La Lunghezza deve essere minore della Lunghezza Totale +6114=La Lunghezza deve essere maggiore del Massimo Materiale +6115=La Lunghezza Totale deve essere maggiore di 0 +6116=La Lunghezza Totale deve essere maggiore della Lunghezza +6117=Il Massimo Materiale deve essere minore di 1/3 del Diametro +6118=Il Diametro deve essere minore del Diametro Totale +6119=Il Diametro deve essere maggiore di 3 volte il Massimo Materiale +6120=Il Diametro Totale deve essere maggiore di 0 +6121=Lunghezza troppo piccola con il portautensile +6122=Sei sicuro di voler cancellare l'utensile +6123=? +6124=CANCELLA +6125=File di configurazione attrezzaggio non trovato! +6126=Errore +6127=Impostare il tipo di testa. +6128=Impostare il tipo di uscita. +6129=Utensile non valido, correggerlo o cancellarlo prima di uscire dal Db Utensili. +6130=Impossibile ricaricare il database utensili. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +6131=Lo Spessore deve essere differente da 0 +6132=L'Angolo di Lato deve essere minore di 90 +6133=L'Angolo di Lato deve essere maggiore di -90 +6134=La Lunghezza Totale deve essere maggiore di Lunghezza + Spessore +6135=Raggio Corner ha un valore troppo grande +6136=Lo Spessore ha un valore troppo piccolo rispetto al Raggio Corner +6137=Il diametro risultante supera il Diametro Totale +6138=Il diametro risultante è minore di 0 +6139=Il diametro stelo risultante è minore o uguale a 0 +6140=Massimo Materiale deve essere maggiore del Raggio Corner +6141=Massimo Materiale risultante deve essere >= 0 +6142=Raggio Corner non deve superare metà Spessore +6143=Salvataggio utensile +6144=Utensile modificato! Tutti gli utensili devono essere salvati prima di cambiare le attivazioni. Salvare l'utensile {0}? +6145=Posizione già occupata! +6146=Posizione non definita! +// Machinings Db Page +6201=Foratura +6202=Taglio di lama +6203=Fresatura +6204=Svuotatura +6205=Mortasatura +6206=Sgrossatura con lama +6207=Finitura con lama +6208=Lav. generica +6209=Scalpellatura +6210=Sgrossatura superfici +6211=Finitura superfici +6212=WaterJet +6251=Inverti +6252=Tab +6253=Tipo +6254=Lato di lavoro +6255=Lato della testa +6256=Attacco +6257=Collegamento +6258=Uscita +6259=Uso curve +6260=Tipo di Step +6261=Sottotipo +6262=Tipo approccio +6263=Rotazione +6264=Feed +6265=Feed iniziale +6266=Feed finale +6267=Feed di testa +6268=Offset radiale +6269=Offset longitudinale +6270=Affondamento +6271=Angolo di fianco +6272=Approssimazione +6273=Dist. di sicurezza +6274=Lungh. rallent. iniziale +6275=Lungh. rallent. finale +6276=Lungh. passante agg. +6277=Passo +6278=Posizione di ritorno +6279=Lunghezza +6280=Distanza +6281=Altezza +6282=Angolo +6283=Dist. tangente attacco +6284=Dist. perp. attacco +6285=Elevazione attacco +6286=Lungh. correz. attacco +6287=Dist. tangente di uscita +6288=Dist. perp. di uscita +6289=Elevazione di uscita +6290=Lungh. correz. di uscita +6291=Lungh. addiz. attacco +6292=Lungh. addiz. di uscita +6293=Passo su esterno arco +6294=Passo su interno arco +6295=Passo di lato +6296=Feed verticale +6297=Nome +6298=Utensile +6299=Affondamento +6300=Note +6301=Sovrapposizione +6302=Offset +6303=Sottotipo +6304=SCC +6305=Nessuno +6306=Standard +6307=Opposto +6308=AuxDir Destra +6309=AuxDir Sinistra +6310=AuxDir Dietro +6311=AuxDir Davanti +6312=AuxDir Sopra +6313=AuxDir Sotto +6314=Più Vicino AuxDir +6315=Più Lontano AuxDir +6320=Centro +6321=Sinistra +6322=Destra +6323=Estendi +6324=Standard +6325=Interno +6326=Esterno +6327=Esteso centrato +6328=Esteso esterno +6329=Nessuno +6330=Lineare +6331=Tangente +6332=Inseguimento +6333=Elica +6334=Estendi precedente +6335=Estendi successivo +6336=Estendi entrambi +6337=Come attacco +6338=Salta +6339=Approssima +6340=Convesso +6341=Mantieni +6342=ZigZag +6343=Una via +6344=Spirale +6345=Va e torna +6346=Longitudinale +6347=Trasversale +6348=Spirale In +6349=Spirale Out +6350=Avanzati +6351=Inverti direz. utensile +6352=Lavorazione faccia +6353=Non definito +6354= Parallelo +6355= Ortogonale +6356= Ortog. Su +6357=Sotto +6358=Sopra +6359=Davanti +6360=Dietro +6361=Sinistra +6362=Destra +6363=Contorno +6364=Angoli Suggeriti +6365=Asse Bloccato +6366=N° massimo +6367=N° minimo +// Machining errors +6370=Salvare la lavorazione modificata? +6371=SALVA +6372=Nome non valido +6373=I caratteri \ / : * ? " < > | non sono permessi +6374=Sei sicuro di voler cancellare +6375=? +6376=CANCELLA +6377=Impossibile ricaricare database lavorazioni. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +6378=Oscillazione +6379=Ampiezza di oscill. +6380=Lungh. rampa di oscill. +6381=Lungh. cresta di oscill. +// Machining Option Page +6401=Z di sicurezza +6402=Spezzatura archi +6403=Mai +6404=Piano generico +6405=Piano diverso da XY +6406=Sempre +6407=Attrezzaggio predefinito +6408=Sicurezza rinvio da sotto +6409=Tolleranza fori +// SetUp Window +6451=SetUp +6452=Applica +6453=Salva +6454=Recupera +6455=Auto +6456=Applicare l'attrezzaggio corrente prima di uscire? +6457=Nuovo +// SetUp Errors +6471=Errore +6472=Avviso +6473=Impossibile trovare l'utensile +6474=nel DB utensili. +6475=La posizione predefinita dell'utensile non è valida. +6476=La posizione predefinita dell'utensile è già occupata. +6477=Il file di configurazione non esiste! +6478=L'attrezzaggio usa una testa che non esiste sulla macchina! +6479=Errore nel caricamento del setup +// Option Page +6501=Lingua corrente +6502=La nuova lingua diventerà corrente dal prossimo avvio del programma. +6503=Curve +6504=Superfici +6505=Curve e Superfici +6506=Geometria selezionabile +6507=Aggiungi la nuova lavorazione alla fine +6508=Usa script di disposizione +6509=Unità di misura +6510=Colore della vista in alto +6511=Colore della vista in basso +6512=Colore di default +6513=Tolleranza geometrica +6514=Generale +6515=CAD +6516=CAM +6517=Colore della griglia +6518=Superfici smussate +6519=Import +6520=DXF +6521=STL +6522=Immagini +6523=Export +6524=Immagine +6525=Larghezza (pixel) +6526=Altezza (pixel) +6527=Aggiorna Macchina +6528=La macchina "{0}" esiste già,
cosa vuoi fare ? +6529=Il file {0} non contiene una macchina. +6530=La macchina "{0}" è stata aggiornata con successo. +6531=Sostituisci +6532=Aggiorna +6533=Annulla +6534=Avviso +6535=L'aggiornamento della macchina "{0}" non è riuscito. +6536=Linee spesse +6537=Lunghezza extra del riferimento +6538=Lunghezza della freccia +6539=Distanza del testo +6540=Unità di misura +6541=Decimali +6542=Font +6543=Altezza del testo +6544=Quotatura +6545=Unità corrente +6546=Altra +6547=Unità di misura +6548=Fattore di scala +6549=Esporta Macchina Corrente +6550=Seleziona la cartella in cui si desidera esportare la Macchina +6551=L'esportazione della macchina "{0}" non è riuscita. +6552=La macchina "{0}" è stata esportata con successo. +6553=Aggiorna Licenza +// Heads +6601=Verticale +6602=Orizzontale +6603=Aggr. 2 uscite +6604=Aggr. 3 uscite +6605=Aggr. 4 uscite +6606=Testa 3 assi +6607=Testa 4 assi +6608=Testa 5 assi +6609=Navetta 1 +6610=Navetta 2 +6611=Multi rotante +6612=Gr. a forare +6613=Multi scalp. +6614=Rinvio sotto +6615=Lama 5 assi +6616=Sega a catena +6617=Aggr. 1 uscite +6618=Testa tastatura +6619=Flottante 360° +6620=Seconda Testa 5 assi +6621=Foratore orizzontale +6622=Mortasatrice +6623=Seconda Lama 5 assi +6624=Aggr. 1 uscita tilt. +6625=Estrusore +6799= +// StatusBar +6801=Direttorio Machines non trovato. EgtCAM5 funzionerà in modo solo CAD. +// Doors +8001=Crea nuova MTable +8002=Salva MTable +8003=Salva MTable Come +8004=Elimina MTable +8005=Salva file MTable +8006=Sei sicuro di voler cancellare questa MTable? +8007=Salva la MTable modificata? +8008=Lista delle macchine attive +8009=Nome della macchina +8010=Genera Cn +8011=Aggiorna grezzo +8012=On +8013=Nome Geometria +8014=Operazione +8015=MId +8016=Spost. +8017=Tipo Lavorazione +8018=Lavorazione 1 +8019=Lavorazione 2 +8020=Lavorazione 3 +8021=Aggiungi Macchina +8022=Elimina Macchina +8023=Aggiungi Lavorazione +8024=Elimina Lavorazione +8025=CORR +8026=Imposta MTable corrente +8027=GId +8028=Proprietà +8029=Lavorazione +8030=Unisci +// Door errors +8101=Errore +8102=Errore nell'esecuzione del file Ddf +8103=Avvertimento +8104=Path della cartella MTable non trovata +8105=La cartella MTable non esiste +8106=Mancano i file di configurazione nella cartella MTable +8107=Errore sconosciuto +8108=Questa è la MTable correntemente attiva. +8109=Non può essere cancellata. +8110=Sei sicuro di voler cancellare la lavorazione selezionata? +8111=CANCELLA +8112=Sei sicuro di voler cancellare la macchina selezionata? +8113=Impossibile trovare la cartella delle macchine {0}. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +8114=Provare a ricaricare la macchina? +8115=Impossibile trovare la cartella {0}. Se la cartella Doors è su un server, verificare che la connessione sia attiva. +8116=Provare a ricaricare la cartella Doors? +8117=Errore di esecuzione (guarda il file di log) +// GunStock +8201=Nuovo pezzo +8202=Gunstock Nuovo Pezzo +8203=Mod pezzo +8204=Gunstock Modifica Pezzo +8205=Parametri calcio +8206=Nome file +8207=Descrizione +8208=Ok +8209=Cancella +8210=deve avere un valore. +8211=Il valore deve essere compreso tra +8212=e +8213=Dimensioni del grezzo +// GunStock errors +8251=Errore +8252=Errore nel lancio dell'ambiente Gunstock +8253=Errore nella lettura del file Modello +8254=Errore nella scrittura del file Pezzo +// ----- Beams & Wall ----- +9000=Tabelle delle lavorazioni delle travi +9001=On +9002=Nome +9003=Tipo +9004=Aggiungi +9005=Elimina +9006=Salva +9007=Salvare le modifiche apportate? +9008=Errore +9009=Impossibile aprire l'Editor delle lavorazioni delle travi.
Mancano i file di configurazione. +9010=Tabelle delle lavorazioni delle pareti +9011=Impossibile aprire l'Editor delle lavorazioni delle pareti.
Mancano i file di configurazione. +// ----- Errori ----- +10001=Errore +10002=Errore nella creazione di un nuovo file +10003=Errore nell'apertura del file +10004=Errore nel salvataggio del file +10005=Tipo di file sconosciuto +10006=Errore nell'importazione del file +10007=Errore nell'esportazione del file +10008=Errore caricando o creando il Gruppo di Lavoro +10009=Non esiste il file +// Missing Key Window +10101=Errore ! +10102=Chiave non presente. +10103=Inserirla e riavviare il programma. +10104=Ok +10105=Programma senza licenza. +10106=Caricala e riavvia il programma. +10107=Esegui GetMachineId e invia i risultati al fornitore. +// Numeric virtual keyboard +10201=Espressione errata +// ----- MessageBox ----- +15001=Errore +15002=Avviso +15003=Informazione +15010=Errore interno (guarda log file) +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Espressione errata +// EgtCalculatorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Canc +20043=SI +20044=NO +// ----- EgtWPFLib5 ----- +// EgtSaveFileDialog +30001=Salva +30002=Annulla +30003=esiste già. +30004=Sostituirlo? +30005=Nome file: +30006=Apri +30007=ERRORE +30008=Il nome non può essere vuoto! +30009=ATTENZIONE +30010=Nome File +30011=Nome Cartella +// Top CommandBar +30501=Nuovo +30502=Apri +30503=Salva +30504=Salva come +30505=Inserisci +30506=Importa +30507=Esporta +30508=Esegui +30509=Opzioni +30510=Indirizzo mail di supporto non trovato. +30511=Salvare il progetto corrente prima di mandare il feedback? +30512=Mandare il feedback a {0} con allegata la cartella {1}. +30513=Feedback +30514=Mail di feedback pronta. +// Grid View Panel +30801=Wireframe +30802=Linee Nascoste +30803=Ombreggiatura +30804=Zoom All +30805=Zoom In +30806=Zoom Out +30807=Vista da Sopra +30808=Vista di Fronte +30809=Vista da Sinistra +30810=Vista da Dietro +30811=Vista da Destra +30812=Vista Isometrica da SW +30813=Vista Isometrica da SE +30814=Vista Isometrica da NE +30815=Vista Isometrica da NW +30816=Mostra Direzione Curve +30817=Analizza +30818=Distanza +30819=Griglia da Sopra +30820=Griglia di Fronte +30821=Griglia da Destra +30822=Griglia da Dietro +30823=Griglia da Sinistra +30824=Griglia da Sotto +30825=Griglia da Vista +30826=Elevazione Griglia +30827=Origine Griglia +30828=Ruota Griglia +30829=Griglia da 3 Punti +30830=Griglia Perpendicolare a Curva +30831=Griglia da Oggetto +30832=Vista da Griglia +// MachGroupPanel +30901=Nuovo gruppo di lavorazione +30902=Nome: +30903=Macchina: +// ToolDbWindow +31001=Punta +31002=Lama +31003=Fresa +31004=Mortasatrice +31005=Composito +31006=Punta lunga +31007=Lama piatta +31008=Fresa senza punta +31009=Scalpello +31010=Waterjet +31051=Correttore +31052=Uscita +31053=Tipo +31054=Refrigerante +31055=Raggio Corner +31056=Diametro +31057=Diametro Totale +31058=Avanzamento +31059=Avanzamento Finale +31060=Avanzamento Iniziale +31061=Avanzamento di Punta +31062=Lunghezza +31063=Lunghezza totale +31064=Massimo Materiale +31065=Offset Longitudinale +31066=Offset Radiale +31067=Rotazione +31068=Angolo di Lato +31069=Rotazione Massima +31070=Spessore +31071=Assorbimento Massimo +31072=Avanzamento Minimo +31073=Disegno +31074=Testa +31075=Nome +31076=Note +31077=Posiz. Cambio Utensile +31078=Posizione +31079=Foratura +31080=Tagliente +// ToolDb Errors +31100=Salvare l'utensile modificato ? +31101=SALVA +31102=Il file deve essere .nge +31103=Il file non esiste o non è di tipo Nge +31104=Non esiste il ToolMaker per questo tipo di utensile +31105=Impossibile creare l'utensile con questi parametri +31106=Il Massimo Materiale deve essere maggiore di 0 +31107=Il Massimo Materiale deve essere minore di Len +31108=Lo Spessore deve essere maggiore di 0 +31109=Il Diametro deve essere >= 0 +31110=La Lunghezza deve essere maggiore di 0 +31111=La Rotazione deve essere minore della Rotazione Massima +31112=Nome non valido +31113=La Lunghezza deve essere minore della Lunghezza Totale +31114=La Lunghezza deve essere maggiore del Massimo Materiale +31115=La Lunghezza Totale deve essere maggiore di 0 +31116=La Lunghezza Totale deve essere maggiore della Lunghezza +31117=Il Massimo Materiale deve essere minore di {0} +31118=Il Diametro deve essere minore del Diametro Totale +31119=Il Diametro deve essere maggiore di 8/3 del Massimo Materiale +31120=Il Diametro Totale deve essere maggiore di 0 +31121=Lunghezza troppo piccola con il portautensile +31122=Sei sicuro di voler cancellare l'utensile +31123=? +31124=CANCELLA +31125=File di configurazione attrezzaggio non trovato! +31126=Errore +31127=Impostare il tipo di testa. +31128=Impostare il tipo di uscita. +31129=Utensile non valido, correggerlo o cancellarlo prima di uscire dal Db Utensili. +31130=Impossibile ricaricare il database utensili. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +31131=Lo Spessore deve essere differente da 0 +31132=L'Angolo di Lato deve essere minore di 90° +31133=L'Angolo di Lato deve essere maggiore di -90° +31134=La Lunghezza Totale deve essere maggiore di Lunghezza + Spessore +31135=Raggio Corner ha un valore troppo grande +31136=Lo Spessore ha un valore troppo piccolo rispetto al Raggio Corner +31137=Il Diametro risultante supera il Diametro Totale +31138=Il Diametro risultante è minore di 0 +31139=Il Diametro stelo risultante è minore o uguale a 0 +31140=Il Massimo Materiale deve essere più grande del Raggio Corner +31141=Il Massimo Materiale risultante deve essere >= 0 +31142=Il Tagliente deve essere maggiore di 0 +31143=Il Tagliente deve essere minore di Len +// ImportExportToolWindow +31161=Importa +31162=Esporta +31163=Utensili +31164=L'utensile esiste già, sovrascriverlo? +31165=L'utensile verrà importato col nome seguito da "_imp" +31166=I seguenti Utensili sono stati importati correttamente: +31167=Reset +// MachiningDbWindow +31201=Foratura +31202=Taglio di lama +31203=Fresatura +31204=Svuotatura +31205=Mortasatura +31206=Sgrossatura con lama +31207=Finitura con lama +31208=Lav. generica +31209=Scalpellatura +31210=Waterjetting +31211=Finitura superfici +31251=Inverti +31252=Tab +31253=Tipo +31254=Lato di lavoro +31255=Lato della testa +31256=Attacco +31257=Collegamento +31258=Uscita +31259=Uso curve +31260=Tipo di Step +31261=Sottotipo +31262=Tipo approccio +31263=Rotazione +31264=Avanzamento +31265=Avanzamento iniziale +31266=Avanzamento finale +31267=Avanzamento di testa +31268=Offset radiale +31269=Offset longitudinale +31270=Affondamento +31271=Angolo di fianco +31272=Approssimazione +31273=Dist. di sicurezza +31274=Lungh. rallent. iniziale +31275=Lungh. rallent. finale +31276=Lungh. passante agg. +31277=Passo +31278=Posizione di ritorno +31279=Lunghezza +31280=Altezza +31281=Angolo +31282=Distanza +31283=Dist. tangente +31284=Dist. perp. +31285=Elevazione +31286=Lungh. correz. +31287=N° minimo +31288=N° massimo +31291=Lungh. addiz. +31293=Passo su esterno arco +31294=Passo su interno arco +31295=Passo di lato +31296=Feed verticale +31297=Nome +31298=Utensile +31299=Affondamento +31300=Note +31301=Sovrapposizione +31302=Offset +31303=Sottotipo +31304=SCC +31305=Nessuno +31306=Standard +31307=Opposto +31308=AuxDir Destra +31309=AuxDir Sinistra +31310=AuxDir Dietro +31311=AuxDir Davanti +31312=AuxDir Sopra +31313=AuxDir Sotto +31314=Più Vicino AuxDir +31315=Più Lontano AuxDir +31320=Centro +31321=Sinistra +31322=Destra +31323=Estendi +31324=Standard +31325=Interno +31326=Esterno +31327=Esteso centrato +31328=Esteso esterno +31329=Nessuno +31330=Lineare +31331=Tangente +31332=Inseguimento +31333=Elica +31334=Estendi precedente +31335=Estendi successivo +31336=Estendi entrambi +31337=Come attacco +31338=Salta +31339=Approssima +31340=Convesso +31341=Mantieni +31342=ZigZag +31343=Una via +31344=Spirale +31345=Va e torna +31346=Longitudinale +31347=Trasversale +31348=Spirale In +31349=Spirale Out +31350=Avanzati +31351=Inverti direz. utensile +31352=Lavorazione faccia +31353=Non definito +31354= Parallelo +31355= Ortogonale +31356= Ortog. Su +31357=Sotto +31358=Sopra +31359=Davanti +31360=Dietro +31361=Sinistra +31362=Destra +31363=Contorno +31364=Angoli Suggeriti +31365=Asse Bloccato +31366=Feed ultimo all'indietro +31367=Passo all'indietro +31368=Passo inclinato +31369=Passo all'indietro inclinato +31370=Inclinazione in avanti +31371=Tastatura +31372=Min dist. punti +31373=Max dist. punti +31374=Esterni +31375=Interni +31376=Lungh. rall. +31377=Rallentam. % +31378=Foro di attacco +31379=Raggio +31380=Num. giri in LP +31381=Num. giri in HP +31382=Oscillazione +31383=Ampiezza +31384=Lungh. rampa +31385=Lungh. cresta +31386=Generici +31387=Avanzati +31388=Tang+Perp +31389=Perp+Tang +// MachiningTreeView +31391=Normale +31392=Rallenta +31393=Anello +31394=Abilitazione +31395=Allunga +31396=Inizio +31397=Fine +31398=Note di sistema +31399=Raggio epicicli +31400=Distanza epicicli +// MachiningDb Errors +31401=Salvare la lavorazione modificata? +31402=SALVA +31403=Nome non valido +31404=I caratteri \ / : * ? " < > | non sono permessi +31405=Sei sicuro di voler cancellare +31406=? +31407=CANCELLA +31408=Impossibile ricaricare database lavorazioni. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +31409=Materiale della macchina non riconosciuto +31410=Lavorazione non valida, correggerla o cancellarla prima di uscire. +31411=La Lunghezza deve essere positiva +31412=La Distanza deve essere positiva +31413=L'Altezza deve essere positiva +31414=L'Angolo deve essere compreso tra {0}° e {1}° +31415=N° massimo deve essere nullo o positivo +31416=N° massimo deve essere maggiore o uguale al minimo +31417=N° minimo deve essere nullo o positivo +31418=N° minimo deve essere minore o uguale al massimo +31419=L'abilitazione di {0} disabiliterà {1}. Procedere? +// ImportExportMachiningWindow +31450=Importa +31451=Esporta +31452=Lavorazioni +31453=La lavorazione esiste già, sovrascriverla? +31454=La lavorazione verrà importata col nome seguito da "_imp" +31455=Le seguenti Lavorazioni sono state importate correttamente: +31456=Reset +// SetUp Window +31501=SetUp +31502=Applica +31503=Archivia +31504=Recupera +31505=Auto +31506=Applicare l'attrezzaggio corrente prima di uscire? +// SetUp Errors +31551=Errore +31552=Avviso +31553=Impossibile trovare l'utensile +31554=nel DB utensili. +31555=La posizione predefinita dell'utensile non è valida. +31556=La posizione predefinita dell'utensile è già occupata. +31557=Il file di configurazione non esiste! +31558=L'attrezzaggio usa una testa che non esiste sulla macchina! +31559=Errore nel caricamento del setup +// Simulation +31601=Simulazione completata +31602=Extra corsa +31603=Direzione utensile irrangiungibile +31604=Errore +31605=ERRORE +31606=Errore in generazione! +31607=Simulazione +31608=Un passo alla volta +31609=Play/Pausa +31610=Stop/Home +31611=Pausa +31612=Simulazione interrotta +31613=Impossibile uscire ora. Prima fermare la simulazione o aspettarne la fine! +31614=ATTENZIONE +31615=File delle stime non trovato +31616=Stime dettagliate +//MachiningDbWindow/ToolDbWindow/WaterjetDbWindow buttons +31701=Nuovo +31702=Salva +31703=Rimuovi +31704=Modifica +//Db Waterjet +31751=Db Waterjet +31752=Spessore +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=Salvare le modifiche? +// ----- EgtDOORCreator ----- +//General +50001=Larghezza +50002=Altezza +50003=Spessore +50004=???Swing +50005=Lato-serratura +50006=Lato-cerniera +50007=???Top +50008=Fondo +50009=Tipo +50010=Angolo +50011=???Extension +50012=Lato +50013=???Offset wide side +50014=Margine +50015=???Top to center application +50016=Traverso basso +50017=???Lock stile +50018=???Offset from center +50019=???Point to pocket +50020=???Pocket length +50021=???Pocket offset narrow side +50022=???Point to arm +50023=???Arm length +50024=???CenterHung +50025=Traslato +50026=Intermedio traslato +50027=Raggio +50028=Traverso alto +50029=Posizione +50030=Lunghezza +50031=Modello +50032=???Up +50033=???Down +50034=???Shape +50035=Cerniera +50036=???Top to top application +50037=???Center from top application +50038=???Center from top lock +50039=Profondità +50040=Generale +50041=Centro +50042=???Thru +50043=???Face to center line application +50044=Tipo di spigolo +50045=Sovramateriale +50046=Invia Feedback +50047=Peso +50048=???Angle +50049=???Face +50050=???Secure +50051=???Keyway +50052=???Brand +50053=???Folder +50054=???Main Folder +50055=???Jamb +50056=???Light Up +50057=???Light Lock +50058=???Light Bottom +50059=???Light Hinge +50060=???Thickness Head +50061=???Overlap Hinge +50062=???Overlap Lock +50063=???Overlap Top +50064=???Delta T +50065=???Exterior +50066=???Number of Doors +50067=???Jambs and Doors +50068=Ordine +50069=Disposizione +50070=Cliente +50071=Inverti profilo serratura +//Compo Name +50072=Catenacci +50073=Maniglia di superficie +50074=Cerniera +50075=Serratura +50076=Passaggio animali +50077=Buca delle lettere +50078=Ferramenta lato superiore +50079=Cerniera perno +50080=Fermo rullo +50081=???Stops And Closer +50082=Piastrina di battuta +50083=Maniglia incassata tirare +50084=Spioncino +50085=Sfinestratura +50086=Gole +50087=Ribassi +50088=???Ept +50089=???Raceway +50090=Decorazioni +//error messages +50100=Direttorio non trovato +50101=Errore +50102=Fallita lettura del file ddf. Manca un parametro fondamentale {0}. +50103=Fallita lettura valore. +50104=Fallita lettura nella riga del file ddf +50105=Riga +50106=Valore non accettabile in +50107=File vuoto. +50108=Impossibile aggiunegere la componente. Inserire una porta! +50109=Vuoi salvare questo file ({0}) ? +50110=Domanda +50111=Aggiungi nuova porta +50112=Rimuovi porta +50113=Nuova Porta +50114=Il nome del file già esiste nel direttorio corrente ({0}). +50115=Attenzione +50116=Vuoi cancellare questo file ({0}.ddf) ? +50117=Confermi la cancellazione ({0}.ddf) ? +50118=Informazione +50119=Errore nella lettura dei messaggi. Non esiste corrispondenza con il numero {0}. +50120=Errore nella lettura del nome {0} in {1}. Attesa una corrispondenza numerica. +50121=Errore nella lettura {0} nel parametro {1} della componente: non esiste. +50122=Errore nel parametro {0} della componente {1} della componente. +50123=Errore nella lettura {0} nel parametro {1} della componente: non esiste la lista. +50124=Errore nella lettura {0} nel parametro {1} della componente: {2}. +50125=Errore nel parametro {0} della componente {1} della componente: non esiste il valore. +50126=Elimina +50127=Errore in EgtLoadMessages +50128=Impossibile salvare un file se non esiste una porta! +50129=Errore nella creazione della scena. +50130=Errore nella lettura della riga {0}. +50131=Errore in lettura {0}: riga {1}. Atteso ':' dopo il nome. +50132=Errore in lettura {0}: riga {1}. Atteso 'template' o 'shape'. +50133={0} non è stato creato. +50134=Errore nella lettura di 'Template' nel file {0}\{1}. Atteso nome. +50135=Errore nella lettura di 'Template' nel file {0}\{1}. File {0}\{2} .lua non esiste. +50136=Errore nella lettura {0}: riga {1}. Non esite la componente nel file 'Default.ini'. +50137=Errore nella lettura {0}: riga {1}. Non è un memebro della lista. +50138=Questo parametro sarà inizializzato di default. +50139=Errore in lettura: riga {0}. Atteso {1}. +50140=Tutti i parametri mancanti saranno inizializzati di default. +50141=Espressione non valida in {0}. +50142=Rimuovi componente +50143=Espressione non valida +50144=Avvertenza +50145=Impossibile creare la porta corrente. +50146=Vuoi aprire un modello? +50147=Errore nell'espressione {0}. {1} non associa nulla. +50148=Valore non valido. +50149=Attenzione: il peso è selezionato nella pagine delle impostazioni. Vuoi disabilitarlo? +50150=Attenzione: il peso è un parametro del file .ddf. Vuoi aggiungerlo alle impostazioni? +50151={0} Non appartiene alla lista degli spigoli. Seleziona il Bevel nella pagina delle impostazioni. +50152=Vuoi salvare questo file ({0})? +50153=Attenzioni: il peso è un parametro della porta corrente. Vuoi rimuoverlo dalla porta? +50154=Questo bevel è selezionato nella porta corrente. Vuoi procedere? +50155=Impossibile creare un modello se non esite una porta! +50156=???Errore nella lettura ddf: la porta non è completa o il ddf è stato separato male da '---'. +50157=???Script Lua ( {0}\{1} )has not been found. +50158=???Bevel {0} can not be acceptable in Jamb. +50159=??? Missing parameter in ddf! +50160=Il file {0} nel direttorio {1} non esite. +50161=???parameter +50162=???In file {0} param 'Default' must be numeric. +50163=???Error in reading General Assembly in DDF +50164=???In General Assembly: +50165=???CompoDir not found : +50166=???Jamb compo does not exist +50167=???Empty Line +50168=???No matching param +50169=???Door disposition has been modify. +50170=???Incongruity between the bevel, it has been resolved by default. +50171=???In file StdTempate.ini is missing numeric param in [Type]. +50172=???File does not exist. +50173=???Definition type is not correct: +50174=???Missing name of the new template! +50175=???The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=???Error in copying: {0} +50177=???Do you want to save the current changes? +50179=Il file Default.ini non esiste nella cartella {0} . +50180=Attenzione : {0} non esiste. +50181=Errore nella stampa dell'immagine. +50182=Errore nell'esecuzione della stampa +50183=Alcune porte potrebbero usare questa ferramenta, confermi l'eliminazione? +50184=???Impossible to delete Hardware if there is no Hardware selected! +50185=???Impossible to duplicate Hardware if there is no Hardware selected! +50186=Il progetto deve essere salvato prima di essere copiato. +50187=Vuoi copiare tutti i files ? {0} (No: per copiare solo il file corrente) +50188=Esporta in macchina +50189=Direttorio macchina non trovato +50190=Errore durante la copia: {0} +50191=Non c'è alcuna porta, impossibile copiare +50192=Non c'è alcuna porta, impossibile esportare verso la macchina +50193=Non c'è alcuna porta, impossibile stampare +50194=Le proprietà sono state cancellate +50195=La configurazione del ddf corrente ({0}) è differente dalla configurazione del programma ({1}).{2}Per caricare la configurazione del ddf corrente devi rilanciare il programma, vuoi farlo? +50196=La configurazione del ddf ({0}) non esiste! +50197=Porta ad arco modificata perchè la configurazioe non la pravede. +50198=Il profilo sul lato serratura dovrebbe essere invertito. +//Option +50200=Unità di misura +50201=Generale +50202=???LockEdgeOverMaterial +50203=???HingeEdgeOverMaterial +50204=???TopOverMaterial +50205=???BottomOverMaterial +50206=Apri finestra +50207=Ultimo progetto +50208=Vuoto +50209=Pagina delle opzioni +50210=Avvio programma +50211=Unità di misura nuova porta. +50212=???Directory Project +50213=Impostazione di avvio +50214=???Current Directory +50215=???Edge Type +50216=???Over Material +50217=???Browse +50218=Chiudi +50219=???Bevel +50220=???Bevel Up +50221=???Bevel Down +50222=Posizionamento porta in lavorazione. +50223=Salva come modello +50224=Associazione +50225=Marca +50226=Modello +50227=???Template +50228=???Enable template +50229=???Enable Order +50230=???Open template door. +50231=???Open window order. +50232=Direttorio modelli +//Scene +50301=Aggiorna +50302=Aggiungi Nuova Porta +50303=Rimuovi Porta +50304=Nuovo Progetto +50305=???Help +50306=Direttorio Macchina +50307=Macchina +50308=Anta +50309=???Wide Side Down (BU) +50310=???Wide Side Up (BD) +50311=???Resize +50312=???Design +50313=Salva come pdf +//Launcher +50400=???Launcher +50401=Apri Nuovo Progetto +50402=Apri Progetto +50403=Apri Ultimo Progetto +50404=Nuovo Progetto +50405=Nuova Ferramenta +50406=???Elevation +50407=???Project +50408=???PO +50409=???Line +50410=Salva +50411=Stampa +50412=Annulla +50413=Ferramenta +50414=???Dimensioning +50415=Duplica +50416=Esporta in macchina +50417=???New Template +50418=???Dimension +50419=Nuovo Direttorio +50420=Ricalcola posizione Hardware +50421=Aggiorna +50422=Salva come +50423=Ricarica componente +//Error (continue) +50501=Errore nella lettura del parametro {0 nel componente {1} : definizione incompleta (controlla StdTemplate.ini). +50502=Errore nella lettura del parametro {0 nel componente {1} : nessuna associazione (controlla StdTemplate.ini e GeometryNameList.ini). +50503=Vuoi salvare? +50504=Il nome del file contiene spazi vuoti agli estremi, vuoi eliminarli ? +50505=Il DDF non è un assemblato, le parti resenti sono: {0}, vuoi salvare? +50506=Impossibile trovare la prima anta! +50507=???The swing is not a member of the swing list of single door. +50508=???The swing of left door is not a member of the swing list of left door. +50509=???The swing of right door is not a member of the swing list of right door. +50510=???The swing of left door is on the right door and viceverse. +50511=???The swing of left door is not a member of the swing list of left door. +50512=???The swing of right door is not a member of the swing list of right door. +50513=???Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=???The swing are absolutly wrong! +50515=???The first door is not realy the first, check the ddf. +50516=???The current ddf contains {0} jambs. +50517=???The current ddf does not contains doors! +50518=???The current ddf is not an assembly. +50519=???Impossible to open a ddf with no doors. +50520=???The current ddf is an assembly. +50521=Il ddf corrente è un pezzo del telaio: {0}. +50522=???The profile {0} is not a member of the {1} profile list. +50523=Manca il profile sul lato {0}. +50524={0} file aperto da un altro EgtDOORCreator {1}. +50525={0} file in lettura da un altro EgtDOORCreator {1}. +50526=Il direttorio {0} già esiste! Vuoi sovrascriverlo? +50527=Impossibile sovrascrivere {0} +50528=Impossibile salvare il file fuori dal progetto corrente! +50530=La proprietà {0} non esiste nella lista {1}. Verificare nel file "../Compo/Default.ini". +50531=Il materiale corrente {0} non esiste nella lista dei materiali. Verificare nel file "../Compo/Default.ini". +50532=Lista dei materiali non trovata "../Compo/Default.ini". +50533=Impossible caricare più di una proprietà alla volta. +50534=La proprietà {0} non esiste. Verificre nel file "../Compo/Default.ini". +50535=Impossibile eliminare u progetto se non è selezionato! +50536=Vuoi eliminare il progetto? (Tutte le porte saranno eliminate!) +50537=Vuoi eliminare il sottodirettorio {0} ? (Tutte le porte saranno eliminate!) +50538=Impossibile creare un modello senza avere un porta in lettura! +50539=Vuoi cambiare progetto? +50540=???The current ddf is a part of a frame, do you want to save? +50541=???{0} in reading {1}. +50542=???{0}: Directory does not exist! +50543=Il file è stato rinominato: {0} {1}. +50544=Nuovo file: {0} {1}. +50545=Il file è stato eliminato: {0} {1}. +50546=Abilita porta singola +50547=Progetto +50548=La nuova configurazione sarà attiva dal prossimo riavvio. +50549=Il file {0} esiste, ma non è nel direttorio corretto! +50550=Ogni compenente verrà ricalcolata, vuoi continuare? +50551=Questo parametro è stato modificato: +50552=Vuoi sovrascireve? +50553= non è stato creato. +50554=Il parametro {0} è già stato definito nella geometria {1} +50555=Impossibile salvare. +50556=Il file ha estensione nge. +50557=Errore in fase di cancellazione file: {0} +50558=Impossibile importare una ferramenta differente. +50559=Apertura file +50560=La ferramenta non è stata generata correttamente. +50561=Il direttorio è già esistente. +50562=Il direttorio {0} non esiste. Verificare nella pagina delle impostazioni. +50563=La componente non esiste. +50564=Nel gruppo {0} al parametro {1} non esiste: {2} +50565=il brand {0} non è stato trovato. +50566=il modello {0} non è stato trovato. +50567=Errore nell'avvio del programma EgtCam5. +50568=Errore nella definizione di {0} nel file GeometryNameList.ini . +50569=Errore nella definizione di {0} in file StdTemplate.ini . +50570=Nessun elemento selezionato +//Added General messages +50701=Linee +50702=Rettangoli +50703=Nessuna +50704=Raggio +50705=Angolo +50706=Pos_x +50707=Top ad Arco +50708=Top ad Angolo +50709=Proprietà +50710=Materiali +50711=???Mach. +50712=???HardwarePart +50713=Assemblato +50714=Dimensioni totali +50715=Profondità +50716=Sovrapposizione fondo +50717=Spessore fondo +50718=Profondità fondo +50719=Delta fondo +50720=VaiAssemblato +50721=Nuova geometria +50722=Nome geometria +50723=Tipo di ferramenta +50724=Parametro +50725=Dimensione parte +50726=Applica +50727=Telaio +50728=Aggiorna direttori +50729=???General +50730=???Report +50731=Faccia opposta +// ----- EgtBEAMEditor ------ +60951=Taglio +60952=Taglio Longitudinale +60953=Doppio Taglio +60954=Cantonale o Conversa +60955=Taglio con lama +60956=Scanalatura +60957=Scanalatura frontale +60958=Tacca +60959=Tacca cantonale +60960=Mezzolegno di colmo +60961=Mezzolegno +60962=Scanalatura o Battuta +60963=Mezzolegno chalet +60964=Rivestimento +60965=Mezzolegno colmo francese +60966=Smusso +60967=Mezzolegno chalet +60968=Mezzolegno chalet frontale +60969=Tasca +60970=Foratura +60971=Tenone +60972=Mortasa +60973=Mortasa frontale +60974=Avanzamento +60975=Abbassamento +60976=Tenone a coda di rondine +60977=Mortasa a coda di rondine +60978=Mortasa frontale a coda di rondine +60979=Marcatura +60980=Testo +60981=Giunto Gerber +60982=Giunto a dardo di giove +60983=Incastro dietro +60984=Incastro semplice +60985=Piallatura +60986=Profilo di testa +60987=Profilo concavo +60988=Profilo convesso +60989=Profilo caudato +60990=Arco +60991=Testa sagomata +60992=Sfera +60993=Taglio a triangolo +60994=Incastro tirolese +60995=Incastro a coda di rondine +60996=Contorno libero +60997=Contorno +60998=Apertura +61001=Distanza dall'inizio della trave al punto di riferimento +61002=Distanza dal bordo di riferimento al punto di riferimento +61003=Distanza dal lato di riferimento al punto di riferimento (ortogonale) +61004=Angolo tra il bordo di taglio e il bordo di riferimento +61005=Inclinazione tra faccia e lato di riferimento +61008=Limite dei 2 estremi, codice binario +61009=Inclinazione rispetto al lato di riferimento +61010=Profondità +61011=Lunghezza +61012=Angolo in faccia all'inizio +61013=Angolo in faccia all'estremità +61015=Distanza dal punto di riferimento al bordo di riferimento +61016=Angolo tra il primo tagliente e il bordo di riferimento +61017=Inclinazione del primo taglio verso il lato di riferimento +61018=Angolo tra il secondo tagliente e il bordo di riferimento +61019=Inclinazione del secondo taglio verso il lato di riferimento +61023=Inclinazione tra la prima faccia e il lato di riferimento +61024=Inclinazione tra la seconda faccia e il lato di riferimento +61025=Profondità +61027=Angolo in faccia al bordo di riferimento all'inizio +61028=Angolo in faccia al bordo di riferimento all'estremità +61029=Angolo in faccia opposto al bordo di riferimento all'inizio +61030=Angolo in faccia opposto al bordo di riferimento all'estremità +61033=Spostamento sul lato di riferimento +61036=Angolo rispetto al bordo di riferimento nella faccia di taglio +61037=Profondità, ortogonale al lato di riferimento +61038=Lunghezza +61041=Distanza dal punto di riferimento ortogonale al lato di riferimento +61042=Limite delle 6 facce della fessura, codice binario +61043=Angolo rispetto al bordo di riferimento nel lato di riferimento +61045=Angolo interno al punto di riferimento +61046=Angolo interno opposto al punto di riferimento +61047=Aggiunta a P09 +61048=Profondità ortogonale al lato di riferimento +61049=Lunghezza +61050=Spessore +61051=Spostamento del bordo di ingresso nel punto di riferimento +61052=Spostamento del bordo di ingresso in corrispondenza del punto di riferimento +61055=Distanza dal punto di riferimento ortogonale al lato di riferimento +61056=Limite delle 6 facce della fessura frontale, codice binario +61059=Angolo tra l'asse longitudinale dell'asola e il lato di riferimento +61060=Profondità +61061=Lunghezza +61062=Larghezza +61065=Posizione di P09 / P10 +61066=P05 = 1: foro, P05 = 0: nessun foro +61067=Angolo rispetto al bordo di riferimento nell'area di riferimento +61068=Inclinazione tra faccia 1 e lato di riferimento +61069=Inclinazione tra faccia 2 e lato di riferimento +61070=Primo angolo di taglio della controparte +61071=Inclinazione primo taglio della controparte +61072=Profondità 1 ortogonale al lato di riferimento +61073=Profondità 2 ortogonale al lato di riferimento +61074=Profondità di scanalatura nella direzione trasversale del componente +61075=Altezza controparte +61076=Larghezza controparte +61079=P05 = 1: foro, P05 = 0: nessun foro +61080=Tacca angolo 1 rispetto al bordo di riferimento nell'area di riferimento +61081=Tacca angolo 2 rispetto al bordo di riferimento opposto nell'area di riferimento +61082=Inclinazione tra l'area di base delle tacche e il lato di riferimento +61083=Profondità ortogonale al lato di riferimento +61084=Larghezza della tacca 1 +61085=Larghezza della tacca 2 +61087=0: punto di riferimento sul bordo di riferimento. 1: punto di riferimento sul bordo opposto +61088=Angolo rispetto al bordo di riferimento nel lato di riferimento +61089=Profondità della tasca +61090=Larghezza della tasca +61091=Diametro del foro +61094=Spostamento rispetto al lato di riferimento +61095=Limite delle 6 facce dell tasca, codice binario +61096=Angolo rispetto al bordo di riferimento nel lato di riferimento +61098=Angolo tra bordo e lato di riferimento in faccia +61099=Angolo nella superficie del pavimento +61100=Angolo tra la faccia di base e una faccia della tasca +61101=Distanza (ortogonale) dal lato di riferimento al punto sotto il punto di riferimento +61102=Lunghezza +61103=Angolo di smusso +61104=Profondità di scanalatura +61107=Limite delle 6 facce della tacca / battuta, codice binario +61108=Profondità tacca / battuta +61109=Lunghezza tacca / battuta +61110=Larghezza tacca / battuta +61113=Profondità della tasca sul lato di riferimento +61114=Profondità della tasca opposta al lato di riferimento +61115=Lunghezza del mezzo legno / Dado +61117=Profondità di taglio +61118=Lunghezza del taglio +61120=0: punto di riferimento sul riferimento bordo; 1: punto di riferimento sul bordo opposto +61121=Angolo rispetto al bordo di riferimento nel lato di riferimento +61122=Diametro del foro +61124=Ingresso bordo (i) da smussare, codice binario: Bit 0 = bordo 1; Bit 1 = fronte 2; Bit 2 = bordo 3; Bit 3 = fronte 4. Esempio: P04 = 9: fronte 1 + 4; P04 = 3: bordo 1 + 2 +61125=Profondità +61126=Lunghezza +61127=Forma per uscita smusso: 0 = ortogonale, 1 = a 45 gradi, 2 = rotondo +61129=Profondità ortogonale al lato di riferimento della tasca 2 e 4 +61130=0: tutti i giri sono simmetrici tra loro; 1: sovrapposizione sul bordo di riferimento spostato alla trave iniziale, sovrapposizione in opposizione al bordo di riferimento spostata alla trave finale; 2: sovrapposizione sul bordo di riferimento spostata alla trave finale, sovrapposizione in opposizione al bordo di riferimento spostata alla trave iniziale; +61131=P05 = 1: foro, P05 = 0: nessun foro +61132=Tasca 1: profondità +61133=Tasca 1: lunghezza +61134=Tasca 2: profondità +61135=Tasca 2: lunghezza +61136=Tasca 3: Profondità +61137=Tasca 3: lunghezza +61138=Tasca 4: profondità +61139=Tasca 4: lunghezza +61140=Distanza dalla fine dell'arco ortogonale al lato di riferimento +61141=Raggio dell'arco +61142=Distanza dal punto di riferimento al centro dell'arco +61143=Quale arco (A, B, C o D) deve essere prodotto, codice binario +61145=0: un solo giro sul lato di riferimento; 1: un giro sul lato di riferimento e uno sul lato opposto +61146=Angolo rispetto al bordo di riferimento nel lato di riferimento +61147=Profondità al punto di riferimento +61148=Profondità opposta al punto di riferimento +61149=Profondità al bordo di riferimento +61150=Lunghezza +61153=Limite delle 6 facce della tasca, codice binario +61154=Angolo di rotazione attorno all'asse z locale del parallelepipedo +61155=Angolo di rotazione attorno all'asse y locale del parallelepipedo, ruotato con P06 +61156=Angolo di rotazione attorno all'asse x locale del parallelepipedo, ruotato con P06 e P07 +61157=Angolo interno nel punto di riferimento +61158=Profondità del punto di riferimento ortogonale al lato di riferimento +61159=Lunghezza del mezzo legno +61160=Larghezza del mezzo legno +61163=Distanza dalla faccia di riferimento al punto di riferimento +61164=P03 = 0: angolo rispetto al bordo di riferimento nel lato di riferimento +61165=Inclinazione tra foratura e lato di riferimento +61166=Profondità ortogonale al lato di riferimento o al lato anteriore. +61167=Diametro del foro +61170=Arrotondamento +61171=Smusso +61174=Angolo tra l'asse del tenone e il lato di riferimento +61175=Raggio per P04 = 4 +61176=Altezza tenone +61177=Larghezza tenone +61178=Margine sul lato di riferimento +61179=Margine opposto al lato di riferimento +61182=Spostamento rispetto al lato di riferimento +61183=Arrotondamento +61184=Angolo tra l'asse e il bordo di riferimento +61185=Inclinazione tra puntone e lato di riferimento +61186=Inclinazione delle pareti laterali del foro verso il lato di riferimento +61187=Raggio per P04 = 4 +61188=Profondità mortasa +61189=Larghezza mortasa +61190=Altezza del montante +61191=Margine sul punto di riferimento +61192=Margine opposto al punto di riferimento +61193=Inclinazione del lato anteriore del foro verso il lato di riferimento +61196=Arrotondamento +61199=Angolo tra l'asse del tenone e il lato di riferimento +61200=Raggio per P04 = 4 +61201=Profondità mortasa +61202=Larghezza mortasa +61203=Margine sul lato di riferimento +61204=Margine opposto al lato di riferimento +61205=Processident del tenone associato o del tenone a coda di rondine +61206=Processident della mortasa associata o mortasa a coda di rondine +61209=0: con arrotondamento in basso; 1: senza arrotondamento, illimitato +61210=Angolo tra bordo e bordo di riferimento +61212=Angolo tra l'asse del tenone e il lato di riferimento +61213=Appiattimento centrale +61214=Angolo del cono +61215=Altezza tenone +61216=Diametro della curva +61217=Margine sul lato di riferimento +61218=Margine opposto al lato di riferimento +61221=Spostamento rispetto al lato di riferimento +61222=0: con arrotondamento in basso; 1: senza arrotondamento, illimitato +61223=0: con allungamento; 1: con tasca +61224=Angolo tra l'asse e il bordo di riferimento +61225=Inclinazione tra puntone e lato di riferimento +61226=Appiattimento centrale +61227=Angolo del cono +61228=Profondità mortasa +61229=Diametro della curva +61230=Altezza del montante +61231=Margine sul punto di riferimento +61232=Margine opposto al punto di riferimento +61235=Spostamento sul lato anteriore +61236=0 = con arrotondamento in basso; 1 = senza arrotondamenti, illimitato +61237=0 = con allungamento; 1 = con tasca +61240=Angolo tra l'asse del tenone e il lato di riferimento +61241=Appiattimento centrale +61242=Angolo del cono +61243=Profondità mortasa +61244=Diametro della curva. Se P12 <0, il raggio deve essere definito sul lato macchina. +61245=Margine sul lato di riferimento +61246=Margine opposto al lato di riferimento +61249=Posizione e allineamento del testo +61250=Angolo tra l'asse e il bordo di riferimento +61251=Angolo interno +61252=Larghezza del quadrilatero +61253=Altezza del quadrilatero +61254=Altezza del testo +61255=Testo (stringa max.256 caratteri) +61258=Angolo tra l'asse e il bordo di riferimento +61259=Allineamento verticale. 0 = in basso, 1 = al centro, 2 = in alto +61260=Allineamento orizzontale. 0 = sinistra, 1 = centro, 2 = destra +61261=Allineamento in caso di testo su più righe. 0 = allineato a sinistra, 1 = centrato, 2 = allineato a destra. +61262=Lettere standard o orizzontali. 0 = standard, 1 = lettere posizionate orizzontalmente +61263=Altezza del testo. Se P13 è uguale a zero, la macchina determina l'altezza del testo. +61266=Profondità sul lato di riferimento +61267=Profondità opposta al lato di riferimento +61268=Lunghezza della sovrapposizione +61269=Foratura 1 diametro. P15 = 0: questa foratura è posta a 1/2 P13. P15> 0: questa foratura è posta a 1/3 P13 +61270=Foratura 2 diametri. Posizionato a 2/3 P13 +61272=Angolo di inclinazione della base della sciarpa lappata +61273=Forma o identificazione classica dell' incastro +61274=Lunghezza della base della sciarpa lappata +61275=Profondità della base della sciarpa lappata +61276=Profondità della base della sciarpa lappata ortogonale al lato di riferimento +61277=Lunghezza +61278=Foratura 1 diametro. P15 = 0: questa foratura è posta a 1/2 P13. P15> 0: questa foratura è posta a 1/3 P13 +61279=Foratura 2 diametri. Posizionato a 2/3 P13 +61281=Tipo di tacca del tallone: ​​0 = normale; 1 = rastremato +61282=Puntone inclinato +61283=Giunzione gradino di profondità +61284=Profondità del tallone +61285=Altezza tenone. Quale implementazione (A o B) viene utilizzata dipende dalla macchina +61286=Larghezza tenone +61289=Tipo di tacca del tallone: ​​0 = normale; 1 = rastremato +61290=Inclinazione tra puntone e lato di riferimento +61291=Larghezza della tacca +61292=Giunzione gradino di profondità +61293=Profondità del tallone +61294=Altezza del montante +61295=Profondità di mortasa. Quale implementazione (A o B) viene utilizzata dipende dalla macchina +61296=Larghezza della mortasa +61298=Specifica dei lati da piallare; codice binario +61299=Profondità di piallatura +61300=Lunghezza dell'area da piallare +61303=Angolo di rotazione della prima curva del profilo +61304=Angolo di rotazione del profilo verso il bordo di riferimento +61305=Angolo di offset +61306=Raggio della prima curva +61307=Raggio della seconda curva +61309=Raggio +61310=Profondità +61311=Spostamento +61312=Profondità +61313=Spostamento +61315=Raggio +61316=Profondità +61317=Spostamento +61318=Profondità +61319=Spostamento +61321=Lunghezza profilo +61322=Profondità nel punto di riferimento +61323=Profondità massima del profilo +61324=Profondità minima del profilo +61325=Profondità all'estremità del profilo +61326=Premill: 0 = rotondo; 1 = angolare +61328=Profondità del segmento dell'arco +61329=Lunghezza del segmento dell'arco +61331=Tipo di arco (convesso, concavo), codificato binario. Vedere la tabella di seguito. +61332=Lunghezza della tasca 1 +61333=Profondità della tasca 1 +61334=Arco di spostamento 1 +61335=Arco di lunghezza orizzontale 1 +61336=Lunghezza arco verticale 1 +61337=Arco di campanatura 2 +61338=Lunghezza della tasca 2 +61339=Profondità della tasca 2 +61340=Arco di spostamento 2 +61341=Arco di lunghezza orizzontale 2 +61342=Lunghezza arco verticale 2 +61343=Arco di campanatura 2 +61344=Lunghezza della tasca 3 +61345=Profondità della tasca 3 +61348=Distanza dal lato di riferimento al punto di riferimento +61349=Raggio +61350=Offset iniziale +61351=Lunghezza +61354=Distanza dal lato di riferimento al punto di riferimento +61355=Vettore normale 1: lunghezza della componente X +61356=Vettore normale 1: lunghezza della componente Y +61357=Vettore normale 1: lunghezza della componente Z +61358=Vettore normale 2: lunghezza della componente X +61359=Vettore normale 2: lunghezza della componente Y +61360=Vettore normale 2: lunghezza della componente Z +61362=Distanza tra "dentro" un lato del pezzo +61363=Distanza ortogonale al lato di riferimento +61364=0: "dentro" al bordo di riferimento, 1: "dentro" al bordo di riferimento +61365=0: senza ribasso o obliquo, -1: con taglio obliquo,> 0: con ribasso +61366=Angolo rispetto al bordo di riferimento nel lato di riferimento +61367=Larghezza +61368=Profondità +61369=Inclinazione +61370=Altezza +61371=Raggio +61372=Lunghezza dell'utensile (parte dell'arco) +61373=0: giunto angolare angolare, 1: raccordo diritto a T a parete +61374=Lunghezza +61375=0:Entrambi i lati, 1:lato di riferimento, 2:lato opposto +61377=Distanza tra "dentro" un lato del pezzo +61378=Distanza ortogonale al lato di riferimento +61379=0: "interno" al bordo di riferimento, 1: "interno" all'opposto del bordo di riferimento +61380=0: senza ribasso o taglio obliquo, -1: con taglio obliquo,> 0: con ribasso +61381=Inclinazione +61382=Profondità 1 +61383=Profondità 2 +61384=0: coda di rondine europea, 1: coda di rondine americana +61385=Lunghezza +61386=0:Entrambi i lati, 1:lato di riferimento, 2:lato opposto +61387=Profondità +61388=Modalità: 0 = solo contorno, 1 = svasatura completa. Solo per contorni chiusi. +61389=Tipo di contorno +61390=Il parametro dipende dal tipo di profilo (P13) +61391=Il parametro dipende dal tipo di profilo (P13) +61400=Punto di riferimento sul bordo di riferimento +61401=Punto di riferimento sul bordo opposto +61402=Punto di riferimento sul bordo di riferimento +61403=Punto di riferimento sul bordo opposto +61404=ortogonale +61405=a 45 gradi +61406=rotondo +61407=tutti i giri sono simmetrici tra loro +61408=Tasca sul bordo di riferimento spostato alla trave finale. Tasca opposto al bordo di riferimento spostato per iniziare il raggio +61409=Tasca sul bordo di riferimento spostato per iniziare il raggio. Tasca opposto al bordo di riferimento spostato alla trave finale +61410=una sola tasca sul lato di riferimento +61411=Una tasca sul lato di riferimento e uno sul lato opposto +61412=con arrotondamento in basso +61413=senza arrotondamenti, illimitato +61414=con allungamento +61415=con tasca +61416=fondo +61417=centro +61418=in alto +61419=sinistra +61420=destra +61421=allineato a sinistra +61422=centrato +61423=allineato a destra +61424=standard +61425=lettere posizionate orizzontalmente +61426=durante il taglio ortogonale al lato di riferimento +61427=quando si taglia ortogonalmente al lato base +61428=definizione classica, P10 e P12 non vengono utilizzati +61429=normale +61430=rastremato +61431=rotondo +61432=angolare +61433="interno" al bordo di riferimento +61434="dentro" all'opposto del bordo di riferimento +61435=Giunto angolare angolare +61436=Raccordo diritto a T a parete +61437=Lavorazione sul lato di riferimento e opposto al lato di riferimento +61438=Elaborazione solo sul lato di riferimento +61439=Elaborazione solo di fronte al lato di riferimento +61440=coda di rondine europea +61441=coda di rondine americana +// ---Custom Parameter (Q) +61451=Profondità smusso +61452=0=Automatico;1=Ciclo longitudinale con lama +61453=Spessore testimone centrale per ciclo Q02 +61454=0=Attacco centrato 1=Attacco interno +61455=0=Automatico 1=Lavorazione con fresa di lato +61456=1=Forza Lama 0=Automatico +61457=1=Solo smusso +61458=0=Automatico; 1=Massima profondità +61459=0=Automatico; 1=Truciolatore; 2=Truciolatore di lato; 3=Fresa; 4=Fresa di lato +61460=0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +61461=0=Automatico; 1=Massimo raggio ammesso su tasche non passanti +61462=Diametro utensile per Q05 +61463=Diametro utensile per Q07 +61464=0=Raggio su spigolo; 1=Foro su spigolo; 2=Spigolo vivo +61465=Diametro foro quando P05=1 +61466=0=Automatico; 1=Sgrossatura con lama +61467=Antischeggia : 0=No; 1=Con lama; 2=Con fresa +61468=Aumenta dimensioni tasca +61469=Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico +61470=0=Automatico; 1=Solo contorno ; 2=Svuota +61471=0=Automatico; 1=Lavoro da un lato solo +61472=Incrementare/decrementare valore P01 per fori nei tenoni +61473=0=Foratura rompi truciolo; 1=Foratura scarico truciolo +61474=Profondità smusso quando P05=1 +61475=Riduzione profondità tenone +61476=Riduzione larghezza tenone +61477=Riduzione altezza tenone +61478=Riduzione profondità tenone +61479=Ridurre/Allargare sagoma tenone +61480=Ridurre/Allargare altezza tenone +61481=aumenta profondità mortasa +61483=Profondità di lavoro +61484=Aumenta dimensioni P10 +61485=0=Automatico; 1=Truciolatore +61486=Riduzione lunghezza P14 +61487=Riduzione larghezza P15 +61488=Sovramateriale finitura +61489=Numero divisioni ondulazioni dello smusso sulla lunghezza +61490=1=Disabilita fresatura gradini +61491=1=Attiva smusso superiore +61492=1=Smusso superiore con lama +61493=Spessore legno per supporto lavorazione +61494=Attiva antischeggia +61495=Profondità antischeggia +61496=Massima elevazione (0=Automatico, >10=Manuale) +61497=0=Automatico; 1=Lama +61498=0=Automatico; 1=Disabilita controllo lunghezza fresa +61499=0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61500=0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61501=0=Automatico 1=Lavorazione con fresa orizzontale se sopra o sotto (disabilita lama) +61502=0=Automatico 1=Usa truciolatore se sotto +61503=0=Attacco e uscita centrati 1=Attacco e uscita interni +61504=0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +61505=0=Automatico; 1=Lavora come Taglio Longitudinale +61506=0=Automatico 1=Lavorazione con fresa +// ----- EgtBEAMWALL - BTLParam ----- +61601=SN +61602=Abilita +61603=Descrizione +61604=L +61605=W +61606=H +61607=Materiale +61608=Richiesti +61609=In produzione +61610=Prodotti +61611=Ruotare +61612=Gruppo +61613=Unit Time +61614=Parametro +61615=Valore +61616=Minimo +61617=Massimo +61618=Numero pezzo +61619=Ordine Assemblaggio +61620=Numero Ordine +61621=Designazione +61622=Annotazione +61623=Sottogruppo +61624=Gruppo +61625=Package +61626=Materiale +61627=Qualità del legno +61628=Grado di qualità +61629=Quantità +61630=Colore +61631=Trasparenza +61632=Lunghezza di piallatura +61633=Start offset +61634=End offset +61635=Transformazione: Origine +61636=Transformazione: Asse X +61637=Transformazione: Asse Y +61638=Camber: Lato di riferimento +61639=Camber: P01,P02,P03,P04 +61640=Part offset: Lato rif. pinza +61641=Part offset: P11,P12,P13,P14 +61642=Qualità di lavorazione +61643=Recesso +61644=Tipo di piano +61645=Numero Elemento +61646=Layer +61647=Numero modulo +61648=USERATTRIBUTE +61649=Comment +61650=Direzione fibre: X, Y, Z +61651=Direzione fibre: allineate +61652=Lato di riferimento +61653=Lato di riferimento: Allineato +61654=Allineamento: posizione +61655=Allineamento: finale +61656=Tipo di materiale: Gruppo +61657=Tipo di materiale: Specifica +61658=AUTOMATICO +61659=VISIBILE +61660=VELOCE +61661=MANUALE +61662=SOFFITTO +61663=TETTO +61664=PARETE +61665=inattivo +61666=BR +61667=TR +61668=BA +61669=TA +61670=HC +61671=VC +61672=AC +61673=R +61674=A +61675=D +61676=Perline +61677=Rivestimento +61678=Legno massiccio +61679=Membrana +61680=Cartongesso +61681=Fibra di gesso +61682=Isolamento +61683=Componente foglio +61684=Pannello per facciate +61685=Pannello profilato +61686=Intonaco +61687=Lato di riferimento 1 +61688=Lato di riferimento 2 +61689=Lato di riferimento 3 +61690=Lato di riferimento 4 +61691=UID +61692=Numero del progetto +61693=Nome del progetto +61694=Parte del progetto +61695=GUID +61696=Nome elenco +61697=Cliente +61698=Architetto +61699=Nome del disegnatore +61700=Data di consegna +61701=Data di esportazione +61702=Ora di esportazione +61703=Versione di esportazione +61704=Lingua +61705=Intervallo +61706=Nome computer +61707=Nome utente +61708=Percorso e nome del file CAD +61709=Percorso e nome del file BTL +61710=STANDARD +61711=ESTESO +61712=Vol unit +61713=Vol tot +61714=Tempo unit +61715=Tempo tot +61716=Numero totale pezzi +61717=Volume totale +61718=Tempo totale +61719=Tempo totale stimato +61720=Tempo rimanente +61721=Numero di grezzi +61722=Numero di pezzi da BTL +61723=Numero di pezzi aggiunti +61724=Numero di pezzi inseriti nei grezzi +61725=Numero di pezzi completati +61726=Quantita' +61727=Stampa PDF +//Warehouse +61751=Current S +61752=Current L +61753=StartOffset +61754=Kerf +61755=Offset +61756=Parametri S +61757=Parametri L +61758=Nuovo valore: +61759=W +61760=L +61761=Conferma +61762=Salva +61763=Annulla +61764=Errore +61765=Il valore immesso è gia presente +61766=Il valore immesso non è corretto +61767=La coppia di valori immessi è gia presente +61768=Uno o più valori immessi non sono corretti +61769=Attenzione +61770=Il parametro selezionato corrisponde al parametro corrente. Sei sicuro di volerlo rimuovere? +61771=SectionXMaterial +61772=Alias +61773=Valori +61774=Quantità +61775=Spessore minimo +61776=Spessore massimo +61777=Aumentare lo Spessore massimo dell'ultimo intervallo prima di aggiungerne un altro +// +61801=Custom +61802=Default +61803=L +61804=T +61805=Processo +61806=Tempo sezione +61807=Tempo pezzo +61808=Nome +61809=PDN +61810= +61811=Posizione X +61812=Posizione Y +61813=Aggiunti +61814=Lavorati +61815=ID +61816=Ritaglio iniziale +61817=% utilizzo +61818=Scarto +61819=Nome file BTL +61820=Nome lista +61821=Data esportazione +61822=Data creazione +61823=Elimina +61824=Faccia +61825=Gruppo +61826=Modifica +61827=Salva +61828=Annulla +61829=Nesting +61830=Visualizzatore +61831=Ottimizzatore +61832=Configurazione +61833=Ottimizza +61834=Aggiorna BTL +61835=Vai a ottimizzazione +61836=Tipo filtro +61837=Cerca +61838=Esporta progetto +61839=Importa progetto +61840=Importa BTL +61841=Copia su Clipboard +61842=DisplayIndex +61843=Nome colonna +61844=CanUserReorder +61845=CanUserResize +61846=CanUserSort +61847=IsReadOnly +61848=Visible +61849=Path Variabile +61850=Tipo +// +61851=La modifica di questo parametro comporta la rimozione del pezzo da {0} grezzi. Procedere comunque? +61852=Impossibile creare una feature con questi valori +61853=Impossibile creare un pezzo con questi valori +61854=Impossibile creare una barra con questi valori +61855=Impossibile creare una parete con questi valori +61856=Valore non compreso tra minimo e massimo +61857=Impossibile inserire una quantita' inferiore al numero di pezzi gia' inseriti nei grezzi! +61858=Impossibile modificare questi valori +61859=Errore nella scrittura di un parametro Macchina +61860=Salvare le modifiche apportate ai parametri Macchina? +61861=Salvare le modifiche apportate ai valori di default? +61862=Passando ad un altro tipo verra' eliminato il secondo percorso. Procedere? +61863=Raggiunto numero di pezzi da produrre: +61864= da BTL; +61865= aggiunti. Aggiungerne un altro? +61866=Il pezzo selezionato ha sezione diversa dalla barra selezionata. Impossibile aggiungerlo. +61867=Il pezzo selezionato supera la lunghezza dalla barra selezionata. Impossibile aggiungerlo. +61868=Il pezzo selezionato ha spessore diverso dalla parete selezionata. Impossibile aggiungerlo. +61869=Errore nell'esecuzione del file Macro! +61870=Impossibile creare una Macro senza selezionare una Feature o col Nome vuoto +61871=File non trovato! +61872=Impossibile cancellare il progetto correntemente aperto +61873=Impossibile cancellare il progetto perche' gia' collegato ad una produzione +61874=Impossibile cancellare il progetto perche' alcuni grezzi sono gia' stati mandati in produzione +61875=Salvare le modifiche apportate al progetto? +61876=Impossibile creare un nuovo file! +61877=Salvare progetto modificato prima di continuare? +61878=Impossibile procedere con un nuovo progetto non salvato! +61879=La macchina corrente è di tipo sia Beam che Wall. Scegli il tipo a cui settare il progetto: +61880=Selezionare macchina e/o tipo tra i disponibili. Altrimenti annullare l'importazione del progetto. +61881=Il tipo del progetto aperto non è compatibile col tipo della macchina corrente +61882=Salvare le modifiche apportate alle colonne delle DataGrid? +61883=La colonna "{0}" della tabella "{1}" specificata nel file ini delle colonne delle datagrid non è stata trovata nel programma +61884=Selezionare la macchina che si desidera associare al progetto: +61885=La macchina associata al progetto in apertura non è presente tra quelle disponibili +61886=Macchina +61887=Impossibile creare il numero di grezzi specificato +61888=Quante copie del grezzo realizzare? +61889=Area punte lunghe +61890=Punteggio minimo +61891=Non è possibile inviare feedback dall'Ottimizzatore se non c'è alcun Prod aperto +61892=Non è possibile continuare con un progetto non salvato! Prego salvarlo prima di aggiornare. +// +61900=Cambio parametro +61901=Verifica +61902=Simula +61903=Nuovo grezzo +61904=Aggiungi al grezzo +61905=Copia pezzo +61906=Aggiungi pezzo +61907=Rimuovi pezzo +61908=Copia feature +61909=Crea macro +61910=Aggiungi feature +61911=Rimuovi feature +61912=Produrre grezzo +61913=Produrre tutti i grezzi +61914=Copia grezzo +61915=Rimuovi grezzo +61916=Riordina pezzi +61917=Muovi su pezzo +61918=Muovi giu pezzo +61919=Rimuovi pezzo +61920=Magazzino +61921=Aggiungi progetto a ottimizzazione +61922=Vai a progetto +61923=Statistiche +61924=Reset +61925=Mostra tutti i pezzi +61926=Mostra solido +61927=Mostra assemblato +61928=Verifica tutti +61929=Non è possibile cambiare macchina poichè il Proj è già associato ad un Prod +61930=Ingressi +61931=Uscite +61932=Calcola Flip e Rotazione +61933=Sblocca Flip +61934=Sblocca Rotazione +61935=Lunghezza +61936=Larghezza +61937=Offset +61938=Kerf +61939=Modifica +61940=Reset +61941=Scegli macchina +61942=File BTL gia' importato ed ottimizzato. Importarlo di nuovo? +61943=File BTL gia' importato. Sovrascriverlo? +61944=Muovi pezzi +61945=Direzione spostamento +61946=Lunghezza spostamento +61947=Non è possibile muovere i pezzi fuori dal grezzo +61948=Il valore inserito per lo spostamento non è valido +61949=Filtri di ricerca +61950=Tipo Parametro +61951=Valore Prametro +61952=R +61953=A +61954=I +61955=P +61956=Tutti +61957=Filtrati +61958=Aggiorna +61959=Accoda +61960=Checkare i pezzi che si desidera aggiungere per aggiornare il BTL +61961=Cambio materiale +61962=Materiale progetto +61963=Materiale magazzino +61964=Standard +61965=Da BTL +61966=Salva +61967=Non Salvare +61968=In attesa di salvataggio in optimizer +61969=Annulla +// +62500=Supervisore +62501=Canale +62502=Modo operativo +62503=Produci Tutti +62504=Pannello Lavorato +62505=Reset Pannello +62506=Elimina Pannello +62507=Stampa etichetta +62508=Pezzo fatto +62509=Riprendere lavorazione barra iniziata? +// Loading +63000=Apertura progetto +63001=Caricamento geometrie del progetto +63002=Caricamento gruppi di lavorazione +63003=Caricamento dati di produzione +63004=Apertura ottimizzazione +63005=Caricamento pezzi +63006=Caricameno grafica +63007=Salvataggio progetto +63008=Importazione file BTL +63009=Lettura file BTL +63010=Esportazione progetto +63011=Caricamento ambiente +63012=Salvataggio geometrie +63013=Salvataggio dati su Db +63014=Modifica parametri +63015=Apertura visualizzatore +63016=Aggiungendo informazioni di esportazione +63017=Esportando... +63018=Importazione progetto +63019=Caricamento progetto +63020=Creando progetto importato +63021=Modifica materiali +// ----- FromLua ----- +65001= +// ----- OmagCUT ----- +// General +90001=IN LAVORO +90002=TAGLI DIRETTI +90003=TAGLI CAD +90004=CORNICI +90005=MACCHINA +90006=OPZIONI +// WorkInProgress +90101= +// DirectCut +90201=Movimento manuale +90202=Taglio singolo +90203=Taglio multiplo +90204=Taglio griglia +90205=MTH +90206=Spianatura +90207=Test lama +90208=Tasta lama +90209=Copia dima +90210=Acquisisci P1 +90211=Acquisisci P2 +90212=Laser +90213=Affondamento +90214=Lunghezza +90215=Direzione +90216=Inclinazione +90217=Numero +90218=Dimensioni +90219=Numero X +90220=Dimensioni X +90221=Numero Y +90222=Dimensioni Y +90223=Tagli lato motore +90224=Lama +90225=Disegno +90226=Larghezza +90227=Sovrapposizione +90228=Offset +90229=Blocca Asse C +90230=Esegui +90231=Lucidatura +90232=Spessore lama +90241=Tastatura lama +90242=Tastatura in corso... +90243=Tastatura completata con successo +90244=Errore in tastatura lama +90245=Nuovo nome della dima +90246=Tastatura interrotta dall'utente +90250=Linea +90251=Arco +90252=Rimuovi +90253=Chiudi +90254=Salva +90255=Test +90256=Verifica posizione taglio +90257=Verifica posizione in corso... +90258=Foro singolo +// CadCut +90301=Simula +90302=Esegui +90303=Nuovo +90304=Carica +90305=Salva +90306=Salva come +90307=Nuovo nome del progetto +90308=CSV +90309=Vein Match +90310=Esporta +90311=Utensile +90312=Lavorazione +90313=Fotografia non riuscita +90314=Errore nella generazione del programma CN +90315=Errore nella trasmissione del programma CN +90316=Non connesso alla macchina +90317=Programma CN trasmesso +90318=La macchina non accetta il programma CN +90319=Programma già trasmesso, vuoi ritrasmetterlo ? +90320=Macchina diversa +90321=Ridotte alcune lavorazioni per evitare interferenze +90322=Mancano gli utensili : +90323=Fotografia di sfondo eseguita +90324=Riconoscimento contorno non riuscito +90325=Errore nel salvataggio delle statistiche +90326=Confermi ripartenza dalla fase {0} ? +90327=Inseriti Nuovi Pezzi Rovinati +90328=Area Pezzi : +90329=Da Produrre : +90330=Programma già trasmesso, è una nuova lastra ? +// NestPage +90331=Inserisci pezzo +90332=Parcheggia pezzo +90333=Elimina pezzo +90334=Seleziona tutto +90335=Deseleziona tutto +90336=Reset +90337=Uno o più pezzi con spessore, materiale o finitura non compatibili +90338=Rotazione oltre i limiti +90339=Rotazione impossibile +90340=Nesting Automatico in corso +// SplitPage +90341=On/Off +90342=Tutti On +90343=Tutti Off +90344=Allunga/Accorc +90345=Inizio All/Acc +90346=Fine All/Acc +90347=Inizio Centro/Fuori +90348=Inizi Tutti Fuori +90349=Inizi Tutti Centro +90350=Calcolo automatico non riuscito +90351=Lama troppo grande per utilizzo ventosa +90352=Fine Centro/Fuori +90353=Fine Tutti Fuori +90354=Fine Tutti Centro +90355=Tutti Allunga +90356=Tutti Accorc. +90357=Modif. +90358=Auto +90359=Restart +// MoveRawPart +90361=Rimuovi +90362=Pezzo troppo piccolo : non si può muovere +90363=Posizione scelta già occupata +90364=Pezzo troppo pesante: non si può muovere +90365=Pezzo oltre le corse: non si può muovere +// SplitPage 2 +90371=Pausa On/Off +90372=Pausa +90373=Inizio Modif. +90374=Fine Modif. +90375=Allungamento +90376=Inverti +// DrawPage +90381=Numero pezzi +90382=Misure +90383=Inclina lati +90384=Indica Lato Sopra +90385=Disegno Parametrico +90386=Selezionare un contorno +90387=Non ci sono lati modificabili +90388=Nome +90389=Dati Trf +90390=Codice ordine +90391=Descrizione ordine +90392=Codice materiale +90393=Codice superficie +90394=Spessore +90395=Selezionare uno o più fori +90396=Codice pezzo +90397=Incidi +90398=Dati Csv +90399=Aggiornate tutte le lavorazioni +90400=Filo Top +// Component +// Massimo 30 caratteri senza immagine e massimo 20 con l'immagine +90401=Triangolo +90402=Rettangolo +90403=Trapezio +90404=Quadrilatero +90405=Piedoca +90406=Soglia +90407=Piano Cucina +90408=Piano Bagno +90409=Altri +90410=Triangolo2L +90411=Triangolo3L +90412=Isoscele +90413=Rettangolo +90414=Scaleno +90415=Scaleno +90416=4Lati 1Ang +90417=3Lati 2Ang +90418=3Lati 2Diag +90419=4Lati 1Diag +90420=4Lati 3Diag +90421=4Lati 3Ang +90422=4Lati 3Ang +90423=Angolo Retto +90424=Angolo Retto Smussato +90425=Angolo Allineato +90426=Angolo All. Smussato +90427=Parte A +90428=Parte B +90429=Angolo +90430=Angolo Smussato +90431=Ellisse +90432=Ovale +90433=Arco +90434=Arco LHF +90435=Arco LLH +90436=Arco LLF +90437=Rettangolo smussato +90438=Bombato +90439=Foro +90440=2 Fori +90441=3 Fori +90442=Arco RHa +90443=Poligono +90444=Foro da sotto +90445=Dxf +90446=Ribasso +90447=Componenti interni +90448=Aggiungi +90449=Rimuovi +90450=Conferma +// Import +90451=Usa layer +90452=Usa regioni +90453=Reset +90454=mm +90455=inch +90456=Usa curve chiuse +90457=Inclina lati +90458=Incidi da sotto +90459=Angolo +90460=Offset +90461=Affondamento +90462=Accorciamento +90463=Importa DXF +90464=Fora da sotto +90465=Quantità +90466=Offset2 +90467=Ordine +90468=Distinta +90469=Nome +// Component 2 +90470=Incisioni Ribasso +90471=Incisioni +90472=TriangoloCH +90473=TriangoloRT +90474=TrapezioRtA +90475=3Lati 2Ang +90476=Soglia smusso +// FastGrid +90480=Nome ordine +90481=N° Lastra +90482=Ultima lastra +90483=Tipo pezzo +90484=Inserisci pezzi +90485=Conferma ordine +// Open +90491=Progetto non valido +90492=Progetto con interferenze. Per caricarlo disabilita rispetto tagli completi. +// RawPart +90499=Grezzo non definito +90500=Rotazione +90501=Rettangolo +90502=Per punti +90503=Lunghezza +90504=Larghezza +90505=Spessore +90506=Offset X +90507=Offset Y +90508=Kerf +90509=Materiale +90510=Zona rovinata +90511=Nuovo +90512=Cancella +90513=Punti +90514=Aggiungi +90515=Cancella +90516=Massima lunghezza = +90517=Massima larghezza = +90518=Non sono ammessi spessori negativi +90519=Minimo offset X = +90520=Minimo offset Y = +90521=Minimo kerf = +90522=Massimo kerf = +90523=Tasta grezzo +90524=Conferma +90525=Tastatura grezzo +90526=Tastatura in corso... +90527=Tastatura completata con successo +90528=Errore nella tastatura del grezzo +90529=Dal disegno +90530=Dal laser +90531=Chiudi +90532=Errore nell'acquisizione del punto +90533=Contorno +90534=Lama troppo grande per tastatura +90535=Da fotografia +// ChooseMachining +90536=Scegliere la lavorazione di lama +90537=Scegliere la lavorazione secondaria +90538=Scegliere la foratura +90539=Scegliere la fresatura +90540=Nessuna +90541=Foratura +90542=Fresatura +90543=Entrambe +90544=Scelta lavorazioni correnti +90545=Scegliere il waterjet +90546=Taglio waterjet +90547=Errore nella posizione o dimensione del grezzo +90548=Massimo offset X = +90549=Massimo offset Y = +90550=Scegliere la svuotatura +// Simulation +90551=Simulazione completata +90552=Extracorsa +90553=Direzione utensile irraggiungibile +90554=Errore +90555=ERRORE +90556=Errore in generazione! +90557=Simulazione +90558=Un passo alla volta +90559=Play/Pausa +90560=Stop/Home +90561=Pausa +90562=Simulazione interrotta +90563=Vista macchina +90564=Home +90565=Tempo +90566=Lunghezza +90567=Area pezzi +90568=Utilizzo +90569=Stime +90570=Dettagli +// FrameCut +90601=Lungo X +90602=Lungo Y +90603=Rimuovi +90604=Sgrossatura +90605=Finitura +90606=Spatolatura +90607=Specchia +90608=Distanza sopra +90609=Distanza inizio +90610=Accorcia inizio +90611=Accorcia fine +90612=Taglio singolo +90613=Arco +90614=Guida +90615=Sezione +90616=Guida +90617=Rad +90618=Ang +90619=Errore : raggio più piccolo della larghezza della sezione +90620=Errore : creazione della cornice non riuscita +90621=Distanza X +90622=Distanza Y +90623=Lato Opposto +// Machine +90701=Msg_Ita.xpi +90705=Dati macchina +90706=DB utensili +90707=DB lavorazioni +90708=Macchina +90709=Statistiche +90715=Nuovo +90716=Nuova +90717=Salva +90718=Elimina +//ToolsDb +//param +90719=Lunghezza portautensili +90720=Anima +90721=Nome +90722=Posizione +90723=Testa +90724=Uscita +90725=Rotazione +90726=Normale +90727=Massima +90728=Feed +90729=Avanzamento +90730=Testa +90731=Ingresso +90732=Uscita +90733=Acqua +90734=Correttore +90735=Sovramateriale +90736=Longitudinale +90737=Radiale +90738=Max assorb. +90739=Feed minima +90740=Max affond. +90741=Lunghezza +90742=Diametro +90743=Spessore +90744=Tagliente +90745=Note +90746=Numero di Serie +90747=Codice +90748=Fornitore +90749=Fine Servizio +//tools families +90751=Lama +90752=Foretto +90753=Fresa +90754=Mola da scasso +90755=Waterjet +90756=Mola lucidante +//Tool Setup +90759=Posizione utensile predefinita già occupata +//MachiningsDb +//param +90761=Nome +90762=Affondamento +90763=Angolo sbandamento +90764=Inverti +90765=Tipo di step +90766=Lato di lavoro +90767=Lato testa +90768=Posizione inizio +90769=Attacco +90770=Collegamento +90771=Uscita +90772=Utilizza curve +90773=Tolleranza +90774=Passo di affondamento +90775=Normale +90776=Passo di affondamento +90777=Interno archi +90778=Esterno archi +90779=Lunghezza del rallentamento +90780=Iniziale +90781=Finale +90782=Affondamento agg. +90783=Posizione di ritorno +90784=Utensile +90785=Spessore minimo +90786=Spessore massimo +90787=Passo +90788=In affondo +90789=Di lato +90790=In verticale +//machinings families +90791=Taglio +90792=Foratura +90793=Fresatura +90794=Sgrossatura con lama +90795=Finitura con lama +90796=Svuotatura +90797=Waterjet +//ComboBox Param +90801=No +90802=Interna +90803=Esterna +90804=Entrambe +90821=Centro +90822=Sinistra +90823=Destra +90824=Centrato +90825=Interno +90826=Esterno +90827=Esteso centrato +90828=Esteso esterno +90829=Esteso precedente +90830=Esteso successivo +90831=Estesi entrambi +90832=Centrata +90833=Interna +90834=Esterna +90835=Salta +90836=Approssima +90837=Convesso +90838=Zig Zag +90839=Una via +90840=Va e vieni +90841=Lavora +90842=Nessuno +90843=Normale +90844=Rallenta +90845=Anello +90846=Lineare +90847=Tangente +90848=Inseguimento +90849=Elica +90850=Come attacco +// param2 +90861=Spatolatura +90862=Inclinato +90863=Incl. ritorno +90864=Andata +90865=Ritorno +90866=Ultimo ritorno +90867=Inclinazione in avanti +90868=Tastatura +90869=Min dist. punti +90870=Max dist. punti +90871=Esterni +90872=Interni +90873=Lungh. rall. +90874=Rallentam. % +90875=Foro di attacco +90876=Raggio +90877=Num. giri in LP +90878=Num. giri in HP +90879=Abilitazione +90880=Angoli +// Barcode +90881=Codice a barre +90882=Blocco +90883=Numero +90884=Dati lastra +// param3 +90890=Dist. tang. +90891=Dist. perp. +90892=Dist. tang. +90893=Dist. perp. +90894=Attacco ceramica +90895=Lunghezza +90896=Passo +90897=Ultimo taglio +90898=Tagli inclinati +// Alarms +90900=Waterjet corrente +90901=Lama corrente +90902=Utensile ausiliario +90903=Foretto corrente +90904=Fresa corrente +90905=Z sicura +90906=Sicurezza tagli +90907=Sicur. angoli +90908=Rispetta i tagli completi +90909=Offset fori +90910=Sovrapp. fori +90911=Tolleranza fori +90912=Lista errori CN +90913=Materiali +90914=Aggiungi +90915=Rimuovi +90916=Utensili correnti +90917=Parametri fori +90918=Rmin archi est. +90919=Parametri macchina +90920=Nessuno +90921=Foretto +90922=Fresa +90923=Entrambi +90924=Amax archi int. +90925=Parametri lama +90926=Un solo foro in angolo +90927=Tagli diretti +90928=Home finale +90929=Parametri fresature +90930=Sempre sugli interni +90931=Nesting +90932=Allineato +90933=Attrezzaggio +90934=Nuovo +90935=Elimina +90936=Altezza sovratavola +90937=Contorno da Foto +90938=Sfondo +90939=Soglia +90940=Tolleranza +90941=Lavaggio +90942=Confermi la cancellazione del materiale selezionato? +90943=Setup di default +90944=Sempre sugli angoli +90945=Selezionare l'utensile da tastare +90946=Tagli Feed inizio/fine +90947=Lunghezza +90948=Riduzione % +90949=Accorciamento +90950=Tastatura +// Machine +90951=Start +90952=Stop +90953=Reset +90954=Auto +90955=Single +90956=MDI +90957=Manual +90958=Home +90959=Download +90960=Upload +90961=Activate +90962=Delete +90963=MDI Confirm +90964=Modalità CN +90965=Comandi macchina +90966=Stringa MDI +90967=Trasferimento part program +90968=Vuoi cambiare tavola? +// Options +90981=Lingua +90982=La nuova lingua diventerà corrente dal prossimo avvio del programma. +90983=Unità di misura +90984=Rotazione vista +90985=Angolo inclinato +90986=Un solo valore +90987=Più valori +90988=Inserimento diretto dei pezzi +90989=Parametrici e DXF +90990=CSV +90991=Fast grid +90992=Abilita la creazione di pezzi standard +90993=Colore testo +90994=Slab Dxf +90995=Layer Lastra +90996=Layer Pezzi +90997=Layer Scarti +90998=Spessore std +90999=Inclinazione da Colore +91000=Abilita +91001=Tolleranza +91002=Tallone +91003=Inclinazione +91004=Feedback +91005=Temi +91006=Incisioni da colore +91007=Affondamento +91008=Larghezza +91009=Avvio programma +91010=Seleziona modalità di avvio +91011=Progetti recenti +91012=Ultima apertura +91013=Ultimo progetto +91014=Nuovo progetto +91015=Apri cartella +91016=Mostra finestra +//Alarms2 +91051=Lavorazioni +91052=Taglio lama +91053=Foratura +91054=Fresatura +91055=DripSawing +91056=DripDrilling +91057=WaterJet +91058=Parametri waterjet +91059=Automatico +91060=Allineato e Ghigliottina +91061=Parametri incisioni +91062=Con fresa +91063=Profondità +91064=Larghezza +91065=Pretaglio uscite +91066=Ghigliottina +91067=Inserisci pausa +91068=Cornici +91069=Svuotatura +91070=Scasso corrente +//Statistics +91071=Produzione del giorno +91072=Produzione della settimana +91073=Progetto +91074=Area Pezzi +91075=Area Tagli +91076=Giorno +91077=Settimana +91078=Reset +91079=Area da Tagliare +//Lucidature +91089=Offset +91090=DB Lucidature +91091=Lucidature +91092=Movimento +91093=Ripetizioni +91094=Attacco/Uscita +91095=Altezza +91096=Lista utensili +91097=Lunghezza +91098=Su +91099=Giù +91100=Precarico +//EgtMsgBox +91101=Salvare il progetto corrente? +91102=Salvare l'utensile corrente? +91103=Salvare la lavorazione corrente? +91104=Nome già utilizzato +91105=Ci sono interferenze, alcuni pezzi saranno parcheggiati. Vuoi continuare? +91106=Esiste già un file con questo nome. Sovrascriverlo? +91107=CONNESSIONE AL CN +91108=Connessione in corso... +91109=Connessione non riuscita +91110=Connessione riuscita +91111=Tavola da usare ? +91112=Vuoi cancellare anche i pezzi provenienti da lista Csv ? +91113=Pezzi non rimossi perché liberi +91114= o di altre liste Csv +91115=Errore +91116=Opzione Linea di produzione non abilitata +91117=Errore in copia file per OmagVIEW +91118=Conservo i pezzi in parcheggio ? +91119=Errore nella gestione dei pezzi rovinati +91120=I caratteri \ / : * ? " < > | non sono permessi +91121=Sei sicuro di voler cancellare i pezzi selezionati? +91122=Avvertimento +91123=Tavola +91124=Salvare la lucidatura corrente? +91125=Salvare le modifiche correnti? +91126=Esporta +91127=Importa +91128=DB WaterJet +91129=Origine da laser +91130=Esegui programma? +// CSV +91201=Apri +91202=Inserisci +91203=Nuovo +91204=Rimuovi +91205=Errore nel salvataggio del file CSV, vuoi continuare lo stesso ? +91206=Errore nella lettura del file CSV +// OmagVIEW +91301=Tutti Validi +91302=Pezzo Valido +91303=Pezzo Rovinato +91304=Stampa Etichetta +91305=Conferma +91306=Stampa +// OmagOFFICE +// OptionPanel +91401=Grezzo +91402=Disponi +91403=Lavora +91404=Simula +// MachiningDbWindow +91451=Materiale +91452=Spessore minimo +91453=Spessore massimo +// Errori di stampa +91461=Errore connessione stampante +91462=Errore formato dati +91463=Errore in fase di stampa +91464=Nessun pezzo selezionato +// TopCommandBar +91501=E' necessario salvare il progetto prima di esportarlo +91502=Seleziona il direttorio di esportazione +91503=Errore nell'esportazione +91504=Esportazione completata con successo +91505=Esporta in macchina +91506=Esporta DXF +// Rawpart +91551=Errore nel caricamento della fotografia +91552=Importa fotografia +// VeinMatching +91601=Esporta +91602=Mostra Info +91603=Modifica +91604=Verifica +91605=Magnetico +91606=Pezzo non selezionabile in questa situazione +91607=Pezzo non selezionabile perchè appartenente a gruppo di lavoro non corrente : +91608=Ingombro dei pezzi DXF troppo grande per VeinMatching +// Generic +91651=Ok +91652=Annulla +91653=A° +91654=T +91655=Inizio +91656=Fine +// ----- OmagPHOTO ----- +// General +92001=Db non trovato! +92002=Impossiblie avviare il programma +// OptionPanel +92051=Salva +92052=Aggiungi +92053=Annulla +92054=Elimina +92055=Sei sicuro di voler cancellare la lastra corrente? +92056=Etichetta +92057=Etichetta Freccia +92058=Sfoglia +92059=Stampa +92060=Seleziona +// Slab +92071=Id +92072=Nome immagine +92073=Stato +92074=Progetto assegnato +92075=Posizione in magazzino +92076=Data +92101=Nome già utilizzato +92102=Il nome è obbligatorio +92103=L'immagine è obbligatoria +// SearchPanel +92151=Cerca +92152=Tolleranza spessore +92153=Data d'inizio +92154=Data di fine +92155=Reset +//Messaggi +92200=Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=Avviso +92202=Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// General +101001=Importa BTL +101002=Disegna +101003=Posiziona +101004=Opzioni +// ImportPage +101101 +// DrawPage +101201=Parete +101202=Porta +101203=Finestra +101204=Aggiungi +101205=Annulla +101206=Applica +101207=Elimina +101208=Distanziale +// PlacePage +101301=Genera +101302=Trasmetti +101303=Posizionamento parete +101304=Inserisci +101305=Parcheggia +101306=Elimina +101307=Spessore strati +101308=Numero tavole in cima +101309=Inserimento non riuscito +101310=Generazione riuscita +101311=Errore in generazione +101312=Lancio trasmissione riuscito +101313=Errore in lancio trasmissione +101314=Trasmissione completata con successo +101315=Trasmissione non riuscita +101316=Ponti tutti disabilitati +101317=File di Generazione mancante +// OptionsPage +101401=Opzioni macchina +101402=Caratteristiche incollaggio +101403=Extra grezzo in X +101404=Extra grezzo in Y +101405=Extra colla +101406=Caratteristiche tavole +101407=Larghezza tavola +101408=N° tavole in un piano +101409=Attivazione ponti +101410=Ponte colla +101411=Ponte tavole +101421=Opzioni software +101422=Selezione lingua +101423=La nuova lingua diventerà corrente dal prossimo avvio del programma +101424=Numero progetti da salvare +101425=Posiziona tavole su porte e finestre +101426=Anticipo apertura colla +101427=Anticipo chiusura colla +// OpenPage +101501=Progetto non valido +// ----- End ----- diff --git a/ProgramData/EgtBeamWall/Config/EgalTechPor.txt b/ProgramData/EgtBeamWall/Config/EgalTechPor.txt new file mode 100644 index 0000000..039351b --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/EgalTechPor.txt @@ -0,0 +1,3318 @@ +// Ficheiro das mensagens EgalTech Português 2022/05/02 +0=PT +// File +1=Ficheiro +3=Novo +5=Abrir +6=Abrir
Ficheiros recentes (Shift) +7=Inserir +9=Guardar +11=Copiar +13=Importar +15=Exportar +17=Executar +19=Ficheiros Recentes +20=Script Recentes +// Vista +101=Vista +103=Linhas +105=Bordas +107=Sólidos +109=ZoomAll +111=ZoomIn +113=ZoomOut +115=Acima +117=Frente +119=Direita +121=Atrás +123=Esquerda +125=Embaixo +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Grelha +136=Configurar Vista perpendicular à Grelha atual +137=DirCurvas +139=Análise +141=Distância +// Grelha +201=Grelha +203=Acima +205=Frente +207=Direita +209=Atrás +211=Esquerda +213=Embaixo +215=Vista +216=Configurar Grelha perpendicular à direção de Vista +217=Elevação +218=Configurar Elevação da Grelha +219=Origem +220=Configurar Origem da Grelha +221=Girar +222=Girar Grelha
Girar Grelha em 3d (Shift) +223=3 Pontos +224=Configurar Grelha a partir de 3 Pontos +225=Perp +226=Configurar Grelha Perpendicular ao Objeto +227=Objeto +228=Configurar Grelha a partir do Objeto +// Desenhar +301=Desenha +303=Ponto +304=Ponto
Vetor (Shift)
Referência (Ctrl) +305=Lin 2P +306=Linha : 2 Pontos
Linha : 2 pontos com Continuação (Ctrl) +307=Lin PDL +308=Linha : Ponto inicial, Direção, Comprimento
Linha : Ponto inicial, Vetor direção, Comprimento (Shift) +309=Circ +310=Circunferência : Centro, Ponto
Circunferência : Centro, Diâmetro (Shift) +311=Con +312=Conexão : Raio
Chanfro : Dist (Shift) +313=Arco CIF +314=Arco : Centro, Ponto inicial, Ponto final +315=Arco 3P +316=Arco : 3 Pontos +317=Arc IDF +318=Arco : Ponto inicial, Direção, Ponto final
Arco : Ponto inicial, Vetor direção, Ponto final (Shift)
Arco : Ponto inicial, Direção, Ponto final com Continuação (Ctrl) +319=Ret 2P +320=Retângulo : 2 Pontos +321=Polígono +322=Polígono : Raio ou Apótema
Polígono : Lado com 2 Pontos (Shift) +323=Texto +324=Texto
Texto Avançado (Shift) +399=Continuação : 'L' com linha, 'A' com arco +// Construir +401=Construir +403=Plano +404=Superfície : plano contornado por uma ou várias curvas
Região plana (Shift) +405=Extrudir +406=Superfície : da extrusão de uma ou várias curvas +407=Girar +408=Superfície : da rotação de uma curva +409=Aparafusar +410=Superfície : da rototranslação de uma curva +411=Riscada +412=Superfície : riscada entre 2 curvas +413=Combinar +414=Combina uma ou várias Superfícies +415=Inverter +416=Inverte o exterior de uma ou de várias Superfícies +417=Explodir +418=Explode Superfícies ou Regiäes Planas +419=Swept +420=Superficie : da spostamento di una curva lungo un'altra +// Modificar +501=Modificar +503=Cancelar +504=Cancela os Objetos +505=Camada +506=Leva os Objetos na Camada atual +507=Cor +508=Modifica Cor
Remove Cor específico (Shift)
Modifica Transparência (Ctrl) +509=Inverte +510=Inverte Curva +511=Trim/Est +512=Corta ou Expande Curva +513=Quebrar +514=Quebra Curva
Divide Curva em Partes (Shift) +515=Unir +516=Une Curvas
Une Curvas criando uma Cópia (Shift)
Mesclar Curvas em Composta (Ctrl) +517=Explodir +518=Explode Textos ou Curvas em Componentes +519=Espess +520=Configura Espessura e direção de Extrusão numa ou em várias Curvas +521=Início +522=Modifica Início de Curva Fechada +// Transformar +601=Transformar +603=Mover +604=Move um ou vários Objetos +605=Girar +606=Gira um ou vários Objetos
Gira um ou vários Objetos em 3D (Shift) +607=Espelh. +608=Espelha um ou vários Objetos
Espelha um ou vários Objetos em 3D (Shift) +609=Escalar +610=Escala um ou vários Objetos
Escala um ou vários Objetos em 3D (Shift) +611=Deslocar +612=Deslocamento de uma Curva +// Especial +701=Especial +703=Peças 2d +704=Inserir Peças Planas de DXF ou NGE +705=Compo +706=Inserir Componentes Paramétricos +// Cenas : Menu Seleção Objetos +1001=Seleciona Tudo +1003=Deseleciona Tudo +1005=Seleciona com Janela +1007=Seleciona Peça +1009=Seleciona Camada +1011=Seleciona Percurso +1013=Seleciona Percurso Completo +1015=Seleciona Objetos +1016=Seleciona Todos os Visíveis +// Cenas : Menu Ponto notável +1101=Ponto Sketch +1102=Ponto Sketch +1103=Ponto Grelha +1104=Ponto Grelha +1105=Ponto Final +1106=Ponto Final +1107=Ponto Médio +1108=Ponto Médio +1109=Centro +1110=Centro +1111=Baricentro +1112=Baricentro +1113=Ponto Próximo +1114=Ponto Próximo +1115=Intersecção +1116=Intersecção +1117=Ponto Tangente +1118=Ponto Tang +1119=Ponto Perpendicular +1120=Ponto Perp +1121=Ponto a Mínima Distância +1122=Ponto MinDist +1123=Excluir Superfícies +// Cenas : Menu Diversos +1201=Desativa Arrasto +1203=Ativa Arrasto +// Cenas : Diversos +1301=Dist= +// Controller +2001=Cópia (V) +2002=Erro +2003=Alarme +2051=O Ponto deve ser diferente do anterior +2052=Os Pontos devem ser não alinhados +2053=Valores Nulos ou Negativos não são admitidos +2054=Valores Negativos ou Dois Valores Nulos não são admitidos +2055=Pelo menos um Objeto não ‚ escalável +2056=Distância grande demais +2057=Curva não plana (no seu plano) +// Controller : Desenha +2101= +// Controller : Constrói +2201= +// Controller : Modifica +2301= +// Controller : Transforma +2401=CÓPIA +2402=MOVE +2403=Inserir Ponto Base +2404=Inserir Ponto Destinação +2406=GIRAR +2407=Inserir Centro +2408=Inserir Ponto Base +2409=Inserir Ângulo ou Ponto +2411=GIRAR 3D +2412=Inserir Primeiro Ponto Eixo +2413=Inserir Segundo Ponto Eixo +2414=Inserir Ponto Base +2415=Inserir Ângulo ou Ponto +2416=ESPELHA +2417=Inserir Primeiro Ponto +2418=Inserir Segundo Ponto +2421=ESPELHA 3D +2422=Inserir Primeiro Ponto +2423=Inserir Segundo Ponto +2424=Inserir Terceiro Ponto +2426=ESCALA +2427=Inserir Centro +2428=Inserir Coeficiente +2431=ESCALA 3D +2432=Inserir Centro +2433=Inserir Coeficientes +2436=DESLOCAMENTO +2437=Inserir Distƒncia +2438=Conexão +2439=Chanfro +2440=Estender +// ----- EgtCAM5 ----- +5001=DESENHAR +5002=PROCESSAR +5003=Bd Ferramentas +5004=Bd Processamentos +5005=Opções +5006=Bd Ferr. +5007=Bd Proc. +5008=Opções Máquina +5009=Db Att. +5010=Db Attrezzaggio +5020=Tabelas Processamentos +//BarraComandos Topo +5101=Novo +5102=Abrir
Abrir Ficheiros recentes (Tecla Direita) +5103=Guardar +5104=Guardar como +5105=Inserir +5106=Importar +5107=Exportar +5108=Executar Script
Executar Script recentes (Tecla Direita) +5109=Opções +5110=Endereço mail de suporte inexistente. +5111=Guardar o projeto corrente antes de enviar o feedback? +5112=Enviar o feedback a {0} com a pasta {1} anexada. +5113=Feedback +5114=Mail de feedback pronto. +//Painel de Desenho +5150=???Estrai Bordi Liberi di Superfici e Regioni Piane +5151=Mesclar Superfícies e Regiões Planas +5152=Subtrair Superfícies e Regiões Planas
Taglia Superficie con Superficie Inversa (Shift) +5153=Interseção de Superfícies e Regiões Planas
Taglia Superficie con Superficie (Shift) +5154=Pontos, Curvas e Faces de interseção entre superfícies +5155=Dimensão Linear
Dimensão Alinhada (Shift) +5156=Círculo 3 Pontos +5157=???Estrai Bordi di Facce di Superfici e Parti di Regioni Piane +5158=???Estrai Faccia da Superficie +5159=Arco Invertido
Arco Esplementare (Shift) +5160=???Modifica forma +5161=???Aggiungi Punto
Trasforma in Arco (Shift)
Chiudi Curva Composita (Ctrl) +5162=???Rimuovi Punto
Trasforma in Retta (Shift)
Apri Curva Composita (Ctrl) +5163=???Approssima Curva
Approssima Curva con Linee (Shift) +5201=Ponto
Vetor (Shift)
Referência (Ctrl) +5202=Linha 2 Pontos
Linha 2 Pontos com Continuação (Ctrl) +5203=Linha Ponto Direção Comprimento
Linha Ponto Vetor Direção Comprimento (Shift) +5204=Círculo Centro Ponto +5205=Círculo Centro Diâmetro +5206=Arco Centro Pontos Início e Fim +5207=Arco 3 Pontos +5208=Arco Ponto e Direção Início Ponto Fim
Arco Ponto e Vetor Direção Início Ponto Fim (Shift)
Arco Ponto e Direção Início Ponto Fim com Continuação (Ctrl) +5209=Conexão +5210=Chanfro +5211=Retângulo 2 Pontos +5212=Polígono +5213=Polígono de Lado +5214=Texto
Texto Avançado (Shift) +5215=Plano contornado
Região plana (Shift) +5216=Extrusão +5217=Revolução +5218=Aparafusamento +5219=Riscada +5220=Unir Superfícies +5221=Explodir Superfícies e Regiões Planas +5222=Inverter Superfícies e Regiões Planas +5223=Cancelar +5224=Modificar Camada
Modificar Camada com Transformações (Shift) +5225=Modifica Transparência +5226=Anula Cor +5227=Modificar Cor +5228=Inverter Curva +5229=Modificar Ponto Inicial de Curva Fechada +5230=Extender ou Encurtar Curva +5231=Quebrar Curva +5232=Dividir Curva +5233=Unir Curvas
Unir Curvas criando uma Cópia (Shift)
Mesclar Curvas em Composta (Ctrl) +5234=Explodir Curvas e Textos +5235=Espessura e Extrusão Curva +5236=Mover +5237=Girar +5238=Gira 3D +5239=Espelha +5240=Espelha 3D +5241=Escala +5242=Escala 3D +5243=Deslocamento +5244=Desenho 2D +5245=Desenho 3D +5246=Modificar +5247=Transformar +5248=Varrido (Seção, Guia) +5249=Editar Texto +// Painel Vista Grelha +5251=Wireframe +5252=Linhas Escondidas +5253=Ensombramento +5254=Zoom All +5255=Zoom In +5256=Zoom Out +5257=Vista de Cima +5258=Vista de Frente +5259=Vista da Esquerda +5260=Vista de Atrás +5261=Vista da Direita +5262=Vista Isométrica de SW +5263=Vista Isométrica de SE +5264=Vista Isométrica de NE +5265=Vista Isométrica de NW +5266=Mostra Direção Curvas +5267=Analisar +5268=Distância +5269=Grelha de Cima +5270=Grelha de Frente +5271=Grelha de Direita +5272=Grelha de Atrás +5273=Grelha da Esquerda +5274=Grelha de Embaixo +5275=Grelha de Vista +5276=Elevação Grelha +5277=Origem Grelha +5278=Gira Grelha
Gira Grelha em 3d (Shift) +5279=Grelha a partir de 3 Pontos +5280=Grelha Perpendicular a Curva +5281=Grelha a partir de Objeto +5282=Vista da Grelha +5283=Zoom Seleção +// Painel Opções de Desenho +// Painel Opções Processamento +// Simulação +5301=END +5302=Sobrecurso +5303=Direção ferramenta não alcançável +5304=Erro +5305=ERRO +5306=Erro em geração! +5307=Simulação +5308=Um passo de cada vez +5309=Play/Pausa +5310=Stop/Home +5311=PAUSA +5312=STOP +5313=Não é possível sair agora. Primeiro parar a simulação ou aguardar a sua conclusão! +5314=HOME +5315=AVISO +5316=Fresagem Virtual +5317=Erro no cálculo das estimativas! +5318=Ficheiro das estimativas inexistente +5319=Colisão! +5320=INFORMAÇÃO +5330=GERAR +5331=O projeto deve ser guardado antes da geração CN. Quer guardar? +5332=Gerado com sucesso +5333=A licença não permite a geração CN +5340=Estimativas +5341=Tempo total +5342=Comprimento total +5343=Detalhes +5344=Estimativas detalhadas +// Opções de Desenho +5351=Propriedade +5352=Peça Nova +5353=Camada Nova +5354=Cor +5355=Parâmetros de desenho +5356=Selecionar +5357=Deselecionar +5358=Nome +5359=Info +5360=Deslocar +5361=Copiar +5362=Eliminar +5363=Guardar +5364=Mostrar +5365=Confirmar +5366=Confirma Cancelamento +5367=Peça em processamento, quer cancelá-la na mesma ? +// Operações +5401=Operações +5402=Parâmetros Operação +5403=Aplicar Processamento +5404=Novo Proc +5405=Nova Disp +5406=Cancelar +5407=Genéricos +5408=Desloca em cima +5409=Desloca em baixo +5410=Atualizar +5411=Atualização concluída com sucesso +5412=Novos Processamentos +5413=Previsualização Ferramenta +5414=Adiante +5415=Atrás +5416=Duplicar +5417=Copiar no Bd +5418=Nome processamento no Bd +5419=Inserção processamento falida +5420=Renomear +5421=O nome não pode começar com "Disp" +5422=Nome já utilizado +5423=???La lavorazione non può essere applicata per i seguenti motivi: +// Disposição +5431=Ok +5432= +5433=Novo +5434=Remover +5435=Comprimento +5436=Largura +5437=Altura +5438=Posição +// Erros Process & Disposição +5461=ERRO DE EXECUÇÃO SCRIPT +5462=Erro na execução do script automático de disposição +5463=Erro na execução do script de início processamentos +5464=Erro na execução do script de completamento processamentos +// Grupo Process. +5501=Tem certeza de querer limpar o Grupo de Processamento? +5502=Tem certeza de querer cancelar o Grupo de Processamento? +5551=Não há Grupos de Processamento :
selecionar as peças a inserir e
repetir o comando para criar o primeiro +5552=Quer criar um novo Grupo de Processamento
com as peças selecionadas ? +// Página Bd Ferramentas +6001=Ponta +6002=Lâmina +6003=Fresa +6004=Entalhadeira +6005=Composto +6006=Ponta comprida +6007=Lâmina plana +6008=Fresa sem ponta +6009=Cinzel +6010=WaterJet +6051=Corretor +6052=Saída +6053=Tipo +6054=Refrigerante +6055=Raio Corner +6056=Diâmetro +6057=Diâmetro Total +6058=Avanço +6059=Avanço Final +6060=Avanço Inicial +6061=Avanço de Ponta +6062=Comprimento +6063=Comprimento total +6064=Máximo Material +6065=Deslocamento Longitudinal +6066=Deslocamento Radial +6067=Rotação +6068=Ângulo do Flanco +6069=Rotação Máxima +6070=Espessura +6071=Absorção Máxima +6072=Avanço Mínimo +6073=Desenho +6074=Cabeçote +6075=Nome +6076=Notas +6077=Posiç. Troca Ferramenta +6078=Posição +6079=Distância +6080=???Overtable +// Erros Ferramentas +6100=Guardar a ferramenta modificada ? +6101=GUARDA +6102=O ficheiro deve ser .nge +6103=O ficheiro é inexistente +6104=Não há o ToolMaker para este tipo de ferramenta +6105=Impossível criar a ferramenta com estes parâmetros +6106=O Máximo Material deve ser maior que 0 +6107=O Máximo Material deve ser menor que Len +6108=A Espessura deve ser maior que 0 +6109=O Diâmetro deve ser maior que 0 +6110=O Comprimento deve ser maior que 0 +6111=A Speed deve ser menor que a Speed Máxima +6112=Nome não válido +6113=O Comprimento deve ser menor que o Comprimento Total +6114=O Comprimento deve ser maior do Máximo Material +6115=O Comprimento Total deve ser maior que 0 +6116=O Comprimento Total deve ser maior que o Comprimento +6117=O Máximo Material deve ser menor que 1/3 do Diâmetro +6118=O Diâmetro deve ser menor que o Diâmetro Total +6119=O Diâmetro deve ser 3 vezes maior que o Mássimo Material +6120=O Diâmetro Total deve ser maior que 0 +6121=Comprimento demasiado pequeno com o porta-ferramentas +6122=Tem certeza de querer cancelar a ferramenta +6123=? +6124=CANCELA +6125=Ficheiro de configuração equipamento inexistente! +6126=Erro +6127=Configurar o tipo de cabeçote. +6128=Configurar o tipo de saída. +6129=Ferramenta não válida, corrigir ou cancelar antes de sair do Bd Ferramentas. +6130=Impossível carregar o banco de dados ferramentas. Se a pasta das máquinas se encontrar num servidor, verificar que a conexão esteja ativa. +6131=A Espessura deve ser diferente do 0 +6132=O Ângulo do Flanco deve ser inferior de 90 +6133=O Ângulo do Flanco deve ser maior de -90 +6134=O Comprimento Total deve ser maior que Comprimento + Espessura +6135=Raio Corner tem um valor demasiado grande +6136=A Espessura tem um valor demasiado pequeno relativamente ao Raio Corner +6137=O diâmetro resultante supera o Diâmetro Total +6138=O diâmetro resultante ‚ menor que 0 +6139=O diâmetro haste resultante ‚ menor ou ugual a 0 +6140=Máximo Material deve ser maior que o Raio Corner +6141=Máximo Material resultante deve ser >= 0 +6142=Raio Corner não deve superar metade da Espessura +6143=???Salvataggio utensile +6144=???Utensile modificato! Tutti gli utensili devono essere salvati prima di cambiare le attivazioni. Salvare l'utensile {0}? +6145=???Posizione già occupata! +6146=???Posizione non definita! +// Página Bd Processamentos +6201=Perfuração +6202=Corte de lâmina +6203=Fresagem +6204=Esvaziamento +6205=Entalhamento +6206=Desbaste de espessura com lâmina +6207=Acabamento com lâmina +6208=Proc. genérico +6209=Cinzeladura +6210=Sgrossatura superfici +6211=Finitura superfici +6212=WaterJet +6251=Inverter +6252=Soltar Tab +6253=Tipo +6254=Lado de processamento +6255=Lado do cabeçote +6256=Engate +6257=Conexão +6258=Saída +6259=Uso curvas +6260=Tipo de Step +6261=Subtipo +6262=Tipo abordagem +6263=Velocidade +6264=Alimentar +6265=Alimentação inicial +6266=Alimentação final +6267=Alimentação de cabeçote +6268=Deslocamento radial +6269=Deslocamento longitudinal +6270=Afundamento +6271=Ângulo do Flanco +6272=Aproximação +6273=Dist. de segurança +6274=Compr. desacel. Inicial +6275=Compr. desacel. Final +6276=Compr. passante atual. +6277=Passo +6278=Posição de retorno +6279=Comprimento +6280=Distância +6281=Altura +6282=Ângulo +6283=Dist. tangente engate +6284=Dist. perp. engate +6285=Elevação engate +6286=Compr. correç. engate +6287=Dist. tangente de saída +6288=Dist. perp. de saída +6289=Elevação de saída +6290=Compr. correç. de saída +6291=Compr. adic. engate +6292=Compr. adic. de saída +6293=Passo no externo arco +6294=Passo no interno arco +6295=Passo de lado +6296=Alimentação vertical +6297=Nome +6298=Ferramenta +6299=Afundamento +6300=Notas +6301=Sovraposição +6302=Deslocamento +6303=Subtipo +6304=SCC +6305=Nenhum +6306=Standard +6307=Oposto +6308=AuxDir Direita +6309=AuxDir Esquerda +6310=AuxDir Atrás +6311=AuxDir Adiante +6312=AuxDir Em cima +6313=AuxDir Embaixo +6314=Mais Perto AuxDir +6315=Mais Longe AuxDir +6320=Centro +6321=Esquerda +6322=Direita +6323=Estender +6324=Standard +6325=Interno +6326=Externo +6327=Extenso centrado +6328=Extenso externo +6329=Nenhum +6330=Linear +6331=Tangente +6332=Seguimento +6333=Hélice +6334=Estender anterior +6335=Estender sucessivo +6336=Estender ambos +6337=Como engate +6338=Saltar +6339=Aproximar +6340=Convexo +6341=Manter +6342=Zigue-Zague +6343=Uma via +6344=Espiral +6345=Vai e volta +6346=Longitudinal +6347=Transversal +6348=Espiral In +6349=Espiral Out +6350=Avançados +6351=Inverter direç. ferramenta +6352=Processamento face +6353=Não definido +6354= Paralelo +6355= Ortogonal +6356= Ortog. Acima +6357=Embaixo +6358=Em cima +6359=Adiante +6360=Atrás +6361=Esquerda +6362=Direita +6363=Contorno +6364=Ângulos Sugeridos +6365=Eixo Bloqueado +6366=???Numero massimo +6367=???Numero minimo +// Erros processamentos +6370=Guardar o processamento modificado? +6371=GUARDAR +6372=Nome não válido +6373="Os carácteres \ / : * ? "" < > | não são aceitos" +6374=Tem certeza de querer cancelar +6375=? +6376=CANCELAR +6377=Impossível recarregar o banco de dados dos processamentos. Se a pasta das máquinas se encontrar num servidor, verificar que a conexÆo esteja ativa. +6378=???Oscillazione +6379=???Ampiezza +6380=???Lungh. rampa +6381=???Lungh. cresta +// Página Opções Processamentos +6401=Z de segurança +6402=Quebra arcos +6403=Nunca +6404=Plano genérico +6405=Plano diferente de XY +6406=Sempre +6407=Instrumentação pré-definida +6408=Segurança reenvio debaixo +6409=Tolerância furos +// Janela de Configuração +6451=Configuração +6452=Aplicar +6453=Arquiviar +6454=Recuperar +6455=Auto +6456=Aplicar a instrumentação corrente antes de sair? +6457=???New +// Erros de Configuração +6471=Erro +6472=Aviso +6473=Ferramenta inexistente +6474=no BD ferramentas. +6475=A posição pré-definida da ferramenta não é válida. +6476=A posição pré-definida da ferramenta está já ocupada. +6477=O ficheiro de configuração não existe! +6478=A instrumentação usa um cabeçote que não existe na máquina! +6479=Erro no carregamento do setup +// Página Opções +6501=Idioma corrente +6502=O novo idioma se tornerá corrente a partir do próximo arranque do programa. +6503=Curvas +6504=Superfícies +6505=Curvas e Superfícies +6506=Geometria selecionável +6507=Adicionar o novo processamento no final +6508=Utilizar script de disposição +6509=Unidade de medição +6510=Cor da vista em cima +6511=Cor da vista em baixo +6512=Cor padrão +6513=Tolerância geométrica +6514=Geral +6515=CAD +6516=CAM +6517=Cor da grelha +6518=Superfícies chanfradas +6519=Importar +6520=DXF +6521=STL +6522=Imagens +6523=Exportar +6524=Imagem +6525=Largura (pixel) +6526=Altura (pixel) +6527=Atualizar Máquina +6528=A máquina "{0}" já existe,
o que você faz? +6529=O ficheiro {0} não contém uma máquina. +6530=A máquina "{0}" foi atualizada com sucesso. +6531=Substituir +6532=Atualizar +6533=Anular +6534=Aviso +6535=A atualização da máquina "{0}" falhou. +6536=Linhas grossas +6537=???Lunghezza extra del riferimento +6538=???Lunghezza della freccia +6539=???Distanza del testo +6540=???Unità di misura +6541=???Decimali +6542=???Font +6543=???Altezza del testo +6544=???Quotatura +6545=???Unità corrente +6546=???Altra +6547=???Unità di misura +6548=Fator de escala +6549=Exportar Máquina atual +6550=???Select the folder where you want to save the machine +6551=???The exportation of the "{0}" machine failed. +6552=???The machine "{0}" has been successfully exported. +6553=???Update Licence +// Cabeçotes +6601=Vertical +6602=Horizontal +6603=Agr. 2 saídas +6604=Agr. 3 saídas +6605=Agr. 4 saídas +6606=Cabeçote 3 eixos +6607=Cabeçote 4 eixos +6608=Cabeçote 5 eixos +6609=Lançadeira 1 +6610=Lançadeira 2 +6611=Multi rotante +6612=Gr. a perfurar +6613=Multi cinz. +6614=Reenvio em baixo +6615=Lâmina 5 eixos +6616=Motosserra manual +6617=Agr. 1 saídas +6618=Cabeçote apalpagem +6619=Flutuante 360° +6620=???Seconda Testa 5 assi +6621=???Foratore orizzontale +6622=???Mortasatrice +6623=???Seconda Lama 5 assi +6624=???Aggr. 1 uscita tilt. +6625=???Estrusore +6799= +// Barra Estado +6801=Diretório Máquinas inexistente. EgtCAM5 funcionará apenas na modalidade CAD. +// Portas +8001=Criar nova MTable +8002=Guardar MTable +8003=Guardar MTable Como +8004=Eliminar MTable +8005=Guardar ficheiro MTable +8006=Tem certeza de querer cancelar esta MTable? +8007=Guardar a MTable modificada? +8008=Lista das máquinas ativas +8009=Nome da máquina +8010=Gerar Cn +8011=Atualizar bruto +8012=On +8013=Nome Geometria +8014=Operação +8015=MId +8016=Desloc. +8017=Tipo Processamento +8018=Processamento 1 +8019=Processamento 2 +8020=Processamento 3 +8021=Adicionar Máquina +8022=Eliminar Máquina +8023=Adicionar Processamento +8024=Eliminar Processamento +8025=CORR +8026=Configurar MTable corrente +8027=GId +8028=Propriedades +8029=Processamento +8030=Unir +// Erros portas +8101=Erro +8102=Erro na execução do ficheiro Ddf +8103=Aviso +8104=Path da pasta MTable inexistente +8105=A pasta MTable inexistente +8106=Faltam os ficheiros de configuração na pasta MTable +8107=Erro desconhecido +8108=Esta é a MTable correntemente ativa. +8109=Impossível cancelar. +8110=Tem certeza de querer cancelar o processamento selecionado? +8111=CANCELAR +8112=Tem certeza de querer cancelar a máquina selecionada? +8113=Impossível encontrar a pasta das máquinas {0}. Se a pasta das máquinas se encontrar num servidor, verificar que a conexão esteja ativa. +8114=Quer provar recarregar a máquina? +8115=Impossível encontrar a pasta {0}. Se a pasta Doors se encontrar num servidor, verificar que a conexão esteja ativa. +8116=Quer provar recarregar a pasta Doors? +8117=Erro de execução (ver o ficheiro de log) +// GunStock +8201=Nova peça +8202=Gunstock Nova peça +8203=Mod peça +8204=Gunstock Modificar Peça +8205=Parâmetros cálcio +8206=Nome ficheiro +8207=Descrição +8208=Ok +8209=Cancelar +8210=deve haver um valor. +8211=O valor deve situar-se entre +8212=e +8213=Dimensões do bruto +// Erros GunStock +8251=Erro +8252=Erro no lançamento do ambiente Gunstock +8253=Erro na leitura do ficheiro Modelo +8254=Erro na escrita do ficheiro Peça +// ----- Beams ----- +9000=Tabelas de usinagem de viga +9001=Ligado +9002=Nome +9003=Tipo +9004=Adicionar +9005=Excluir +9006=Salvar +9007=Deseja salvar suas alterações? +9008=Erro +9009=Não foi possível abrir o editor de usinagem de viga.
Arquivos de configuração ausentes. +9010=Tabelas de processamento de parede +9011=Não é possível abrir o Editor de Recursos de Parede.
Arquivos de configuração ausentes. +// ----- Erros ----- +10001=Erro +10002=Erro na criação de um novo ficheiro +10003=Erro na abertura do ficheiro +10004=Erro na gravação do ficheiro +10005=Tipo de ficheiro desconhecido +10006=Erro na importação do ficheiro +10007=Erro na exportação do ficheiro +10008=Erro carregando ou criando o Grupo de Trabalho +10009=Non esiste il file +// Janela Chave Ausente +10101=Erro ! +10102=Chave não presente. +10103=Inseri-la e reinicializar o programa. +10104=Ok +10105=Programa sem licença. +10106=Carregá-la e reinicializar o programa. +10107=Executar GetMachineId e enviar os resultados ao fornecedor. +// Teclado numérico virtual +10201=Expressão errada +// ----- CaixaMensagens ----- +15001=Erro +15002=Aviso +15003=Informação +15010=Erro desconhecido +// ----- EgtWPFLib ----- +// CalculadorEgt +20011=Expressão errada +// CalculadorEgtWD +20021= +// TecladoEgt +20031= +// EgtCxMsg +20041=Ok +20042=Canc +20043=SIM +20044=NÃO +// ----- EgtWPFLib5 ----- +// EgtGuardaFicheiroDialog +30001=Guardar +30002=Anular +30003=já existe. +30004=Substitui-lo? +30005=Nome ficheiro: +30006=Abrir +30007=ERRO +30008=O nome não pode ser vazio! +30009=ATENÇÃO +30010=Nome Ficheiro +30011=Nome Pasta +// BarraComandos Topo +30501=Novo +30502=Abrir +30503=Guardar +30504=Guardar como +30505=Inserir +30506=Importar +30507=Exportar +30508=Executar +30509=Opções +30510=Endereço email de suporte inexistente. +30511=Guardar o projeto corrente antes de enviar o feedback? +30512=Enviar o feedback a {0} com a pasta anexada {1}. +30513=Feedback +30514=Email de feedback pronta. +// Grid View Panel +30801=Wireframe +30802=Linhas Escondidas +30803=Ensombramento +30804=Zoom All +30805=Zoom In +30806=Zoom Out +30807=Vista de Cima +30808=Vista de Frente +30809=Vista da Esquerda +30810=Vista de Atrás +30811=Vista da Direita +30812=Vista Isométrica de SW +30813=Vista Isométrica de SE +30814=Vista Isométrica de NE +30815=Vista Isométrica de NW +30816=Mostra Direção Curvas +30817=Analizar +30818=Distância +30819=Grelha de Cima +30820=Grelha de Frente +30821=Grelha de Direita +30822=Grelha de Atrás +30823=Grelha da Esquerda +30824=Grelha de Embaixo +30825=Grelha da Vista +30826=Elevação Grelha +30827=Origem Grelha +30828=Gira Grelha +30829=Grelha a partir de 3 Pontos +30830=Grelha Perpendicular à Curva +30831=Grelha do Objeto +30832=Vista da Grelha +// MachGroupPanel +30901=Novo grupo de processamento +30902=Nome: +30903=Máquina: +// ToolDbWindow +31001=Ponta +31002=Lâmina +31003=Fresa +31004=Entalhadeira +31005=Composto +31006=Ponta longa +31007=Lâmina plana +31008=Fresa sem ponta +31009=Cinzel +31010=???Waterjet +31051=Corretor +31052=Saída +31053=Tipo +31054=Refrigerante +31055=Raio Corner +31056=Diâmetro +31057=Diâmetro Total +31058=Avanço +31059=Avanço Final +31060=Avanço Inicial +31061=Avanço de Ponta +31062=Comprimento +31063=Comprimento total +31064=Máximo Material +31065=Deslocamento Longitudinal +31066=Deslocamento Radial +31067=Rotação +31068=Ângulo do flanco +31069=Rotação Máxima +31070=Espessura +31071=Absorção Máxima +31072=Avanço Mínimo +31073=Desenho +31074=Cabeçote +31075=Nome +31076=Note +31077=Posiç. Troca Ferramenta +31078=Posição +31079=???Drilling +31080=???Tagliente +// ToolDb Errors +31100=Guardar a ferramenta modificada ? +31101=GUARDAR +31102=O ficheiro deve ser .nge +31103=O ficheiro não existe +31104=Não existe o ToolMaker para este tipo de ferramenta +31105=Impossível criar a ferramenta com estes parâmetros +31106=O Máximo Material deve ser maior que 0 +31107=O Máximo Material deve ser menor que Len +31108=A Espessura deve ser maior que 0 +31109=O Diâmetro deve ser maior que 0 +31110=O Comprimento deve ser maior que 0 +31111=A Velocidade deve ser inferior à Velocidade Máxima +31112=Nome não válido +31113=O Comprimento deve ser menor que o Comprimento Total +31114=O Comprimento deve ser maior que o Máximo Material +31115=O Comprimento Total deve ser maior que o 0 +31116=O Comprimento Total deve ser maior que o Comprimento +31117=O Máximo Material deve ser menor que {0} +31118=O Diâmetro deve ser menor que o Diâmetro Total +31119=O Diâmetro deve ser 3 vezes maior que o Máximo Material +31120=O Diâmetro Total deve ser maior que 0 +31121=Comprimento demasiado pequeno com o porta-ferramenta +31122=Tem certeza de querer cancelar a ferramenta +31123=? +31124=CANCELAR +31125=Ficheiro de configuração instrumentação inexistente! +31126=Erro +31127=Configurar o tipo de cabeçote. +31128=Configurar o tipo de saída. +31129=Ferramenta não válida, corrigir ou cancelar antes de sair do Bd Ferramentas. +31130=Impossível recarregar o banco de dados ferramentas. Se a pasta das máquinas se encontrar num servidor, verificar que a conexão esteja ativa. +31131=A Espessura deve ser diferente do 0 +31132=O Ângulo do Flanco deve ser inferior de 90 +31133=O Ângulo do Flanco deve ser superior de -90 +31134=O Comprimento Total deve ser maior que Comprimento + Espessura +31135=Raio Corner tem um valor demasiado grande +31136=A Espessura tem um valor demasiado pequeno com respeito ao Raio Corner +31137=O diâmetro resultante supera o Diâmetro Total +31138=O diâmetro resultante é menor que 0 +31139=O diâmetro haste resultante é inferior ou igual a 0 +31140=O Máximo Material deve ser maior do Raio Corner +31141=O Máximo Material resultante deve ser >= 0 +31142=???Il Tagliente deve essere maggiore di 0 +31143=???Il Tagliente deve essere minore di Len +// ImportExportToolWindow +31161=???Import +31162=???Export +31163=???Tools +31164=???Tool already existing in DB. Overwrite? +31165=???Tool will be imported with the name followed by "_imp" +31166=???The following Tools have been imported succesfully: +31167=Reset +// MachiningDbWindow +31201=Perfuração +31202=Corte de lâmina +31203=Fresagem +31204=Esvaziamento +31205=Entalhamento +31206=Desbaste de espessura com lâmina +31207=Acabamento com lâmina +31208=Proc. genérico +31209=Cinzeladura +31210=???Waterjetting +31211=???Surffinishing +31251=Inverter +31252=Soltar Tab +31253=Tipo +31254=Lado de processamento +31255=Lado do cabeçote +31256=Engate +31257=Conexão +31258=Saída +31259=Uso curvas +31260=Tipo de Step +31261=Subtipo +31262=Tipo abordagem +31263=Speed +31264=Feed +31265=Feed inicial +31266=Feed final +31267=Feed de cabeçote +31268=Deslocamento radial +31269=Deslocamento longitudinal +31270=Afundamento +31271=Ângulo do flanco +31272=Aproximação +31273=Dist. de segurança +31274=Compr. desacel. inicial +31275=Compr. desacel. final +31276=Compr. passante atual. +31277=Passo +31278=Posição de retorno +31279=Comprimento +31280=Altura +31281=Ângulo +31282=Distância +31283=Dist. tangente +31284=Dist. perp. +31285=Elevação +31286=Compr. correç. +31287=???Numero minimo +31288=???Numero massimo +31291=Compr. adic. +31293=Passo no externo arco +31294=Passo no interno arco +31295=Passo de lado +31296=Feed vertical +31297=Nome +31298=Ferramenta +31299=Afundamento +31300=Notas +31301=Sovraposição +31302=Deslocamento +31303=Subtipo +31304=SCC +31305=Nenhum +31306=Standard +31307=Oposto +31308=AuxDir Direita +31309=AuxDir Esquerda +31310=AuxDir Atrás +31311=AuxDir Adiante +31312=AuxDir Em cima +31313=AuxDir Embaixo +31314=Mais Perto AuxDir +31315=Mais Longe AuxDir +31320=Centro +31321=Esquerda +31322=Direita +31323=Estender +31324=Standard +31325=Interno +31326=Externo +31327=Extenso centrado +31328=Extenso externo +31329=Nenhum +31330=Linear +31331=Tangente +31332=Seguimento +31333=Hélice +31334=Estender anterior +31335=Estender sucessivo +31336=Estender ambos +31337=Como engate +31338=Saltar +31339=Aproximar +31340=Convexo +31341=Manter +31342=Zigue-Zague +31343=Uma via +31344=Espiral +31345=Vai e volta +31346=Longitudinal +31347=Transversal +31348=Espiral In +31349=Espiral Out +31350=Avançados +31351=Inverter direç. ferramenta +31352=Processamento face +31353=Não definido +31354= Paralelo +31355= Ortogonal +31356= Ortog. Acima +31357=Embaixo +31358=Em cima +31359=Adiante +31360=Atrás +31361=Esquerda +31362=Direita +31363=Contorno +31364=Ângulos Sugeridos +31365=Eixo Bloqueado +31366=Feed £ltimo para trás +31367=Passo para trás +31368=Passo inclinado +31369=Passo para trás inclinado +31370=Inclinar para frente +31371=Sondando +31372=Dist. Mín. pontos +31373=Dist. Máx. pontos +31374=Externo +31375=Interno +31376=Comprimento lento. +31377=Desaceleração. % +31378=Orifício de fixação +31379=Raio +31380=Num. voltas no LP +31381=Num. rotações em HP +31382=Oscilação +31383=Largura +31384=Comprimento rampa +31385=Comprimento crista +31386=Genérico +31387=Avançado +31388=Tang+Perp +31389=Perp+Tang +//MachiningTreeView +31391=???Standard +31392=???Slowdown +31393=???Loop +31394=???Enable +31395=???Add Length +31396=???Start +31397=???End +31398=???System notes +31399=???Epicycles radius +31400=???Epicycles distance +// MachiningDb Errors +31401=Guardar o processamento modificado? +31402=GUARDAR +31403=Nome não válido +31404=Os carácteres \ / : * ? "" < > | não são aceitos +31405=Tem certeza de querer cancelar +31406=? +31407=CANCELAR +31408=Impossível recarregar o banco de dados dos processamentos. Se a pasta das máquinas se encontrar num servidor, verificar que a conexão esteja ativa. +31409=???Machine material not recognized +31410=???Lavorazione non valida, correggerla o cancellarla prima di uscire. +31411=???La Lunghezza deve essere positiva +31412=???La Distanza deve essere positiva +31413=???L'Altezza deve essere positiva +31414=???L'Angolo deve essere compreso tra {0}° e {1}° +31415=???N° massimo deve essere nullo o positivo +31416=???N° massimo deve essere maggiore o uguale al minimo +31417=???N° minimo deve essere nullo o positivo +31418=???N° minimo deve essere minore o uguale al massimo +31419=???L'abilitazione di {0} disabiliterà {1}. Procedere? +// ImportExportMachiningWindow +31450=???Import +31451=???Export +31452=???Machinings +31453=???Machining already existing in DB. Overwrite? +31454=???Machining will be imported with the name followed by "_imp" +31455=???The following Machinings have been imported succesfully: +31456=???Reset +// SetUp Window +31501=Configurar +31502=Aplicar +31503=Arquiviar +31504=Recuperar +31505=Auto +31506=Aplicar a instrumentação corrente antes de sair? +// SetUp Errors +31551=Erro +31552=Aviso +31553=Ferramenta inexistente +31554=no BD ferramentas. +31555=A posição pré-definida da ferramenta não é válida. +31556=A posição pré-definida da ferramenta está já ocupada. +31557=O ficheiro de configuração não existe! +31558=A instrumentação usa um cabeçote que não existe na máquina! +31559=Erro no carregamento da configuração +// Simulation +31601=Simulação concluída +31602=Sobrecurso +31603=Direção ferramenta não alcançável +31604=Erro +31605=ERRO +31606=Erro em geração! +31607=Simulação +31608=Um passo de cada vez +31609=Reproduzir/Pausar +31610=Parar/Home +31611=Pausa +31612=Simulação interrompida +31613=Impossível sair agora. Primeiro parar a simulação ou esperar pelo fim da mesma! +31614=ATENÇÃO +31615=Ficheiro das estimativas inexistente +31616=Estimativas pormenorizadas +//MachiningDbWindow/ToolDbWindow buttons +31701=Novo +31702=Salvar +31703=Remover +31704=???Edit +//Db Waterjet +31751=???Waterjet Db +31752=???Thickness +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=???Do you want to save edits? +// ----- EgtDOORCreator ----- +//General +50001=Largura +50002=Altura +50003=Espessura +50004=Batente +50005=Lado-fechadura +50006=Lado-dobradiça +50007=Topo +50008=Fundo +50009=Tipo +50010=Ângulo +50011=Extensão +50012=Lado +50013=Deslocamento lado largo +50014=Margem +50015=Aplicação do topo para o centro +50016=Transversal baixa +50017=Tipo fechadura +50018=Deslocamento a partir do centro +50019=Aponta para o embutimento +50020=Comprimento embutimento +50021=Deslocamento lado estreito embutimento +50022=Apontar para braço +50023=Comprimento braço +50024=Pendurado ao centro +50025=Traslado +50026=Intermédio traslado +50027=Raio +50028=Transversal alta +50029=Posição +50030=Comprimento +50031=Modelo +50032=Em cima +50033=Em baixo +50034=Forma +50035=Dobradiça +50036=Aplicação do topo para topo +50037=Aplicação do topo para o centro +50038=Bloqueio do topo para o centro +50039=Profundidade +50040=Geral +50041=Centro +50042=Através +50043=Aplicação face para linha do centro +50044=Tipo de aresta +50045=Sobrematerial +50046=Enviar Feedback +50047=Peso +50048=Ângulo +50049=Face +50050=Segurar +50051=Ranhura de chaveta +50052=Marca +50053=Pasta +50054=Pasta principal +50055=Ombreira +50056=Iluminação +50057=Luz Fechadura +50058=Luz Base +50059=Luz Dobradiça +50060=Espessura Cabeçote +50061=Sobreposição Dobradiça +50062=Sobreposição Fechadura +50063=Sobreposição Topo +50064=Delta T +50065=Exterior +50066=Número de Portas +50067=Ombreiras e Portas +50068=Ordem +50069=Disposição +50070=Cliente +50071=Inverter perfil fechadura +//Compo Name +50072=Ferrolhos +50073=Puxador de superfície +50074=Dobradiça +50075=Fechadura +50076=Passagem animais +50077=Caixa de correio +50078=Ferragens lado superior +50079=Dobradiça perno +50080=Trava rolo +50081=???Travar e aproximar +50082=Placa de encosto +50083=Puxador encastrado puxar +50084=Olho mágico +50085=Passamuro +50086=???Grove +50087=???Malhete +50088=???Ept +50089=???Raceway +50090=???Decorazioni +//error messages +50100=Diretório inexistente +50101=Erro +50102=Leitura falida do ficheiro ddf. Falta um parâmetro fundamental {0}. +50103=Leitura valor falida. +50104=Leitura na linha do ficheiro ddf falida +50105=Linha +50106=Valor não aceitável em +50107=Ficheiro vazio. +50108=Impossível adicionar a componente. Inserir uma porta! +50109=Quer guardar este ficheiro ({0}) ? +50110=Demanda +50111=Adicionar nova porta +50112=Remover porta +50113=Nova Porta +50114=O nome do ficheiro já existe no diretório corrente ({0}). +50115=Atenção +50116=Quer cancelar este ficheiro ({0}.ddf) ? +50117=Confirmar o cancelamento ({0}.ddf) ? +50118=Informação +50119=Erro na leitura das mensagens. Não há correspondência com o número {0}. +50120=Erro na leitura do nome {0} em {1}. A aguardar uma correspondência numérica. +50121=Erro na leitura {0} no parâmetro {1} da componente: não existe. +50122=Erro no parâmetro {0} da componente {1} da componente. +50123=Erro na leitura {0} no parâmetro {1} da componente: lista inexistente. +50124=Erro na leitura {0} no parâmetro {1} da componente: {2}. +50125=Erro no parâmetro {0} da componente {1} da componente: valor inexistente. +50126=Eliminar +50127=Erro em EgtLoadMessages +50128=Impossível guardar um ficheiro se não há uma porta! +50129=Erro na criação da cena. +50130=Erro na leitura da linha {0}. +50131=Erro na leitura {0}: linha {1}. A aguardar ':' após o nome. +50132=Erro na leitura {0}: linha {1}. A aguardar 'template' ou 'shape'. +50133={0} não foi criado. +50134=Erro na leitura de 'Template' no ficheiro {0}\{1}. A aguardar o nome. +50135=Erro na leitura de 'Template' no ficheiro {0}\{1}. Ficheiro {0}\{2} .lua inexistente. +50136=Erro na leitura {0}: linha {1}. não existe a componente no ficheiro 'Default.ini'. +50137=Erro na leitura {0}: linha {1}. não é um membro da lista. +50138=Este parâmetro será inicializado de default. +50139=Erro na leitura: linha {0}. A aguardar {1}. +50140=Todos os parâmetros ausentes serão inicializados de default. +50141=Expressão não válida em {0}. +50142=Remover componente +50143=Expressão não válida +50144=Aviso +50145=Impossível criar a porta corrente. +50146=Quer abrir um modelo? +50147=Erro na expressão {0}. {1} não associa nada. +50148=Valor não válido. +50149=Atenção: o peso é selecionado na página das configurações. Quer desativá-lo? +50150=Atenção: o peso é um parâmetro do ficheiro .ddf. Quer adicioná-lo às configurações? +50151={0} Não pertence à lista das arestas. Seleciona o Bevel na página das configurações. +50152=Quer guardar este ficheiro ({0})? +50153=Atenção: o peso é um parâmetro da porta corrente. Quer removê-lo da porta? +50154=Este bevel é selecionado na porta corrente. Quer continuar? +50155=Impossível criar um modelo se não existe uma porta! +50156=Erro na leitura ddf: a porta não é completa ou o ddf foi separado num modo errado da '---'. +50157=O script Lua ( {0}\{1} ) é inexistente. +50158=Bevel {0} não pode ser aceito em Jamb. +50159=Parâmetro ausente em ddf! +50160=O ficheiro {0} diretório {1} é inexistente. +50161=parâmetro +50162=No ficheiro {0} parâm 'Default' deve ser numérico. +50163=Erro na leitura da Assemblagem Geral em DDF +50164=Em Assemblagem Geral: +50165=CompoDir inexistente : +50166=Compo Ombreira não existe +50167=Linha Vazia +50168=Nenhum parâm compatível +50169=A disposição da porta foi modificada. +50170=Incongruência entre os chanfros, foi resolvida por defeito. +50171=No ficheiro StdTempate.ini falta o parâm numérico em [Type]. +50172=Ficheiro inexistente. +50173=Tipo de definição não correto: +50174=Falta nome do novo modelo! +50175=O ficheiro: {0} já existe no diretório {1} . Quer sobrescrevê-lo +50176=Erro na cópia: {0} +50177=Quer guardar as alterações atuais? +50179=Compo Portas Default.ini inexistente +50180=Atenção : {0} inexistente. +50181=Erro na impressão da imagem. +50182=Erro na execução da impressão +50183=Algumas portas poderiam usar esta ferramenta, confirma a eliminação? +50184=Não é possível cancelar Hardware se não está selecionado algum Hardware! +50185=Não é possível duplicar Hardware se não está selecionado algum Hardware! +50186=O projeto deve ser guardado antes de ser copiado. +50187=Quer copiar todos os ficheiros ? {0} (Não: para copiar apenas o ficheiro corrente) +50188=Exportar em máquina +50189=Diretório máquina inexistente +50190=Erro durante a cópia: {0} +50191=Não há alguma porta, impossível copiar +50192=Não há alguma porta, impossível exportar para a máquina +50193=Não há alguma porta, impossível imprimir +50194=As propriedades foram canceladas +50195=A configuração do ddf corrente ({0}) é diferente da configuração do programa ({1}).{2}Para carregar a configuração do ddf corrente deve relan‡ar o programa quer fazê-lo? +50196=A configuração do ddf ({0}) não existe! +50197=Porta arco modificada porque a configuração não a prevê. +50198=O perfil no lado fechadura deveria ser invertido. +//Option +50200=Unidade de medida +50201=Geral +50202=???LockEdgeOverMaterial +50203=???HingeEdgeOverMaterial +50204=???TopOverMaterial +50205=???BottomOverMaterial +50206=Abrir janela +50207=Último projeto +50208=Vazio +50209=Página das opções +50210=Arranque programa +50211=Unidade de medição nova porta. +50212=Diretório Projeto +50213=Configuração de arranque +50214=Diretório Atual +50215=Tipo Bordo +50216=Over Material +50217=Navegar +50218=Fechar +50219=Chanfro +50220=Chanfro em cima +50221=Chanfro em baixo +50222=Posicionamento porta em processamento. +50223=Guarda como modelo +50224=Associação +50225=Marca +50226=Modelo +50227=Modelo +50228=Habilitar modelo +50229=Habilitar Encomenda +50230=Abrir porta modelo. +50231=Abrir encomenda janela. +50232=???Directory Template +//Scene +50301=Atualizar +50302=Adicionar Nova Porta +50303=Remover Porta +50304=Novo Projeto +50305=Ajuda +50306=Diretório Máquina +50307=Máquina +50308=Portinhola +50309=Lado Largo em baixo (BU) +50310=Lado Largo em cima (BD) +50311=Resize +50312=Design +50313=???Save as pdf +//Launcher +50400=Lançador +50401=Abrir Novo Projeto +50402=Abrir Projeto +50403=Abrir Último Projeto +50404=Novo Projeto +50405=Nova Ferragem +50406=Elevação +50407=Projeto +50408=PO +50409=Linha +50410=Guardar +50411=Imprimir +50412=Anular +50413=Ferragens +50414=Dimensionar +50415=Duplicar +50416=Exportar na máquina +50417=Modelo Novo +50418=Dimensão +50419=Novo Diretório +50420=Recalcular posição Hardware +50421=???Reload Directory +50422=???Save As +50423=???Reaload Compo on Jamb +//Error (continue) +50501=Erro na leitura do parâmetro {0 na componente {1} : definição incompleta (controlar StdTemplate.ini). +50502=Erro na leitura do parâmetro {0 na componente {1} : nenhuma associação (controlar StdTemplate.ini e GeometryNameList.ini). +50503=Quer guardar? +50504=O nome do ficheiro contém espaços vazios nas extremidades, quer eliminá-los ? +50505=O DDF não é um conjunto, as partes presentes são: {0}, quer guardar? +50506=Impossível encontrar a primeira portinhola! +50507=O batente não é um elemento da lista de batentes duma porta única. +50508=O batente da porta esquerda não é um elemento da lista de batentes do porta esquerda. +50509=O batente da porta direita não é um elemento da lista de batentes do porta direita. +50510=O batente da porta esquerda se encontra na porta direita e vice-versa. +50511=O batente da porta esquerda não é um elemento da lista de batentes do porta esquerda. +50512=O batente da porta direita não é um elemento da lista de batentes do porta direita. +50513=não é possível encontrar a primeira porta (DO_1) e a segunda porta (DO_2)! +50514=Os batentes estão decisamente errados! +50515=A primeira porta não é realmente a primeira, verificar o ddf. +50516=O ddf atual contém {0} ombreiras. +50517=O ddf atual não contém portas! +50518=O ddf atual não é um conjunto. +50519=Não é possível abrir um ddf sem portas. +50520=O ddf atual é um conjunto. +50521=O ddf corrente é uma peça do chassis: {0}. +50522=O perfil {0} não é um elemento da lista de perfiles {1}. +50523=Falta o perfil no lado {0}. +50524=???{0} file aperto da un altro EgtDOORCreator {1}. +50525=???{0} file open by another EgtDOORCreator {1}. +50526=???Il direttorio {0} già esiste! Vuoi sovrascriverlo? +50527=???Impossibile sovrascrivere {0} +50528=???Impossibile salvare il file fuori dal progetto corrente! +50530=???Property {0} does not exist in the list of {1}. Look at file "../Compo/Default.ini". +50531=???The current material {0} does not exist in the list of material. Look at file "../Compo/Default.ini". +50532=???Missing list of material at file "../Compo/Default.ini". +50533=???Impossible to load more than one property at time. +50534=???Property {0} does not exist in the list. Look at file "../Compo/Default.ini". +50535=???Impossible to delete a project if there is not a project! +50536=???Do you want to delete entire project? +50537=???Do you want to delete subdirectory {0} ? +50538=???Impossible to vreate a template door if there is not a door! +50539=???Do you want to change project? ( All doors will be deleted!) +50540=???The current ddf is a part of a frame, do you want to save? +50541=???{0} in reading {1}. +50542=???{0}: Directory does not exist! +50543=???It has been renamed file: {0}, {1}. +50544=???It has been created new file: {0}, {1}. +50545=???It has been deleted file: {0}, {1}. +50546=???Enable single door. +50547=???Project +50548=???The new configuration will take effect after restart. +50549=???File {0} exist, but it is not in the correct Directory! +50550=???Every componente on jambs will be relocated, do you want to continue +50551=???The current parameters have been modified: +50552=???Do you want to overwrite? +50553=??? has not been created. +50554=???Parameter {0} is already deinfed in geometry {1}. +50555=???Impossible to save. +50556=???File has nge extension. +50557=???Error in deleting file: {0} +50558=???Impossible to import a different hardware! +50559=???Open File Dialog +50560=???The hardware part has not been generated correctly. +50561=???Directory already exists +50562=???Folder {0} does not exist. Check in OptionPage. +50563=???Compo {0} does not exist. +50564=???In group {0} at paramater {1} does not exist: {2} +50565=???Brand {0} has not been found in HardwareManager. +50566=???Template {0} has not been found in HardwareManager. +50567=???Error in executing EgtCam5. +50568=???Error in definition {0} in file GeometryNameList.ini . +50569=???Error in definition {0} in file StdTemplate.ini . +50570=???Nothing has been selected. +//Added General messages +50701=Linhas +50702=Retângulo +50703=???None +50704=???Radius +50705=???Angle +50706=???Pos_x +50707=???Top Arc +50708=???Top Angle +50709=???Properties +50710=???Material +50711=???Mach. +50712=???HardwarePart +50713=???Assemby +50714=???Total Dimension +50715=???Depth +50716=???Overlap Bottom +50717=???Thickness Bottom +50718=???Depth Bottom +50719=???Delta Bottom +50720=???GoToAssembly +50721=???New Geometry +50722=???Geometry Name +50723=???Type Hardware +50724=???Parameter +50725=???Part Dimension +50726=???Apply +50727=???Frame +50728=???Refresh Directory +50729=???General +50730=???Report +50731=???Opposite face +// ----- EgtBEAMEditor ------ +60951=???Cut +60952=???Longitudinal Cut +60953=???Double Cut +60954=???Ridge or Valley Cut +60955=???Saw Cut +60956=???Slot +60957=???Front Slot +60958=???Birds Mouth +60959=???Hip or Valley Rafter Notch +60960=???Ridge Lap +60961=???Lap Joint +60962=???Notch/Rabbet +60963=???Block House Half Lap, Stairs Riser Dado +60964=???Seathing Cut +60965=???French Ridge Lap +60966=???Chamfer +60967=???Block House Half Lap +60968=???Block House Front +60969=???Pocket +60970=???Drilling +60971=???Tenon +60972=???Mortise +60973=???Mortise Front +60974=???House +60975=???House Mortise +60976=???Dovetail Tenon +60977=???Dovetail Mortise +60978=???Dovetail Mortise Front +60979=???Marking/Labeling +60980=???Text +60981=???Simple Scarf +60982=???Scarf Joint +60983=???Step Joint +60984=???Step Joint Notch +60985=???Planing +60986=???Profile Front +60987=???Profile Head concave +60988=???Profile Head convex +60989=???Profile Head cambered +60990=???Round Arch +60991=???Profile Head +60992=???Sphere +60993=???Triangle Cut +60994=???Tyrolean Dovetail +60995=???Dovetail +60996=???Free Contour +60997=???Outline +60998=???Aperture +61001=???Distance from beam start to the reference point +61002=???Distance from the reference edge to the reference point +61003=???Distance from the reference side to the reference point (orthogonal) +61004=???Angle between cut edge and reference edge +61005=???Inclination between face and reference side +61008=???Limit of the 2 ends, binary code +61009=???Inclination to the reference side +61010=???Depth: If P11 is zero, then the face of the cut dispreads to the neigbour-sides or opposite-side to referenceside +61011=???Length: If P12 and P04 equal to zero, the processing is performed along the whole component length +61012=???Angle in face at start +61013=???Angle in face at end +61015=???Distance from the reference point to the reference edge +61016=???Angle between the first cutting edge and the reference edge +61017=???Inclination of the first cutting towards the reference side +61018=???Angle between the second cutting edge and the reference edge +61019=???Inclination of the second cutting towards the reference side +61023=???Inclination between the first face and the reference side +61024=???Inclination between the second face and the reference side +61025=???Depth +61027=???Angle in face at reference edge at start +61028=???Angle in face at reference edge at end +61029=???Angle in face in opposite to reference edge at start +61030=???Angle in face in opposite to reference edge at end +61033=???Displacement to the reference side +61036=???Angle to the reference edge in the cut face +61037=???Depth, orthogonal to the reference side +61038=???Length +61041=???Distance to the reference point orthogonal to the reference side P03 = 0: Slot on one of the 4 sides of the component. P03 > 0: Slot on one of the 2 front sides of the component +61042=???Limit of the 6 faces of the slot, binary code +61043=???Angle to the reference edge in the reference side +61045=???Interior angle at reference point +61046=???Interior angle at opposite of reference point +61047=???Addition to P09 +61048=???Depth orthogonal to the reference side +61049=???Length +61050=???Thickness +61051=???Displacement of the entrance edge at reference point +61052=???Displacement of the entrance edge at opposite of reference point +61055=???Distance to the reference point orthogonal to the reference side +61056=???Limit of the 6 faces of the Frotn Slot, binary code +61059=???Angle between the longitudinal axis of the slot and the reference side +61060=???Depth +61061=???Length +61062=???Width +61065=???Location of P09/P10, if P09>0 and P10>0. If P04=-1, then the location must be defined on the machineside +61066=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole. +61067=???Angle to the reference edge in the reference area +61068=???Inclination between face 1 and reference side +61069=???Inclination between face 2 and reference side +61070=???First cut angle of the counterpart. If P09 is zero, the limit face beside face 1 is parallel to component side. +61071=???First cut inclination of the counterpart. If P10 is zero, the limit face beside face 1 is parallel to component side. +61072=???Depth 1 orthogonal to reference side +61073=???Depth 2 orthogonal to reference side +61074=???Grooving depth in the transverse direction of the component. If P13 is zero, then its value must be calculated:P13=WRS-P02 +61075=???Height Counterpart. Zero means: no limit. Measurement orthogonal to face 1 (P07). +61076=???Width Counterpart. Zero means: no limit. Measurement orthogonal to face 2 (P08). +61079=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole +61080=???Angle notch 1 to the reference edge in the reference area +61081=???Angle notch 2 to the opposite reference edge in the reference area +61082=???Inclination between base area of notches and reference side +61083=???Depth orthogonal to reference side +61084=???Width of notch 1. If this value is equal 0, then the notch is not limited. +61085=???Width of notch 2. If this value is equal 0, then the notch is not limited. +61087=???0: Reference point on referene edge. 1: Reference point on the opposite edge +61088=???Angle to the reference edge in the reference side +61089=???Depth of Half Lap +61090=???Width of Half Lap +61091=???Drill hole diameter +61094=???Displacement to the reference side +61095=???Limit of the 6 faces of the lap, binary code +61096=???Angle to the reference edge in the reference side +61098=???Angle between edge and reference side in face +61099=???Angle in the floor face +61100=???Angle between base face and one face of lap +61101=???Distance (orthogonal) from reference side to point below reference point +61102=???Length +61103=???Chamfer angle +61104=???Grooving depth (length of the lapped scarf in transverse direction). If P14 is zero, then its value must be calculated: P14=WRS-P02 +61107=???Limit of the 6 faces of the notch/rabbet, binary code +61108=???Notch/Rabbet depth +61109=???Notch/Rabbet length +61110=???Notch/Rabbet width +61113=???Depth of the Half Lap on the reference side +61114=???Depth of the Half Lap opposite of the reference side +61115=???Length of the Half Lap / Dado +61117=???Depth of Seathing Cut +61118=???Length of Seathing Cut +61120=???0: Reference point on reference edge; 1: Reference point on the opposite edge +61121=???Angle to the reference edge in the reference side +61122=???Drill hole diameter +61124=???Input of edge(s) to be beveled, binary code: Bit 0=edge 1 ; Bit 1=edge 2; Bit 2=edge 3; Bit 3=edge 4. Example: P04=9: edge 1+4; P04=3: edge 1+2 +61125=???Depth +61126=???Length: If P12 is equal to zero, the processing is performed along the whole component length. +61127=???Shape for bevel exit: 0 = orthogonal, 1 = at 45 deg, 2 = round; +61129=???Depth orthogonal to reference side of the lap 2 and 4. If P03 is zero, then its value must be calculated: P03=HRS +61130=???0:all laps are symmetric to each other; 1:lap on reference edge moved to start beam, lap in opposite of reference edge moved to end beam; 2: lap on reference edge moved to end beam, lap in opposite of reference edge moved to start beam; +61131=???P05=1: drilhole for drop rod, P05=0: no drillhole. The machines defines place and direction of the drillhole. +61132=???lap 1: Depth +61133=???lap 1: Length +61134=???lap 2: Depth +61135=???lap 2: Length +61136=???lap 3: Depth +61137=???lap 3: Length +61138=???lap 4: Depth +61139=???lap 4: Length +61140=???Distance from end of arc orthogonal to the reference side +61141=???Radius of arc +61142=???Distance reference point to center of arc +61143=???Which arc (A, B,C or D) is to produced, binary code +61145=???0:only one lap on reference side; 1:one lap on reference side and one on the opposite side +61146=???Angle to the reference edge in the reference side +61147=???Depth at reference point +61148=???Depth opposite to the reference point +61149=???Depth at reference edge +61150=???Length +61153=???Limit of the 6 faces of the pocket, binary code +61154=???Rotation angle around the local z-axis of the cuboid +61155=???Rotation angle around the local y-axis of the cuboid, rotated with P06 +61156=???Rotation angle around the local x-axis of the cuboid, rotated with P06 and P07 +61157=???Internal angle at the reference point +61158=???Depth of reference point orthogonal to reference side +61159=???Length of Half Lap +61160=???Width of Half Lap +61163=???Distance from the reference face to the reference point. P03 = 0:Drilling on one of the 4 sides of the component. P03 <> 0:Drilling on one of the 2 front sides of the component. +61164=???P03 = 0:Angle to the reference edge in the reference side. P03 <> 0:Angle in the front side. +61165=???Inclination between drilling and reference side. P03 = 0: Inclination between drilling and reference side. P03 > 0: Inclination between drilling and front side +61166=???Depth, orthogonal to reference side or front side. +61167=???Drill hole diameter +61170=???Rounding +61171=???Chamfer +61174=???Angle between axis of the tenon and reference side +61175=???Radius for P04=4 +61176=???Tenon height +61177=???Tenon width +61178=???Margin on the reference side +61179=???Margin opposite the reference side +61182=???Displacement to the reference side +61183=???Rounding +61184=???Angle between axis and reference edge +61185=???Inclination between strut and reference side +61186=???Inclination of hole side walls towards reference side +61187=???Radius for P04=4 +61188=???Mortise depth +61189=???Mortise width +61190=???Height of strut +61191=???Margin on the reference point +61192=???Margin opposite the reference point +61193=???Inclination of hole front side towards reference side +61196=???Rounding +61199=???Angle between axis of the tenon and reference side +61200=???Radius for P04=4 +61201=???Mortise depth +61202=???Mortise width +61203=???Margin on the reference side +61204=???Margin opposite the reference side +61205=???Processident of the associated tenon or dovetail tenon +61206=???Processident of the associated mortise or dovetail mortise +61209=???0:with rounding at the bottom; 1:without rounding, unbounded +61210=???Angle between edge and reference edge +61212=???Angle between axis of the tenon and reference side +61213=???Middle flattening +61214=???Angle of cone +61215=???Tenon height +61216=???Diameter of the curve: If P12 < 0, then the radius must be defined on the machineside. +61217=???Margin on the reference side +61218=???Margin opposite the reference side +61221=???Displacement to the reference side +61222=???0:with rounding at the bottom; 1:without rounding, unbounded +61223=???0:with elongation; 1:with pocket +61224=???Angle between axis and reference edge +61225=???Inclination between strut and reference side +61226=???Middle flattening +61227=???Angle of cone +61228=???Mortise depth +61229=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61230=???Height of strut +61231=???Margin on the reference point +61232=???Margin opposite the reference point +61235=???Displacement to the front side +61236=???0=with rounding at the bottom; 1=without rounding, unbounded +61237=???0=with elongation; 1=with pocket +61240=???Angle between axis of the tenon and reference side +61241=???Middle flattening +61242=???Angle of cone +61243=???Mortise depth +61244=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61245=???Margin on the reference side +61246=???Margin opposite the reference side +61249=???Position and alignment of the text. P04 = 0 if there is no text. +61250=???Angle between axis and reference edge. If P06 equals 180°, then a horizontal line is defined, P12 defines the length of the line. +61251=???Interior angle. If P07 equals zero, 2 single markings have to be produced. +61252=???Width of quadrangle. If P11 equals zero, there is only a single marking. +61253=???Height of quadrangle. If P12 equals zero, marking is limited by the edge opposite to the reference edge. +61254=???Height of text. If P13 equals zero, the machine determines the text height. +61255=???Text (String max. 256 characters) +61258=???Angle between axis and reference edge +61259=???Alignment vertical. 0 = bottom, 1=middle, 2=top +61260=???Alignment horizontal. 0 = left, 1=middle, 2=right +61261=???Alignment in case of a multiline text. 0 = left-aligned, 1=centered, 2=right-aligned. A new line must be defined with this 2 letters: \n +61262=???Letters standard or horizontal placed. 0 = standard, 1=letters horizontal placed +61263=???Height of text. If P13 equals zero, the machine determines the text height. +61266=???Depth at the reference side +61267=???Depth at the opposite of reference side +61268=???Length of the overlap +61269=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61270=???Drilling 2 diameter. Placed at 2/3 P13 +61272=???Angle of inclination of the lapped scarf base +61273=???Shape of the lapped scarf or classic data identification: 1:when cutting orthogonal to reference side; -1:when cutting orthogonal to base side; 0:classic definition, P10 and P12 are not used +61274=???Length of the lapped scarf base +61275=???Depth of the lapped scarf base +61276=???Depth of the lapped scarf base orthogonal to reference side +61277=???Length +61278=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61279=???Drilling 2 diameter. Placed at 2/3 P13 +61281=???Type of heel notch:0=normal; 1=tapered +61282=???Inclination strut +61283=???Depth step joint +61284=???Depth heel notch +61285=???Height tenon. Which implementation (A or B) is used depends on the machine +61286=???Width tenon +61289=???Type of heel notch: 0=normal; 1=tapered +61290=???Inclination between strut and reference side +61291=???Width of the notch +61292=???Depth step joint +61293=???Depth heel notch +61294=???Height of strut +61295=???Depth of mortise. Which implementation (A or B) is used depends on the machine +61296=???Width of mortise +61298=???Specification of side(s) to be planed; binary coded +61299=???Planing depth +61300=???Length of the area to be planed +61303=???Rotation angle of the first curve of the profile +61304=???Rotation angle of the profile towards the reference edge +61305=???Offset angle +61306=???Radius of the first curve +61307=???Radius of the second curve +61309=???Radius +61310=???Depth +61311=???Displacement +61312=???Depth +61313=???Displacement +61315=???Radius +61316=???Depth +61317=???Displacement +61318=???Depth +61319=???Displacement +61321=???Profile length +61322=???Depth at the reference point +61323=???Maximum depth of profile +61324=???Minimum depth of profile +61325=???Depth at the profile end +61326=???Premill: 0=round; 1=angular +61328=???Depth of the arch segment +61329=???Length of the arch segment +61331=???Type of arc (convex, concave), binary coded. See table below. +61332=???Length of lap 1 +61333=???Depth of lap 1 +61334=???Displacement arc 1 +61335=???Horizontal length arc 1 +61336=???Vertical length arc 1 +61337=???Camber arc 2 +61338=???Length of lap 2 +61339=???Depth of lap 2 +61340=???Displacement arc 2 +61341=???Horizontal length arc 2 +61342=???Vertical length arc 2 +61343=???Camber arc 2 +61344=???Length of lap 3 +61345=???Depth of lap 3 +61348=???Distance from the reference side to the reference point +61349=???Radius +61350=???Start offset +61351=???Length +61354=???Distance from the reference side to the reference point +61355=???Normal vector 1: Length of X-component +61356=???Normal vector 1: Length of Y-component +61357=???Normal vector 1: Length of Z-component +61358=???Normal vector 2: Length of X-component +61359=???Normal vector 2: Length of Y-component +61360=???Normal vector 2: Length of Z-component +61362=???Distance between "inside" an side of part +61363=???Distance orthogonal to the reference side +61364=???0:"inside" at reference edge, 1:"inside" at opposite of reference edge +61365=???0:Without rebate or mitre, -1:With mitre, >0:With rebate +61366=???Angle to the reference edge in the reference side +61367=???Width +61368=???Depth +61369=???Inclination +61370=???Height +61371=???Radius +61372=???Length of tool (part of arc) +61373=???0:Angular corner joint, 1:Straight T-wall connection +61374=???Length +61375=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61377=???Distance between "inside" an side of part +61378=???Distance orthogonal to the reference side +61379=???0:"inside" at reference edge, 1:"inside" at oppostite of reference edge +61380=???0:Without rebate or mitre, -1:with mitre, >0:with rebate +61381=???Inclination +61382=???Depth 1 +61383=???Depth 2 +61384=???0:European Dovetail, 1:American Dovetail +61385=???Length +61386=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61387=???Depth +61388=???Mode: 0=contour only, 1=countersink completely. Only for closed contours. +61389=???Contour type +61390=???Parameter depends on contour type(P13) +61391=???Parameter depends on the contour type(P13) +61400=???Reference point on referene edge +61401=???Reference point on the opposite edge +61402=???Reference point on referene edge +61403=???Reference point on the opposite edge +61404=???orthogonal +61405=???at 45 deg +61406=???round +61407=???all laps are symmetric to each other +61408=???lap on reference edge moved to end beam. lap in opposite of reference edge moved to start beam +61409=???lap on reference edge moved to start beam. lap in opposite of reference edge moved to end beam +61410=???only one lap on reference side +61411=???one lap on reference side and one on the opposite side +61412=???with rounding at the bottom +61413=???without rounding, unbounded +61414=???with elongation +61415=???with pocket +61416=???bottom +61417=???middle +61418=???top +61419=???left +61420=???right +61421=???left-aligned +61422=???centered +61423=???right-aligned +61424=???standard +61425=???letters horizontal placed +61426=???when cutting orthogonal to reference side +61427=???when cutting orthogonal to base side +61428=???classic definition, P10 and P12 are not used +61429=???normal +61430=???tapered +61431=???round +61432=???angular +61433=???"inside" at reference edge +61434=???"inside" at opposite of reference edge +61435=???Angular corner joint +61436=???Straight T-wall connection +61437=???Processing on the reference side and opposite the reference side +61438=???Processing only on the reference side +61439=???Processing only opposite the reference side +61440=???European Dovetail +61441=???American Dovetail +// ---Custom Parameter (Q) +61451=???Profondità smusso +61452=???0=Automatico; 1=Ciclo longitudinale con lama +61453=???Spessore testimone centrale per ciclo Q02 +61454=???0=Attacco centrato; 1=Attacco interno +61455=???0=Automatico; 1=Lavorazione con fresa di lato +61456=???1=Forza Lama; 0=Automatico +61457=???1=Solo smusso +61458=???0=Automatico; 1=Massima profondità +61459=???0=Automatico; 1=Truciolatore; 2=Truciolatore di lato; 3=Fresa; 4=Fresa di lato +61460=???0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +61461=???0=Automatico; 1=Massimo raggio ammesso su tasche non passanti +61462=???Diametro utensile per Q05 +61463=???Diametro utensile per Q07 +61464=???0=Raggio su spigolo; 1=Foro su spigolo; 2=Spigolo vivo +61465=???Diametro foro quando P05=1 +61466=???0=Automatico; 1=Sgrossatura con lama +61467=???Antischeggia: 0=No; 1=Con lama; 2=Con fresa +61468=???Aumenta dimensioni tasca +61469=???Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico +61470=???0=Automatico; 1=Solo contorno ; 2=Drill or Pocket +61471=???0=Automatico; 1=Lavoro da un lato solo +61472=???Incrementare/decrementare valore P01 per fori nei tenoni +61473=???0=Foratura rompi truciolo; 1=Foratura scarico truciolo +61474=???Profondità smusso quando P05=1 +61475=???Riduzione profondità tenone +61476=???Riduzione larghezza tenone +61477=???Riduzione altezza tenone +61478=???Riduzione profondità tenone +61479=???Ridurre/Allargare sagoma tenone +61480=???Ridurre/Allargare altezza tenone +61481=???aumenta profondità mortasa +61483=???Profondità di lavoro +61484=???Aumenta dimensioni P10 +61485=???0=Automatico; 1=Truciolatore +61486=???Riduzione lunghezza P14 +61487=???Riduzione larghezza P15 +61488=???Sovramateriale finitura +61489=???Numero divisioni ondulazioni dello smusso sulla lunghezza +61490=???1=Disabilita fresatura gradini +61491=???1=Attiva smusso superiore +61492=???1=Smusso superiore con lama +61493=???Spessore legno per supporto lavorazione +61494=???Attiva antischeggia +61495=???Profondità antischeggia +61496=???Massima elevazione (0=Automatico, >10=Manuale) +61497=???0=Automatico; 1=Lama +61498=???0=Automatico; 1=Disabilita controllo lunghezza fresa +61499=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61500=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61501=???0=Automatico 1=Lavorazione con fresa orizzontale se sopra o sotto (disabilita lama) +61502=???0=Automatico 1=Usa truciolatore se sotto +61503=???0=Attacco e uscita centrati 1=Attacco e uscita interni +61504=???0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +61505=???0=Automatico; 1=Lavora come Taglio Longitudinale +61506=???0=Automatico; 1=Lavorazione con fresa +// ----- EgtBEAMWALL - BTLParam ----- +61601=???SN +61602=???Abilita +61603=???Descrizione +61604=L +61605=W +61606=H +61607=???Material +61608=???Richiesti +61609=???In produzione +61610=???Prodotti +61611=???Ruotare +61612=???Group +61613=???Unit Time +61614=???Parametro +61615=???Valore +61616=???Minimo +61617=???Massimo +61618=???Single member number +61619=???Assembly number +61620=???Order number +61621=???Designation +61622=???Annotation +61623=???Subgroup/Storey +61624=???Group +61625=???Package +61626=???Material +61627=???Timber grade +61628=???Quality grade +61629=???Count +61630=???Colour +61631=???Transparency +61632=???Planing length +61633=???Start offset +61634=???End offset +61635=???Transformation: Origin +61636=???Transformation: X-axis dir. vect. +61637=???Transformation: Y-axis dir. vect. +61638=???Camber: Reference side +61639=???Camber: P01,P02,P03,P04 +61640=???Part offset: ref. side fix clamp +61641=???Part offset: P11,P12,P13,P14 +61642=???Processing quality +61643=???Recess +61644=???Storey type +61645=???Element number +61646=???Layer +61647=???Module number +61648=???USERATTRIBUTE +61649=???Comment +61650=???Grain direction: X,Y,Z +61651=???Grain direction: Align +61652=???Reference side +61653=???Reference side: Align +61654=???Alignment: Location +61655=???Alignment: Endtype +61656=???Material type: Group +61657=???Material type: Specification +61658=???AUTOMATIC +61659=???VISIBLE +61660=???FAST +61661=???MANUAL +61662=???CEILING +61663=???ROOF +61664=???WALL +61665=???inactiv +61666=???BR +61667=???TR +61668=???BA +61669=???TA +61670=???HC +61671=???VC +61672=???AC +61673=???R +61674=???A +61675=???D +61676=???Batten +61677=???Cladding +61678=???Massive timber +61679=???Membrane +61680=???Gypsum Board +61681=???Gypsum Fibre +61682=???Insulation +61683=???Sheet Component +61684=???Facade Panel +61685=???Profiled Panel +61686=???Plaster +61687=???Reference side 1 +61688=???Reference side 2 +61689=???Reference side 3 +61690=???Reference side 4 +61691=???UID +61692=???Project number +61693=???Project name +61694=???Project part +61695=???GUID +61696=???Listname +61697=???Customer +61698=???Architect +61699=???Editor name +61700=???Delivery date +61701=???Export date +61702=???Export time +61703=???Export release +61704=???Language +61705=???Range +61706=???Computername +61707=???User name +61708=???Path & name of CAD-File +61709=???Path & name of BTL-File +61710=???STANDARD +61711=???EXTENDED +61712=???Vol unit +61713=???Vol tot +61714=???Time unit +61715=???Time tot +61716=???Total parts number +61717=???Total volume +61718=???Total time +61719=???Total estimed time +61720=???Remaining time +61721=???Rawpart counter +61722=???BTL part counter +61723=???Added part counter +61724=???Part in rawpart counter +61725=???Done part counter +61726=???Quantity +61727=???Print PDF +//Ware???house +61751=???Current S +61752=???Current L +61753=???StartOffset +61754=???Kerf +61755=???Offset +61756=???S Parameters +61757=???L Parameters +61758=???New Value: +61759=???W +61760=???L +61761=???Confirm +61762=???Save +61763=???Cancel +61764=???Error +61765=???Input value already present +61766=???Input value not correct +61767=???Input pair already present +61768=???One or more input values not correct +61769=???Attention +61770=???Selected parameter is equivalent to current L/S. Are you sure you want to remove it? +61771=???SectionXMaterial +61772=???Alias +61773=???Values +61774=???Quantity +61775=???Min thickness +61776=???Max thickness +61777=???Increment Max thickness of the last range before adding a new range +// +61801=???Custom +61802=???Default +61803=???L +61804=???T +61805=???Process +61806=???Section time +61807=???Part time +61808=???Name +61809=???PDN +61810=???DO +61811=???X position +61812=???Y position +61813=???Added +61814=???Done +61815=???ID +61816=???Start offset +61817=???% Used +61818=???Waste +61819=???BTL File Name +61820=???List Name +61821=???Export Date +61822=???Creation Date +61823=???Delete +61824=???Face +61825=???Group +61826=???Modify +61827=???Save +61828=???Cancel +61829=???Nesting +61830=???Viewer +61831=???Optimizer +61832=???Configuration +61833=???Optimize +61834=???Update BTL +61835=???Go to optimization +61836=???Filter type +61837=???Search +61838=???Export project +61839=???Import project +61840=???Import BTL +61841=???Copy to Clipboard +61842=???DisplayIndex +61843=???Column name +61844=???CanUserReorder +61845=???CanUserResize +61846=???CanUserSort +61847=???IsReadOnly +61848=???Visible +61849=???Variable Path +61850=???Type +// +61851=???This part modification will cause the removal of the part from {0} raw parts. Do you want to proceed anyway? +61852=???Impossible create feature with this values +61853=???Impossible create part with this values +61854=???Impossible create bar with this values +61855=???Impossible create wall with this values +61856=???Value outside minimum and maximum +61857=???Impossible to insert a quantity inferior to the number of parts already in rawparts! +61858=???Impossible to modify these values +61859=???Error in machine parameter writing +61860=???Save machine parameters modification? +61861=???Save default values modification? +61862=???Changing type second path will be deleted. Do you want to proceed? +61863=???To produce part number reached: +61864=??? from BTL; +61865=??? added. Do you want to add another one? +61866=???Selected part has different section from selected bar. Impossible to add. +61867=???Selected part lenght is more then the selected bar lenght. Impossible to add. +61868=???Selected part has different height from selected wall. Impossibl to add. +61869=???Error in macro file execution! +61870=???Impossible create a Macro without selecting a Feature or with empty name +61871=???File not found! +61872=???Impossibie deleting current project +61873=???Impossibile deleting the project because already linked to an optimization +61874=???Impossibile deleting the project because some parts are already sent to production +61875=???Do you want to save the project modifications? +61876=???Impossible creating a new file! +61877=???Save project modification before continuing? +61878=???Impossible proceding with a new unsaved project! +61879=???Type of current machine is both Beam and Wall. Select the type you want to set the project to: +61880=???Select one of the available machines and/or types. Otherwise cancel the project import. +61881=???The opened project type is not compatible with the current machine type +61882=???Do you want to save the modifications to the DataGrid columns? +61883=???The columnn specified as "{0}" in the "{1}" table in the datagrid columns ini file was not found in the program +61884=???Select the machine you want to associate to the project: +61885=???The machine linked to the opening project cannot be found among the available machines +61886=???Machine +61887=???Impossible creating the inserted rawparts quantity +61888=???How many copies of the rawpart do you want to create? +61889=???Long Drill Area +61890=???Min Rule +61891=???Can't send feedback from Optimizer if there is no open Prod +61892=???Can't proceed with an unsaved project! Please save before updating it. +// +61900=???Change paramter +61901=???Verify +61902=???Simulate +61903=???New raw part +61904=???Add to raw part +61905=???Copy part +61906=???Add part +61907=???Remove part +61908=???Copy feature +61909=???Create macro +61910=???Add feature +61911=???Remove feature +61912=???Produce rawpart +61913=???Produce all rawpart +61914=???Copy rawpart +61915=???Remove rawpart +61916=???Reorder parts +61917=???Move up part +61918=???Move down part +61919=???Remove part +61920=???Warehouse +61921=???Add project to optimization +61922=???Go to project +61923=???Statistics +61924=???Reset +61925=???Show all parts +61926=???Show solid +61927=???Show building +61928=???Verify all +61929=???Can't change machine because the Proj is already linked to a Prod +61930=???Inputs +61931=???Outputs +61932=???Calculate Flip & Rotation +61933=???Unlock Flip +61934=???Unlock Rotation +61935=???Length +61936=???Width +61937=???Offset +61938=???Kerf +61939=???Edit +61940=???Reset +61941=???Choose machine +61942=???BTL file already imported and optimized. Do you want to import it again? +61943=???BTL file already imported. Do you want to overwrite it? +61944=???Shift parts +61945=???Shift direction +61946=???Shift length +61947=???Parts can't be shifted outside the raw part +61948=???The inserted shift value is not valid +61949=???Search & Filter +61950=???Parameter Type +61951=???Parameter Value +61952=???R +61953=???A +61954=???P +61955=???D +61956=???All +61957=???Filtered +61958=???Update +61959=???Append +61960=???Check the parts you would like to add to update BTL +61961=???Change material +61962=???Project material +61963=???Warehouse material +61964=???Standard +61965=???From BTL +61966=???Save +61967=???Do NOT save +61968=???Waiting for optimizer save +61969=???Cancel +// +62500=???Supervisor +62501=???Channel +62502=???OPMode +62503=???Produce All +62504=???Done RawPart +62505=???Reset RawPart +62506=???Delete RawPart +62507=???Print Label +62508=???Done Part +62509=???Resume started processing? +// Loading +63000=???Project opening +63001=???Loading project geometries +63002=???Loading machining groups +63003=???Loading production data +63004=???Optimization opening +63005=???Loading parts +63006=???Loading graphics +63007=???Project saving +63008=???BTL file importing +63009=???Reading BTL file +63010=???Project exporting +63011=???Loading environment +63012=???Saving geometry +63013=???Saving data on Db +63014=???Modifying parameters +63015=???Part viewer opening +63016=???Adding export info +63017=???Exporting... +63018=???Project importing +63019=???Loading project +63020=???Creating imported project +63021=???Modifying materials +// ----- FromLua ----- +65001= +// ----- OmagCUT ----- +// General +90001=PROCESSAMENTO EM CURSO +90002=CORTES DIREITOS +90003=CORTES CAD +90004=MOLDURAS +90005=MÁQUINA +90006=OPÇÕES +// WorkInProgress +90101= +// DirectCut +90201=Movimento manual +90202=Corte único +90203=Corte múltiplo +90204=Corte grelha +90205=MTH +90206=Aplainamento +90207=Teste lâmina +90208=Apalpar lâmina +90209=Cópia molde +90210=Adquirir P1 +90211=Adquirir P2 +90212=Laser +90213=Afundamento +90214=Comprimento +90215=Direção +90216=Inclinação +90217=Número +90218=Dimensões +90219=Número X +90220=Dimensões X +90221=Número Y +90222=Dimensões Y +90223=Cortes lado motor +90224=Lâmina +90225=Desenho +90226=Largura +90227=Sobreposição +90228=Deslocamento +90229=???Blocca Asse C +90230=Executar +90231=???Lucidatura +90232=Espessura lâmina +90241=Apalpagem lâmina +90242=Apalpagem em curso... +90243=Apalpagem concluída com sucesso +90244=Erro na apalpagem lâmina +90245=Novo nome do molde +90246=Apalpagem interrompida pelo utilizador +90250=Linha +90251=Arco +90252=Remover +90253=Fechar +90254=Guardar +90255=???Test +90256=???Verifica posizione taglio +90257=???Verifica posizione in corso... +90258=???Single drill +// CadCut +90301=Simular +90302=Executar +90303=Novo +90304=Carregar +90305=Guardar +90306=Guardar como +90307=Novo nome do projeto +90308=CSV +90309=Vein Match +90310=Exportar +90311=Ferramenta +90312=Processamento +90313=Fotografia não bem sucedida +90314=Erro na geração do programa CN +90315=Erro na transmissão do programa CN +90316=Não conectado à máquina +90317=Programa CN transmitido +90318=A máquina não aceita o programa CN +90319=Programa já transmitido, quer retransmiti-lo ? +90320=Máquina diferente +90321=Reduzidos alguns processamentos para evitar interferências +90322=Faltam as ferramentas : +90323=Fotografia de fundo executada +90324=Reconhecimento contorno não bem sucedido +90325=Erro na gravação das estatísticas +90326=Confirmar recomeço da fase {0} ? +90327=Inseriti Nuovi Pezzi Rovinati +90328=Área peças : +90329=???Da Produrre : +90330=Programa já transmitido, é uma laje nova ? +// NestPage +90331=Inserir peça +90332=Estacionar peça +90333=Eliminar peça +90334=Selecionar tudo +90335=Deselecionar tudo +90336=Reset +90337=Uma ou duas peças com espessura, material ou acabamento não compatíveis +90338=Rotação além dos limites +90339=Rotação impossível +90340=Aninhamento automático em andamento +// SplitPage +90341=On/Off +90342=Todos On +90343=Todos Off +90344=Alongar/Encurtar +90345=Início Al/Enc +90346=Fim Al/Enc +90347=Início Centro/Fora +90348=Iniciar Todos Fora +90349=Iniciar Todos Centro +90350=Cálculo automático falido +90351=Lâmina demasiado grande para utilizar a ventosa +90352=Fim Centro/Fora +90353=Fim Todos Fora +90354=Fim Todos Centro +90355=Todos Alonga +90356=Todos Enc. +90357=Modif. +90358=Auto +90359=Restart +// MoveRawPart +90361=Remover +90362=Peça pequena demais : não se pode mover +90363=Posição escolhida já ocupada +90364=???Part too havy : can not be moved +90365=???Part beyond strokes : can not be moved +// SplitPage 2 +90371=Pausa On/Off +90372=Pausa +90373=Início Modif. +90374=Fim Modif. +90375=Alongamento +90376=Reverter +// DrawPage +90381=Número peças +90382=Medidas +90383=Inclinar lados +90384=Indicar Lado Em cima +90385=Desenho Paramétrico +90386=Selecionar um contorno +90387=Não há lados modificáveis +90388=Nome +90389=Dados Trf +90390=Código encomenda +90391=Descrição encomenda +90392=Código material +90393=Código superfície +90394=Espessura +90395=Selecionar um ou vários furos +90396=Código peça +90397=Incisar +90398=Dados Csv +90399=Todos processamentos atualizados +90400=???Filo Top +// Component +// Máximo 30 carácteres sem imagem e máximo 20 com a imagem +90401=Triângulo +90402=Retângulo +90403=Trapézio +90404=Quadrilátero +90405=Piedoca +90406=Limiar +90407=Plano Cozinha +90408=Plano Banho +90409=Outros +90410=Triângulo2L +90411=Triângulo3L +90412=Isóscele +90413=Retângulo +90414=Escaleno +90415=Escaleno +90416=4Lados 1Âng +90417=3Lados 2Âng +90418=3Lados 2Diag +90419=4Lados 1Diag +90420=4Lados 3Diag +90421=4Lados 3Ang +90422=4Lados 3Ang +90423=Ângulo Reto +90424=Ângulo Reto Chanfrado +90425=Ângulo Alinhado +90426=Ângulo Al. Chanfrado +90427=Parte A +90428=Parte B +90429=Ângulo +90430=Ângulo Chanfrado +90431=Elipse +90432=Oval +90433=Arco +90434=Arco LHF +90435=Arco LLH +90436=Arco LLF +90437=Retângulo chanfrado +90438=Convexo +90439=Furo +90440=2 Furos +90441=3 Furos +90442=Arco RHa +90443=Polígono +90444=Furo debaixo +90445=Dxf +90446=Ribasso +90447=Componentes internos +90448=Adicionar +90449=Remover +90450=Confirmar +// Import +90451=Usar camada +90452=Usar regiões +90453=Reset +90454=mm +90455=inch +90456=Usar curvas fechadas +90457=Inclinar lados +90458=Incisar por debaixo +90459=Ângulo +90460=Deslocamento +90461=Afundamento +90462=Encurtamento +90463=Importar DXF +90464=Perfurar por debaixo +90465=Número +90466=Deslocamento2 +90467=???Ordine +90468=???Distinta +90469=???Nome +// Component 2 +90470=???Incisioni Ribasso +90471=???Incisioni +90472=TriânguloCH +90473=TriânguloRT +90474=TrapézioRtA +90475=3Lados 2Ang +90476=???Nuova soglia +// FastGrid +90480=Nome encomenda +90481=N° Chapa +90482=Última chapa +90483=Tipo peça +90484=Inserir peças +90485=Confirmar encomenda +// Open +90491=Projeto não válido +90492=Projeto com interferências. Para carregá-lo desativar respeito cortes completos. +// RawPart +90499=???Grezzo non definito +90500=Rotação +90501=Retângulo +90502=Mediante pontos +90503=Comprimento +90504=Largura +90505=Espessura +90506=Deslocamento X +90507=Deslocamento Y +90508=Kerf +90509=Material +90510=Área danificada +90511=Novo +90512=Cancelar +90513=Pontos +90514=Adicionar +90515=Cancelar +90516=Máximo comprimento +90517=Máxima largura +90518=Não são admitidas espessuras negativas +90519=Mínimo deslocamento X +90520=Mínimo deslocamento Y +90521=Mínimo kerf +90522=Máximo kerf +90523=Apalpar bruto +90524=Confirmar +90525=Apalpagem bruto +90526=Apalpagem em curso... +90527=Apalpagem concluída com sucesso +90528=Erro na apalpagem do bruto +90529=A partir do desenho +90530=A partir do laser +90531=Fechar +90532=Erro na aquisição do ponto +90533=Contorno +90534=Lâmina grande demais para apalpagem +90535=Segundo fotografia +//ChooseMachining +90536=Escolher o processamento de lâmina +90537=Escolher o processamento secundário +90538=Escolher a perfuração +90539=Escolher a fresagem +90540=Nenhuma +90541=Perfuração +90542=Fresagem +90543=Ambas +90544=Escolha processamentos correntes +90545=Escolher a jato de água +90546=Corte a jato de água +90547=Erro na posição ou dimensão do bruto +90548=Máximo deslocamento X +90549=Máximo deslocamento Y +90550=???Scegliere la svuotatura +// Simulation +90551=Simulação concluída +90552=Sobrecurso +90553=Direção utensílio inalcançável +90554=Erro +90555=ERRO +90556=Erro em geração! +90557=Simulação +90558=Um passo de cada vez +90559=Play/Pausa +90560=Stop/Home +90561=Pausa +90562=Simulação interrompida +90563=Vista máquina +90564=Home +90565=Tempo +90566=Comprimento +90567=Área peças +90568=Utilizo +90569=Estimativas +90570=Pormenores +// FrameCut +90601=Comprido X +90602=Comprido Y +90603=Remover +90604=Desbastamento +90605=Acabamento +90606=Aplicação de massas +90607=Espelhar +90608=Distância em cima +90609=Distância início +90610=Encurtar início +90611=Encurtar fim +90612=Corte único +90613=Arco +90614=Guida +90615=Seção +90616=Guida +90617=Rad +90618=Ang +90619=Errore : raggio più piccolo della larghezza della sezione +90620=Errore : creazione della cornice non riuscita +90621=Distanza X +90622=Distanza Y +90623=Lado oposto +// Machine +90701=Msg_Ita.xpi +90705=Dados máquina +90706=BD ferramentas +90707=BD process. +90708=Máquina +90709=???Statistics +90715=Novo +90716=Nova +90717=Guardar +90718=Eliminar +//ToolsDb +//param +90719=???Lunghezza portautensili +90720=???Anima +90721=Nome +90722=Posição +90723=Cabeçote +90724=Saída +90725=Rotação +90726=Normal +90727=Máxima +90728=Feed +90729=Avanço +90730=Cabeçote +90731=Entrada +90732=Saída +90733=µgua +90734=Corretor +90735=Supramaterial +90736=Longitudinal +90737=Radial +90738=Máx absorb. +90739=Feed mínima +90740=Máx afund. +90741=Comprimento +90742=Diâmetro +90743=Espessura +90744=Cortante +90745=Notas +90746=Número de série +90747=Código +90748=Fornecedor +90749=Fim do serviço +//tools families +90751=Lâmina +90752=Mandril helicoidal +90753=Fresa +90754=???Mola da scasso +90755=Jato de água +90756=???Mola lucidante +//Tool Setup +90759=???Posizione utensile predefinita già occupata +//MachiningsDb +//param +90761=Nome +90762=Afundamento +90763=Ângulo de inclinação +90764=Inverter +90765=Tipo de step +90766=Lado de trabalho +90767=Lado cabeçote +90768=Posição início +90769=Engate +90770=Conexão +90771=Saída +90772=Utilizar curvas +90773=Tolerância +90774=Passo de afundamento +90775=Normal +90776=Passo de afundamento +90777=Interno arcos +90778=Externo arcos +90779=Comprimento de desaceleração +90780=Inicial +90781=Final +90782=Afundamento adicional +90783=Posição de retorno +90784=Ferramenta +90785=Espessura mínima +90786=Espessura máxima +90787=Passo +90788=Afundo +90789=De lado +90790=Na vertical +//machinings families +90791=Corte +90792=Perfuração +90793=Fresagem +90794=Desbastamento com lâmina +90795=Acabamento com lâmina +90796=???Svuotatura +90797=Jato de água +//ComboBox Param +90801=Não +90802=Interna +90803=Externa +90804=Ambas +90821=Centro +90822=Esquerda +90823=Direita +90824=Centrado +90825=Interno +90826=Externo +90827=Extenso centrado +90828=Extenso externo +90829=Extenso anterior +90830=Extenso sucessivo +90831=Extensos ambos +90832=Centrada +90833=Interna +90834=Externa +90835=Saltar +90836=Aproximar +90837=Convexo +90838=Zigue-Zague +90839=Uma via +90840=Vai e volta +90841=Processar +90842=Nessuno +90843=???Normale +90844=???Rallenta +90845=???Anello +90846=???Lineare +90847=???Tangente +90848=???Inseguimento +90849=???Elica +90850=???Come attacco +// param2 +90861=Aplicação de massas +90862=Inclinado +90863=Incl. retorno +90864=Ida +90865=Volta +90866=Último retorno +90867=???Inclinazione in avanti +90868=Sondagem +90869=???Min dist. punti +90870=???Max dist. punti +90871=???Esterni +90872=???Interni +90873=???Lungh. rall. +90874=???Rallentam. % +90875=???Foro di attacco +90876=???Raggio +90877=???Num. giri in LP +90878=???Num. giri in HP +90879=???Abilitazione +90880=???Angoli +// Barcode +90881=Código a barras +90882=???Blocco +90883=???Numero +90884=???Dati lastra +// param3 +90890=???Dist. tang. +90891=???Dist. perp. +90892=???Dist. tang. +90893=???Dist. perp. +90894=???Attacco ceramica +90895=???Lunghezza +90896=???Passo +90897=???Last cut +90898=???Side angle cuts +// Alarms +90900=Jato de água corrente +90901=Lâmina corrente +90902=Ferramenta auxiliária +90903=Mandril helicoidal corrente +90904=Fresa corrente +90905=Z segura +90906=Segurança cortes +90907=Segur. ângulos +90908=Respeitar os cortes concluídos +90909=Deslocamento furos +90910=Sobrep. furos +90911=Tolerância furos +90912=Lista erros CN +90913=Materiais +90914=Adicionar +90915=Remover +90916=Ferramentas correntes +90917=Parâmetros furos +90918=Rmín arcos ext. +90919=Parâmetros máquina +90920=Nenhum +90921=Mandril helicoidal +90922=Fresa +90923=Ambos +90924=Amáx arcos int. +90925=Parâmetros lâmina +90926=Um único furo no ângulo +90927=Cortes diretos +90928=Home final +90929=Parâmetros fresagem +90930=Sempre nos internos +90931=Nesting +90932=Alinhado +90933=Instrumentação +90934=Novo +90935=Eliminar +90936=Altura plataforma +90937=Contorno segundo a Foto +90938=Fundo +90939=Limiar +90940=Tolerância +90941=Lavagem +90942=Confirma o cancelamento do material selecionado? +90943=Setup de default +90944=Sempre nos ângulos +90945=Selecionar a ferramenta a apalpar +90946=Cortes Feed início/fim +90947=Comprimento +90948=Redução % +90949=Encurtamento +90950=Sondagem +//Machine +90951=Arrancar +90952=Parar +90953=Reinicializar +90954=Auto +90955=Single +90956=MDI +90957=Manual +90958=Home +90959=Download +90960=Upload +90961=Activate +90962=Delete +90963=MDI Confirm +90964=Modalidades CN +90965=Comandos máquina +90966=Seqüência MDI +90967=Transferência part program +90968=???Do you want to change table? +// Options +90981=Idioma +90982=O novo idioma se tornerá corrente a partir do próximo arranque do programa. +90983=Unidade de medição +90984=Rotação vista +90985=Ângulo inclinado +90986=Apenas um valor +90987=Vários valores +90988=Inserção direta das pe‡as +90989=Paramétricos e DXF +90990=CSV +90991=Fast grid +90992=Ativa a criação de peças standard +90993=Cor texto +90994=Folha Dxf +90995=Layer Folha +90996=Layer Peças +90997=Layer Lixo +90998=Espessura std +90999=Inclinação a partir da cor +91000=Abilita +91001=Tolerância +91002=Tallone +91003=Inclinação +91004=???Feedback +91005=???Themes +91006=???Engrave from color +91007=???Depth +91008=???Width +91009=???Start program +91010=???Select start mode +91011=???Recent project +91012=???Last opening +91013=???Last project +91014=???New project +91015=???Open folder +91016=???Show window +//Alarms2 +91051=Processamentos +91052=Corte +91053=Perfuração +91054=Fresagem +91055=???DripSawing +91056=???DripDrilling +91057=Jato de água +91058=Parâmetros jato de água +91059=???Automatic +91060=Alinhado e Guilhotina +91061=Parâmetros de gravação +91062=Com Cortador +91063=Profundidade +91064=Largura +91065=Sair do pré-corte +91066=Guilhotina +91067=Inserir pausa +91068=Molduras +91069=Esvaziamento +91070=???Scasso corrente +//Statistics +91071=???Day Production +91072=???Week Production +91073=???Project +91074=???Parts Area +91075=???Cuts Area +91076=???Day +91077=???Week +91078=???Reset +91079=???To Produce Area +//Lucidature +91089=???Offset +91090=???DB Lucidature +91091=???Lucidature +91092=???Movimento +91093=???Ripetizioni +91094=???Attacco/Uscita +91095=???Altezza +91096=???Lista utensili +91097=???Lunghezza +91098=↑ +91099=↓ +91100=???Precarico +//EgtMsgBox +91101=Guardar o projeto corrente? +91102=Guardar a ferramenta corrente? +91103=Guardar o processamento corrente? +91104=Nome já utilizado +91105=Há interferências, algumas peças serão estacionadas. Quer continuar? +91106=Há já um ficheiro com este nome. Quer sobrescrever? +91107=CONEXÇO AO CN +91108=Conexão em curso... +91109=Conexão falida +91110=Conexão bem sucedida +91111=Plataforma a usar ? +91112=Quer cancelar também as peças provenientes da lista Csv ? +91113=Peças não removidas porquanto livres +91114= ou de outras listas Csv +91115=Erro +91116=Opção Linha de produção não habilitada +91117=Erro em cópia ficheiro para OmagVIEW +91118=Manter as peças no estacionamento ? +91119=Erro na gestão das peças erradas +91120=Os carácteres \ / : * ? "" < > | não são aceitos +91121=Tem certeza de querer cancelar as peças selecionadas? +91122=Aviso +91123=Plataforma +91124=???Salvare la lucidatura corrente? +91125=???Salvare le modifiche correnti? +91126=???Export +91127=???Import +91128=???DB WaterJet +91129=???Origine da laser +91130=???Start program? +// CSV +91201=Abrir +91202=Inserir +91203=Novo +91204=Remover +91205=Erro em guardar o ficheiro CSV, quer continuar na mesma? +91206=Erro na leitura do ficheiro CSV +// OmagVIEW +91301=Todos Válidos +91302=Peça Válida +91303=Peça Errada +91304=Imprime Etiqueta +91305=Confirmar +91306=Imprimir +// OmagOFFICE +// OptionPanel +91401=Bruto +91402=Dispor +91403=Processar +91404=Simular +// MachiningDbWindow +91451=Material +91452=Espessura mínima +91453=Espessura máxima +// Errori di stampa +91461=???Error connection printer +91462=???Error formatting data +91463=???Error during print +91464=???No selection +// TopCommandBar +91501=É necessário guardar o projeto antes de exportá-lo +91502=Selecionar o diretório de exportação +91503=Erro na exportação +91504=Exportação concluída com sucesso +91505=???Esporta in macchina +91506=???Esporta DXF +// Rawpart +91551=Erro no carregamento da fotografia +91552=Importar fotografia +// VeinMatching +91601=Exportar +91602=Mostrar Info +91603=Modificar +91604=Verificar +91605=Magnético +91606=Peça não selecionável nesta situação +91607=Peça não selecionável porque pertence a um grupo de trabalho não corrente : +91608=???Ingombro dei pezzi DXF troppo grande per VeinMatching +// Generic +91651=Ok +91652=Anular +91653=A° +91654=S +91655=Começar +91656=Fim +// ----- OmagPHOTO ----- +// General +92001=Bd inexistente! +92002=???Unable starting the program +// OptionPanel +92051=Guardar +92052=Adicionar +92053=Anular +92054=Eliminar +92055=Tem certeza de querer cancelar a chapa corrente? +92056=???Etichetta +92057=???Etichetta Freccia +92058=???Sfoglia +92059=???Stampa +92060=???Seleziona +// Slab +92071=Id +92072=Nome imagem +92073=Estado +92074=Projeto atribuído +92075=Posição no armazém +92076=Data +92101=Nome já utilizado +92102=O nome é obligatório +92103=A imagem é obligatória +// SearchPanel +92151=Pesquisar +92152=Tolerância espessura +92153=Data de início +92154=Data de fim +92155=Reinicializar +//Messaggi +92200=???Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=???Avviso +92202=???Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=???Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=???Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// General +101001=Importa BTL +101002=Desenhar +101003=Posicionar +101004=Opções +// ImportPage +101101 +// DrawPage +101201=Parede +101202=Porta +101203=Janela +101204=Adicionar +101205=Anular +101206=Aplicar +101207=Eliminar +101208=Distancial +// PlacePage +101301=Gerar +101302=Transmitir +101303=Posicionamento parede +101304=Inserir +101305=Estacionar +101306=Eliminar +101307=Espessura camadas +101308=Número plataformas em cima +101309=Inserção falida +101310=Geração bem sucedida +101311=Erro em geração +101312=Arranque transmissão bem sucedido +101313=Erro no arranque transmissão +101314=Transmissão conclu¡da com sucesso +101315=Transmissão falida +101316=Pontes todas desativadas +101317=Ficheiro de Geração em falta +// OptionsPage +101401=Opções máquina +101402=Características colagem +101403=Extra bruto em X +101404=Extra bruto em Y +101405=Extra cola +101406=Características plataformas +101407=Largura plataforma +101408=N° plataformas num plano +101409=Ativação pontes +101410=Ponte cola +101411=Ponte plataformas +101421=Opções software +101422=Seleção idioma +101423=O novo idioma se tornerá corrente a partir do próximo arranque do programa. +101424=Número projetos a guardar +101425=Posiciona plataformas em portas e janelas +101426=Adiantar abertura cola +101427=Adiantar fechadura cola +// OpenPage +101501=Projeto não válido +// ----- End ----- diff --git a/ProgramData/EgtBeamWall/Config/EgtBEAMWALL.ini b/ProgramData/EgtBeamWall/Config/EgtBEAMWALL.ini new file mode 100644 index 0000000..dbda5eb --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/EgtBEAMWALL.ini @@ -0,0 +1,112 @@ +; Commento per evitare BOM con UTF-8 +[General] +Debug=5 +Licence=Key-000335-EgtBeamWall-Carlo Baronchelli_OK.lic +UserLevel=1 +MaxInstances=1 +Instances=0 +MaxCamInstances=4 +CommandLog=1 +Messages=Italiano +WinPlace=1,-1791,220,1986,1152 +LastImpDir=E:\EGALWARE\ProgramData\BeamWall +Support=support@egaltech.com +LastProj=C:\ProgramData\Egaltech\EgtBeamWall\Projs\0001\0001.nge +Warehouse=2 +UserName=Utente Windows +ViewOptimInstances=1 + +[Languages] +Count=2 +Language1=Italiano,EgalTechIta.txt +Language2=English,EgalTechEng.txt +Language3=Francais,EgalTechFra.txt +Language4=Deutsch,EgalTechDeu.txt +Language5=Espagnol,EgalTechEsp.txt +Language6=Portugues,EgalTechPor.txt + +[Lua] +LibsDir=C:\ProgramData\EgalTech\EgtBeamWall\LuaLibs +BaseLib=EgtBase + +[GeomDB] +DefaultFont=ModernPropS.Nfe +NfeFontDir=C:\ProgramData\EgalTech\EgtBeamWall\Fonts +DefaultColor=128,0,0 +SaveType=2 ; 0=testo, 1=binario, 2=testo compresso +SurfTmToler=0.05 + +[OpenGL] +DoubleBuffer=1 +ColorBits=32 +DepthBits=24 +Driver=3 ; 1=software, 2=OldWay, 3=NewWay + +[Scene] +BackTop=176,208,210 +BackBottom=145,177,196 +ShowGFrame=1 +Mark=255,255,0 +SelSurf=255,64,64 +ShowMode=2 +CurveDir=0 +ShowTriaAdv=1 +ShowZmap=9 ; +1=surf, +2=lines, +4=normals, +8=più colori +TextureMaxLinPixels=2048 +ZoomWin=0,255,255,255,30 +DistLine=255,0,0 +MmUnits=1 +LineWidth=1 +ShowBuilding=0 + +[Grid] +DrawShowGrid=1 +MachiningShowGrid=0 +ShowFrame=1 +SnapStep=15 +SnapStepInch=25.4 +MinLineSStep=1 +MajLineSStep=10 +ExtSStep=100 +MinLnColor=153,153,153 +MajLnColor=153,153,153 + +[Import] +BtlFlag=8 ; +1=FlatPos +2=VertPos +4=SpecialTrim +8=TS3Pos +16=Sort +32=UserAttr +64=OutlineFlatPos +WallBtlFlag=64 + +[Beam] +CalcPath=C:\Program Files (x86)\Egaltech\EgtCAM5\EgtCAM5R32.exe +BaseDir=C:\ProgramData\Egaltech\EgtCAM5\Beam +BweExec=BatchProcessNew.lua + +[Wall] +CalcPath=C:\Program Files (x86)\Egaltech\EgtCAM5\EgtCAM5R32.exe +;BaseDir=C:\ProgramData\Egaltech\EgtCAM5\Wall +BaseDir=C:\ProgramData\Egaltech\Progetto Restyling Wall\Wall +BweExec=BatchProcessNew.lua + +[Nest] +NestExec=NestProcess.lua +FlipRot=NestFlipAndRotate.lua +NestDir=C:\ProgramData\Egaltech\EgtCAM5\Wall +LDIntersOther=0 +MinScore=0 + +[Mach] +MachinesDir=C:\EgtData\Machines +ToolMakersDir=C:\ProgramData\Egaltech\EgtCAM5\ToolMakers +CurrMach=Essetre-90480027 +SupervisorMach= + +[DimensionStyle] +TextHeight=30 +[MruProjFiles] +File1=C:\ProgramData\Egaltech\EgtBeamWall\Projs\0001\0001.nge +File2= +File3= +File4= +File5= +File6= +File7= +File8= diff --git a/ProgramData/EgtBeamWall/Config/Key-000335-EgtBeamWall-Carlo Baronchelli.lic b/ProgramData/EgtBeamWall/Config/Key-000335-EgtBeamWall-Carlo Baronchelli.lic new file mode 100644 index 0000000..549b972 --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/Key-000335-EgtBeamWall-Carlo Baronchelli.lic @@ -0,0 +1,13 @@ +; Commento per evitare BOM con UTF-8 +[Licence] +Customer=Key-000335-EgtBeamWall-Carlo Baronchelli +LockId=EGTECH-000335-oOoCcE +Product=5327 +Ver=2404 +Lev=1 +ExpDays=19388 +Opt1=175 +Opt2=27 +OptExpDays=19388 +Key=+lTlApqOYxxY9skEbspi7pcOGOMzlIvMXW/WIb34Y3XJpjnK + diff --git a/ProgramData/EgtBeamWall/Config/Key-000335-EgtBeamWall-Carlo Baronchelli_OK.lic b/ProgramData/EgtBeamWall/Config/Key-000335-EgtBeamWall-Carlo Baronchelli_OK.lic new file mode 100644 index 0000000..811d834 --- /dev/null +++ b/ProgramData/EgtBeamWall/Config/Key-000335-EgtBeamWall-Carlo Baronchelli_OK.lic @@ -0,0 +1,13 @@ +; Commento per evitare BOM con UTF-8 +[Licence] +Customer=Key-000335-EgtBeamWall-Carlo Baronchelli +LockId=EGTECH-000335-oOoCcE +Product=5327 +Ver=2401 +Lev=1 +ExpDays=19388 +Opt1=687 +Opt2=11 +OptExpDays=19388 +Key=tTLnO5c9Ky4IitnioXwE8LVP7nsnpyj5AFMeyG3chcCJOqpZ + diff --git a/ProgramData/EgtBeamWall/DataRoot.ini b/ProgramData/EgtBeamWall/DataRoot.ini new file mode 100644 index 0000000..d701eb7 --- /dev/null +++ b/ProgramData/EgtBeamWall/DataRoot.ini @@ -0,0 +1,3 @@ +; Commento per evitare BOM con UTF-8 +[Data] +DataRoot=C:\ProgramData\Egaltech\EgtCAM5 diff --git a/ProgramData/EgtBeamWall/Fonts/ModernProp.Nfe b/ProgramData/EgtBeamWall/Fonts/ModernProp.Nfe new file mode 100644 index 0000000..7a4efc7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Fonts/ModernProp.Nfe differ diff --git a/ProgramData/EgtBeamWall/Fonts/ModernPropS.Nfe b/ProgramData/EgtBeamWall/Fonts/ModernPropS.Nfe new file mode 100644 index 0000000..c316e84 Binary files /dev/null and b/ProgramData/EgtBeamWall/Fonts/ModernPropS.Nfe differ diff --git a/ProgramData/EgtBeamWall/Fonts/ScriptS.Nfe b/ProgramData/EgtBeamWall/Fonts/ScriptS.Nfe new file mode 100644 index 0000000..bdbf7b7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Fonts/ScriptS.Nfe differ diff --git a/ProgramData/EgtBeamWall/LuaLibs/EgtBBox3d.lua b/ProgramData/EgtBeamWall/LuaLibs/EgtBBox3d.lua new file mode 100644 index 0000000..bb1ea3a --- /dev/null +++ b/ProgramData/EgtBeamWall/LuaLibs/EgtBBox3d.lua @@ -0,0 +1,313 @@ +-- EgtBBox3d.lua by EgalTech s.r.l. 2021/12/26 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtBBox3d = {} + +EgtOutLog( 'EgtBBox3d started', 1) + +-- Include +require( 'EgtPoint3d') +--EnableDebug( false) + + +-- Definizione classe BBox3d +BBox3d = {{},{}} +BBox3d.__index = BBox3d + +-- funzione di utilita' per identificazione tipo +function isBBox3d( a) + return ( getmetatable( a) == BBox3d) +end + +local function New( a, b) + local b3d = setmetatable( {{GEO.INFINITO,GEO.INFINITO,GEO.INFINITO},{-GEO.INFINITO,-GEO.INFINITO,-GEO.INFINITO}}, BBox3d) + if not a then + b3d[1] = Point3d( GEO.INFINITO, GEO.INFINITO, GEO.INFINITO) + b3d[2] = Point3d( -GEO.INFINITO, -GEO.INFINITO, -GEO.INFINITO) + elseif isBBox3d( a) then + b3d[1] = Point3d( a[1]) + b3d[2] = Point3d( a[2]) + elseif isBBox3d( a) and isBBox3d( b) then + b3d[1] = Point3d( a[1]) + b3d[2] = Point3d( a[2]) + BBox3d.AddPoint( b3d, b[1]) + BBox3d.AddPoint( b3d, b[2]) + elseif type(a) == 'table' and #a >= 2 and + type(a[1]) == 'table' and #a[1] >= 3 and + type(a[2]) == 'table' and #a[2] >= 3 then + b3d[1] = Point3d( GEO.INFINITO, GEO.INFINITO, GEO.INFINITO) + b3d[2] = Point3d( -GEO.INFINITO, -GEO.INFINITO, -GEO.INFINITO) + if a[1][1] < ( a[2][1] + GEO.EPS_SMALL) and + a[1][2] < ( a[2][2] + GEO.EPS_SMALL) and + a[1][3] < ( a[2][3] + GEO.EPS_SMALL) then + BBox3d.AddPoint( b3d, a[1]) + BBox3d.AddPoint( b3d, a[2]) + end + elseif isPoint3d( a) and isPoint3d( b) then + b3d[1] = Point3d(GEO.INFINITO,GEO.INFINITO,GEO.INFINITO) + b3d[2] = Point3d(-GEO.INFINITO,-GEO.INFINITO,-GEO.INFINITO) + BBox3d.AddPoint( b3d, a) + BBox3d.AddPoint( b3d, b) + elseif isPoint3d( a) then + b3d[1] = Point3d(GEO.INFINITO,GEO.INFINITO,GEO.INFINITO) + b3d[2] = Point3d(-GEO.INFINITO,-GEO.INFINITO,-GEO.INFINITO) + BBox3d.AddPoint( b3d, a) + else + error( 'A parameter is wrong', 2) + end + return b3d +end + +setmetatable( BBox3d, { __call = function( _, ...) return New( ...) end }) + +-- verifico se vuoto +function BBox3d:isEmpty() + -- il minimo non è minore del massimo + return not ( self[1][1] < ( self[2][1] + GEO.EPS_SMALL) and + self[1][2] < ( self[2][2] + GEO.EPS_SMALL) and + self[1][3] < ( self[2][3] + GEO.EPS_SMALL) ) +end + +-- somma di due box (+) +function BBox3d.__add( a, b) + if isBBox3d( a) and isBBox3d( b) then + return New( a, b) + else + error( 'A parameter is not a BBox3d', 2) + end +end + +-- aggiungo box o punto +function BBox3d:Add( a) + if isBBox3d( a) then + if not a:isEmpty() then + self:AddPoint( a[1]) + self:AddPoint( a[2]) + end + else + self:AddPoint( a) + end +end + +-- aggiungo un punto (solo per uso interno) +function BBox3d:AddPoint( ptP) + if ptP[1] < self[1][1] then + self[1][1] = ptP[1] + end + if ptP[2] < self[1][2] then + self[1][2] = ptP[2] + end + if ptP[3] < self[1][3] then + self[1][3] = ptP[3] + end + if ptP[1] > self[2][1] then + self[2][1] = ptP[1] + end + if ptP[2] > self[2][2] then + self[2][2] = ptP[2] + end + if ptP[3] > self[2][3] then + self[2][3] = ptP[3] + end + return true +end + +-- espansione isotropa +function BBox3d:expand( dDelta) + if not isBBox3d( self) then + return false + end + if BBox3d.isEmpty(self) then + return true + end + self[1][1] = self[1][1] - dDelta + self[1][2] = self[1][2] - dDelta + self[1][3] = self[1][3] - dDelta + self[2][1] = self[2][1] + dDelta + self[2][2] = self[2][2] + dDelta + self[2][3] = self[2][3] + dDelta +end + +-- traslazione +function BBox3d:move( m) + if not isBBox3d( self) then + return false + end + if BBox3d.isEmpty(self) then + return true + end + if isVector3d( m) or ( type( m) == 'table' and #m >= 3) then + self[1][1] = self[1][1] + m[1] + self[1][2] = self[1][2] + m[2] + self[1][3] = self[1][3] + m[3] + self[2][1] = self[2][1] + m[1] + self[2][2] = self[2][2] + m[2] + self[2][3] = self[2][3] + m[3] + return true + else + return false + end +end + +function BBox3d:rotate( ptAx, vtAx, dAngDeg) + if not isBBox3d( self) or not isPoint3d( ptAx) or not isVector3d( vtAx) or type( dAngDeg) ~= 'number' then + return false + end + if BBox3d.isEmpty(self) then + return true + end + local bOk, b3New = EgtBBoxRotate( self, ptAx, vtAx, dAngDeg) + if bOk then + self[1] = Point3d( b3New[1]) + self[2] = Point3d( b3New[2]) + end + return bOk +end + +-- trasformazione di riferimento verso globale +function BBox3d:toGlob( fTool) + if not isBBox3d( self) or not isFrame3d( fTool) then + return false + end + if BBox3d.isEmpty(self) then + return true + end + local bOk, b3New = EgtBBoxToGlob( self, fTool) + if bOk then + self[1] = Point3d( b3New[1]) + self[2] = Point3d( b3New[2]) + end + return bOk +end + +-- trasformazione di riferimento verso locale +function BBox3d:toLoc( fTool) + if not isBBox3d( self) or not isFrame3d( fTool) then + return false + end + if BBox3d.isEmpty(self) then + return true + end + local bOk, b3New = EgtBBoxToLoc( self, fTool) + if bOk then + self[1] = Point3d( b3New[1]) + self[2] = Point3d( b3New[2]) + end + return bOk +end + +-- trasformazione di riferimento da locale a locale +function BBox3d:locToLoc( fOri, fDest) + if not isBBox3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then + return false + end + if BBox3d.isEmpty(self) then + return true + end + local bOk, b3New = EgtBBoxLocToLoc( self, fOri, fDest) + if bOk then + self[1] = Point3d( b3New[1]) + self[2] = Point3d( b3New[2]) + end + return bOk +end + +-- restituzione componenti +function BBox3d:getMin() + if BBox3d.isEmpty(self) then + return nil + end + return Point3d( self[1]) +end + +function BBox3d:getMax() + if BBox3d.isEmpty(self) then + return nil + end + return Point3d( self[2]) +end + +function BBox3d:getDimX() + if BBox3d.isEmpty(self) then + return nil + end + return ( self[2][1] - self[1][1]) +end + +function BBox3d:getDimY() + if BBox3d.isEmpty(self) then + return nil + end + return ( self[2][2] - self[1][2]) +end + +function BBox3d:getDimZ() + if BBox3d.isEmpty(self) then + return nil + end + return ( self[2][3] - self[1][3]) +end + +function BBox3d:getCenter() + if BBox3d.isEmpty(self) then + return nil + end + return 0.5 * ( Point3d( self[1]) + Point3d( self[2])) +end + +function BBox3d:getRadius() + if BBox3d.isEmpty(self) then + return nil + end + return 0.5 * dist( Point3d( self[1]), Point3d( self[2])) +end + +-- conversione in stringa (tostring) +function BBox3d:__tostring() + if BBox3d.isEmpty(self) then + return '(empty)' + end + return '('.. tostring(self[1])..','..tostring(self[2])..')' +end + +-- verifica che il box includa il punto in XY +function EnclosesPointXY( b3Box, ptP) + if b3Box[2][1] < ptP[1] - GEO.EPS_SMALL or b3Box[1][1] > ptP[1] + GEO.EPS_SMALL then + return false + end + if b3Box[2][2] < ptP[2] - GEO.EPS_SMALL or b3Box[1][2] > ptP[2] + GEO.EPS_SMALL then + return false + end + return true +end + +-- verifica che il primo box includa il secondo in XY +function EnclosesXY( b3First, b3Second) + if not isBBox3d( b3First) or not isBBox3d( b3Second) then + return false + end + if BBox3d.isEmpty( b3First) or BBox3d.isEmpty( b3Second) then + return false + end + return EnclosesPointXY( b3First, b3Second:getMin()) and EnclosesPointXY( b3First, b3Second:getMax()) +end + +-- verifica di interferenza tra due box in XY +function OverlapsXY( b3First, b3Second) + if not isBBox3d( b3First) or not isBBox3d( b3Second) then + return false + end + if BBox3d.isEmpty( b3First) or BBox3d.isEmpty( b3Second) then + return false + end + if b3First[2][1] < b3Second[1][1] - GEO.EPS_SMALL or b3First[1][1] > b3Second[2][1] + GEO.EPS_SMALL then + return false + end + if b3First[2][2] < b3Second[1][2] - GEO.EPS_SMALL or b3First[1][2] > b3Second[2][2] + GEO.EPS_SMALL then + return false + end + return true +end + + +return EgtBBox3d diff --git a/ProgramData/EgtBeamWall/LuaLibs/EgtBase.lua b/ProgramData/EgtBeamWall/LuaLibs/EgtBase.lua new file mode 100644 index 0000000..cdfb48f --- /dev/null +++ b/ProgramData/EgtBeamWall/LuaLibs/EgtBase.lua @@ -0,0 +1,647 @@ +-- EgtLib.lua libreria di base EgalTech per Lua 2022/04/12 +-- 2019/12/04 EgtTestBreak interruzione se valore 1. +-- 2020/06/04 Aggiunta funzione EgtCurveIsACircle. +-- 2020/06/16 Aggiunta funzione EgtSurfTmGetFacetBBoxRef. +-- 2021/11/27 Aggiunta funzione EgtClamp. +-- 2022/04/12 Aggiunta funzione EgtGetValInNotes. + +-- Tavola per definizione modulo (serve ma non usata) +local EgtBase = {} + +EgtOutLog( 'EgtBase started', 1) + +-- Funzioni del package matematico rese globali e con angoli in gradi +abs = math.abs +fmod = math.fmod +floor = math.floor +ceil = math.ceil +min = math.min +max = math.max +huge = math.huge +modf = math.modf +sqrt = math.sqrt +pow = function( x, y) return x ^ y end +exp = math.exp +log = math.log +log10 = function( x) return math.log( x, 10) end +ldexp = function( x, exp) return x * 2.0 ^ exp end +deg = math.deg +rad = math.rad +pi = math.pi +sin = function( x) return math.sin( math.rad( x)) end +cos = function( x) return math.cos( math.rad( x)) end +tan = function( x) return math.tan( math.rad( x)) end +asin = function( x) return math.deg( math.asin( x)) end +acos = function( x) return math.deg( math.acos( x)) end +atan = function( y, x) return math.deg( math.atan( y, x)) end +atan2 = function( y, x) return math.deg( math.atan( y, x)) end +random = math.random +randomseed = math.randomseed +tointeger = math.tointeger + +---------------------------------------------------------------------------- +function EgtIf( bCond, Val1, Val2) + if bCond then + return Val1 + else + return Val2 + end +end + +---------------------------------------------------------------------------- +function EgtClamp( Val, Min, Max) + if Min > Max then + Min, Max = Max, Min + end + if Val < Min then + return Min + elseif Val > Max then + return Max + else + return Val + end +end + +---------------------------------------------------------------------------- +-- Funzione per protezione variabili e funzioni globali +function EgtProtectGlobal() + local newgt = {} + setmetatable( newgt, {__index = _G, + __newindex = function( t, k, v) + local k3 = string.sub( k, 1, 3) + if k3 == 'Egt' or k3 == 'Emt' or + k3 == 'GEO' or k3 == 'GDB' or k3 == 'SCE' or k3 == 'MCH' then + error( "attempting to change global "..tostring( k)..' to '..tostring( v), 2) + else + rawset( t, k, v) + end + end + }) + return newgt +end + +-- Funzione per lancio, se richiesta, predisposizione debug +function EgtEnableDebug( bOn) + if not bOn then + EgtOutLog( 'Release Mode', 1) + return true + elseif EgtIs64bit() then + -- non funziona a 64 bit + EgtOutLog( 'Skipped Debug Activation (64bit)') + return false + else + -- carico il modulo opportuno + EgtOutLog( 'Debug Mode (32bit)', 1) + return require( 'mobdebug').start() + end +end + +-- Funzione per reset librerie +function EgtResetLibs() + package.loaded.EgtTest = nil + package.loaded.EgtBase = nil + package.loaded.EgtConst = nil + package.loaded.EgtVector3d = nil + package.loaded.EgtPoint3d = nil + package.loaded.EgtFrame3d = nil + package.loaded.EgtBBox3d = nil + package.loaded.EgtColor3d = nil + package.loaded.Dimension = nil + package.loaded.EgtLinearDimension = nil + package.loaded.EmtGenerator = nil +end + +---------------------------------------------------------------------------- +-- Funzione per OutLog di tutte le variabili globali +function EgtOutLogAllGlobVars() + local a = {} + for k,v in pairs( _G) do + a[#a+1] = k .. " => ".. tostring( v) + end + table.sort( a) + EgtOutLog( 'Global Variables (#' .. #a .. ') :') + for _,v in ipairs( a) do + EgtOutLog( v) + end +end + +---------------------------------------------------------------------------- +-- Funzione per avere direttorio del file che lancia la funzione +function EgtGetSourceDir( nUp) + local nSou = 2 + if nUp then nSou = nSou + nUp end + local info = debug.getinfo( nSou, 'S') + local dir = info.source:match("^@?(.-)([^\\/]-%.?([^%.\\/]*))$") + return dir +end + +---------------------------------------------------------------------------- +-- Funzione per avere direttorio e file che lancia la funzione +function EgtGetSourcePath( nUp) + local nSou = 2 + if nUp then nSou = nSou + nUp end + local info = debug.getinfo( nSou, 'S') + local dir = string.gsub( info.source, '@', '') + return dir +end + +-- Funzione per accodare path di ricerca librerie lua +function EgtAddToPackagePath( path) + if not package.path:find( path, 1, true) then + if package.path:sub( -1) == ';' then + package.path = package.path .. path .. ';' + else + package.path = package.path .. ';' .. path .. ';' + end + end +end + +-- Funzione per rimuovere direttori macchine da path di ricerca librerie lua +function EgtRemoveBaseMachineDirFromPackagePath() + local vLibDir = EgtSplitString( _G.package.path, ';') + if not vLibDir or #vLibDir == 0 then return end + local sBaseMachDir = EgtSplitPath( EgtGetCurrMachineDir() or '') + if not sBaseMachDir or #sBaseMachDir == 0 then return end + package.path = '' + for i = 1, #vLibDir do + if #vLibDir[i] > 0 and not vLibDir[i]:find( sBaseMachDir, 1, true) then + package.path = package.path .. vLibDir[i] .. ';' + end + end +end + +-- Funzione per dividere Path in Direttorio, NomeFile e Estensione +function EgtSplitPath( sPath) + local sDir, sFile = string.match(sPath, "(.-)([^\\/]*)$") + local sName, sExt + if sFile and string.find(sFile,'%.') then + sName, sExt = string.match(sFile,'(.*)([%.].-)$') + else + sName = sFile + sExt = '' + end + return sDir, sName, sExt +end + +-- Funzione per cambiare estensione di una Path +function EgtChangePathExtension( sPath, sExt) + local sFileDir, sFileName, sFileExt = EgtSplitPath( sPath) + if string.sub( sExt, 1, 1) == '.' then + return sFileDir .. sFileName .. sExt + else + return sFileDir .. sFileName .. '.' .. sExt + end +end + +---------------------------------------------------------------------------- +-- Funzioni di trim di stringhe di caratteri +function EgtTrimRight( sStr) + if not sStr then return nil end + return sStr:match( "(.-)%s*$") +end +function EgtTrimLeft( sStr) + if not sStr then return nil end + return sStr:match( "^%s*(.*)") +end +function EgtTrim( sStr) + if not sStr then return nil end + return sStr:match( "^%s*(.-)%s*$") +end + +---------------------------------------------------------------------------- +-- Funzione per aggiungere/togliere coppie chiave/valore da una stringa di note +function EgtAdjustNotes( sNotes, sKey, Val) + local sNewNotes = '' + local vItem = EgtSplitString( sNotes, ';') or {} + for i = 1, #vItem do + local sItem = EgtTrim( vItem[i]) + if sItem and #sItem > 0 and not sItem:find( sKey, 1, true) then + sNewNotes = sNewNotes .. sItem .. ';' + end + end + if Val and Val ~= '' then + sNewNotes = sNewNotes .. EgtSetVal( sKey, Val) + end + return sNewNotes +end + +---------------------------------------------------------------------------- +-- Funzione per recuperare un valore data la chiave da una stringa di note +function EgtGetValInNotes( sNotes, sKey, sType) + local vItem = EgtSplitString( sNotes, ';') or {} + for i = 1, #vItem do + local sItem = EgtTrim( vItem[i]) + if sItem and #sItem > 0 and sItem:find( sKey..'=', 1, true) then + return EgtGetVal( sItem, sKey, sType) + end + end + return nil +end + +---------------------------------------------------------------------------- +-- Funzione per creare tabella da primo indice per numero indici consecutivi +function EgtTableFill( nStart, nCount) + if not nStart or nCount <= 0 then return nil end + local T = {} + for i = 0,nCount-1 do + table.insert( T, nStart+i) + end + return T +end + +-- Funzione per aggiungere a tabella da primo indice per numero indici consecutivi +function EgtTableAdd( T, nStart, nCount) + if not nStart or nCount <= 0 then return T end + for i = 0,nCount-1 do + table.insert( T, nStart+i) + end + return T +end + +-- Funzione per unire due tabelle +function EgtJoinTables( Ta, Tb) + for k, v in ipairs( Tb) do + table.insert( Ta, v) + end + return Ta +end + + +---------------------------------------------------------------------------- +-- Funzione per aggiornare interfaccia e consentire interruzione esecuzione +function EgtTestBreak( nProc, nPause) + local nRet = EgtProcessEvents( nProc, nPause) + if nRet == 1 then + error( "User aborted", 2) + end +end + +---------------------------------------------------------------------------- +-- Richiamo librerie componenti +require( 'EgtConst') +require( 'EgtVector3d') +require( 'EgtPoint3d') +require( 'EgtFrame3d') +require( 'EgtBBox3d') +require( 'EgtColor3d') + + +-- Ridefinizione funzioni per ritornare Vector3d +local o_EgtGetGridVersZ = EgtGetGridVersZ +EgtGetGridVersZ = function(...) + local vtV = o_EgtGetGridVersZ(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtSV = EgtSV +EgtSV = function(...) + local vtV = o_EgtSV(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtEV = EgtEV +EgtEV = function(...) + local vtV = o_EgtEV(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtMV = EgtMV +EgtMV = function(...) + local vtV = o_EgtMV(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtUV = EgtUV +EgtUV = function(...) + local vtV = o_EgtUV(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtET = EgtET +EgtET = function(...) + local vtV = o_EgtET(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtCurveExtrusion = EgtCurveExtrusion +EgtCurveExtrusion = function(...) + local vtV = o_EgtCurveExtrusion(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtArcNormVersor = EgtArcNormVersor +EgtArcNormVersor = function(...) + local vtV = o_EgtArcNormVersor(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtSurfFrNormVersor = EgtSurfFrNormVersor +EgtSurfFrNormVersor = function(...) + local vtV = o_EgtSurfFrNormVersor(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtSurfTmFacetNormVersor = EgtSurfTmFacetNormVersor +EgtSurfTmFacetNormVersor = function(...) + local vtV = o_EgtSurfTmFacetNormVersor(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtTextNormVersor = EgtTextNormVersor +EgtTextNormVersor = function(...) + local vtV = o_EgtTextNormVersor(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtGetCalcToolDirFromAngles = EgtGetCalcToolDirFromAngles +EgtGetCalcToolDirFromAngles = function(...) + local vtV = o_EgtGetCalcToolDirFromAngles(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtGetCalcAuxDirFromAngles = EgtGetCalcAuxDirFromAngles +EgtGetCalcAuxDirFromAngles = function(...) + local vtV = o_EgtGetCalcAuxDirFromAngles(...) + if vtV then return Vector3d( vtV) end +end + +-- Ridefinizione funzioni per ritornare Vector3d e altri parametri +local o_EgtCurveIsFlat = EgtCurveIsFlat +EgtCurveIsFlat = function(...) + local bFlat, vtN, dDist = o_EgtCurveIsFlat(...) + if vtN then return bFlat, Vector3d( vtN), dDist end +end +local o_EgtCurveArea = EgtCurveArea +EgtCurveArea = function(...) + local vtN, dDist, dArea = o_EgtCurveArea(...) + if vtN then return Vector3d( vtN), dDist, dArea end +end + +-- Ridefinizione funzioni per ritornare Point3d +local o_EgtSP = EgtSP +EgtSP = function(...) + local ptP = o_EgtSP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtEP = EgtEP +EgtEP = function(...) + local ptP = o_EgtEP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtMP = EgtMP +EgtMP = function(...) + local ptP = o_EgtMP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtCP = EgtCP +EgtCP = function(...) + local ptP = o_EgtCP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGP = EgtGP +EgtGP = function(...) + local ptP = o_EgtGP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtUP = EgtUP +EgtUP = function(...) + local ptP = o_EgtUP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtNP = EgtNP +EgtNP = function(...) + local ptP = o_EgtNP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtIP = EgtIP +EgtIP = function(...) + local ptP = o_EgtIP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtCurveCompoCenter = EgtCurveCompoCenter +EgtCurveCompoCenter = function(...) + local ptP = o_EgtCurveCompoCenter(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGetTableRef = EgtGetTableRef +EgtGetTableRef = function(...) + local ptP = o_EgtGetTableRef(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGetCalcTipFromPositions = EgtGetCalcTipFromPositions +EgtGetCalcTipFromPositions = function(...) + local ptP = o_EgtGetCalcTipFromPositions(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGetRawPartCenter = EgtGetRawPartCenter +EgtGetRawPartCenter = function(...) + local ptP = o_EgtGetRawPartCenter(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGetMachiningStartPoint = EgtGetMachiningStartPoint +EgtGetMachiningStartPoint = function(...) + local ptP = o_EgtGetMachiningStartPoint(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGetMachiningEndPoint = EgtGetMachiningEndPoint +EgtGetMachiningEndPoint = function(...) + local ptP = o_EgtGetMachiningEndPoint(...) + if ptP then return Point3d( ptP) end +end + +-- Ridefinizione funzioni per ritornare Point3d e altri parametri +local o_EgtSurfTmFacetsContact = EgtSurfTmFacetsContact +EgtSurfTmFacetsContact = function(...) + local bAdj, ptP1, ptP2, dAng = o_EgtSurfTmFacetsContact(...) + if bAdj and ptP1 and ptP2 and dAng then + return bAdj, Point3d( ptP1), Point3d( ptP2), dAng + else + return bAdj + end +end +local o_EgtSurfTmFacetOppositeSide = EgtSurfTmFacetOppositeSide +EgtSurfTmFacetOppositeSide = function(...) + local ptP1, ptPm, ptP2, vtV1, vtV2, dL, dW = o_EgtSurfTmFacetOppositeSide(...) + if ptP1 and ptPm and ptP2 and vtV1 and vtV2 then + return Point3d( ptP1), Point3d( ptPm), Point3d( ptP2), Vector3d( vtV1), Vector3d( vtV2), dL, dW + end +end +local o_EgtPointCurveDist = EgtPointCurveDist +EgtPointCurveDist = function(...) + local dDist, ptNear, dU = o_EgtPointCurveDist(...) + if dDist then return dDist, Point3d( ptNear), dU end +end +local o_EgtGetLastSelInfo = EgtGetLastSelInfo +EgtGetLastSelInfo = function(...) + local nId, nSub, ptSel = o_EgtGetLastSelInfo(...) + if nId then return nId, nSub, Point3d( ptSel) end +end +local o_EgtGetPrevSelInfo = EgtGetPrevSelInfo +EgtGetPrevSelInfo = function(...) + local nId, nSub, ptSel = o_EgtGetPrevSelInfo(...) + if nId then return nId, nSub, Point3d( ptSel) end +end +local o_EgtSurfBezierGetPoint = EgtSurfBezierGetPoint +EgtSurfBezierGetPoint = function(...) + local ptP = o_EgtSurfBezierGetPoint(...) + if ptP then + return Point3d( ptP) + end +end +local o_EgtSurfBezierGetPointD1 = EgtSurfBezierGetPointD1 +EgtSurfBezierGetPointD1 = function(...) + local ptP, vtDerU, vtDerV = o_EgtSurfBezierGetPointD1(...) + if ptP and vtDerU and vtDerV then + return Point3d( ptP), Vector3d( vtDerU), Vector3d( vtDerV) + end +end +local o_EgtSurfBezierGetPointNrmD1 = EgtSurfBezierGetPointNrmD1 +EgtSurfBezierGetPointNrmD1 = function(...) + local ptP, vtN, vtDerU, vtDerV = o_EgtSurfBezierGetPointNrmD1(...) + if ptP and vtDerU and vtDerV then + return Point3d( ptP), Vector3d( vtN), Vector3d( vtDerU), Vector3d( vtDerV) + end +end + +-- Ridefinizione funzioni per ritornare Point3d e Vector3d +local o_EgtSurfTmFacetNearestEndPoint = EgtSurfTmFacetNearestEndPoint +EgtSurfTmFacetNearestEndPoint = function(...) + local ptP, vtN = o_EgtSurfTmFacetNearestEndPoint(...) + if ptP and vtN then return Point3d( ptP), Vector3d( vtN) end +end +local o_EgtSurfTmFacetNearestMidPoint = EgtSurfTmFacetNearestMidPoint +EgtSurfTmFacetNearestMidPoint = function(...) + local ptP, vtN = o_EgtSurfTmFacetNearestMidPoint(...) + if ptP and vtN then return Point3d( ptP), Vector3d( vtN) end +end +local o_EgtSurfTmFacetCenter = EgtSurfTmFacetCenter +EgtSurfTmFacetCenter = function(...) + local ptP, vtN = o_EgtSurfTmFacetCenter(...) + if ptP and vtN then return Point3d( ptP), Vector3d( vtN) end +end +local o_EgtCurveIsACircle = EgtCurveIsACircle +EgtCurveIsACircle = function(...) + local bCirc, ptC, vtN, dRad, bCCW = o_EgtCurveIsACircle(...) + if bCirc then return bCirc, Point3d( ptC), Vector3d( vtN), dRad, bCCW end +end + +-- Ridefinizione funzioni per ritornare Frame3d +local o_EgtGetGridFrame = EgtGetGridFrame +EgtGetGridFrame = function() + local frRef = o_EgtGetGridFrame() + if frRef then return Frame3d( frRef) end +end +local o_EgtGetGlobFrame = EgtGetGlobFrame +EgtGetGlobFrame = function(...) + local frRef = o_EgtGetGlobFrame(...) + if frRef then return Frame3d( frRef) end +end +local o_EgtGetGroupGlobFrame = EgtGetGroupGlobFrame +EgtGetGroupGlobFrame = function(...) + local frRef = o_EgtGetGroupGlobFrame(...) + if frRef then return Frame3d( frRef) end +end +local o_EgtFR = EgtFR +EgtFR = function(...) + local frRef = o_EgtFR(...) + if frRef then return Frame3d( frRef) end +end +local o_EgtGetTextureFrame = EgtGetTextureFrame +EgtGetTextureFrame = function(...) + local frRef = o_EgtGetTextureFrame(...) + if frRef then return Frame3d( frRef) end +end + +-- Ridefinizione funzioni per ritornare Frame3d e altri parametri +local o_EgtCurveMinAreaRectangleXY = EgtCurveMinAreaRectangleXY +EgtCurveMinAreaRectangleXY = function(...) + local frRect, dDimX, dDimY = o_EgtCurveMinAreaRectangleXY(...) + if frRect then return Frame3d( frRect), dDimX, dDimY end +end +local o_EgtSurfTmFacetMinAreaRectangle = EgtSurfTmFacetMinAreaRectangle +EgtSurfTmFacetMinAreaRectangle = function(...) + local frRect, dDimX, dDimY = o_EgtSurfTmFacetMinAreaRectangle(...) + if frRect then return Frame3d( frRect), dDimX, dDimY end +end + +-- Ridefinizione funzioni per ritornare BBox3d +local o_EgtGetBBox = EgtGetBBox +EgtGetBBox = function(...) + local b3Box = o_EgtGetBBox(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtGetBBoxGlob = EgtGetBBoxGlob +EgtGetBBoxGlob = function(...) + local b3Box = o_EgtGetBBoxGlob(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtGetBBoxRef = EgtGetBBoxRef +EgtGetBBoxRef = function(...) + local b3Box = o_EgtGetBBoxRef(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtGetTableArea = EgtGetTableArea +EgtGetTableArea = function(...) + local b3Box = o_EgtGetTableArea(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtGetRawPartBBox = EgtGetRawPartBBox +EgtGetRawPartBBox = function(...) + local b3Box = o_EgtGetRawPartBBox(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtSurfTmGetFacetBBox = EgtSurfTmGetFacetBBox +EgtSurfTmGetFacetBBox = function(...) + local b3Box = o_EgtSurfTmGetFacetBBox(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtSurfTmGetFacetBBoxGlob = EgtSurfTmGetFacetBBoxGlob +EgtSurfTmGetFacetBBoxGlob = function(...) + local b3Box = o_EgtSurfTmGetFacetBBoxGlob(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtSurfTmGetFacetBBoxRef = EgtSurfTmGetFacetBBoxRef +EgtSurfTmGetFacetBBoxRef = function(...) + local b3Box = o_EgtSurfTmGetFacetBBoxRef(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtVolZmapGetPartBBox = EgtVolZmapGetPartBBox +EgtVolZmapGetPartBBox = function(...) + local b3Box = o_EgtVolZmapGetPartBBox(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtVolZmapGetPartBBoxGlob = EgtVolZmapGetPartBBoxGlob +EgtVolZmapGetPartBBoxGlob = function(...) + local b3Box = o_EgtVolZmapGetPartBBoxGlob(...) + if b3Box then return BBox3d( b3Box) end +end + +-- Ridefinizione funzioni per ritornare Color3d +local o_EgtStdColor = EgtStdColor +EgtStdColor = function(...) + local c3Col = o_EgtStdColor(...) + if c3Col then return Color3d( c3Col) end +end +local o_EgtGetColor = EgtGetColor +EgtGetColor = function(...) + local c3Col = o_EgtGetColor(...) + if c3Col then return Color3d( c3Col) end +end +local o_EgtGetCalcColor = EgtGetCalcColor +EgtGetCalcColor = function(...) + local c3Col = o_EgtGetCalcColor(...) + if c3Col then return Color3d( c3Col) end +end +local o_EgtGetBackground = EgtGetBackground +EgtGetBackground = function(...) + local c3Top, c3Bot = o_EgtGetBackground(...) + if c3Top and c3Bot then return Color3d( c3Top), Color3d( c3Bot) end +end + +-- Ridefinizione funzioni per tornare diversi tipi di oggetti +local o_EgtGetInfo = EgtGetInfo +EgtGetInfo = function( Id, Key, sType) + local Val = o_EgtGetInfo( Id, Key, sType) + if sType == 'v' or sType == 'V' then + if Val then return Vector3d( Val) end + elseif sType == 'p' or sType == 'P' then + if Val then return Point3d( Val) end + elseif sType == 'x' or sType == 'X' then + if Val then return BBox3d( Val) end + elseif sType == 'f' or sType == 'F' then + if Val then return Frame3d( Val) end + else + return Val + end +end + + +return EgtBase diff --git a/ProgramData/EgtBeamWall/LuaLibs/EgtColor3d.lua b/ProgramData/EgtBeamWall/LuaLibs/EgtColor3d.lua new file mode 100644 index 0000000..d1541f8 --- /dev/null +++ b/ProgramData/EgtBeamWall/LuaLibs/EgtColor3d.lua @@ -0,0 +1,170 @@ +-- EgtColor3d.lua by EgalTech s.r.l. 2019/03/31 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtColor3d = {} + +EgtOutLog( 'EgtColor3d started', 1) + +-- Include +require( 'EgtConst') +--EnableDebug( false) + + +-- Definizione classe Color3d +Color3d = {} +Color3d.__index = Color3d + +-- funzione di utilita' per identificazione tipo +function isColor3d( a) + return ( getmetatable( a) == Color3d) +end + +local function New( r, g, b, a) + local col = setmetatable( {0,0,0,0}, Color3d) + local function Clip( val, min, max) + if val < min then + return min + elseif val > max then + return max + else + return val + end + end + if not r then + return nil + elseif isColor3d( r) then + col[1] = r[1] + col[2] = r[2] + col[3] = r[3] + if type( g) == 'number' then + col[4] = Clip( g, 0, 100) + else + col[4] = r[4] + end + elseif type( r) == 'table' and #r >= 3 then + col[1] = Clip( r[1], 0, 255) + col[2] = Clip( r[2], 0, 255) + col[3] = Clip( r[3], 0, 255) + if #r >= 4 then + col[4] = Clip( r[4], 0, 100) + else + col[4] = 100 + end + elseif type( r) == 'number' and type( g) == 'number' and type( b) == 'number' then + col[1] = Clip( r, 0, 255) + col[2] = Clip( g, 0, 255) + col[3] = Clip( b, 0, 255) + if type( a) == 'number' then + col[4] = Clip( a, 0, 100) + else + col[4] = 100 + end + elseif type( r) == 'string' then + local stdCol = EgtStdColor( r) + col[1] = stdCol[1] + col[2] = stdCol[2] + col[3] = stdCol[3] + col[4] = stdCol[4] + else + error( 'A parameter is wrong', 2) + end + return col +end + +setmetatable( Color3d, { __call = function( _, ...) return New(...) end }) + +-- restituzione componenti +function Color3d:getRed() + return self[1] +end + +function Color3d:getGreen() + return self[2] +end + +function Color3d:getBlue() + return self[3] +end + +function Color3d:getAlpha() + return self[4] +end + +-- conversione in stringa (tostring) +function Color3d:__tostring() + return '('.. self[1]..','..self[2]..','..self[3]..','..self[4] ..')' +end + +-- funzione di confronto +function AreSameColor( a, b, Tol) + if isColor3d( a) and isColor3d( b) then + if not Tol then + Tol = 0 + end + return math.abs( a[1] - b[1]) < Tol + 0.1 and + math.abs( a[2] - b[2]) < Tol + 0.1 and + math.abs( a[3] - b[3]) < Tol + 0.1 and + math.abs( a[4] - b[4]) < Tol + 0.1 + else + return false + end +end + +-- Colori notevoli +function WHITE() + return Color3d( 'WHITE') +end +function LGRAY() + return Color3d( 'LGRAY') +end +function GRAY() + return Color3d( 'GRAY') +end +function BLACK() + return Color3d( 'BLACK') +end +function RED() + return Color3d( 'RED') +end +function MAROON() + return Color3d( 'MAROON') +end +function YELLOW() + return Color3d( 'YELLOW') +end +function OLIVE() + return Color3d( 'OLIVE') +end +function LIME() + return Color3d( 'LIME') +end +function GREEN() + return Color3d( 'GREEN') +end +function AQUA() + return Color3d( 'AQUA') +end +function TEAL() + return Color3d( 'TEAL') +end +function BLUE() + return Color3d( 'BLUE') +end +function NAVY() + return Color3d( 'NAVY') +end +function FUCHSIA() + return Color3d( 'FUCHSIA') +end +function PURPLE() + return Color3d( 'PURPLE') +end +function ORANGE() + return Color3d( 'ORANGE') +end +function BROWN() + return Color3d( 'BROWN') +end + + +return EgtColor3d diff --git a/ProgramData/EgtBeamWall/LuaLibs/EgtConst.lua b/ProgramData/EgtBeamWall/LuaLibs/EgtConst.lua new file mode 100644 index 0000000..1a93d36 --- /dev/null +++ b/ProgramData/EgtBeamWall/LuaLibs/EgtConst.lua @@ -0,0 +1,975 @@ +-- EgtConst.lua libreria di costanti EgalTech per Lua 2022/02/04 +-- 2018/02/22 Sistemata package.cpath per lua 5.3 con "/bin/clibs53/?.dll;" +-- 2019/07/24 Portato GEO.EPS_ZERO a 1e-8 come nel programma. +-- 2020/01/15 Aggiunta costante GDB_TY.EXT_DIMENSION. +-- 2020/02/06 Aggiunte costanti GDB_CRC. +-- 2020/02/14 Aggiunta costante MCH_GP.MAXDEPTHSAFE. +-- 2020/02/21 Aggiunta costante MCH_TY.MILL_POLISHING. +-- 2020/03/26 Aggiunta costante GDB_TY.SRF_BEZ. +-- 2020/06/05 Aggiunte costanti MCH_MP.TABMIN e MCH_MP.TABMAX. +-- 2020/10/12 Aggiunte costanti EEX_FL. +-- 2021/02/14 Aggiunte costanti NST_CORNER. +-- 2021/05/21 Aggiunta costante MCH_SIM_COB.CONE (tronco di cono). +-- 2021/07/28 Aggiunte costanti MCH_MP.SIDEANGFEED e MCH_MP.STEPLAST. +-- 2021/09/24 Aggiunte costanti MCH_MILL_LI.TG_PERP e MCH_MILL_LO.PERP_TG. +-- 2022/02/04 Aggiunte costanti MCH_MP.EPICYCLESRAD e MCH_MP.EPICYCLESDIST. + +-- Tavola per definizione modulo (serve ma non usata) +local EgtConst = {} + +EgtOutLog( 'EgtConst started', 1) + +-- Per eventuale debug +local ZBS = "c:/ZeroBraneStudio" +if not package.path:find(ZBS,1,true) then + package.path = ZBS .. "/lualibs/?/?.lua;" .. ZBS .. "/lualibs/?.lua;" .. package.path + package.cpath = ZBS .. "/bin/?.dll;" .. ZBS .. "/bin/clibs53/?.dll;" .. package.cpath +end + +-- Funzione per rendere non modificabili le costanti +local protect = function(tbl) + return setmetatable({}, { + __index = tbl, + __newindex = function(t, key, value) + error("attempting to change constant " .. + tbl[1]..tostring(key) .. " to " .. tostring(value), 2) + end + }) +end + +-- Costanti geometriche +GEO = { + 'GEO.', + EPS_SMALL = 1.0e-3, + EPS_ZERO = 1.0e-8, + INFINITO = 1.0e10, + EPS_ANG_SMALL = 1.0e-3, + ONE_MM = 1.0, + ONE_INCH = 25.4 +} +GEO = protect( GEO) +-- Costanti per tipo di file Nge +GDB_NT = { + 'GDB_NT.', + TXT = 0, + BIN = 1, + CMPTXT = 2 +} +GDB_NT = protect( GDB_NT) +-- Costanti per identificativi speciali di GDB +GDB_ID = { + 'GDB_ID.', + ROOT = 0, -- radice + NULL = -1, -- non valido + SEL = -2, -- selezione + GRID = -3, -- griglia + CP = -4, -- current part + CL = -5 -- current layer +} +GDB_ID = protect( GDB_ID) +-- Costanti per posizione di inserimento in GDB in copia/trasferisci +GDB_IN = { + 'GDB_IN.', + FIRST_SON = 0, + LAST_SON = 1, + BEFORE = 2, + AFTER = 3 +} +GDB_IN = protect( GDB_IN) +-- Costanti per riferimento in cui sono espressi i dati della funzione +GDB_RT = { + 'GDB_RT.', + GLOB = 0, -- globale + GRID = -3, -- griglia + LOC = -6 -- locale +} +GDB_RT = protect( GDB_RT) +-- Costanti per tipo di punto +GDB_PT = { + 'GDB_PT.', + STD = 0, + TG = 1, + PERP = 2, + MIND = 3 +} +GDB_PT = protect( GDB_PT) +-- Costanti per famiglie di oggetti +GDB_FY = { + 'GDB_FY.', + NONE = 0, + GEO_ZERODIM = 128, + GEO_CURVE = 256, + GEO_SURF = 512, + GEO_VOLUME = 1024, + GEO_EXTRA = 2048 +} +GDB_FY = protect( GDB_FY) +-- Costanti per tipo di oggetti +GDB_TY = { + 'GDB_TY.', + NONE = 0, + GROUP = 2, + GEO_VECTOR = 128, + GEO_POINT = 129, + GEO_FRAME = 130, + CRV_LINE = 256, + CRV_ARC = 257, + CRV_BEZ = 258, + CRV_COMPO = 259, + SRF_MESH = 512, + SRF_FRGN = 513, + SRF_BEZ = 514, + VOL_ZMAP = 1024, + EXT_TEXT = 2048, + EXT_DIMENSION = 2049 +} +GDB_TY = protect( GDB_TY) +-- Costanti per livello oggetti +GDB_LV = { + 'GDB_LV.', + USER = 1, + SYSTEM = 2, + TEMP = 3 +} +GDB_LV = protect( GDB_LV) +-- Costanti per modo oggetti +GDB_MD = { + 'GDB_MD.', + STD = 1, + LOCKED = 2, + HIDDEN = 3 +} +GDB_MD = protect( GDB_MD) +-- Costanti per stato oggetti +GDB_ST = { + 'GDB_ST.', + OFF = 0, + ON = 1, + SEL = 2 +} +GDB_ST = protect( GDB_ST) +-- Costanti per flag calcolo BBox3d +GDB_BB = { + 'GDB_BB.', + STANDARD = 0, + ONLY_VISIBLE = 1, + EXACT = 2, + IGNORE_TEXT = 4, + IGNORE_DIM = 8 +} +GDB_BB = protect( GDB_BB) +-- Costanti per info di sistema +GDB_SI = { + 'GDB_SI.', + SOURCE = "!SOU", + BASE = "!BAS", + LIST = "!LST", + COPY = "!COP", + MGRPONLY = "!MGO" +} +GDB_SI = protect( GDB_SI) +-- Costanti per tipologia di riferimento +GDB_FR = { + 'GDB_FR.', + TOP = 1, + BOTTOM = 2, + FRONT = 3, + BACK = 4, + LEFT = 5, + RIGHT = 6 +} +GDB_FR = protect( GDB_FR) +-- Costanti per posizione inserimento testo rispetto al punto di riferimento +GDB_TI = { + 'GDB_TI.', + TL = 1, + TC = 2, + TR = 3, + ML = 4, + MC = 5, + MR = 6, + BL = 7, + BC = 8, + BR = 9 +} +GDB_TI = protect( GDB_TI) +-- Costanti per interpolazione punti +GDB_PI = { + 'GDB_PI.', + ARCS = 0, + ARCS_CORNER = 1, + CUBICS = 2 +} +GDB_PI = protect( GDB_PI) +-- Costanti per approssimazione curve +GDB_CA = { + 'GDB_CA.', + LINES = 0, + SPECIAL_LINES = 10, + LEFT_LINES = 1, + LEFT_CONVEX_LINES = 11, + RIGHT_LINES = 2, + RIGHT_CONVEX_LINES = 12, + ARCS = 3 +} +GDB_CA = protect( GDB_CA) +-- Costanti per tipo offset di curve +GDB_OT = { + 'GDB_OT.', + FILLET = 0, + CHAMFER = 1, + EXTEND = 2 +} +GDB_OT = protect( GDB_OT) +-- Costanti per classificazione reciproca di regioni +GDB_RC = { + 'GDB_RC.', + NULL = 0, + IN1 = 1, + IN2 = 2, + SAME = 3, + OUT = 4, + INTERS = 5 +} +GDB_RC = protect( GDB_RC) +-- Costanti per classificazione curva rispetto a regione +GDB_CRC = { + 'GDB_CRC.', + NULL = 0, + IN = 1, + OUT = 2, + ON = 3, + INTERS = 4 +} +GDB_CRC = protect( GDB_CRC) +-- Costanti tipo punto intersezione Linea SurfTriMesh +GDB_SLT = { + 'GDB_SLT.', + NULL = 0, + IN = 1, + OUT = 2, + TG_INI = 3, + TG_FIN = 4, + TOUCH = 5 +} +GDB_SLT = protect( GDB_SLT) +-- Costanti tipo costruzione superficie rigata +GDB_RUL = { + 'GDB_RUL.', + ISOPAR = 'IP', + MINDIST = 'MD' +} +GDB_RUL = protect( GDB_RUL) +-- Costanti scena per tipo visualizzazione +SCE_SM = { + 'SCE_SM.', + WF = 0, + HL = 1, + SH = 2 +} +SCE_SM = protect( SCE_SM) +-- Costanti scena per tipo zoom +SCE_ZM = { + 'SCE_ZM.', + ALL = 1, + IN = 2, + OUT = 3 +} +SCE_ZM = protect( SCE_ZM) +-- Costanti scena per tipo vista +SCE_VD = { + 'SCE_VD.', + NONE = 0, + TOP = 1, + FRONT = 2, + RIGHT = 3, + BACK = 4, + LEFT = 5, + BOTTOM = 6, + ISO_SW = 7, + ISO_SE = 8, + ISO_NE = 9, + ISO_NW = 10, + GRID = 11 +} +SCE_VD = protect( SCE_VD) +-- Flag per import CNC +EIC_FL = { + 'EIC_FL.', + NONE = 0, + CHAIN = 1, + SKIP_ZEROMACH = 2, + SKIP_RAPID = 4 +} +EIC_FL = protect( EIC_FL) +-- Flag per import BTL +EIB_FL = { + 'EIB_FL.', + NONE = 0, + FLAT_POS = 1, + VERT_POS = 2, + SPECIAL_TRIM = 4, + TS3_POS = 8, + SORT = 16, + USEUATTR = 32 +} +EIB_FL = protect( EIB_FL) +-- Flag per export +EEX_FL = { + 'EEX_FL.', + NONE = 0, + COMP_LAYER = 1, + COL_BY_LAYER = 2, + ADV_NAMES = 4 +} +EEX_FL = protect( EEX_FL) +-- Costanti shortest path per tipo di percorso di ottimizzazione +SHP_TY = { + 'SHP_TY.', + NONE = 0, + CLOSED = 1, + OPEN = 2, + ZIGZAG_X = 3, + ZIGZAG_Y = 4, + ONEWAY_XP = 5, + ONEWAY_XM = 6, + ONEWAY_YP = 7, + ONEWAY_YM = 8 +} +SHP_TY = protect( SHP_TY) +-- Costanti shortest path per tipo estremo di percorso aperto +SHP_OB = { + 'SHP_OB.', + NONE = 0, + NEAR_PNT = 1, + XMIN = 2, + XMAX = 3, + YMIN = 4, + YMAX = 5 +} +SHP_OB = protect( SHP_OB) +-- Costanti nesting per interferenza lavorazione +NST_FMI = { + 'NST_FMI.', + NONE = 0, + LI = 1, + RM = 2, + LO = 4 +} +NST_FMI = protect( NST_FMI) +-- Costanti nesting automatico per corner di partenza +NST_CORNER = { + 'NST_CORNER.', + BL = 0, + TL = 1, + BR = 2, + TR = 3 +} +NST_CORNER = protect( NST_CORNER) +-- Costanti lavorazioni per tipo di tavola della macchina +MCH_TT = { + 'MCH_TT.', + FLAT = 1 +} +MCH_TT = protect( MCH_TT) +-- Costanti lavorazioni per tipo assi della macchina +MCH_AT = { + 'MCH_AT.', + LINEAR = 1, + ROTARY = 2 +} +MCH_AT = protect( MCH_AT) +-- Costanti lavorazioni per tipo teste della macchina (standard o multipla) +MCH_HT = { + 'MCH_HT.', + STD = 1, + MULTI = 2, + SPECIAL = 3 +} +MCH_HT = protect( MCH_HT) +-- Costanti lavorazioni per criterio scelta soluzione (Solution Choice Criterion) +-- STD e OPPOSITE si possono usare solo nelle operazioni (non nelle teste) +MCH_SCC = { + 'MCH_SCC.', + NONE = 0, + STD = 1, + OPPOSITE = 2, + ADIR_XP = 11, + ADIR_XM = 12, + ADIR_YP = 13, + ADIR_YM = 14, + ADIR_ZP = 15, + ADIR_ZM = 16, + ADIR_NEAR = 21, + ADIR_FAR = 22 +} +MCH_SCC = protect( MCH_SCC) +-- Costanti lavorazioni per posizionamento grezzo su corner +MCH_CR = { + 'MCH_CR.', + TL = 1, + TR = 2, + BL = 3, + BR = 4 +} +MCH_CR = protect( MCH_CR) +-- Costanti lavorazioni per posizionamento grezzo su centro +MCH_CE = { + 'MCH_CE.', + TC = 1, + ML = 2, + MR = 3, + BC = 4, + MC = 5 +} +MCH_CE = protect( MCH_CE) +-- Costanti lavorazioni per famiglia utensile +MCH_TF = { + 'MCH_TF.', + DRILLBIT = 256, + SAWBLADE = 512, + MILL = 1024, + MORTISE = 2048, + CHISEL = 4096, + WATERJET = 8192, + COMPO = 16384 +} +MCH_TF = protect( MCH_TF) +-- Costanti lavorazioni per tipologia utensile +MCH_TY = { + 'MCH_TY.', + NONE = 0, + DRILL_STD = 256, + DRILL_LONG = 257, + SAW_STD = 512, + SAW_FLAT = 513, + MILL_STD = 1024, + MILL_NOTIP = 1025, + MILL_POLISHING = 1026, + MORTISE_STD = 2048, + CHISEL_STD = 4096, + WATERJET = 8192, + COMPO = 16384 +} +MCH_TY = protect( MCH_TY) +-- Costanti lavorazioni per tipo parametri di utensili +MCH_TP = { + 'MCH_TP.', + ACTIVE = 4096, + CORR = 8192, + EXIT = 8193, + TYPE = 8194, + COOLANT = 8195, + CORNRAD = 16384, + DIAM = 16385, + TOTDIAM = 16386, + FEED = 16387, + ENDFEED = 16388, + STARTFEED = 16389, + TIPFEED = 16390, + LEN = 16391, + TOTLEN = 16392, + MAXMAT = 16393, + LONOFFSET = 16394, + RADOFFSET = 16395, + SPEED = 16396, + SIDEANG = 16397, + MAXSPEED = 16398, + THICK = 16399, + MAXABSORPTION = 16400, + MINFEED = 16401, + DRAW = 32768, + HEAD = 32769, + NAME = 32770, + SYSNOTES = 32771, + USERNOTES = 32772, + TCPOS = 32773, + UUID = 32774 +} +MCH_TP = protect( MCH_TP) +-- Costanti lavorazioni per tipologia operazione +MCH_OY = { + 'MCH_OY.', + NONE = 0, + DISP = 256, + DRILLING = 512, + SAWING = 1024, + MILLING = 2048, + POCKETING = 4096, + MORTISING = 8192, + SAWROUGHING = 16384, + SAWFINISHING = 32768, + GENMACHINING = 65536, + CHISELING = 131072, + SURFROUGHING = 262144, + SURFFINISHING = 524288, + WATERJETTING = 1048576 +} +MCH_OY = protect( MCH_OY) +-- Costanti lavorazioni per tipologia lavorazione +MCH_MY = { + 'MCH_MY.', + NONE = MCH_OY.NONE, + DRILLING = MCH_OY.DRILLING, + SAWING = MCH_OY.SAWING, + MILLING = MCH_OY.MILLING, + POCKETING = MCH_OY.POCKETING, + MORTISING = MCH_OY.MORTISING, + SAWROUGHING = MCH_OY.SAWROUGHING, + SAWFINISHING = MCH_OY.SAWFINISHING, + GENMACHINING = MCH_OY.GENMACHINING, + CHISELING = MCH_OY.CHISELING, + SURFROUGHING = MCH_OY.SURFROUGHING, + SURFFINISHING = MCH_OY.SURFFINISHING, + WATERJETTING = MCH_OY.WATERJETTING +} +MCH_MY = protect( MCH_MY) +-- Costanti lavorazioni per parametri generali delle lavorazioni +MCH_GP = { + 'MCH_GP.', + SPLITARCS = 8192, + SAFEZ = 16384, + EXTRALONCUTREG = 16385, + EXTRARONDRIREG = 16386, + HOLEDIAMTOLER = 16387, + EXTSAWARCMINRAD = 16388, + INTSAWARCMAXSIDEANG = 16389, + SAFEAGGRBOTTZ = 16390, + MAXDEPTHSAFE = 16391 +} +MCH_GP = protect( MCH_GP) +-- Costanti spezzatura archi +MCH_SPLAR ={ + 'MCH_SPLAR.', + NEVER = 0, + GEN_PLANE = 1, + NO_XY_PLANE = 2, + ALWAYS = 3 +} +MCH_SPLAR = protect( MCH_SPLAR) +-- Costanti lavorazioni per tipo parametri di lavorazione +MCH_MP = { + 'MCH_MP.', + INVERT = 4096, + LEAVETAB = 4097, + TOOLINVERT = 4098, + PROBING = 4099, + LIHOLE = 4100, + OSCENABLE = 4101, + TYPE = 8192, + WORKSIDE = 8193, + HEADSIDE = 8194, + LEADINTYPE = 8195, + EXTLINKTYPE = 8196, + LEADOUTTYPE = 8197, + CURVEUSE = 8198, + STEPTYPE = 8199, + SUBTYPE = 8200, + LEADLINKTYPE = 8201, + SCC = 8202, + FACEUSE = 8203, + EXTCORNERTYPE = 8204, + INTCORNERTYPE = 8205, + CORNERSLOWPERC = 8206, + LPTURNS = 8207, + HPTURNS = 8208, + TABMIN = 8209, + TABMAX = 8210, + SPEED = 16384, + TOOLSPEED = 16384, -- per compatibilità + FEED = 16385, + STARTFEED = 16386, + ENDFEED = 16387, + TIPFEED = 16388, + OFFSR = 16389, + OFFSL = 16390, + DEPTH = 16391, + SIDEANGLE = 16392, + APPROX = 16393, + STARTPOS = 16394, + STARTSLOWLEN = 16395, + ENDSLOWLEN = 16396, + THROUADDLEN = 16397, + STEP = 16398, + RETURNPOS = 16399, + OVERLAP = 16400, + TABLEN = 16401, + TABDIST = 16402, + TABHEIGHT = 16403, + TABANGLE = 16404, + LITANG = 16405, + LIPERP = 16406, + LIELEV = 16407, + LICOMPLEN = 16408, + LOTANG = 16409, + LOPERP = 16410, + LOELEV = 16411, + LOCOMPLEN = 16412, + STARTADDLEN = 16413, + ENDADDLEN = 16414, + OFFSET = 16415, + STEPEXTARC = 16416, + STEPINTARC = 16417, + SIDESTEP = 16418, + VERTFEED = 16419, + STEPSIDEANG = 16420, + OVERL = 16421, + STEPBACK = 16422, + STEPSIDEANGBACK = 16423, + BACKFEED = 16424, + LIHOLERAD = 16425, + FORWARDANGLE = 16426, + PROBINGMINDIST =16427, + PROBINGMAXDIST =16428, + CORNERSLOWLEN = 16429, + THICKREF = 16430, + OSCHEIGHT = 16431, + OSCRAMPLEN = 16432, + OSCFLATLEN = 16433, + SIDEANGFEED = 16434, + STEPLAST = 16435, + EPICYCLESRAD = 16436, + EPICYCLESDIST = 16437, + NAME = 32768, + TOOL = 32769, + DEPTH_STR = 32770, + TUUID = 32771, + UUID = 32772, + SYSNOTES = 32773, + USERNOTES = 32774, + OVERLAP_STR = 32775, + OFFSET_STR = 32776, + INITANGS= 32777, + BLOCKEDAXIS= 32778 +} +MCH_MP = protect( MCH_MP) +-- Costanti foratura per sottotipo lavorazione +MCH_DRI_SUB = { + 'MCH_DRI_SUB.', + STD = 0, + ALONG_CURVE = 1 +} +MCH_DRI_SUB = protect( MCH_DRI_SUB) +-- Costanti lavorazioni lama per lato di lavoro +MCH_SAW_WS = { + 'MCH_SAW_WS.', + CENTER = 0, + LEFT = 1, + RIGHT = 2 +} +MCH_SAW_WS = protect( MCH_SAW_WS) +-- Costanti lavorazioni lama per lato testa +MCH_SAW_HS = { + 'MCH_SAW_HS.', + LEFT = 1, + RIGHT = 2 +} +MCH_SAW_HS = protect( MCH_SAW_HS) +-- Costanti lavorazioni lama per tipo di step +MCH_SAW_ST = { + 'MCH_SAW_ST.', + ZIGZAG = 0, + ONEWAY = 1, + TOANDFROM = 2 +} +MCH_SAW_ST = protect( MCH_SAW_ST) +-- Costanti lavorazioni lama per tipo di attacco +MCH_SAW_LI = { + 'MCH_SAW_LI.', + CENT = 0, + STRICT = 1, + OUT = 2, + EXT_CENT = 3, + EXT_OUT = 4 +} +MCH_SAW_LI = protect( MCH_SAW_LI) +-- Costanti lavorazioni lama per link esterno +MCH_SAW_EL = { + 'MCH_SAW_EL.', + CENT = 0, + EXT_PREV = 1, + EXT_NEXT = 2, + EXT_BOTH = 3 +} +MCH_SAW_EL = protect( MCH_SAW_EL) +-- Costanti lavorazioni lama per tipo di uscita ( EXT conservato per compatibilità) +MCH_SAW_LO = { + 'MCH_SAW_LO.', + CENT = 0, + STRICT = 1, + EXT = 2, + EXT_CENT = 2, + OUT = 3, + EXT_OUT = 4 +} +MCH_SAW_LO = protect( MCH_SAW_LO) +-- Costanti lavorazioni lama per gestione curve +MCH_SAW_CRV = { + 'MCH_SAW_CRV.', + SKIP = 0, + APPROX = 1, + CONVEX = 2, + KEEP = 3 +} +MCH_SAW_CRV = protect( MCH_SAW_CRV) +-- Costanti lavorazioni fresa per lato di lavoro +MCH_MILL_WS = { + 'MCH_MILL_WS.', + CENTER = 0, + LEFT = 1, + RIGHT = 2 +} +MCH_MILL_WS = protect( MCH_MILL_WS) +-- Costanti lavorazioni fresa per tipo di step +MCH_MILL_ST = { + 'MCH_MILL_ST.', + ZIGZAG = 0, + ONEWAY = 1, + SPIRAL = 2 +} +MCH_MILL_ST = protect( MCH_MILL_ST) +-- Costanti lavorazioni fresa per tipo di attacco +MCH_MILL_LI = { + 'MCH_MILL_LI.', + NONE = 0, + LINEAR = 1, + TANGENT = 2, + GLIDE = 3, + ZIGZAG = 4, + HELIX = 5, + TG_PERP = 6 +} +MCH_MILL_LI = protect( MCH_MILL_LI) +-- Costanti lavorazioni fresa per tipo di uscita +MCH_MILL_LO = { + 'MCH_MILL_LO.', + NONE = 0, + LINEAR = 1, + TANGENT = 2, + GLIDE = 3, + AS_LI = 4, + PERP_TG = 5 +} +MCH_MILL_LO = protect( MCH_MILL_LO) +-- Costanti lavorazioni fresa per tipo lavorazione faccia +MCH_MILL_FU = { + 'MCH_MILL_FU.', + NONE = 0, + PARAL_DOWN = 1, + PARAL_TOP = 2, + PARAL_FRONT = 3, + PARAL_BACK = 4, + PARAL_LEFT = 5, + PARAL_RIGHT = 6, + ORTHO_DOWN = 33, + ORTHO_TOP = 34, + ORTHO_FRONT = 35, + ORTHO_BACK = 36, + ORTHO_LEFT = 37, + ORTHO_RIGHT = 38, + ORTHO_CONT = 39, + ORTUP_DOWN = 65, + ORTUP_TOP = 66, + ORTUP_FRONT = 67, + ORTUP_BACK = 68, + ORTUP_LEFT = 69, + ORTUP_RIGHT = 70, + ORTUP_CONT = 71 +} +MCH_MILL_FU = protect( MCH_MILL_FU) +-- Costanti lavorazioni svuotatura per sottotipo +MCH_POCK_SUB = { + 'MCH_POCK_SUB.', + ZIGZAG = 0, + ONEWAY = 1, + SPIRALIN = 2, + SPIRALOUT = 3 +} +MCH_POCK_SUB = protect( MCH_POCK_SUB) +-- Costanti lavorazioni svuotatura per tipo di attacco +MCH_POCK_LI = { + 'MCH_POCK_LI.', + NONE = 0, + GLIDE = 1, + ZIGZAG = 2, + HELIX = 3 +} +MCH_POCK_LI = protect( MCH_POCK_LI) +-- Costanti lavorazioni svuotatura per tipo di uscita +MCH_POCK_LO = { + 'MCH_POCK_LO.', + NONE = 0, + GLIDE = 1 +} +MCH_POCK_LO = protect( MCH_POCK_LO) +-- Costanti lavorazioni sgrossatura con lama per lato testa +MCH_SAWROU_HS = { + 'MCH_SAWROU_HS.', + LEFT = 1, + RIGHT = 2 +} +MCH_SAWROU_HS = protect( MCH_SAWROU_HS) +-- Costanti lavorazioni sgrossatura con lama per tipo di step +MCH_SAWROU_ST = { + 'MCH_SAWROU_ST.', + ZIGZAG = 0, + ONEWAY = 1 +} +MCH_SAWROU_ST = protect( MCH_SAWROU_ST) +-- Costanti lavorazioni sgrossatura con lama per tipo di attacco +MCH_SAWROU_LL = { + 'MCH_SAWROU_LL.', + CENT = 0, + OUT = 1 +} +MCH_SAWROU_LL = protect( MCH_SAWROU_LL) +-- Costanti lavorazioni finitura con lama per lato testa +MCH_SAWFIN_HS = { + 'MCH_SAWFIN_HS.', + LEFT = 1, + RIGHT = 2 +} +MCH_SAWFIN_HS = protect( MCH_SAWFIN_HS) +-- Costanti lavorazioni finitura con lama per tipo di step +MCH_SAWFIN_ST = { + 'MCH_SAWFIN_ST.', + ZIGZAG = 0, + ONEWAY = 1 +} +MCH_SAWFIN_ST = protect( MCH_SAWFIN_ST) +-- Costanti lavorazioni finitura con lama per tipo di attacco +MCH_SAWFIN_LL = { + 'MCH_SAWFIN_LL.', + CENT = 0, + OUT = 1 +} +MCH_SAWFIN_LL = protect( MCH_SAWFIN_LL) +-- Costanti lavorazioni scalpellatura per lato di lavoro +MCH_CHISEL_WS = { + 'MCH_CHISEL_WS.', + LEFT = 1, + RIGHT = 2 +} +MCH_CHISEL_WS = protect( MCH_CHISEL_WS) +-- Costanti lavorazioni mortasatura per lato di lavoro +MCH_MORTISE_WS = { + 'MCH_MORTISE_WS.', + LEFT = 1, + RIGHT = 2 +} +MCH_MORTISE_WS = protect( MCH_MORTISE_WS) +-- Costanti lavorazioni mortasatura per tipo di step +MCH_MORTISE_ST = { + 'MCH_MORTISE_ST.', + ZIGZAG = 0, + ONEWAY = 1 +} +MCH_MORTISE_ST = protect( MCH_MORTISE_ST) +-- Costanti lavorazioni fresa per tipo lavorazione faccia +MCH_MORTISE_FU = { + 'MCH_MORTISE_FU.', + NONE = 0, + PARAL_DOWN = 1, + PARAL_TOP = 2, + PARAL_FRONT = 3, + PARAL_BACK = 4, + PARAL_LEFT = 5, + PARAL_RIGHT = 6 +} +MCH_MORTISE_FU = protect( MCH_MORTISE_FU) +-- Costanti lavorazioni getto d'acqua per lato di lavoro +MCH_WJET_WS = { + 'MCH_WJET_WS.', + CENTER = 0, + LEFT = 1, + RIGHT = 2 +} +MCH_WJET_WS = protect( MCH_WJET_WS) +-- Costanti lavorazioni getto d'acqua per comportamento su angolo esterno +MCH_WJET_EC = { + 'MCH_WJET_EC.', + NONE = 0, + SLOW = 1, + LOOP = 2 +} +MCH_WJET_EC = protect( MCH_WJET_EC) +-- Costanti lavorazioni getto d'acqua per comportamento su angolo interno +MCH_WJET_IC = { + 'MCH_WJET_IC.', + NONE = 0, + SLOW = 1, +} +MCH_WJET_IC = protect( MCH_WJET_IC) +-- Costanti lavorazioni getto d'acqua per tipo di attacco +MCH_WJET_LI = { + 'MCH_WJET_LI.', + NONE = 0, + LINEAR = 1, + TANGENT = 2 +} +MCH_WJET_LI = protect( MCH_WJET_LI) +-- Costanti lavorazioni getto d'acqua per tipo di uscita +MCH_WJET_LO = { + 'MCH_WJET_LO.', + NONE = 0, + LINEAR = 1, + TANGENT = 2, + AS_LI = 4 +} +MCH_WJET_LO = protect( MCH_WJET_LO) +-- Costanti lavorazioni per stato simulazione +MCH_SIM = { + 'MCH_SIM.', + OK = 0, + END_STEP = 1, + END = 2, + STOP = 3, + OUTSTROKE = 4, + DIR_ERR = 5, + COLLISION = 6, + ERR = 7 +} +MCH_SIM = protect( MCH_SIM) +-- Costanti lavorazioni per stato utente di simulazione +MCH_UISIM = { + 'MCH_UISIM.', + NULL = 0, + STOP = 1, + PLAY = 2, + STEP = 3, + PAUSE = 4 +} +MCH_UISIM = protect( MCH_UISIM) +-- Costanti errore simulatore in cieco +MCH_SHE = { + 'MCH_SHE.', + NONE = 0, + INIT = 1, + OUTSTROKE = 2, + DIR_ERR = 3, + COLLISION = 4, + SPECIAL = 5, + GENERAL = 6 +} +MCH_SHE = protect( MCH_SHE) +-- Costanti per tipi oggetti per collisioni in simulatore +MCH_SIM_COB = { + 'MCH_SIM_COB.', + NONE = 0, + BOX = 1, + CYL = 2, + SPHE = 3, + CONE = 4 +} +MCH_SIM_COB = protect( MCH_SIM_COB) +--Costanti : stato visualizzazione macchina +MCH_LOOK = { + 'MCH_LOOK.', + TAB = 0, + TAB_TOOL = 1, + TAB_HEAD = 2, + ALL = 3 +} +MCH_LOOK = protect( MCH_LOOK) + +return EgtConst diff --git a/ProgramData/EgtBeamWall/LuaLibs/EgtDimension.lua b/ProgramData/EgtBeamWall/LuaLibs/EgtDimension.lua new file mode 100644 index 0000000..b93a347 --- /dev/null +++ b/ProgramData/EgtBeamWall/LuaLibs/EgtDimension.lua @@ -0,0 +1,494 @@ +-- EgtDimension.lua by EgalTech s.r.l. 2019/032/31 +-- Creazione di una quota + +-- Tavola per definizione modulo (serve ma non usata) +local EgtDimension = {} + +EgtOutLog( 'EgtDimension started', 1) + +-- Intestazioni +require( 'EgtBase') + +-- Frecce agli estremi della linea di quotatura +function Arrows(nParentId, ptP1, ptP2, dLenArr, iFrame, cColor, bRadius) + + local Ang = atan2( (ptP2:getY() - ptP1:getY()), (ptP2:getX() - ptP1:getX())) + local iLine1 + local iLine2 + if not bRadius then + iLine1 = EgtLinePDL(nParentId, ptP1, Ang + 30, dLenArr, iFrame) + iLine2 = EgtLinePDL(nParentId, ptP1, Ang - 30, dLenArr, iFrame) + end + local iLine3 = EgtLinePDL(nParentId, ptP2, Ang + 150, dLenArr, iFrame) + local iLine4 = EgtLinePDL(nParentId, ptP2, Ang - 150, dLenArr, iFrame) + + if cColor then + if not bRadius then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + end + EgtSetColor( iLine3, cColor) + EgtSetColor( iLine4, cColor) + end +end + +-- Quota verticale (bSide: false sx, true dx) +function CreateLinearDimensionOnY( nParentId, ptP1, ptP2, sText, iTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor) + + if not iFrame then + iFrame = GDB_RT.LOC + end + + local ptSx -- punto a sinistra + local ptDx -- punto a destra + + if ptP1:getX() < ptP2:getX() - GEO.EPS_SMALL then + ptSx = Point3d(ptP1) + ptDx = Point3d(ptP2) + else + ptSx = Point3d(ptP2) + ptDx = Point3d(ptP1) + end + + if not bSide then -- Quotatura a sinistra + + if abs(ptSx:getY() - ptDx:getY()) < GEO.EPS_SMALL then -- Caso di quota nulla + + local Uvx = Vector3d(-1, 0, 0) + local iLine = EgtLinePVL(nParentId, ptDx, Uvx, dDistance + ptDx:getX() - ptSx:getX(), iFrame) + local pText = Point3d(ptSx:getX() - dDistance - dDistText, ptSx:getY(),0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.MR,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine, cColor) + EgtSetColor( TextId, cColor) + end + else -- Caso di quota non nulla + + local ptSx1 = Point3d(ptSx:getX() - dDistance, ptSx:getY(), 0) + local ptDx1 = Point3d(ptSx:getX() - dDistance, ptDx:getY(), 0) + + local iLine1 = EgtLine(nParentId, ptSx, ptSx1, iFrame) + local iLine2 = EgtLine(nParentId, ptDx, ptDx1, iFrame) + + local ptSx2 = Point3d(ptSx:getX() - (dDistance - 0.5 * dLenArr), ptSx:getY(), 0) + local ptDx2 = Point3d(ptSx:getX() - (dDistance - 0.5 * dLenArr), ptDx:getY(), 0) + + local iLine3 = EgtLine(nParentId, ptSx2, ptDx2, iFrame) + Arrows(nParentId, ptSx2, ptDx2, dLenArr, iFrame, cColor) + + local pText = Point3d(ptSx1:getX() - dDistText, (ptSx1:getY() + ptDx1:getY())/2,0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.MR) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end + end + else -- Quotatura a destra + + if abs(ptSx:getY() - ptDx:getY()) < GEO.EPS_SMALL then -- Caso di quota nulla + + local Uvx = Vector3d(1, 0, 0) + local iLine = EgtLinePVL(nParentId, ptSx, Uvx, dDistance + ptDx:getX() - ptSx:getX(), iFrame) + local pText = Point3d(ptDx:getX() + dDistance + dDistText, ptSx:getY(),0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.ML,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine, cColor) + EgtSetColor( TextId, cColor) + end + else -- Caso di quota non nulla + + local ptSx1 = Point3d(ptDx:getX() + dDistance, ptSx:getY(), 0) + local ptDx1 = Point3d(ptDx:getX() + dDistance, ptDx:getY(), 0) + + local iLine1 = EgtLine(nParentId, ptSx, ptSx1, iFrame) + local iLine2 = EgtLine(nParentId, ptDx, ptDx1, iFrame) + + local ptSx2 = Point3d(ptDx:getX() + (dDistance - 0.5 * dLenArr), ptSx:getY(), 0) + local ptDx2 = Point3d(ptDx:getX() + (dDistance - 0.5 * dLenArr), ptDx:getY(), 0) + + local iLine3 = EgtLine(nParentId, ptSx2, ptDx2, iFrame) + Arrows(nParentId, ptSx2, ptDx2, dLenArr, iFrame, cColor) + + local pText = Point3d(ptDx1:getX() + dDistText, (ptSx1:getY() + ptDx1:getY())/2,0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.ML,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end + end + end +end + +-- Quota orizzontale (bSide: false down, true up) +function CreateLinearDimensionOnX( nParentId, ptP1, ptP2, sText, iTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor, bRadius, bShiftLeft) + + if not iFrame then + iFrame = GDB_RT.LOC + end + + local ptDw -- punto in basso + local ptUp -- punto in alto + + if ptP1:getY() < ptP2:getY() - GEO.EPS_SMALL then + ptDw = Point3d( ptP1) + ptUp = Point3d( ptP2) + else + ptDw = Point3d( ptP2) + ptUp = Point3d( ptP1) + end + + -- Quotatura in basso + if not bSide then + + -- Caso di quota nulla + if abs(ptDw:getX() - ptUp:getX()) < GEO.EPS_SMALL then + + local UvY = Vector3d(0, -1, 0) + local iLine = EgtLinePVL(nParentId, ptUp, UvY, ptUp:getY() - ptDw:getY() + dDistance, iFrame) + local pText = Point3d(ptDw:getX(), ptDw:getY() - dDistance - dDistText,0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.TC,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + if bShiftLeft then + EgtMove( TextId, Vector3d(-dLenArr/2, dLenArr + abs(ptDw:getX() - ptUp:getX()) + 20, 0)) + end + if cColor then + EgtSetColor( iLine, cColor) + EgtSetColor( TextId, cColor) + end + + -- Caso di quota non nulla + else + local ptDw1 + local ptUp1 + local ptDw2 + local ptUp2 + local iLine1 + local iLine2 + + if not bRadius then + ptDw1 = Point3d(ptDw:getX(), ptDw:getY() - dDistance, 0) + ptUp1 = Point3d(ptUp:getX(), ptDw:getY() - dDistance, 0) + + iLine1 = EgtLine(nParentId, ptDw, ptDw1, iFrame) + iLine2 = EgtLine(nParentId, ptUp, ptUp1, iFrame) + + ptDw2 = Point3d(ptDw:getX(), ptDw:getY() - (dDistance - 0.5 * dLenArr), 0) + ptUp2 = Point3d(ptUp:getX(), ptDw:getY() - (dDistance - 0.5 * dLenArr), 0) + else + ptDw1 = Point3d(ptDw:getX(), ptDw:getY(), 0) + ptUp1 = Point3d(ptUp:getX(), ptDw:getY(), 0) + ptDw2 = Point3d(ptDw:getX(), ptDw:getY(), 0) + ptUp2 = Point3d(ptUp:getX(), ptDw:getY(), 0) + end + + local iLine3 = EgtLine(nParentId, ptDw2, ptUp2, iFrame) + Arrows(nParentId, ptDw2, ptUp2, dLenArr, iFrame, cColor, bRadius) + + local pText = Point3d((ptDw1:getX() + ptUp1:getX())/2, ptDw1:getY() - dDistText,0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.TC,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + if bShiftLeft then + EgtMove( TextId, Vector3d(-dLenArr/2, dLenArr + abs(ptDw:getX() - ptUp:getX()) + 20, 0)) + end + + if cColor then + if not bRadius then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + end + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end + end + + -- Quotatura in alto + else + + -- Caso di quota nulla + if abs( ptDw:getX() - ptUp:getX()) < GEO.EPS_SMALL then + + local UvY = Vector3d(0, 1, 0) + local iLine = EgtLinePVL(nParentId, ptDw, UvY, ptUp:getY() - ptDw:getY() + dDistance, iFrame) + local pText = Point3d(ptUp:getX(), ptUp:getY() + dDistance + dDistText,0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.BC,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + if bShiftLeft then + EgtMove( TextId, Vector3d(-dLenArr/2, dLenArr + abs(ptDw:getX() - ptUp:getX()) + 20, 0)) + end + if cColor then + EgtSetColor( iLine, cColor) + EgtSetColor( TextId, cColor) + end + + -- Caso di quota non nulla + else + local ptDw1 + local ptUp1 + local ptDw2 + local ptUp2 + local iLine1 + local iLine2 + + if not bRadius then + + ptDw1 = Point3d( ptDw:getX(), ptUp:getY() + dDistance, 0) + ptUp1 = Point3d( ptUp:getX(), ptUp:getY() + dDistance, 0) + + iLine1 = EgtLine( nParentId, ptDw, ptDw1, iFrame) + iLine2 = EgtLine( nParentId, ptUp, ptUp1, iFrame) + + ptDw2 = Point3d( ptDw:getX(), ptUp:getY() + (dDistance - 0.5 * dLenArr), 0) + ptUp2 = Point3d( ptUp:getX(), ptUp:getY() + (dDistance - 0.5 * dLenArr), 0) + else + + ptDw1 = Point3d( ptDw:getX(), ptUp:getY(), 0) + ptUp1 = Point3d( ptUp:getX(), ptUp:getY(), 0) + ptDw2 = Point3d( ptDw:getX(), ptUp:getY(), 0) + ptUp2 = Point3d( ptUp:getX(), ptUp:getY(), 0) + end + + local iLine3 = EgtLine( nParentId, ptDw2, ptUp2, iFrame) + Arrows( nParentId, ptDw2, ptUp2, dLenArr, iFrame, cColor, bRadius) + + local pText = Point3d( ( ptDw1:getX() + ptUp1:getX()) / 2, ptUp1:getY() + dDistText, 0) + local TextId = EgtTextAdv( nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.BC,iFrame) + if bShiftLeft then + EgtMove( TextId, Vector3d( -dLenArr/2, dLenArr + abs( ptDw:getX() - ptUp:getX()) + 20, 0)) + end + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + if not bRadius then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + end + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end + end + end +end + +-- Quota allineata (bSide: false sx, true dx) +function CreateLinearDimensionAligned( nParentId, ptP1, ptP2, sText, dTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor) + + if not iFrame then + iFrame = GDB_RT.LOC + end + + -- Se punti coincidenti, esco + if AreSamePointApprox(ptP1,ptP2) then + return false + end + + -- Se quotatura orizzontale, uso questa + if abs(ptP1:getY() - ptP2:getY()) < GEO.EPS_SMALL then + -- adatto il lato + if ptP2:getX() > ptP1:getX() then + bSide = not bSide + end + CreateLinearDimensionOnX(nParentId, ptP1, ptP2, sText, dTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor) + return true + end + + local Vv = ptP2 - ptP1 + Vv:normalize() + + local AngText = atan2( Vv:getY(), Vv:getX()) + local bAngModif = false + if AngText > 90 then + AngText = AngText - 180 + bAngModif = true + elseif AngText < - 90 then + AngText = AngText + 180 + bAngModif = true + end + + if bSide then + Vv:rotate(Z_AX(),-90) + if bAngModif then + PointType = GDB_TI.BC + else + PointType = GDB_TI.TC + end + else + Vv:rotate(Z_AX(),90) + if bAngModif then + PointType = GDB_TI.TC + else + PointType = GDB_TI.BC + end + end + + local iLine1 = EgtLinePVL(nParentId,ptP1, Vv, dDistance, iFrame) + local iLine2 = EgtLinePVL(nParentId,ptP2, Vv, dDistance, iFrame) + + local ptP1M = ptP1 + (dDistance - 0.5 * dLenArr) * Vv + local ptP2M = ptP2 + (dDistance - 0.5 * dLenArr) * Vv + + local iLine3 = EgtLine(nParentId, ptP1M, ptP2M, iFrame) + Arrows(nParentId, ptP1M, ptP2M, dLenArr, iFrame, cColor) + + local ptText = 0.5 * ( ptP1 + ptP2) + ( dDistance + dDistText) * Vv + local TextId = EgtTextAdv(nParentId, ptText, AngText , sText,"", 400,"S", dTextSize, 1, 0, PointType,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end +end + +-- Quota radiale (bSide: false sx, true dx) +function CreateRadialDimension( nParentId, ptC, ptP1, sText, dTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor) + + if not iFrame then + iFrame = GDB_RT.LOC + end + + -- Se punti coincidenti, esco + if AreSamePointApprox(ptC,ptP1) then + return false + end + + -- Se quotatura orizzontale, uso questa + if abs( ptC:getY() - ptP1:getY()) < GEO.EPS_SMALL then + -- adatto il lato + if ptP1:getX() > ptC:getX() then + bSide = not bSide + end + CreateLinearDimensionOnX( nParentId, ptC, ptP1, sText, dTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor, true) + return true + end + + local Vv = ptP1 - ptC + Vv:normalize() + + local AngText = atan2( Vv:getY(), Vv:getX()) + local bAngModif = false + if AngText > 90 then + AngText = AngText - 180 + bAngModif = true + elseif AngText < - 90 then + AngText = AngText + 180 + bAngModif = true + end + + local ptText + if bSide == nil then + AngText = 0 + Vv = - Vv + ptText = ptC + ( dDistText + 0.5 * dTextSize) * Vv + PointType = GDB_TI.MC + elseif bSide then + Vv:rotate( Z_AX(), -90) + ptText = 0.5 * ( ptC + ptP1) + ( dDistText) * Vv + PointType = EgtIf( bAngModif, GDB_TI.BC, GDB_TI.TC) + + else + Vv:rotate( Z_AX(), 90) + ptText = 0.5 * ( ptC + ptP1) + ( dDistText) * Vv + PointType = EgtIf( bAngModif, GDB_TI.TC, GDB_TI.BC) + end + + local iLine3 = EgtLine( nParentId, ptC, ptP1, iFrame) + Arrows( nParentId, ptC, ptP1, dLenArr, iFrame, cColor, true) + + local TextId = EgtTextAdv( nParentId, ptText, AngText , sText,"", 400,"S", dTextSize, 1, 0, PointType, iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end +end + +-- Quota angolare (bSide: false = text external, true dx = text internal) +function CreateAngleDimension( nParentId, ptC, dDir, sText, dTextSize, dAngVal, dAmpArc, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor) + + if not iFrame then + iFrame = GDB_RT.LOC + end + + -- Se distanza quota nulla, esco + if abs(dAmpArc) < GEO.EPS_SMALL or abs(dAngVal) < GEO.EPS_SMALL then + return false + end + + -- disegno linee da quotare + local iLine1 = EgtLinePDL(nParentId, ptC, dDir, dAmpArc, iFrame) + local iLine2 = EgtLinePDL(nParentId, ptC, dDir+dAngVal, dAmpArc, iFrame) + -- prendo i punti finali delle due linee + local ptP1 = EgtEP(iLine1) + local ptP2 = EgtEP(iLine2) + -- allungo di nuovo le linee della distanza extra + EgtTrimExtendCurveByLen( iLine1, dDistance,ptP1) + EgtTrimExtendCurveByLen( iLine2, dDistance,ptP2) + -- arco + local iArc1 = EgtArcCPA( nParentId, ptC, ptP1, dAngVal, 0, iFrame) + local pPt3 = EgtMP(iArc1) + + -- frecce + local iLine3 + local ptP4 + local nNeg = -1 + if dAngVal > 0 then + nNeg = 1 + end + -- faccio linee che parte da punto di freccia perpendicolare a linea di quota + iLine3 = EgtLinePDL(nParentId, ptP1, dDir+(90*nNeg), dAmpArc, iFrame) + ptP4 = EgtEP(iLine3) + EgtErase(iLine3) + -- prima freccia sulla prima linea + Arrows( nParentId, ptP4, ptP1, dLenArr, iFrame, cColor, true) + + iLine3 = EgtLinePDL(nParentId, ptP2, dDir+dAngVal-(90*nNeg), dAmpArc, iFrame) + ptP4 = EgtEP(iLine3) + EgtErase(iLine3) + -- seconda freccia sulla seconda linea + Arrows( nParentId, ptP4, ptP2, dLenArr, iFrame, cColor, true) + + local Vv = ptP1 - ptC + Vv:normalize() + + local AngText = 0 + local bAngModif = false + + local ptText + if bSide == nil then + ptText = pPt3 + ( dDistText + 0.5 * dTextSize) * Vv + PointType = GDB_TI.MC + elseif bSide then + ptText = pPt3 + ( dDistText + 0.5 * dTextSize) * Vv + PointType = GDB_TI.MC + else + ptText = pPt3 - ( dDistText + 0.5 * dTextSize) * Vv + PointType = GDB_TI.MC + end + + local TextId = EgtTextAdv( nParentId, ptText, AngText , sText,"", 400,"S", dTextSize, 1, 0, PointType, iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + EgtSetColor( iArc1, cColor) + EgtSetColor( TextId, cColor) + end +end + +return EgtDimension diff --git a/ProgramData/EgtBeamWall/LuaLibs/EgtFrame3d.lua b/ProgramData/EgtBeamWall/LuaLibs/EgtFrame3d.lua new file mode 100644 index 0000000..2c7c98d --- /dev/null +++ b/ProgramData/EgtBeamWall/LuaLibs/EgtFrame3d.lua @@ -0,0 +1,263 @@ +-- EgtFrame3d.lua by EgalTech s.r.l. 2020/09/29 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtFrame3d = {} + +EgtOutLog( 'EgtFrame3d started', 1) + +-- Include +require( 'EgtPoint3d') +--EnableDebug( false) + + +-- Definizione classe Frame3d +Frame3d = {{},{},{},{}} +Frame3d.__index = Frame3d + +-- funzione di utilita' per identificazione tipo +function isFrame3d( a) + return ( getmetatable( a) == Frame3d) +end + +local function New( a, b, c, d) + local f3d = setmetatable( {{0,0,0},{1,0,0},{0,1,0},{0,0,1}}, Frame3d) + local function SetVersors( type) + if type == GDB_FR.FRONT then + f3d[2] = X_AX() ; f3d[3] = Z_AX() ; f3d[4] = -Y_AX() + elseif type == GDB_FR.RIGHT then + f3d[2] = Y_AX() ; f3d[3] = Z_AX() ; f3d[4] = X_AX() + elseif type == GDB_FR.BACK then + f3d[2] = -X_AX() ; f3d[3] = Z_AX() ; f3d[4] = Y_AX() + elseif type == GDB_FR.LEFT then + f3d[2] = -Y_AX() ; f3d[3] = Z_AX() ; f3d[4] = -X_AX() + elseif type == GDB_FR.BOTTOM then + f3d[2] = X_AX() ; f3d[3] = -Y_AX() ; f3d[4] = -Z_AX() + else -- GDB_FR.TOP + f3d[2] = X_AX() ; f3d[3] = Y_AX() ; f3d[4] = Z_AX() + end + end + if not a then + f3d[1] = Point3d( 0, 0, 0) + SetVersors( GDB_FR.TOP) + elseif isFrame3d( a) then + f3d[1] = a[1] + f3d[2] = a[2] + f3d[3] = a[3] + f3d[4] = a[4] + elseif type(a) == 'table' and #a >= 4 and + type(a[1]) == 'table' and #a[1] >= 3 and + type(a[2]) == 'table' and #a[2] >= 3 and + type(a[3]) == 'table' and #a[3] >= 3 and + type(a[4]) == 'table' and #a[4] >= 3 then + f3d[1] = Point3d( a[1]) + f3d[2] = Vector3d( a[2]) + f3d[3] = Vector3d( a[3]) + f3d[4] = Vector3d( a[4]) + f3d[2]:normalize() + f3d[3]:normalize() + f3d[4]:normalize() + if not Frame3d.isValid( f3d) then + error( 'Error in FrameIsValid', 2) + end + elseif isPoint3d( a) and isVector3d( b) and isVector3d( c) and isVector3d( d) then + f3d[1] = a + f3d[2] = b + f3d[3] = c + f3d[4] = d + f3d[2]:normalize() + f3d[3]:normalize() + f3d[4]:normalize() + if not Frame3d.isValid( f3d) then + error( 'Error in FrameIsValid', 2) + end + elseif isPoint3d( a) and isVector3d( b) then + local bOk, Ocs = EgtFrameOCS( a, b) + if bOk then + f3d[1] = Point3d( Ocs[1]) + f3d[2] = Vector3d( Ocs[2]) + f3d[3] = Vector3d( Ocs[3]) + f3d[4] = Vector3d( Ocs[4]) + else + error( 'Error in EgtFrameOCS', 2) + end + elseif isPoint3d( a) and isPoint3d( b) and isPoint3d( c) then + local bOk, f3P = EgtFrameFrom3Points( a, b, c) + if bOk then + f3d[1] = Point3d( f3P[1]) + f3d[2] = Vector3d( f3P[2]) + f3d[3] = Vector3d( f3P[3]) + f3d[4] = Vector3d( f3P[4]) + else + error( 'Error in EgtFrameFrom3Points', 2) + end + elseif isPoint3d( a) then + f3d[1] = a + SetVersors( b) + elseif type(a) == 'number' and type( b) == 'number' and type( c) == 'number' then + f3d[1] = Point3d( a, b, c) + SetVersors( d) + else + error( 'A parameter is wrong', 2) + end + return f3d +end + +setmetatable( Frame3d, { __call = function( _, ...) return New( ...) end }) + +-- verifica validità +function Frame3d:isValid() + -- verifico che i versori siano normalizzati + if not self[2]:isNormalized() or + not self[3]:isNormalized() or + not self[4]:isNormalized() then + return false + end + -- verifico che i versori siano mutuamente ortogonali + if math.abs( self[2][1] * self[3][1] + self[2][2] * self[3][2] + self[2][3] * self[3][3]) > GEO.EPS_ZERO or + math.abs( self[3][1] * self[4][1] + self[3][2] * self[4][2] + self[3][3] * self[4][3]) > GEO.EPS_ZERO or + math.abs( self[4][1] * self[2][1] + self[4][2] * self[2][2] + self[4][3] * self[2][3]) > GEO.EPS_ZERO then + return false + end + -- verifico il senso destrorso della terna + if Vector3d.TripleProd( self[2], self[3], self[4]) < GEO.EPS_ZERO then + return false + end + -- tutto bene + return true +end + +-- traslazione +function Frame3d:move( m) + if not isFrame3d( self) then + return false + end + if isVector3d( m) then + self[1] = self[1] + m + return true + elseif type( m) == 'table' and #m >= 3 then + self[1] = self[1] + Vector3d( m) + return true + else + return false + end +end + +-- rotazione +function Frame3d:rotate( ptAx, vtAx, dAngDeg) + if not isFrame3d( self) or not isPoint3d( ptAx) or not isVector3d( vtAx) or type( dAngDeg) ~= 'number' then + return false + end + local bOk, fRot = EgtFrameRotate( self, ptAx, vtAx, dAngDeg) + if bOk then + self[1] = Point3d( fRot[1]) + self[2] = Vector3d( fRot[2]) + self[3] = Vector3d( fRot[3]) + self[4] = Vector3d( fRot[4]) + end + return bOk +end + +-- inversione (trasformazione inversa) +function Frame3d:invert() + if not isFrame3d( self) then + return false + end + local bOk, frInv = EgtFrameToLoc( Frame3d(), self) + if bOk then + self[1] = Point3d( frInv[1]) + self[2] = Vector3d( frInv[2]) + self[3] = Vector3d( frInv[3]) + self[4] = Vector3d( frInv[4]) + end + return bOk +end + +-- trasformazione di riferimento verso globale +function Frame3d:toGlob( fTool) + if not isFrame3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, fNew = EgtFrameToGlob( self, fTool) + if bOk then + self[1] = Point3d( fNew[1]) + self[2] = Vector3d( fNew[2]) + self[3] = Vector3d( fNew[3]) + self[4] = Vector3d( fNew[4]) + end + return bOk +end + +-- trasformazione di riferimento verso locale +function Frame3d:toLoc( fTool) + if not isFrame3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, fNew = EgtFrameToLoc( self, fTool) + if bOk then + self[1] = Point3d( fNew[1]) + self[2] = Vector3d( fNew[2]) + self[3] = Vector3d( fNew[3]) + self[4] = Vector3d( fNew[4]) + end + return bOk +end + +-- trasformazione di riferimento da locale a locale +function Frame3d:locToLoc( fOri, fDest) + if not isFrame3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then + return false + end + local bOk, fNew = EgtFrameLocToLoc( self, fOri, fDest) + if bOk then + self[1] = Point3d( fNew[1]) + self[2] = Vector3d( fNew[2]) + self[3] = Vector3d( fNew[3]) + self[4] = Vector3d( fNew[4]) + end + return bOk +end + +-- restituzione componenti +function Frame3d:getOrigin() + return self[1] +end + +function Frame3d:getVersX() + return self[2] +end + +function Frame3d:getVersY() + return self[3] +end + +function Frame3d:getVersZ() + return self[4] +end + +-- conversione in stringa (tostring) +function Frame3d:__tostring() + return '('.. tostring(self[1])..','..tostring(self[2])..','..tostring(self[3])..','..tostring(self[4]) ..')' +end + +-- Angoli di rotazione di Eulero da Frame +function GetRotCAC1FromFrame( frRef) + if not isFrame3d( frRef) then + return nil + end + return EgtFrameGetRotCAC1( frRef) +end + +-- Angoli di rotazione attorno ad assi XYZ fissi da Frame +function GetFixedAxesRotABCFromFrame( frRef) + if not isFrame3d( frRef) then + return nil + end + return EgtFrameGetFixedAxesRotABC( frRef) +end + +-- Riferimenti notevoli +function GLOB_FRM() + return Frame3d() +end + +return EgtFrame3d diff --git a/ProgramData/EgtBeamWall/LuaLibs/EgtLinearDimension.lua b/ProgramData/EgtBeamWall/LuaLibs/EgtLinearDimension.lua new file mode 100644 index 0000000..4d75062 --- /dev/null +++ b/ProgramData/EgtBeamWall/LuaLibs/EgtLinearDimension.lua @@ -0,0 +1,15 @@ +-- EgtLinearDimension.lua by EgalTech s.r.l. 2018/12/22 +-- Creazione di una quota +-- 2018/12/22 DS Rinominato in EgtDimension, tenuto per compatibilità. + + + +-- Tavola per definizione modulo (serve ma non usata) +local EgtLinearDimension = {} + +require( 'EgtDimension') + +CreateLinearDimensionRadial = CreateRadialDimension +CreateAngleDimensionRadial = CreateAngleDimension + +return EgtLinearDimension diff --git a/ProgramData/EgtBeamWall/LuaLibs/EgtPoint3d.lua b/ProgramData/EgtBeamWall/LuaLibs/EgtPoint3d.lua new file mode 100644 index 0000000..254f7d7 --- /dev/null +++ b/ProgramData/EgtBeamWall/LuaLibs/EgtPoint3d.lua @@ -0,0 +1,279 @@ +-- EgtPoint3d.lua by EgalTech s.r.l. 2019/03/31 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtPoint3d = {} + +EgtOutLog( 'EgtPoint3d started', 1) + +-- Include +require( 'EgtVector3d') +--EnableDebug( false) + + +-- Definizione classe Point3d +Point3d = {} +Point3d.__index = Point3d + +-- funzione di utilita' per identificazione tipo +function isPoint3d( a) + return ( getmetatable( a) == Point3d) +end + +local function New( x, y, z) + local p3d = setmetatable( {0,0,0}, Point3d) + if not x then + return nil + elseif isPoint3d( x) then + p3d[1] = x[1] + p3d[2] = x[2] + p3d[3] = x[3] + elseif type(x) == 'table' and #x >= 3 then + p3d[1] = x[1] + p3d[2] = x[2] + p3d[3] = x[3] + elseif type( x) == 'number' and type( y) == 'number' and type( z) == 'number' then + p3d[1] = x + p3d[2] = y + p3d[3] = z + else + error( 'A parameter is wrong', 2) + end + return p3d +end + +setmetatable( Point3d, { __call = function( _, ...) return New(...) end }) + +-- opposto di un punto (unary -) +function Point3d:__unm() + return New( - self[1], - self[2], - self[3]) +end + +-- somma di due punti o un punto e un vettore (+) +function Point3d.__add( a, b) + if ( isPoint3d( a) and ( isPoint3d( b) or isVector3d( b))) or + ( isPoint3d( b) and ( isPoint3d( a) or isVector3d( a))) then + return New( a[1] + b[1], a[2] + b[2], a[3] + b[3]) + else + error( 'A parameter is wrong', 2) + end +end + +-- sottrazione di due punti o un punto e un vettore, restituisce un vettore o un punto (-) +function Point3d.__sub( a, b) + if isPoint3d( a) and isPoint3d( b) then + return Vector3d( a[1] - b[1], a[2] - b[2], a[3] - b[3]) + elseif ( isPoint3d( a) and isVector3d( b)) or ( isVector3d( a) and isPoint3d( b)) then + return New( a[1] - b[1], a[2] - b[2], a[3] - b[3]) + else + error( 'A parameter is wrong', 2) + end +end + +-- moltiplicazione di un punto per un numero, di un numero per un punto (*) +function Point3d.__mul( a, b) + if type( a) == 'number' and isPoint3d( b) then + return New( a * b[1], a * b[2], a * b[3]) + elseif isPoint3d( a) and type( b) == 'number' then + return New( a[1] * b, a[2] * b, a[3] * b) + else + error( 'A parameter is wrong', 2) + end +end + +-- divisione di un punto per un numero (/) +function Point3d.__div( a, b) + if isPoint3d( a) and type( b) == 'number' then + return New( a[1] / b, a[2] / b, a[3] / b) + else + error( 'A parameter is wrong', 2) + end +end + +-- traslazione +function Point3d:move( m) + if not isPoint3d( self) then + return false + end + if isVector3d( m) or ( type( m) == 'table' and #m >= 3) then + self[1] = self[1] + m[1] + self[2] = self[2] + m[2] + self[3] = self[3] + m[3] + return true + else + return false + end +end + +-- rotazione +function Point3d:rotate( ptAx, vtAx, dAngDeg) + if not isPoint3d( self) or not isPoint3d( ptAx) or not isVector3d( vtAx) or not type( dAngDeg) == 'number' then + return false + end + local bOk, pRot = EgtPointRotate( self, ptAx, vtAx, dAngDeg) + if bOk then + self[1] = pRot[1] + self[2] = pRot[2] + self[3] = pRot[3] + end + return bOk +end + +-- mirror +function Point3d:mirror( ptOn, vtN) + if not isPoint3d( self) or not isPoint3d( ptOn) or not isVector3d( vtN) then + return false + end + local bOk, pMir = EgtPointMirror( self, ptOn, vtN) + if bOk then + self[1] = pMir[1] + self[2] = pMir[2] + self[3] = pMir[3] + end + return bOk +end + +-- trasformazione di riferimento verso globale +function Point3d:toGlob( fTool) + if not isPoint3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, pNew = EgtPointToGlob( self, fTool) + if bOk then + self[1] = pNew[1] + self[2] = pNew[2] + self[3] = pNew[3] + end + return bOk +end + +-- trasformazione di riferimento verso locale +function Point3d:toLoc( fTool) + if not isPoint3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, pNew = EgtPointToLoc( self, fTool) + if bOk then + self[1] = pNew[1] + self[2] = pNew[2] + self[3] = pNew[3] + end + return bOk +end + +-- trasformazione di riferimento da locale a locale +function Point3d:locToLoc( fOri, fDest) + if not isPoint3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then + return false + end + local bOk, pNew = EgtPointLocToLoc( self, fOri, fDest) + if bOk then + self[1] = pNew[1] + self[2] = pNew[2] + self[3] = pNew[3] + end + return bOk +end + +-- restituzione componenti +function Point3d:getX() + return self[1] +end + +function Point3d:getY() + return self[2] +end + +function Point3d:getZ() + return self[3] +end + +-- conversione in stringa (tostring) +function Point3d:__tostring() + return "(" .. EgtNumToString( self[1], 4) .. ", " + .. EgtNumToString( self[2], 4) .. ", " + .. EgtNumToString( self[3], 4) .. ")" +end + + +-- calcolo quadrato della distanza tra due punti +function sqdist( a, b) + if isPoint3d( a) and isPoint3d( b) then + return ( ( a[1] - b[1]) * ( a[1] - b[1]) + + ( a[2] - b[2]) * ( a[2] - b[2]) + + ( a[3] - b[3]) * ( a[3] - b[3])) + else + error( 'A parameter is not a Point3d', 2) + end +end + +-- calcolo distanza tra due punti +function dist( a, b) + if isPoint3d( a) and isPoint3d( b) then + return math.sqrt( ( a[1] - b[1]) * ( a[1] - b[1]) + + ( a[2] - b[2]) * ( a[2] - b[2]) + + ( a[3] - b[3]) * ( a[3] - b[3])) + else + error( 'A parameter is not a Point3d', 2) + end +end + +-- funzioni di confronto +function AreSamePointApprox( a, b) + if isPoint3d( a) and isPoint3d( b) then + return ( a - b):isSmall() + else + return false + end +end + +function AreSamePointExact( a, b) + if isPoint3d( a) and isPoint3d( b) then + return ( a - b):isZero() + else + return false + end +end + +function AreSamePointEpsilon( a, b, eps) + if isPoint3d( a) and isPoint3d( b) then + return sqdist( a, b) < eps * eps + else + return false + end +end + +-- Creazione di punti da stringhe di tre numeri +function PointFromString( sVal) + if not sVal then + return nil + end + local vsVal = EgtSplitString( sVal) + if not vsVal then + return nil + end + if #vsVal < 3 then + return nil + end + return Point3d( tonumber( vsVal[1]), tonumber( vsVal[2]), tonumber( vsVal[3])) +end + +-- Creazione di punti da info di entità GeomDB +function PointFromInfo( nId, sKey) + PointFromString( EgtGetInfo( nId, sKey)) +end + +-- Punti notevoli +function ORIG() + return Point3d(0,0,0) +end + +-- Punto con num aggiunto +function Point4d( P1, P2, P3, P4) + if isPoint3d( P1) and ( not P2 or type( P2) == 'number') then + return { P1[1], P1[2], P1[3], P2 or 0} + elseif type( P1) == 'number' and type( P2) == 'number' and type( P3) == 'number' and ( not P4 or type( P4) == 'number') then + return { P1, P2, P3, P4 or 0} + end +end + +return EgtPoint3d diff --git a/ProgramData/EgtBeamWall/LuaLibs/EgtVector3d.lua b/ProgramData/EgtBeamWall/LuaLibs/EgtVector3d.lua new file mode 100644 index 0000000..5d9f4d7 --- /dev/null +++ b/ProgramData/EgtBeamWall/LuaLibs/EgtVector3d.lua @@ -0,0 +1,424 @@ +-- EgtVector3d.lua by EgalTech s.r.l. 2022/01/11 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtVector3d = {} + +EgtOutLog( 'EgtVector3d started', 1) + +-- Include +require( 'EgtConst') +--EnableDebug( false) + + +-- Definizione classe Vector3d +Vector3d = {} +Vector3d.__index = Vector3d + +-- funzione di utilita' per identificazione tipo +function isVector3d( a) + return ( getmetatable( a) == Vector3d) +end + +local function New( x, y, z) + local v3d = setmetatable( {0,0,0}, Vector3d) + if not x then + return nil + elseif isVector3d( x) then + v3d[1] = x[1] + v3d[2] = x[2] + v3d[3] = x[3] + elseif type(x) == 'table' and #x >= 3 then + v3d[1] = x[1] + v3d[2] = x[2] + v3d[3] = x[3] + elseif type( x) == 'number' and type( y) == 'number' and type( z) == 'number' then + v3d[1] = x + v3d[2] = y + v3d[3] = z + else + error( 'A parameter is wrong', 2) + end + return v3d +end + +setmetatable( Vector3d, { __call = function( _, ...) return New(...) end }) + +-- opposto di un vettore (unary -) +function Vector3d:__unm() + return New( - self[1], - self[2], - self[3]) +end + +-- somma di due vettori (+) +function Vector3d.__add( a, b) + if isVector3d( a) and isVector3d( b) then + return New( a[1] + b[1], a[2] + b[2], a[3] + b[3]) + else + error( 'A parameter is not a Vector3d', 2) + end +end + +-- sottrazione di due vettori (-) +function Vector3d.__sub( a, b) + if isVector3d( a) and isVector3d( b) then + return New( a[1] - b[1], a[2] - b[2], a[3] - b[3]) + else + error( 'A parameter is not a Vector3d', 2) + end +end + +-- moltiplicazione di un vettore per uno scalare, di uno scalare per un vettore o prodotto scalare (*) +function Vector3d.__mul( a, b) + if type( a) == 'number' then + return New( a * b[1], a * b[2], a * b[3]) + elseif type( b) == 'number' then + return New( a[1] * b, a[2] * b, a[3] * b) + elseif isVector3d( a) and isVector3d( b) then + return ( a[1] * b[1] + a[2] * b[2] + a[3] * b[3]) + else + error( 'A parameter is wrong', 2) + end +end + +-- prodotto vettoriale (^) +function Vector3d.__pow( a, b) + if isVector3d( a) and isVector3d( b) then + return New( a[2] * b[3] - a[3] * b[2], + a[3] * b[1] - a[1] * b[3], + a[1] * b[2] - a[2] * b[1]) + else + error( 'A parameter is not a Vector3d', 2) + end +end + +-- divisione di un vettore per un numero (/) +function Vector3d.__div( a, b) + if isVector3d( a) and type( b) == 'number' then + return New( a[1] / b, a[2] / b, a[3] / b) + else + error( 'A parameter is wrong', 2) + end +end + +-- triplo prodotto (a ^ b) * c +function Vector3d.TripleProd( a, b, c) + if isVector3d( a) and isVector3d( b) and isVector3d( c) then + return ( a[1] * ( b[2] * c[3] - b[3] * c[2]) + + a[2] * ( b[3] * c[1] - b[1] * c[3]) + + a[3] * ( b[1] * c[2] - b[2] * c[1])) + else + error( 'A parameter is wrong', 2) + end +end + +-- verifica di vettore quasi nullo +function Vector3d:isSmall() + return (( self[1] * self[1] + self[2] * self[2] + self[3] * self[3]) < GEO.EPS_SMALL * GEO.EPS_SMALL) +end + +-- verifica di vettore nullo +function Vector3d:isZero() + return (( self[1] * self[1] + self[2] * self[2] + self[3] * self[3]) < GEO.EPS_ZERO * GEO.EPS_ZERO) +end + +-- verifica di vettore normalizzato +function Vector3d:isNormalized() + return ( math.abs( 1.0 - ( self[1] * self[1] + self[2] * self[2] + self[3] * self[3])) < 2.0 * GEO.EPS_ZERO) +end + +-- calcolo quadrato della lunghezza +function Vector3d:sqlen() + return ( self[1] * self[1] + self[2] * self[2] + self[3] * self[3]) +end + +-- calcolo lunghezza +function Vector3d:len() + return math.sqrt( self[1] * self[1] + self[2] * self[2] + self[3] * self[3]) +end + +-- normalizzazione +function Vector3d:normalize() + local sqlen = self[1] * self[1] + self[2] * self[2] + self[3] * self[3] + -- verifico se già normalizzato + if math.abs( 1.0 - sqlen) < 2.0 * GEO.EPS_ZERO then + return true + end + -- verifico se normalizzabile + if sqlen < GEO.EPS_SMALL * GEO.EPS_SMALL then + return false + end + -- eseguo la normalizzazione + local len = math.sqrt( sqlen) + local denom = 1 / len + self[1] = self[1] * denom + self[2] = self[2] * denom + self[3] = self[3] * denom + return true +end + +-- rotazione +function Vector3d:rotate( vtAx, dAngDeg) + if not isVector3d( self) or not isVector3d( vtAx) or not type( dAngDeg) == 'number' then + return false + end + local bOk, vRot = EgtVectorRotate( self, vtAx, dAngDeg) + if bOk then + self[1] = vRot[1] + self[2] = vRot[2] + self[3] = vRot[3] + end + return bOk +end + +-- mirror +function Vector3d:mirror( vtOn) + if not isVector3d( self) or not isVector3d( vtOn) then + return false + end + local bOk, vMir = EgtVectorMirror( self, vtOn) + if bOk then + self[1] = vMir[1] + self[2] = vMir[2] + self[3] = vMir[3] + end + return bOk +end + +-- trasformazione di riferimento verso globale +function Vector3d:toGlob( fTool) + if not isVector3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, vNew = EgtVectorToGlob( self, fTool) + if bOk then + self[1] = vNew[1] + self[2] = vNew[2] + self[3] = vNew[3] + end + return bOk +end + +-- trasformazione di riferimento verso locale +function Vector3d:toLoc( fTool) + if not isVector3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, vNew = EgtVectorToLoc( self, fTool) + if bOk then + self[1] = vNew[1] + self[2] = vNew[2] + self[3] = vNew[3] + end + return bOk +end + +-- trasformazione di riferimento da locale a locale +function Vector3d:locToLoc( fOri, fDest) + if not isVector3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then + return false + end + local bOk, vNew = EgtVectorLocToLoc( self, fOri, fDest) + if bOk then + self[1] = vNew[1] + self[2] = vNew[2] + self[3] = vNew[3] + end + return bOk +end + +-- restituzione componenti +function Vector3d:getX() + return self[1] +end + +function Vector3d:getY() + return self[2] +end + +function Vector3d:getZ() + return self[3] +end + +-- assegnazione componenti +function Vector3d:setX( dX) + self[1] = dX +end + +function Vector3d:setY( dY) + self[2] = dY +end + +function Vector3d:setZ( dZ) + self[3] = dZ +end + +-- conversione in stringa (tostring) +function Vector3d:__tostring() + return "(" .. EgtNumToString( self[1], 6) .. ", " + .. EgtNumToString( self[2], 6) .. ", " + .. EgtNumToString( self[3], 6) .. ")" +end + +-- Alcune funzioni di confronto +function AreSameVectorApprox( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a - b):isSmall() + else + return false + end +end + +function AreSameVectorExact( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a - b):isZero() + else + return false + end +end + +function AreOppositeVectorApprox( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a + b):isSmall() + else + return false + end +end + +function AreOppositeVectorExact( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a + b):isZero() + else + return false + end +end + +function AreSameOrOppositeVectorApprox( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a - b):isSmall() or ( a + b):isSmall() + else + return false + end +end + +function AreSameOrOppositeVectorExact( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a - b):isZero() or ( a + b):isZero() + else + return false + end +end + +-- Creazione di vettori da coordinate sferiche e polari +function VectorFromSpherical( dLen, dAngVertDeg, dAngOrizzDeg) + local dAngVertRad = math.rad( dAngVertDeg) + local dAngOrizzRad = math.rad( dAngOrizzDeg) + local dSinAngVert = math.sin( dAngVertRad) ; + return Vector3d( dLen * dSinAngVert * math.cos( dAngOrizzRad), + dLen * dSinAngVert * math.sin( dAngOrizzRad), + dLen * math.cos( dAngVertRad)) ; +end + +function VectorFromPolar( dLen, dAngDeg) + local dAngRad = math.rad( dAngDeg) + return Vector3d( dLen * math.cos( dAngRad), + dLen * math.sin( dAngRad), + 0) +end + +-- Creazione di vettore perpendicolare a dato e massimamente verso l'alto +function VectorFromUprightOrtho( vtV) + local vtAx = Vector3d( vtV) + if not vtAx then return nil end + -- se vettore nullo, imposto asse Z+ + if vtAx:isZero() then + return Z_AX() + end + -- se vettore coincidente con asse Z, imposto asse X+ + if AreSameOrOppositeVectorExact( vtAx, Z_AX()) then + return X_AX() + end + -- caso generico + vtAx:setZ( 0) + vtAx:normalize() + vtAx:rotate( Z_AX(), 90) + return ( vtV ^ vtAx) +end + +-- Creazione di vettore da altro vettore con rotazione +function VectorFromRotated( vtV, vtAx, dAngDeg) + local vtRot = Vector3d( vtV) + if not vtRot then return nil end + vtRot:rotate( vtAx, dAngDeg) + return vtRot +end + +-- Creazione di vettore da stringa di tre numeri +function VectorFromString( sVal) + if not sVal then + return nil + end + local vsVal = EgtSplitString( sVal) + if not vsVal then + return nil + end + if #vsVal < 3 then + return nil + end + return Vector3d( tonumber( vsVal[1]), tonumber( vsVal[2]), tonumber( vsVal[3])) +end + +-- Creazione di vettore da info di entità GeomDB +function VectorFromInfo( nId, sKey) + return VectorFromString( EgtGetInfo( nId, sKey)) +end + +-- Coordinate sferiche da vettore +function SphericalFromVector( vtV) + if not isVector3d( vtV) then + return nil + end + local dLen = vtV:len() + -- vettore nullo + if math.abs( dLen) < GEO.EPS_ZERO then + return 0, 0, 0 + end + -- vettore diretto come Z o -Z + if math.abs( vtV[1]) < GEO.EPS_ZERO and math.abs( vtV[2]) < GEO.EPS_ZERO then + if vtV[3] > 0 then + return dLen, 0, 0 + else + return dLen, 180, 0 + end + end + -- vettore nel piano XY + if math.abs( vtV[3]) < GEO.EPS_ZERO then + local dAngOri = math.deg( math.atan( vtV[2], vtV[1])) + if dAngOri < 0 then + dAngOri = dAngOri + 360 + end + return dLen, 90, dAngOri + end + -- caso generale + local dAngVert = math.deg( math.acos( vtV[3] / dLen)) + local dAngOri = math.deg( math.atan( vtV[2], vtV[1])) + if dAngOri < 0 then + dAngOri = dAngOri + 360 + end + return dLen, dAngVert, dAngOri +end + +-- Vettori notevoli +function V_NULL() + return Vector3d(0,0,0) +end +function X_AX() + return Vector3d(1,0,0) +end +function Y_AX() + return Vector3d(0,1,0) +end +function Z_AX() + return Vector3d(0,0,1) +end + + +return EgtVector3d diff --git a/ProgramData/EgtBeamWall/LuaLibs/EmtGenerator.lua b/ProgramData/EgtBeamWall/LuaLibs/EmtGenerator.lua new file mode 100644 index 0000000..9f94a93 --- /dev/null +++ b/ProgramData/EgtBeamWall/LuaLibs/EmtGenerator.lua @@ -0,0 +1,987 @@ +-- EmtGenerator.lua by EgalTech s.r.l. 2021/12/28 +-- 2018/02/22 DS Funzioni bit32 sostituite con operatori sui bit. +-- 2018/08/16 DS Corretta ricorsione di SimulMoveAxis. +-- 2018/10/09 DS Controllo nDec anche in EmtLenToString. +-- 2019/03/19 DS Modificate SimulMoveAxis e SimulMoveAxes. +-- 2019/05/19 DS Aggiunta funzione SetToolForVmill. +-- 2019/08/06 DS Aggiunte funzioni AddToCollisionCheck, AddToolToCollisionCheck e DumpCollisionCheck. +-- 2020/02/04 DS Modifiche a SetToolForVmill per gestire frese con gambo piccolo. +-- 2020/02/05 DS Aggiunto parametro sCollGrp a AddToCollisionCheck e riportato nei dati successivi come Grp. +-- 2020/03/23 DS Aggiunta funzione per impostare il numero di decimali nell'emissione coordinate assi. +-- 2020/10/06 DS In AddToolToCollisionCheck ora si usano diametro e lunghezza totali, prima quelli di lavoro. +-- 2020/10/31 DS Corretta AddToCollisionCheck per riferimenti da calcolarsi in globale. +-- 2020/12/07 DS In SetToolForVmill aggiunta gestione WaterJet. +-- 2020/12/22 DS In AddToCollisionCheck per cilindri ora raggio precede altezza. +-- 2021/01/03 DS Aggiunta funzione AddToolToCollisionObj. In MoveAxis e MoveAxes aggiunta gestione delle collisioni. +-- 2021/01/19 DS In AddToolToCollisionCheck aggiunta gestione per mortasatrici/seghe a catena. +-- 2021/02/10 DS In SimulMoveAx* migliorata gestione segnalazione collisioni. +-- 2021/04/14 DS A AddToolToCollisionObj e AddToolToCollisionCheck aggiunto parametro opzionale bUseDiam. +-- 2021/05/24 DS Corretta AddToolToCollisionCheck perchè recuperava sempre l'utensile dell'uscita 1 della testa e uscita indicate. +-- Parametro bUseDiam eliminato perchè superato dalle modifiche. +-- 2021/06/25 DS In AddToolToCollisionCheck corretta gestione lame ora con lunghezza e spessore. +-- 2021/07/12 DS Migliorie a movimento asse/i per simulazione. +-- 2021/12/28 DS Anche a Centro e Punto Medio di Arco si sottrae EMT.ADDORI se definito. + +-- Tavola per definizione modulo (serve ma non usata) +local EmtGenerator = {} + +EgtOutLog( 'EmtGenerator started', 1) + +-- Include +require( 'EgtBase') + +--------------------------------------------------------------------- +-- *** Output *** +--------------------------------------------------------------------- +function EmtOutput( sOut, nId) + if EMT.NUM then + if not nId or nId == 1 then + EMT.LINENBR = EMT.LINENBR + EMT.LINEINC + if EMT.LINEMAX and EMT.LINENBR > EMT.LINEMAX then EMT.LINENBR = EMT.LINEINC end + EmtWrite( EMT.Nt .. EMT.LINENBR .. ' ' .. ( sOut or '')) + else + if not EMT.LINENBRS then EMT.LINENBRS = {} end + if not EMT.LINENBRS[nId] then EMT.LINENBRS[nId] = 0 end + EMT.LINENBRS[nId] = EMT.LINENBRS[nId] + EMT.LINEINC + if EMT.LINEMAX and EMT.LINENBRS[nId] > EMT.LINEMAX then EMT.LINENBRS[nId] = EMT.LINEINC end + OutFile( nId, EMT.Nt .. EMT.LINENBRS[nId] .. ' ' .. ( sOut or '')) + end + else + if not nId or nId == 1 then + EmtWrite( sOut or '') + else + OutFile( nId, sOut or '') + end + end +end + +----------------------------------------------------------------- +-- *** Other Files *** +----------------------------------------------------------------- + +local s_OutFh = {} + +----------------------------------------------------------------- +function OpenOutFile( nId, sFile) + s_OutFh[nId] = io.open( sFile, 'w') + return s_OutFh[nId] +end + +----------------------------------------------------------------- +function OutFile( nId, sOut) + if s_OutFh[nId] then + s_OutFh[nId]:write( sOut .. '\n') + end +end + +----------------------------------------------------------------- +function CloseOutFile( nId) + if s_OutFh[nId] then + s_OutFh[nId]:close() + s_OutFh[nId] = nil + end +end + +----------------------------------------------------------------- +-- *** Utilities *** +--------------------------------------------------------------------- +function EmtUpdatePrev() + EMT.L1p = EMT.L1 + EMT.L2p = EMT.L2 + EMT.L3p = EMT.L3 + EMT.R1p = EMT.R1 + EMT.R2p = EMT.R2 + EMT.R3p = EMT.R3 + EMT.R4p = EMT.R4 + EMT.L1op = EMT.L1o + EMT.L2op = EMT.L2o + EMT.L3op = EMT.L3o + if EMT.MOVE ~= 0 then + if EMT.F then + EMT.Fp = EMT.F + end + else + EMT.Fp = nil + end +end + +function EmtResetPrevLinear() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EMT.L1op = nil + EMT.L2op = nil + EMT.L3op = nil +end + +function EmtResetPrev() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EMT.R1p = nil + EMT.R2p = nil + EMT.R3p = nil + EMT.R4p = nil + EMT.L1op = nil + EMT.L2op = nil + EMT.L3op = nil + EMT.Fp = nil +end + +function EmtSetAdditionalOrig( dAddX, dAddY, dAddZ) + EMT.ADDORI = Point3d( dAddX, dAddY, dAddZ) +end + +function EmtAdjustLinearAxes() + -- salvo i valori rispetto a Zero macchina + EMT.L1o = EMT.L1 + EMT.L2o = EMT.L2 + EMT.L3o = EMT.L3 + -- se emetto rispetto all'origine 1 della tavola + if EMT.USETO1 then + -- sottraggo agli assi lineari l'origine 1 della tavola + if EMT.L1 then + EMT.L1 = EMT.L1 - EMT.TABORI1[1] + if EMT.ADDORI then + EMT.L1 = EMT.L1 - EMT.ADDORI[1] + end + end + if EMT.L2 then + EMT.L2 = EMT.L2 - EMT.TABORI1[2] + if EMT.ADDORI then + EMT.L2 = EMT.L2 - EMT.ADDORI[2] + end + end + if EMT.L3 then + EMT.L3 = EMT.L3 - EMT.TABORI1[3] + if EMT.ADDORI then + EMT.L3 = EMT.L3 - EMT.ADDORI[3] + end + end + end + -- se emetto rispetto a piano locale + if EMT.IPLGL then + local ptP = Point3d( EMT.L1, EMT.L2, EMT.L3) + ptP:toLoc( EMT.IPLGLFR) + EMT.L1 = ptP:getX() + EMT.L2 = ptP:getY() + EMT.L3 = ptP:getZ() + end +end + +function EmtAdjustRotaryAxes() + -- salvo i valori rispetto a Zero macchina + EMT.R1o = EMT.R1 + EMT.R2o = EMT.R2 + EMT.R3o = EMT.R3 + EMT.R4o = EMT.R4 +end + +function EmtAdjustCenterAxes() + -- salvo i valori rispetto a Zero macchina + EMT.C1o = EMT.C1 + EMT.C2o = EMT.C2 + EMT.C3o = EMT.C3 + -- se emetto rispetto all'origine 1 della tavola + if EMT.USETO1 then + -- sottraggo agli assi lineari l'origine 1 della tavola + if EMT.C1 then + EMT.C1 = EMT.C1 - EMT.TABORI1[1] + if EMT.ADDORI then + EMT.C1 = EMT.C1 - EMT.ADDORI[1] + end + end + if EMT.C2 then + EMT.C2 = EMT.C2 - EMT.TABORI1[2] + if EMT.ADDORI then + EMT.C2 = EMT.C2 - EMT.ADDORI[2] + end + end + if EMT.C3 then + EMT.C3 = EMT.C3 - EMT.TABORI1[3] + if EMT.ADDORI then + EMT.C3 = EMT.C3 - EMT.ADDORI[3] + end + end + end + -- se emetto rispetto a piano locale + if EMT.IPLGL then + local ptP = Point3d( EMT.C1, EMT.C2, EMT.C3) + ptP:toLoc( EMT.IPLGLFR) + EMT.C1 = ptP:getX() + EMT.C2 = ptP:getY() + EMT.C3 = ptP:getZ() + end +end + +function EmtAdjustMidPointAxes() + -- salvo i valori rispetto a Zero macchina + EMT.M1o = EMT.M1 + EMT.M2o = EMT.M2 + EMT.M3o = EMT.M3 + -- se emetto rispetto all'origine 1 della tavola + if EMT.USETO1 then + -- sottraggo agli assi lineari l'origine 1 della tavola + if EMT.M1 then + EMT.M1 = EMT.M1 - EMT.TABORI1[1] + if EMT.ADDORI then + EMT.M1 = EMT.M1 - EMT.ADDORI[1] + end + end + if EMT.M2 then + EMT.M2 = EMT.M2 - EMT.TABORI1[2] + if EMT.ADDORI then + EMT.M2 = EMT.M2 - EMT.ADDORI[2] + end + end + if EMT.M3 then + EMT.M3 = EMT.M3 - EMT.TABORI1[3] + if EMT.ADDORI then + EMT.M3 = EMT.M3 - EMT.ADDORI[3] + end + end + end + -- se emetto rispetto a piano locale + if EMT.IPLGL then + local ptP = Point3d( EMT.M1, EMT.M2, EMT.M3) + ptP:toLoc( EMT.IPLGLFR) + EMT.M1 = ptP:getX() + EMT.M2 = ptP:getY() + EMT.M3 = ptP:getZ() + end +end + +local function EmtToEmit( V, Vp) + if not V then + return false + end + if not EMT.MODAL or not Vp then + return true + end + return ( abs( V - Vp) > 0.001) +end + +function EmtGetAxis( Ax, bRotLikeLin) + local Axp = Ax .. 'p' + local Axt = Ax .. 't' + if EMT[Axt] and EmtToEmit( EMT[Ax], EMT[Axp]) then + local nDec = EMT.DECNUM or 3 + if not EMT.INCHES or (( Ax == 'R1' or Ax == 'R2' or Ax == 'R3' or Ax == 'R4') and not bRotLikeLin) then + return ' ' .. EMT[Axt] .. EgtNumToString( EMT[Ax], nDec), true + else + return ' ' .. EMT[Axt] .. EgtNumToString( EMT[Ax] / GEO.ONE_INCH, nDec + 1), true + end + end + return '', false +end + +function EmtGetRapidAxis( Ax, bRotLikeLin) + local MaskVal = {L1=1,L2=2,L3=4,R1=8,R2=16,R3=32,R4=64} -- per lua 5.2 {L1=0,L2=1,L3=2,R1=3,R2=4,R3=5,R4=6} + if ( EMT.MASK & MaskVal[Ax]) ~= 0 then -- per lua 5.2 bit32.extract(EMT.MASK,MaskVal[Ax]) ~= 0 + return EmtGetAxis( Ax, bRotLikeLin) + end + -- mascherato, sistemo attuale come precedente + local Axp = Ax .. 'p' + local Axt = Ax .. 't' + EMT[Ax] = EMT[Axp] + return '', false +end + +function EmtGetHomeAxis( Ax, bRotLikeLin) + local MaskVal = {L1=1,L2=2,L3=4,R1=8,R2=16,R3=32,R4=64} -- per lua 5.2 {L1=0,L2=1,L3=2,R1=3,R2=4,R3=5,R4=6} + if ( EMT.MASK & MaskVal[Ax]) ~= 0 then -- per lua 5.2 bit32.extract(EMT.MASK,MaskVal[Ax]) ~= 0 + local Axo = Ax .. 'o' + local Axt = Ax .. 't' + if EMT[Axt] then + local nDec = EMT.DECNUM or 3 + if not EMT.INCHES or (( Ax == 'R1' or Ax == 'R2' or Ax == 'R3' or Ax == 'R4') and not bRotLikeLin) then + return ' ' .. EMT[Axt] .. EgtNumToString( EMT[Axo], nDec), true + else + return ' ' .. EMT[Axt] .. EgtNumToString( EMT[Axo] / GEO.ONE_INCH, nDec + 1), true + end + end + end + return '', false +end + +function EmtGetHomeAxisByName( Ax, dOffset, bRotLikeLin) + local sToken = EgtGetAxisToken( Ax) + local bLinear = EgtGetAxisType( Ax) + local dVal = EgtGetAxisHomePos( Ax) + if dOffset then + dVal = dVal + dOffset + end + if sToken and bLinear ~= nil and dVal then + local nDec = EMT.DECNUM or 3 + if not EMT.INCHES or ( not bLinear and not bRotLikeLin) then + return ' ' .. sToken .. EgtNumToString( dVal, nDec), true + else + return ' ' .. sToken .. EgtNumToString( dVal / GEO.ONE_INCH, nDec + 1), true + end + else + return '', false + end +end + +function EmtGetFeed() + if EmtToEmit( EMT.F, EMT.Fp) then + if not EMT.INCHES then + return ' ' .. EMT.Ft .. EgtNumToString( EMT.F, 0) + else + return ' ' .. EMT.Ft .. EgtNumToString( EMT.F / GEO.ONE_INCH, 1) + end + end + return '' +end + +function EmtGetArcType( nMove, bInv) + if nMove == 2 then + if bInv then + return 3 + else + return 2 + end + elseif nMove == 3 then + if bInv then + return 2 + else + return 3 + end + else + return nil + end +end + +------------------------------------------------------------------------------- +function EmtGetAngO2( vtZ, vtX, dAngV, dAngO) + -- vettore X di riferimento + local vtRif = Vector3d( X_AX()) + -- lo ruoto prima attorno a Y poi attorno a Z + vtRif:rotate( Y_AX(), dAngV) + vtRif:rotate( Z_AX(), dAngO) + -- prodotto scalare tra vettore riferimento ruotato e vettore vtX + local dCos = vtRif * vtX + -- prodotto scalare tra vettore prodotto vettoriale dei due e vettore vtZ + local dSin = ( vtRif ^ vtX) * vtZ + -- restituisco l'angolo di rotazione richiesto + return atan2( dSin, dCos) +end + +------------------------------------------------------------------------------- +function EmtGetAngO3( vtZ, vtX, dAngV, dAngO) + -- vettore X di riferimento + local vtRif = Vector3d( X_AX()) + -- vettore asse di rotazione + local vtAx = Vector3d( - sin( dAngO), cos( dAngO), 0) + -- ruoto X di rif attorno a questo asse + vtRif:rotate( vtAx, dAngV) + -- prodotto scalare tra vettore riferimento ruotato e vettore vtX + local dCos = vtRif * vtX + -- prodotto scalare tra vettore prodotto vettoriale dei due e vettore vtZ + local dSin = ( vtRif ^ vtX) * vtZ + -- restituisco l'angolo di rotazione richiesto + return atan2( dSin, dCos) +end + +------------------------------------------------------------------------------- +function EmtLenToString( Val, nDec) + nDec = ( nDec or 3) + if not EMT.INCHES then + return EgtNumToString( Val, nDec) + else + return EgtNumToString( Val/GEO.ONE_INCH, nDec + 1) + end +end + +------------------------------------------------------------------------------- +function EmtNum3ToString( Tav, nDec) + nDec = ( nDec or 3) + return EgtNumToString( Tav[1], nDec) .. ",".. + EgtNumToString( Tav[2], nDec) .. ",".. + EgtNumToString( Tav[3], nDec) +end + +------------------------------------------------------------------------------- +function EmtLen3ToString( Tav, nDec) + nDec = ( nDec or 3) + return EmtLenToString( Tav[1], nDec) .. ",".. + EmtLenToString( Tav[2], nDec) .. ",".. + EmtLenToString( Tav[3], nDec) +end + +--------------------------------------------------------------------- +function EmtSecToHMS( dSec) + local nH = floor( dSec / 3600) + local nM = floor(( dSec - nH * 3600) / 60) + local nS = floor( dSec - nH * 3600 - nM * 60) + local sH = EgtIf( nH < 10, '0', '') .. tostring( nH) + local sM = EgtIf( nM < 10, '0', '') .. tostring( nM) + local sS = EgtIf( nS < 10, '0', '') .. tostring( nS) + return sH .. ':' .. sM .. ':' .. sS +end + +--------------------------------------------------------------------- +function EmtLenToMF( dLen) + local dOut + if EMT.INCHES then + dOut = dLen / 304.8 + else + dOut = dLen / 1000 + end + return EgtIf( dOut < 10, ' ', '') .. EgtNumToString( dOut, -1) +end + +--------------------------------------------------------------------- +-- *** Estimation functions *** +--------------------------------------------------------------------- +local s_TleTitle +local s_TleMach = {} +local s_TleTool = {} + +--------------------------------------------------------------------- +function EmtTleStart( sTitle) + -- inizializzazioni + s_TleTitle = sTitle + s_TleMach = {} + s_TleTool = {} +end + +--------------------------------------------------------------------- +function EmtTleAddMachining( sName, sTime, sLen, sTool) + table.insert( s_TleMach, { Name = sName, Time = sTime, Len = sLen, Tool = sTool}) +end + +--------------------------------------------------------------------- +function EmtTleAddTotal( sTotTime, sTotLen) + s_TleMach.Total = { Time = sTotTime, Len = sTotLen} +end + +--------------------------------------------------------------------- +function EmtTleAddTool( sName, sLen) + table.insert( s_TleTool, { Name = sName, Len = sLen}) +end + +--------------------------------------------------------------------- +function EmtTleEnd( sFormat) + -- se richiesto formato HTML + if sFormat:lower() == 'html' then + -- intestazione + EmtOutput( '') + EmtOutput( '') + EmtOutput( '') + EmtOutput( ' ') + EmtOutput( ' ' .. ( s_TleTitle or '') .. '') + EmtOutput( ' ') + EmtOutput( '') + EmtOutput( '') + -- tabella lavorazioni + if s_TleMach and #s_TleMach > 0 then + EmtOutput( ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' ') + for i = 1, #s_TleMach do + EmtOutput( ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' ') + end + EmtOutput( ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' ') + EmtOutput( '
Machinings
Time [h:m:s]Len ' .. EgtIf( EMT.INCHES, '[ft]', '[m]') .. 'Tool
' .. ( s_TleMach[i].Name or '') .. '' .. ( s_TleMach[i].Time or '') .. '' .. ( s_TleMach[i].Len or '') .. '' .. ( s_TleMach[i].Tool or '') .. '
TOTAL' .. ( s_TleMach.Total.Time or '') .. '' .. ( s_TleMach.Total.Len or '') .. '' .. '
') + end + -- tabella utensili + if s_TleTool and #s_TleTool > 0 then + EmtOutput( ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' ') + for i = 1, #s_TleTool do + EmtOutput( ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' ') + end + EmtOutput( '
Tools
Len ' .. EgtIf( EMT.INCHES, '[ft]', '[m]') .. '
' .. ( s_TleTool[i].Name or '') .. '' .. ( s_TleTool[i].Len or '') .. '
') + end + -- conclusione + EmtOutput( '') + EmtOutput( '') + -- altrimenti formato testo + else + -- intestazione + EmtOutput( ' ' .. ( s_TleTitle or '') .. '\r\n \r\n') + -- tabella lavorazioni + if s_TleMach and #s_TleMach > 0 then + EmtOutput( ' Machinings') + EmtOutput( ' ==========') + EmtOutput( ' Time [h:m:s] Len ' .. EgtIf( EMT.INCHES, '[ft]', '[m]') .. ' Tool') + for i = 1, #s_TleMach do + local sName = ( s_TleMach[i].Name or '') + sName = sName .. string.rep( ' ', 18 - #sName) + EmtOutput( sName .. ( s_TleMach[i].Time or '') .. ' ' .. ( s_TleMach[i].Len or '') .. ' ' .. ( s_TleMach[i].Tool or '')) + end + end + EmtOutput( '-------------------------------------------------------') + EmtOutput( 'TOTAL ' .. ( s_TleMach.Total.Time or '') .. ' ' .. ( s_TleMach.Total.Len or '')) + -- tabella utensili + if s_TleTool and #s_TleTool > 0 then + EmtOutput( '\r\n\r\n Tools') + EmtOutput( ' =====') + EmtOutput( ' Len ' .. EgtIf( EMT.INCHES, '[ft]', '[m]')) + for i = 1, #s_TleTool do + local sName = ( s_TleTool[i].Name or '') + sName = sName .. string.rep( ' ', 19 - #sName) + EmtOutput( sName .. ( s_TleTool[i].Len or '')) + end + end + end +end + +--------------------------------------------------------------------- +-- *** Simulation functions *** +--------------------------------------------------------------------- +local function MyPrepareAxis( sName, dPos, dStep, nS) + if not sName then return nil, nS end + local dPrev = EgtGetAxisPos( sName) + if not dPrev then return nil, nS end + if abs( dStep) > GEO.EPS_SMALL then + local nSa = abs( ceil( ( dPos - dPrev) / dStep)) + nS = max( nS, nSa) + end + return dPrev, nS +end + +--------------------------------------------------------------------- +local function MySetAxisPos( sName, dPos) + local bOk, dNewPos = EgtSetAxisPos( sName, dPos) + return ( bOk and abs( dNewPos - dPos) < 10 * GEO.EPS_SMALL) +end + +--------------------------------------------------------------------- +function SimulMoveAxis( sName, dPos, dStep) + -- salvo step attuale + EMT.SIMSTEP = EMT.SIMSTEP or 20 + local dSimStep = EMT.SIMSTEP + -- preparazione asse + local dPrev, nS = MyPrepareAxis( sName, dPos, dStep, 1) + -- l'asse deve essere ben definito + if not dPrev then return false end + -- movimento + if nS > 0 then + for i = 1, nS do + local dCoeff = i / nS + local bOk = MySetAxisPos( sName, ( 1 - dCoeff) * dPrev + dCoeff * dPos) + EgtDraw() + local bCheckOk, nCdInd, nObjInd = EmtExecCollisionCheck() + if not bCheckOk then + local nPrevErr = EMT.ERR + local bCollOk, nErr = EmtOnCollision( nCdInd, nObjInd) + if not bCollOk and nErr == 11 then + if EgtGetEnableUI() then + EgtOutBox( 'Collisione!', 'AVVERTIMENTO', 'WARNING') + EMT.SIMUISTAT = MCH_UISIM.PAUSE + while EMT.SIMUISTAT == MCH_UISIM.PAUSE do + -- Param1 = -11 notifica al simulatore pausa per collisione + EgtProcessEvents( -11, 4) + end + end + else + EMT.ERR = nPrevErr + end + end + if not bOk then + return false + end + if EgtGetEnableUI() then + EgtProcessEvents( 0, 4) + while EMT.SIMUISTAT == MCH_UISIM.PAUSE do + EgtProcessEvents( 0, 4) + end + if EMT.SIMUISTAT == MCH_UISIM.STOP then + error( 'STOP') + end + -- se cambia lo step di simulazione richiesto in modo significativo ... + if abs( EMT.SIMSTEP - dSimStep) > 5 then + local dC = EMT.SIMSTEP / dSimStep + return SimulMoveAxis( sName, dPos, dC * dStep) + end + end + end + end + -- assegno valore finale esatto + return MySetAxisPos( sName, dPos) +end + +--------------------------------------------------------------------- +function SimulMoveAxes( sName, dPos, dStep, sName2, dPos2, dStep2, sName3, dPos3, dStep3, sName4, dPos4, dStep4, sName5, dPos5, dStep5) + -- salvo step attuale + EMT.SIMSTEP = EMT.SIMSTEP or 20 + local dSimStep = EMT.SIMSTEP + -- preparazione dei diversi assi + local dPrev, dPrev2, dPrev3, dPrev4, dPrev5 + local nS = 1 + dPrev, nS = MyPrepareAxis( sName, dPos, dStep, nS) + dPrev2, nS = MyPrepareAxis( sName2, dPos2, dStep2, nS) + dPrev3, nS = MyPrepareAxis( sName3, dPos3, dStep3, nS) + dPrev4, nS = MyPrepareAxis( sName4, dPos4, dStep4, nS) + dPrev5, nS = MyPrepareAxis( sName5, dPos5, dStep5, nS) + -- il primo asse deve essere ben definito + if not dPrev then return false end + -- movimento + if nS > 0 then + for i = 1, nS do + local dCoeff = i / nS + local bOk = MySetAxisPos( sName, ( 1 - dCoeff) * dPrev + dCoeff * dPos) + local bOk2 = not dPrev2 or MySetAxisPos( sName2, ( 1 - dCoeff) * dPrev2 + dCoeff * dPos2) + local bOk3 = not dPrev3 or MySetAxisPos( sName3, ( 1 - dCoeff) * dPrev3 + dCoeff * dPos3) + local bOk4 = not dPrev4 or MySetAxisPos( sName4, ( 1 - dCoeff) * dPrev4 + dCoeff * dPos4) + local bOk5 = not dPrev5 or MySetAxisPos( sName5, ( 1 - dCoeff) * dPrev5 + dCoeff * dPos5) + EgtDraw() + local bCheckOk, nCdInd, nObjInd = EmtExecCollisionCheck() + if not bCheckOk then + local nPrevErr = EMT.ERR + local bCollOk, nErr = EmtOnCollision( nCdInd, nObjInd) + if not bCollOk and nErr == 11 then + EMT.ERR = 11 + if EgtGetEnableUI() then + EgtOutBox( 'Collisione!', 'AVVERTIMENTO', 'WARNING') + EMT.SIMUISTAT = MCH_UISIM.PAUSE + while EMT.SIMUISTAT == MCH_UISIM.PAUSE do + -- Param1 = -11 notifica al simulatore pausa per collisione + EgtProcessEvents( -11, 4) + end + end + else + EMT.ERR = nPrevErr + end + end + if not ( bOk and bOk2 and bOk3 and bOk4 and bOk5) then + return false, bOk, bOk2, bOk3, bOk4, bOk5 + end + if EgtGetEnableUI() then + EgtProcessEvents( 0, 4) + while EMT.SIMUISTAT == MCH_UISIM.PAUSE do + EgtProcessEvents( 0, 4) + end + if EMT.SIMUISTAT == MCH_UISIM.STOP then + error( 'STOP') + end + -- se cambia lo step di simulazione richiesto in modo significativo ... + if abs( EMT.SIMSTEP - dSimStep) > 5 then + local dC = EMT.SIMSTEP / dSimStep + return SimulMoveAxes( sName, dPos, dC * dStep, + sName2, dPos2, dC * ( dStep2 or 0), sName3, dPos3, dC * ( dStep3 or 0), + sName4, dPos4, dC * ( dStep4 or 0), sName5, dPos5, dC * ( dStep5 or 0)) + end + end + end + end + -- assegno valore finale esatto + local bOk = MySetAxisPos( sName, dPos) + local bOk2 = not dPrev2 or MySetAxisPos( sName2, dPos2) + local bOk3 = not dPrev3 or MySetAxisPos( sName3, dPos3) + local bOk4 = not dPrev4 or MySetAxisPos( sName4, dPos4) + local bOk5 = not dPrev5 or MySetAxisPos( sName5, dPos5) + return ( bOk and bOk2 and bOk3 and bOk4 and bOk5), bOk, bOk2, bOk3, bOk4, bOk5 +end + +--------------------------------------------------------------------- +function SetToolForVmill( sTool, sHead, nExit, VMill) + -- se Vmill non definito, esco + if not VMill then return true end + -- se utensile, testa o uscita non definiti, reset ed esco + if not sTool or sTool == '' or not sHead or sHead == '' or not nExit then + EgtVolZmapResetTool( VMill) + return false + end + -- verifico che l'utensile sia corrente + local sOldTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + if sTool ~= sOldTool then + if not EgtTdbSetCurrTool( sTool) then return false end + end + -- dichiaro utensile per Vmill + local nType = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + local dLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) + local dDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) + local dCornR = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) + local dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) + local dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + -- ricerca dell'outline e del diametro gambo + local nExitId = EgtGetFirstNameInGroup( EgtGetHeadId( sHead) or GDB_ID.NULL, 'T' .. tostring( nExit)) + local nToolId = EgtGetFirstNameInGroup( nExitId or GDB_ID.NULL, sTool) + local nOutlineId = EgtGetFirstNameInGroup( nToolId or GDB_ID.NULL, 'Outline') + local dMaxStemDiam = EgtGetInfo( nToolId or GDB_ID.NULL, 'D_STEM', 'd') or dDiam + -- imposto profilo utensile per Vmill + if nOutlineId then + EgtVolZmapSetGenTool( VMill, sTool, nOutlineId) + elseif nType == MCH_TY.MORTISE_STD then + EgtVolZmapSetMortiserTool( VMill, sTool, dLen, dDiam, dThick, dCornR) + elseif nType == MCH_TY.SAW_STD or nType == MCH_TY.SAW_FLAT then + EgtVolZmapSetSawTool( VMill, sTool, dLen, dDiam, dThick, 0, dCornR) + elseif nType == MCH_TY.WATERJET then + EgtVolZmapSetStdTool( VMill, sTool, dLen + 50, dDiam, dCornR, dMaxMat) + elseif abs( dSideAng) < GEO.EPS_ANG_SMALL or abs( dThick) < GEO.EPS_ANG_SMALL then + if dDiam <= dMaxStemDiam then + EgtVolZmapSetStdTool( VMill, sTool, dLen, dDiam, dCornR, dMaxMat) + else + EgtVolZmapSetSawTool( VMill, sTool, dLen, dDiam, dMaxMat, 0, dCornR) + end + else + local bExtra = ( dThick > 0) + local dTipLen = abs( dThick) + local dTotLen = EgtIf( bExtra, dLen + dTipLen, dLen) + local dDelta + if dSideAng > 0 then + if dCornR < GEO.EPS_SMALL then + dDelta = 2 * dTipLen * tan( dSideAng) + else + dDelta = 2 * ( dCornR * cos( dSideAng) + ( dTipLen - dCornR + dCornR * sin( dSideAng)) * tan( dSideAng)) + end + else + dDelta = 2 * tan( dSideAng) * dTipLen + end + local dStemDiam = EgtIf( bExtra, dDiam, dDiam + dDelta) + local dTipDiam = EgtIf( bExtra, dDiam - dDelta, dDiam) + EgtVolZmapSetAdvTool( VMill, sTool, dTotLen, dStemDiam, dTipLen, dTipDiam, dCornR, dMaxMat) + end + -- se l'utensile non era corrente, ripristino il precedente + if sTool ~= sOldTool then + EgtTdbSetCurrTool( sOldTool) + end + return true +end + +--------------------------------------------------------------------- +local function AddGeomToCollisionCheck( CollGrpId, sClass, vColl) + if not CollGrpId then return false end + local sCollGrp = EgtGetName( CollGrpId) or '' + -- ricerca dei box + local BoxId = EgtGetFirstNameInGroup( CollGrpId, 'BOX') + while BoxId do + local FrameId = BoxId + ( EgtGetInfo( BoxId, 'Frame', 'i') or 0) + if FrameId ~= BoxId and EgtGetType( FrameId) == GDB_TY.GEO_FRAME then + local b3Box = EgtGetBBoxRef( BoxId, GDB_BB.STANDARD, EgtFR( FrameId, GDB_ID.ROOT)) + local vtDiag = b3Box:getMax() - b3Box:getMin() + local vtM = b3Box:getMin() - ORIG() + table.insert( vColl, { Cl=sClass, Grp=sCollGrp, Fr=FrameId, Ty=MCH_SIM_COB.BOX, Mv=vtM, P1=vtDiag:getX(), P2=vtDiag:getY(), P3=vtDiag:getZ()}) + BoxId = EgtGetNextName( BoxId, 'BOX') + end + end + -- ricerca dei cilindri + local CylId = EgtGetFirstNameInGroup( CollGrpId, 'CYL') + while CylId do + local FrameId = CylId + ( EgtGetInfo( CylId, 'Frame', 'i') or 0) + if FrameId ~= CylId and EgtGetType( FrameId) == GDB_TY.GEO_FRAME then + local b3Box = EgtGetBBoxRef( CylId, GDB_BB.STANDARD, EgtFR( FrameId, GDB_ID.ROOT)) + local dR = ( b3Box:getDimX() + b3Box:getDimY()) / 4 + local dH = b3Box:getDimZ() + local vtM = Vector3d( 0, 0, b3Box:getMin():getZ()) + table.insert( vColl, { Cl=sClass, Grp=sCollGrp, Fr=FrameId, Ty=MCH_SIM_COB.CYL, Mv=vtM, P1=dR, P2=dH, P3=0}) + CylId = EgtGetNextName( CylId, 'CYL') + end + end + -- ricerca delle sfere + local SphId = EgtGetFirstNameInGroup( CollGrpId, 'SPH') + while SphId do + local FrameId = SphId + ( EgtGetInfo( SphId, 'Frame', 'i') or 0) + if FrameId ~= SphId and EgtGetType( FrameId) == GDB_TY.GEO_FRAME then + local b3Box = EgtGetBBoxRef( SphId, GDB_BB.STANDARD, EgtFR( FrameId, GDB_ID.ROOT)) + local dR = ( b3Box:getDimX() + b3Box:getDimY() + b3Box:getDimZ()) / 6 + local vtM = b3Box:getCenter() - ORIG() + table.insert( vColl, { Cl=sClass, Grp=sCollGrp, Fr=FrameId, Ty=MCH_SIM_COB.SPHE, Mv=vtM, P1=dR, P2=0, P3=0}) + SphId = EgtGetNextName( SphId, 'SPH') + end + end + -- ricerca dei tronchi di cono + local ConId = EgtGetFirstNameInGroup( CollGrpId, 'CON') + while ConId do + local FrameId = ConId + ( EgtGetInfo( ConId, 'Frame', 'i') or 0) + if FrameId ~= ConId and EgtGetType( FrameId) == GDB_TY.GEO_FRAME then + local frRef = EgtFR( FrameId, GDB_ID.ROOT) + local vtZ = frRef:getVersZ() + local dRb, dRt, dOb, dOt + -- ricerca delle facce bottom e top + local nFacCnt = EgtSurfTmFacetCount( ConId) + for i = 0, nFacCnt - 1 do + local vtN = EgtSurfTmFacetNormVersor( ConId, i, GDB_ID.ROOT) + if AreSameVectorApprox( vtN, vtZ) then + local b3Box = EgtSurfTmGetFacetBBoxRef( ConId, i, GDB_BB.STANDARD, frRef) + dRt = ( b3Box:getDimX() + b3Box:getDimY()) / 4 + dOt = b3Box:getCenter():getZ() + elseif AreOppositeVectorApprox( vtN, vtZ) then + local b3Box = EgtSurfTmGetFacetBBoxRef( ConId, i, GDB_BB.STANDARD, frRef) + dRb = ( b3Box:getDimX() + b3Box:getDimY()) / 4 + dOb = b3Box:getCenter():getZ() + end + end + if dRb and dRt and dOb and dOt then + local vtM = Vector3d( 0, 0, dOb) + local dH = dOt - dOb + table.insert( vColl, { Cl=sClass, Grp=sCollGrp, Fr=FrameId, Ty=MCH_SIM_COB.CONE, Mv=vtM, P1=dRb, P2=dRt, P3=dH}) + end + ConId = EgtGetNextName( ConId, 'CON') + end + end + return true +end + +--------------------------------------------------------------------- +function AddToCollisionCheck( sName, sCollGrp, vColl) + if not vColl then return false end + -- ricerca del gruppo base + local GroupId = EgtGetHeadId( sName) + if not GroupId then GroupId = EgtGetAxisId( sName) end + if not GroupId then GroupId = EgtGetTableId( sName) end + if not GroupId then GroupId = EgtGetBaseId( sName) end + if not GroupId then return false end + -- ricerca del gruppo di collisione + local CAxCollId = EgtGetFirstNameInGroup( GroupId, sCollGrp) + if not CAxCollId then return false end + -- recupero della geometria di collisione + return AddGeomToCollisionCheck( CAxCollId, sName, vColl) +end + +--------------------------------------------------------------------- +function AddToolToCollisionCheck( sHeadName, nExit, vColl) + if not vColl then return false end + local sTool = EgtGetLoadedTool( sHeadName, nExit) + if not EgtTdbSetCurrTool( sTool or '') then return false end + local nType = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + local dTotRad = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) / 2 + local dTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + local HeadId = EgtGetHeadId( sHeadName) + local FrameId = EgtGetFirstNameInGroup( HeadId, '_T'..tostring( nExit)) + if nType == MCH_TY.SAW_STD or nType == MCH_TY.SAW_FLAT then + local vtM = Vector3d( 0, 0, -dTotLen) + local dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CYL, Mv=vtM, P1=dTotRad, P2=dThick, P3=0}) + elseif nType == MCH_TY.DRILL_STD or nType == MCH_TY.DRILL_LONG then + local dLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) + local vtMc = Vector3d( 0, 0, -dLen) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CYL, Mv=vtMc, P1=dTotRad, P2=dLen, P3=0}) + if dTotLen > dLen + 0.1 then + local vtMt = Vector3d( 0, 0, -dTotLen) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CONE, Mv=vtMt, P1=0, P2=dTotRad, P3=dTotLen-dLen}) + end + elseif nType ~= MCH_TY.MORTISE_STD then + local dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) + local dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) + if abs( dSideAng) < GEO.EPS_ANG_SMALL or abs( dThick) < GEO.EPS_ANG_SMALL then + local vtM = Vector3d( 0, 0, -dTotLen) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CYL, Mv=vtM, P1=dTotRad, P2=dTotLen, P3=0}) + else + local dLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) + local dDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local bExtra = ( dThick > 0) + local dTipLen = abs( dThick) + local dTotLen = EgtIf( bExtra, dLen + dTipLen, dLen) + local dDelta = 2 * dTipLen * tan( dSideAng) + local dStemRad = EgtIf( bExtra, dDiam, dDiam + dDelta) / 2 + local dTipRad = EgtIf( bExtra, dDiam - dDelta, dDiam) / 2 + local vtMs = Vector3d( 0, 0, -( dTotLen - dTipLen)) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CYL, Mv=vtMs, P1=dStemRad, P2=dTotLen-dTipLen, P3=0}) + local vtMt = Vector3d( 0, 0, -dTotLen) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CONE, Mv=vtMt, P1=dTipRad, P2=dStemRad, P3=dTipLen}) + end + else + EgtErase( EgtGetFirstNameInGroup( HeadId, '_TT'..tostring( nExit)) or GDB_ID.NULL) + local frRef = EgtFR( FrameId) + local SpecFrId = EgtCopy( FrameId, FrameId, GDB_IN.AFTER) + EgtSetName( SpecFrId, '_TT'..tostring( nExit)) + EgtRotate( SpecFrId, frRef:getOrigin(), frRef:getVersY(), 90) + local dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) + local vtMb = Vector3d( 0, -dTotRad, 0) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=SpecFrId, Ty=MCH_SIM_COB.BOX, Mv=vtMb, P1=dTotLen-dTotRad, P2=2*dTotRad, P3=dThick}) + local vtMc = Vector3d( dTotLen-dTotRad, 0, 0) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=SpecFrId, Ty=MCH_SIM_COB.CYL, Mv=vtMc, P1=dTotRad, P2=dThick, P3=0}) + end + return true +end + +--------------------------------------------------------------------- +function DumpCollisionCheck( vColl, sTitle, nDbgLev) + if not vColl then return false end + if EgtGetDebugLevel() < ( nDbgLev or 1) then return true end + if sTitle then EgtOutLog( sTitle, nDbgLev or 1) end + for i, Coll in ipairs( vColl) do + local sOut = ' Class='..Coll.Cl..' Group='..Coll.Grp..' FrId='..tostring( Coll.Fr)..' Type='..tostring( Coll.Ty)..' Mv='..tostring( Coll.Mv) + if Coll.Ty == MCH_SIM_COB.BOX then + sOut = sOut .. ' L='..EgtNumToString( Coll.P1, 3)..' W='..EgtNumToString( Coll.P2, 3)..' H='..EgtNumToString( Coll.P3, 3) + elseif Coll.Ty == MCH_SIM_COB.CYL then + sOut = sOut .. ' R='..EgtNumToString( Coll.P1, 3)..' H='..EgtNumToString( Coll.P2, 3) + elseif Coll.Ty == MCH_SIM_COB.SPHE then + sOut = sOut .. ' R='..EgtNumToString( Coll.P1, 3) + elseif Coll.Ty == MCH_SIM_COB.CONE then + sOut = sOut .. ' Rb='..EgtNumToString( Coll.P1, 3)..' Rt='..EgtNumToString( Coll.P2, 3)..' H='..EgtNumToString( Coll.P3, 3) + end + EgtOutLog( sOut, nDbgLev or 1) + end + return true +end + +--------------------------------------------------------------------- +function AddToolToCollisionObj( sTool, sHeadName, nExit, nInd) + local vToolColl = {} + AddToolToCollisionCheck( sHeadName, nExit, vToolColl) + if #vToolColl == 0 then return false end + DumpCollisionCheck( vToolColl, 'Tool Collision Objects :', 4) + -- aggiungo la geometria trovata + for i = 1, #vToolColl do + EmtAddCollisionObjEx( nInd, vToolColl[i].Fr, vToolColl[i].Ty, vToolColl[i].Mv, vToolColl[i].P1, vToolColl[i].P2, vToolColl[i].P3) + end + return true, vToolColl[1] +end + +--------------------------------------------------------------------- +function AddToolHolderToCollisionObj( sTool, sHeadName, nExit, nInd) + -- recupero il gruppo dell'utensile + local HeadId = EgtGetHeadId( sHeadName) + local ExitId = EgtGetFirstNameInGroup( HeadId, 'T'..tostring( nExit)) + local ToolId = EgtGetFirstInGroup( ExitId) + -- cerco la geometria di collisione in questo gruppo + local vThColl = {} + if not AddGeomToCollisionCheck( ToolId, 'TH_'..sHeadName, vThColl) then return false end + DumpCollisionCheck( vThColl, 'ToolHolder Collision Objects :', 4) + -- aggiungo la geometria trovata + for i = 1, #vThColl do + EmtAddCollisionObjEx( nInd, vThColl[i].Fr, vThColl[i].Ty, vThColl[i].Mv, vThColl[i].P1, vThColl[i].P2, vThColl[i].P3) + end + return true, #vThColl +end + +--------------------------------------------------------------------- +return EmtGenerator diff --git a/ProgramData/EgtBeamWall/Macro/MacroTemplate.ini b/ProgramData/EgtBeamWall/Macro/MacroTemplate.ini new file mode 100644 index 0000000..4959064 --- /dev/null +++ b/ProgramData/EgtBeamWall/Macro/MacroTemplate.ini @@ -0,0 +1,19 @@ +-- %MACRO_NAME%.lua by EgalTech s.r.l. %DATE_TIME% +-- Macro + +-- Variabili predefinite +-- MACRO.W = beam width +-- MACRO.H = beam height +-- MACRO.L = beam length + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +print( 'Macro %MACRO_NAME% started') + +local vPar = {%vPar%} +local sPar = %sPar% + +MACRO.FEATUREID = EgtBeamAddProcess( %AddFeature%, vPar, sPar) \ No newline at end of file diff --git a/ProgramData/EgtBeamWall/Projs/0001/0001-ImportLog.txt b/ProgramData/EgtBeamWall/Projs/0001/0001-ImportLog.txt new file mode 100644 index 0000000..c8379a5 --- /dev/null +++ b/ProgramData/EgtBeamWall/Projs/0001/0001-ImportLog.txt @@ -0,0 +1 @@ +ImportBtl : C:\ProgramData\Egaltech\EgtBeamWall\Projs\0001\Casa Mosca.btl diff --git a/ProgramData/EgtBeamWall/Projs/0001/0001.nge b/ProgramData/EgtBeamWall/Projs/0001/0001.nge new file mode 100644 index 0000000..02c1e8e Binary files /dev/null and b/ProgramData/EgtBeamWall/Projs/0001/0001.nge differ diff --git a/ProgramData/EgtBeamWall/Projs/0001/2.bwe b/ProgramData/EgtBeamWall/Projs/0001/2.bwe new file mode 100644 index 0000000..a70ceea Binary files /dev/null and b/ProgramData/EgtBeamWall/Projs/0001/2.bwe differ diff --git a/ProgramData/EgtBeamWall/Projs/0001/2.html b/ProgramData/EgtBeamWall/Projs/0001/2.html new file mode 100644 index 0000000..b97af33 --- /dev/null +++ b/ProgramData/EgtBeamWall/Projs/0001/2.html @@ -0,0 +1,62 @@ + + + + + EgtCAM5 - C:\ProgramData\Egaltech\EgtBeamWall\Projs\0001\2.bwe 2022/05/04 19:29:45 + + + + + + + + + + + + + + + + + + + + + + + +
Machinings
Time [h:m:s]Len [m]Tool
Cut_2_100:00:18 2.1Lama1200
TOTAL00:00:18 2.1
+ + + + + + + + + + +
Tools
Len [m]
Lama1200 2.1
+ + diff --git a/ProgramData/EgtBeamWall/Projs/0001/2.ori.bwe b/ProgramData/EgtBeamWall/Projs/0001/2.ori.bwe new file mode 100644 index 0000000..a70ceea Binary files /dev/null and b/ProgramData/EgtBeamWall/Projs/0001/2.ori.bwe differ diff --git a/ProgramData/EgtBeamWall/Projs/0001/2.txt b/ProgramData/EgtBeamWall/Projs/0001/2.txt new file mode 100644 index 0000000..a2ac4f6 --- /dev/null +++ b/ProgramData/EgtBeamWall/Projs/0001/2.txt @@ -0,0 +1,11 @@ +ERR=0 +--- +ROT=0 +CUTID=369 +TASKID=1849 +ERR=0 +--- +ROT=0 +CUTID=0 +TASKID=0 +TIME=19 diff --git a/ProgramData/EgtBeamWall/Projs/0001/5.bwe b/ProgramData/EgtBeamWall/Projs/0001/5.bwe new file mode 100644 index 0000000..f8d7b38 Binary files /dev/null and b/ProgramData/EgtBeamWall/Projs/0001/5.bwe differ diff --git a/ProgramData/EgtBeamWall/Projs/0001/5.html b/ProgramData/EgtBeamWall/Projs/0001/5.html new file mode 100644 index 0000000..c6f64d6 --- /dev/null +++ b/ProgramData/EgtBeamWall/Projs/0001/5.html @@ -0,0 +1,62 @@ + + + + + EgtCAM5 - C:\ProgramData\Egaltech\EgtBeamWall\Projs\0001\5.bwe 2022/05/19 11:53:22 + + + + + + + + + + + + + + + + + + + + + + + +
Machinings
Time [h:m:s]Len [m]Tool
Cut_5_100:00:17 1.9Lama1200
TOTAL00:00:17 1.9
+ + + + + + + + + + +
Tools
Len [m]
Lama1200 1.9
+ + diff --git a/ProgramData/EgtBeamWall/Projs/0001/7.bwe b/ProgramData/EgtBeamWall/Projs/0001/7.bwe new file mode 100644 index 0000000..6a34609 Binary files /dev/null and b/ProgramData/EgtBeamWall/Projs/0001/7.bwe differ diff --git a/ProgramData/EgtBeamWall/Projs/0001/7.html b/ProgramData/EgtBeamWall/Projs/0001/7.html new file mode 100644 index 0000000..86a252c --- /dev/null +++ b/ProgramData/EgtBeamWall/Projs/0001/7.html @@ -0,0 +1,102 @@ + + + + + EgtCAM5 - C:\ProgramData\Egaltech\EgtBeamWall\Projs\0001\7.bwe 2022/05/04 19:19:42 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Machinings
Time [h:m:s]Len [m]Tool
Free_700:00:17 1.0Fresa25x130
Drill_100:00:06 0.5Fresa25x130
Drill_200:00:07 0.5Fresa25x130
Cut_7_400:00:42 7.4Lama1200
Cut_7_500:00:13 2.5Lama1200
Cut_7_600:00:41 7.6Lama1200
Cut_7_100:00:20 2.5Lama1200
TOTAL00:02:2921.9
+ + + + + + + + + + + + + + +
Tools
Len [m]
Fresa25x130 1.9
Lama120020.0
+ + diff --git a/ProgramData/EgtBeamWall/Projs/0001/7.ori.bwe b/ProgramData/EgtBeamWall/Projs/0001/7.ori.bwe new file mode 100644 index 0000000..6a34609 Binary files /dev/null and b/ProgramData/EgtBeamWall/Projs/0001/7.ori.bwe differ diff --git a/ProgramData/EgtBeamWall/Projs/0001/7.txt b/ProgramData/EgtBeamWall/Projs/0001/7.txt new file mode 100644 index 0000000..2b5117a --- /dev/null +++ b/ProgramData/EgtBeamWall/Projs/0001/7.txt @@ -0,0 +1,21 @@ +ERR=0 +--- +ROT=0 +CUTID=562 +TASKID=572 +ERR=0 +--- +ROT=0 +CUTID=562 +TASKID=574 +ERR=0 +--- +ROT=0 +CUTID=562 +TASKID=576 +ERR=0 +--- +ROT=0 +CUTID=0 +TASKID=0 +TIME=150 diff --git a/ProgramData/EgtBeamWall/Projs/0001/Casa Mosca.btl b/ProgramData/EgtBeamWall/Projs/0001/Casa Mosca.btl new file mode 100644 index 0000000..3ddcbca --- /dev/null +++ b/ProgramData/EgtBeamWall/Projs/0001/Casa Mosca.btl @@ -0,0 +1,3850 @@ +VERSION: "BTL V10.4" +BUILD: "10400" +[GENERAL] +PROJECTNUMBER: " " +PROJECTNAME: "Casa Mosca" +PROJECTPART: " " +LISTNAME: "Casa Mosca" +CUSTOMER: "Sig Mosca Davide" +ARCHITECT: " " +EDITOR: "Giovanni" +DELIVERYDATE: " " +EXPORTDATE: "2019-08-06" +EXPORTTIME: "16:18:28" +EXPORTRELEASE: "CADWORK-3D_23.0 Build: 339" +LANGUAGE: "it" +SCALEUNIT: 2 +COMPUTERNAME: "GIOVANNI-PC" +USER: "Giovanni" +SOURCEFILE: "\\SRV01\Area Tecnica\geom GIOVANNI\Esecutivi e Produzioni\Sig-Mosca-Davide\Cadwork\Produzione BARRE SCALA.3d" +EXPORTFILE: "\\SRV01\Area Tecnica\geom GIOVANNI\Esecutivi e Produzioni\Sig-Mosca-Davide\Cadwork\Casa Mosca.btl" +RECESS: AUTOMATIC +[RAWPART] +SINGLEMEMBERNUMBER: 2000001 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato corto" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2539352 +TRANSFORMATION: OX:00000000 OY:00-20000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00716351 OY:00000000 OZ:00026770 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1836709 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00158024 OY:00000000 OZ:00015000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2218945 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00046774 OY:00000000 OZ:00047250 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207402 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000002 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato corto" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2539353 +TRANSFORMATION: OX:00000000 OY:0-300000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00619215 OY:00000000 OZ:00024894 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1836675 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00014379 OY:00000000 OZ:00039343 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1836725 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00306715 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1873572 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000003 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato lungo3" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2559944 +TRANSFORMATION: OX:00000000 OY:0-580000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00524698 OY:00000000 OZ:00066500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207291 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00025647 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2205669 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:01105000 OY:00000000 OZ:00013750 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207298 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00932000 OY:00000000 OZ:00013750 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2205623 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00766000 OY:00000000 OZ:00013750 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2205642 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00559000 OY:00000000 OZ:00003500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207214 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00675500 OY:00000000 OZ:00013750 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1822441 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00466500 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1951187 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000004 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato lungo4" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2559946 +TRANSFORMATION: OX:00000000 OY:0-860000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00480725 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2036201 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:01230177 OY:00000000 OZ:00056802 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1880464 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00003199 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2205650 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:01230177 OY:00000000 OZ:00003200 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1951227 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000005 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato lungo5" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2559948 +TRANSFORMATION: OX:00000000 OY:-1140000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00625673 OY:00000000 OZ:00097500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1804262 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00167397 OY:00000000 OZ:00065000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207307 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00974673 OY:00000000 OZ:00015000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2244504 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00033997 OY:00000000 OZ:00032000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1822336 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00568177 OY:00000000 OZ:00215369 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1951251 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00648423 OY:00000000 OZ:00009600 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207383 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00524983 OY:00000000 OZ:00009600 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1951239 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000006 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato lungo6" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2559950 +TRANSFORMATION: OX:00000000 OY:-1420000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00694240 OY:00000000 OZ:00075250 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1804253 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00016288 OY:00000000 OZ:00112500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207217 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00998298 OY:00000000 OZ:00004750 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207415 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00672048 OY:00000000 OZ:00004750 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2205648 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00422148 OY:00000000 OZ:00004750 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207372 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00538648 OY:00000000 OZ:00004750 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1822341 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00030372 OY:00000000 OZ:00004750 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207304 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000007 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato lungo7" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2559952 +TRANSFORMATION: OX:00000000 OY:-1700000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00807059 OY:00000000 OZ:00001951 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207379 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00393448 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1938946 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:01023750 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1804264 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00848750 OY:00000000 OZ:00084923 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2205662 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00241948 OY:00000000 OZ:00095000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207409 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000010 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato lungo10" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2559958 +TRANSFORMATION: OX:00000000 OY:-1980000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00411467 OY:00000000 OZ:00037700 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1836678 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00646597 OY:00000000 OZ:00009603 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1824023 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00059765 OY:00000000 OZ:00010250 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207266 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00998298 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207430 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00008353 OY:00000000 OZ:00167500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1959218 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000011 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato lungo11" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2559960 +TRANSFORMATION: OX:00000000 OY:-2260000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00710765 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1804250 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00366765 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207220 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00040515 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1804259 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:01037500 OY:00000000 OZ:00005662 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2020101 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000012 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato lungo12" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2559962 +TRANSFORMATION: OX:00000000 OY:-2540000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:01023750 OY:00000000 OZ:00042500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207190 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00045000 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207207 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00697500 OY:00000000 OZ:00069500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2252117 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00371250 OY:00000000 OZ:00001600 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207406 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000014 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.60x13.50 lato lungo14" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2595665 +TRANSFORMATION: OX:00000000 OY:-2820000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00367990 OY:00000000 OZ:00087500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1804256 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00041740 OY:00000000 OZ:00080000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2036317 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:01020490 OY:00000000 OZ:00097500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207187 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00694240 OY:00000000 OZ:00092500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2205646 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000015 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "2.95x13.50 lato lungo" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01350000 +HEIGHT: 00010000 +WIDTH: 00295000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2674841 +TRANSFORMATION: OX:00000000 OY:-3100000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00014750 OY:00000000 OZ:00107000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2405733 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00030415 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1822345 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00653500 OY:00000000 OZ:00133062 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2020099 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00341000 OY:00000000 OZ:00133062 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2020107 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00579397 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2205666 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00969423 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2205672 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00966000 OY:00000000 OZ:00117048 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207257 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00163815 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1959182 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00253147 OY:00000000 OZ:00005000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207302 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000016 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "A" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 00290000 +HEIGHT: 00010000 +WIDTH: 00140000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2677769 +TRANSFORMATION: OX:01370000 OY:-3177500 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00038969 OY:00000000 OZ:00036550 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207341 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00185000 OY:00000000 OZ:00008500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207433 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000017 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "B" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 00150000 +HEIGHT: 00010000 +WIDTH: 00094000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2677773 +TRANSFORMATION: OX:01680000 OY:-3200500 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00004503 OY:00000000 OZ:00005796 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207426 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000018 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "C" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 00260000 +HEIGHT: 00010000 +WIDTH: 00220000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2677776 +TRANSFORMATION: OX:00000000 OY:-3435000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00026770 OY:00000000 OZ:00015000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:1836706 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000019 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "D" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 00200000 +HEIGHT: 00010000 +WIDTH: 00075000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2677779 +TRANSFORMATION: OX:00280000 OY:-3507500 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00047250 OY:00000000 OZ:00001875 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207351 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000020 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "F" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 01144000 +HEIGHT: 00010000 +WIDTH: 00260000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2677782 +TRANSFORMATION: OX:00500000 OY:-3415000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00354048 OY:00000000 OZ:00004000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2205627 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00354048 OY:00000000 OZ:00119500 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207369 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00004347 OY:00000000 OZ:00005969 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207413 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00678298 OY:00000000 OZ:00037897 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207436 +COMMENT: "Attributo pezzo" +[RAWPART] +SINGLEMEMBERNUMBER: 2000021 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: "G" +STOREY: " " +GROUP: " " +ANNOTATION: " " +MATERIAL: "XLAM 3 Strati" +TIMBERGRADE: " " +QUALITYGRADE: " " +PACKAGE: " " +COUNT: 1 +LENGTH: 00310000 +HEIGHT: 00010000 +WIDTH: 00096000 +COLOUR: R:137 G:205 B:173 A:100 +UID: 2677800 +TRANSFORMATION: OX:01664000 OY:-3497000 OZ:000-5000 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00200266 OY:00000000 OZ:00009375 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207203 +COMMENT: "Attributo pezzo" +PROCESSKEY: 0-300-1 +REFERENCEPLANE: OX:00020266 OY:00000000 OZ:00009375 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +PROCESSPARAMETERS: UID:2207180 +COMMENT: "Attributo pezzo" +[PART] +SINGLEMEMBERNUMBER: 1 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1804250 +TRANSFORMATION: OX:00382500 OY:00185000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00096500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00299650 P02:00096500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00299650 P02:00119500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00119500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00085106 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00165106 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00243000 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00321250 P13:00000000 P14:00007000 +PROCESSIDENT: 12 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 2 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00650760 +HEIGHT: 00010000 +WIDTH: 00180000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1804253 +TRANSFORMATION: OX:00970000 OY:00010000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00356828 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00356828 P02:00022021 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00383032 P02:00022021 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00383032 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00650760 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00650760 P02:00140000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00500000 P02:00140000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00500000 P02:00160000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00160000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00180000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00180000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00635760 P02:00082251 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00250000 P02:00153000 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00250000 P13:00000000 P14:00007000 +PROCESSIDENT: 17 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00500000 P02:00133000 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00150760 P13:00000000 P14:00007000 +PROCESSIDENT: 18 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 3 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00167500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1804256 +TRANSFORMATION: OX:01150000 OY:00852000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00215000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00215000 P02:00022750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00022750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00074750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00074750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00085250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00085250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00137250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00137250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00147750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00147750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00167500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00167500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00117478 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00057478 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00146500 P13:00000000 P14:00007000 +PROCESSIDENT: 18 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00215000 P02:00022750 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00081250 P13:00000000 P14:00007000 +PROCESSIDENT: 20 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 4 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1804259 +TRANSFORMATION: OX:00010000 OY:00619500 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00154000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00299650 P02:00154000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00299650 P02:00177000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00177000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00230000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00230000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00123264 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00321250 P13:00000000 P14:00007000 +PROCESSIDENT: 13 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00250000 P02:00223000 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00071250 P13:00000000 P14:00007000 +PROCESSIDENT: 15 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 5 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00719327 +HEIGHT: 00010000 +WIDTH: 00157500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1804262 +TRANSFORMATION: OX:01140000 OY:00167500 OZ:00714327 XX:00000000 XY:00000000 XZ:-1000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00044188 P02:00006250 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00068567 P02:00006250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00068567 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00336295 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00336295 P02:00012021 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00362499 P02:00012021 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00362499 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00719327 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00719327 P02:00157500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00469327 P02:00157500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00469327 P02:00132500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00132500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00044188 P02:00006250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00037127 P02:00071830 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00125500 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00469327 P13:00000000 P14:00007000 +PROCESSIDENT: 16 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 6 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1804264 +TRANSFORMATION: OX:00787000 OY:00535000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00299650 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00299650 P02:00033500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00033500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00082750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00082750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00093250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00093250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00145250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00145250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00155750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00155750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00207750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00207750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00218250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00218250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00125192 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00243000 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00125167 P13:00000000 P14:00007000 +PROCESSIDENT: 21 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00194125 P02:00243000 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00127125 P13:00000000 P14:00007000 +PROCESSIDENT: 22 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 101 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00128400 +HEIGHT: 00010000 +WIDTH: 00223000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1822336 +TRANSFORMATION: OX:00111000 OY:00-99000 OZ:00318350 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00128400 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00128400 P02:00223000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00223000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00113400 P02:00111500 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +[PART] +SINGLEMEMBERNUMBER: 102 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00128400 +HEIGHT: 00010000 +WIDTH: 00099000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1822341 +TRANSFORMATION: OX:00324000 OY:00-99000 OZ:00318350 XX:00000000 XY:00000000 XZ:01000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00128400 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00128400 P02:00099000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00099000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00113400 P02:00049500 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +[PART] +SINGLEMEMBERNUMBER: 103 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00128400 +HEIGHT: 00010000 +WIDTH: 00099000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1822345 +TRANSFORMATION: OX:00121000 OY:00000000 OZ:00318350 XX:00000000 XY:00000000 XZ:01000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00128400 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00128400 P02:00099000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00099000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00113400 P02:00049500 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +[PART] +SINGLEMEMBERNUMBER: 301 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00085500 +HEIGHT: 00010000 +WIDTH: 00044731 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1822441 +TRANSFORMATION: OX:00560731 OY:00437500 OZ:00320792 XX:00000000 XY:01000000 XZ:00000000 YX:00000000 YY:00000000 YZ:-1000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00085500 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00085500 P02:00044731 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00044731 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00003000 P12:00085500 P13:00000000 P14:00016000 +PROCESSIDENT: 6 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 104 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00346702 +HEIGHT: 00010000 +WIDTH: 00245397 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1824023 +TRANSFORMATION: OX:00462500 OY:00852000 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00010500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00010500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00064118 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00064118 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00074618 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00074618 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00128235 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00128235 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00138735 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00138735 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00192353 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00192353 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00202853 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00202853 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00225397 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00225397 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00245397 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00245397 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00328202 P02:00120955 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00324750 P13:00000000 P14:00007000 +PROCESSIDENT: 24 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00238397 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00126500 P13:00000000 P14:00007000 +PROCESSIDENT: 25 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00265000 P02:00218397 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00078972 P13:00000000 P14:00007000 +PROCESSIDENT: 26 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 7 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00725785 +HEIGHT: 00010000 +WIDTH: 00230106 +COLOUR: R:180 G: 30 B: 30 A:100 +UID: 1836675 +TRANSFORMATION: OX:00131031 OY:01359500 OZ:00214106 XX:-1000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00725785 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00725785 P02:00215814 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00011200 P02:00230106 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00011200 P02:00222115 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00222115 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00259471 P02:00210138 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00459471 P02:00206138 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +[PART] +SINGLEMEMBERNUMBER: 8 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00230130 +HEIGHT: 00010000 +WIDTH: 00217300 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1836678 +TRANSFORMATION: OX:00131031 OY:00862000 OZ:00214130 XX:00000000 XY:00000000 XZ:-1000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00008015 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00230130 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00230130 P02:00210300 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00217130 P02:00210300 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00217130 P02:00217300 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00217300 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00020200 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00008015 P02:00020200 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00008015 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00015000 P02:00108628 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +[PART] +SINGLEMEMBERNUMBER: 9 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00228230 +HEIGHT: 00010000 +WIDTH: 00200000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1836706 +TRANSFORMATION: OX:00026031 OY:00862000 OZ:00212230 XX:00000000 XY:00000000 XZ:-1000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000200 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00228230 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00228230 P02:00193000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00215230 P02:00193000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00215230 P02:00200000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000200 P02:00200000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000200 P02:00000000 P03:00000000 P06:0000-115 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00015200 P02:00099807 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +[PART] +SINGLEMEMBERNUMBER: 10 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00628649 +HEIGHT: 00010000 +WIDTH: 00228230 +COLOUR: R:180 G: 30 B: 30 A:100 +UID: 1836709 +TRANSFORMATION: OX:0-602618 OY:01072000 OZ:00212230 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00628649 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00628649 P02:00228230 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00215657 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00217125 P02:00204997 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00417125 P02:00208997 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +[PART] +SINGLEMEMBERNUMBER: 11 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00287336 +HEIGHT: 00010000 +WIDTH: 00215657 +COLOUR: R:180 G: 30 B: 30 A:100 +UID: 1836725 +TRANSFORMATION: OX:0-585021 OY:01359236 OZ:00199657 XX:00-26425 XY:0-999651 XZ:00000000 YX:0-999651 YY:00026425 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00287336 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00287336 P02:00215657 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00215657 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00143668 P02:00200657 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +[PART] +SINGLEMEMBERNUMBER: 105 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00307500 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:180 G: 30 B: 30 A:100 +UID: 1873572 +TRANSFORMATION: OX:00211031 OY:01369500 OZ:00215930 XX:00000000 XY:-1000000 XZ:00000000 YX:00-19996 YY:00000000 YZ:00999800 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00307500 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00307500 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00025000 P02:00235000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00282500 P02:00235000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00282500 P02:00015000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 3 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00025000 P02:00015000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 4 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +[PART] +SINGLEMEMBERNUMBER: 106 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00114823 +HEIGHT: 00010000 +WIDTH: 00200000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1880464 +TRANSFORMATION: OX:00016231 OY:01062000 OZ:00212034 XX:00999800 XY:00000000 XZ:00019996 YX:00-19996 YY:00000000 YZ:00999800 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00114823 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00114823 P02:00200000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00200000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00099823 P02:00185000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00099823 P02:00015000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00015000 P02:00015000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 3 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00015000 P02:00185000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 4 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +[PART] +SINGLEMEMBERNUMBER: 107 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00450302 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1938946 +TRANSFORMATION: OX:00382500 OY:00077500 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00404077 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00404077 P02:00021500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00450302 P02:00021500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00370327 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00399566 P02:00121052 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00243000 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00372777 P13:00000000 P14:00007000 +PROCESSIDENT: 9 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 302 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00087500 +HEIGHT: 00010000 +WIDTH: 00046244 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1951187 +TRANSFORMATION: OX:00885000 OY:00437500 OZ:00064332 XX:00000000 XY:01000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00036244 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00087500 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00087500 P02:00046244 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00046244 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00036244 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +[PART] +SINGLEMEMBERNUMBER: 303 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00107395 +HEIGHT: 00010000 +WIDTH: 00050602 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1951227 +TRANSFORMATION: OX:00875636 OY:00484250 OZ:00026412 XX:00923880 XY:00382683 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00086591 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00107395 P02:00050225 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00106485 P02:00050602 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00003247 P02:00007839 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +[PART] +SINGLEMEMBERNUMBER: 304 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00118440 +HEIGHT: 00010000 +WIDTH: 00040836 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1951239 +TRANSFORMATION: OX:00978750 OY:00521250 OZ:00045372 XX:0-707107 XY:0-707107 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00035533 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00107354 P02:00029749 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00118440 P02:00040836 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00005303 P02:00040836 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00035533 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00035533 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +[PART] +SINGLEMEMBERNUMBER: 305 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00080000 +HEIGHT: 00010000 +WIDTH: 00039631 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1951251 +TRANSFORMATION: OX:00895000 OY:00477131 OZ:00007452 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:00000000 YZ:01000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00080000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00080000 P02:00039631 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00006494 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +[PART] +SINGLEMEMBERNUMBER: 306 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00084332 +HEIGHT: 00010000 +WIDTH: 00087500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1959182 +TRANSFORMATION: OX:00895000 OY:00437500 OZ:00064332 XX:00000000 XY:00000000 XZ:-1000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00067332 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00067332 P02:00014000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00084332 P02:00014000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00084332 P02:00087500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00087500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +[PART] +SINGLEMEMBERNUMBER: 307 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00046412 +HEIGHT: 00010000 +WIDTH: 00087500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 1959218 +TRANSFORMATION: OX:00975000 OY:00437500 OZ:00026412 XX:00000000 XY:00000000 XZ:-1000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00029412 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00029412 P02:00014000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00046412 P02:00014000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00046412 P02:00087500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00018960 P02:00087500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00018960 P02:00047869 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00047869 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +[PART] +SINGLEMEMBERNUMBER: 108 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00307500 +HEIGHT: 00010000 +WIDTH: 00156938 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2020099 +TRANSFORMATION: OX:0-445775 OY:01369500 OZ:00202794 XX:00000000 XY:-1000000 XZ:00000000 YX:00-19996 YY:00000000 YZ:00999800 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00008130 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00307500 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00307500 P02:00156938 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00156938 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00008130 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00015000 P02:00023130 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00292500 P02:00023130 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00292500 P02:00141938 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 3 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00015000 P02:00141938 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 4 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00010000 P02:00149938 P03:00000000 P04:00000800 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00287500 P13:00000000 P14:00007000 +PROCESSIDENT: 10 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 109 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00307500 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2020101 +TRANSFORMATION: OX:00-38919 OY:01369500 OZ:00210931 XX:00000000 XY:-1000000 XZ:00000000 YX:00-19996 YY:00000000 YZ:00999800 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00307500 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00307500 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00292500 P02:00235000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00015000 P02:00235000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00010000 P02:00000000 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00287500 P13:00000000 P14:00007000 +PROCESSIDENT: 8 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 110 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00307500 +HEIGHT: 00010000 +WIDTH: 00156938 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2020107 +TRANSFORMATION: OX:0-288869 OY:01369500 OZ:00205932 XX:00000000 XY:-1000000 XZ:00000000 YX:00-19996 YY:00000000 YZ:00999800 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00307500 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00307500 P02:00156938 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00156938 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00015000 P02:00141938 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00292500 P02:00141938 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00010000 P02:00000000 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00287500 P13:00000000 P14:00007000 +PROCESSIDENT: 8 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00010000 P02:00149938 P03:00000000 P04:00000800 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00287500 P13:00000000 P14:00007000 +PROCESSIDENT: 9 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 12 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00744452 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2036201 +TRANSFORMATION: OX:00537000 OY:00535000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00744452 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00744452 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321900 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321900 P02:00216500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00299650 P02:00216500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00299650 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00729452 P02:00155014 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00729452 P02:00095014 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00145167 P02:00000000 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00010423 +PROCESSIDENT: 12 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00125167 P13:00000000 P14:00007000 +PROCESSIDENT: 13 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00194125 P02:00000000 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00127125 P13:00000000 P14:00007000 +PROCESSIDENT: 14 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00296833 P02:00198539 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00017962 +PROCESSIDENT: 15 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00221000 P02:00087615 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00033731 +PROCESSIDENT: 16 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00239958 P02:00115346 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00033731 +PROCESSIDENT: 17 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00258917 P02:00143077 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00033731 +PROCESSIDENT: 18 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00183083 P02:00032154 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00033731 +PROCESSIDENT: 19 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00164125 P02:00004423 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00033731 +PROCESSIDENT: 20 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00202042 P02:00059885 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00033731 +PROCESSIDENT: 21 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00277875 P02:00170808 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00033731 +PROCESSIDENT: 22 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 13 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00175000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2036317 +TRANSFORMATION: OX:00382500 OY:00010000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00175000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00175000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00087500 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00321250 P13:00000000 P14:00007000 +PROCESSIDENT: 7 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 14 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00170000 +HEIGHT: 00010000 +WIDTH: 00071250 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2205623 +TRANSFORMATION: OX:00010000 OY:00769500 OZ:00316250 XX:00000000 XY:-1000000 XZ:00000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00170000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00170000 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00085000 P02:00056250 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00163000 P02:00000000 P03:00000000 P04:00001400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00071250 +PROCESSIDENT: 7 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00001300 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00071250 +PROCESSIDENT: 8 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 15 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00112500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2205627 +TRANSFORMATION: OX:00010000 OY:00862000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00102500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00222800 P02:00102500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00222800 P02:00112500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00112500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00056816 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00250000 P02:00020000 P03:00000000 P04:00000600 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00071250 P13:00000000 P14:00007000 +PROCESSIDENT: 12 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 16 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00163000 +HEIGHT: 00010000 +WIDTH: 00071250 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2205642 +TRANSFORMATION: OX:00010000 OY:00315500 OZ:00316250 XX:00000000 XY:-1000000 XZ:00000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00013000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00163000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00163000 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00049650 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00013000 P02:00049650 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00013000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00085657 P02:00056250 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00156000 P02:00000000 P03:00000000 P04:00001400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00071250 +PROCESSIDENT: 9 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00013000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00049650 +PROCESSIDENT: 11 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 17 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00162500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2205646 +TRANSFORMATION: OX:00010000 OY:00172500 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00142500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00142500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00162500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00162500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00079121 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00250000 P02:00135500 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00071250 P13:00000000 P14:00007000 +PROCESSIDENT: 10 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 18 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00067000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2205648 +TRANSFORMATION: OX:00010000 OY:00369500 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00299650 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00299650 P02:00036000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00036000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00067000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00067000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00284650 P02:00033476 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00060000 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00321250 P13:00000000 P14:00007000 +PROCESSIDENT: 9 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00250000 P02:00000000 P03:00000000 P04:00000600 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00049650 P13:00000000 P14:00007000 +PROCESSIDENT: 10 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 111 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00472527 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2205650 +TRANSFORMATION: OX:00010000 OY:00369500 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00385027 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00450477 P02:00187000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00404077 P02:00187000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00404077 P02:00203750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00435910 P02:00203750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00435910 P02:00220500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00462202 P02:00220500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00472527 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00414046 P02:00128318 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00387477 P13:00000000 P14:00007000 +PROCESSIDENT: 13 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00243000 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00472527 P13:00000000 P14:00007000 +PROCESSIDENT: 14 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 112 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00170000 +HEIGHT: 00010000 +WIDTH: 00170077 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2205662 +TRANSFORMATION: OX:00010000 OY:00769500 OZ:00756327 XX:00000000 XY:-1000000 XZ:00000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00170000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00170000 P02:00170077 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00110577 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00090812 P02:00126469 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00163000 P02:00000000 P03:00000000 P04:00001400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00170077 +PROCESSIDENT: 7 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00001300 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00113027 +PROCESSIDENT: 8 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 113 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00385027 +HEIGHT: 00010000 +WIDTH: 00109500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2205666 +TRANSFORMATION: OX:00010000 OY:00119500 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00006250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00348889 P02:00006250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00385027 P02:00109500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00109500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00350110 P02:00055144 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00102500 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00385027 P13:00000000 P14:00007000 +PROCESSIDENT: 9 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 114 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00494052 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2205669 +TRANSFORMATION: OX:00010000 OY:00619500 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00472527 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00494052 P02:00061500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00462289 P02:00152250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00418202 P02:00152250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00418202 P02:00168750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00456514 P02:00168750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00435077 P02:00230000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00230000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00458011 P02:00119066 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00474977 P13:00000000 P14:00007000 +PROCESSIDENT: 14 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00265000 P02:00223000 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00172527 P13:00000000 P14:00007000 +PROCESSIDENT: 16 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 115 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00375577 +HEIGHT: 00010000 +WIDTH: 00102500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2205672 +TRANSFORMATION: OX:00010000 OY:00852000 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:-1000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00375577 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00348889 P02:00096250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00096250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00102500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00102500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00348137 P02:00052993 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00265000 P02:00020000 P03:00000000 P04:00000600 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00110577 P13:00000000 P14:00007000 +PROCESSIDENT: 12 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 116 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00170000 +HEIGHT: 00010000 +WIDTH: 00081702 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207180 +TRANSFORMATION: OX:00307500 OY:00010000 OZ:00586250 XX:-1000000 XY:00000000 XZ:00000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00003500 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00015779 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00015779 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00026279 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00026279 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00079897 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00079897 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00090397 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00090397 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00133765 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00133765 P02:00022192 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00170000 P02:00022192 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00170000 P02:00081702 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00081702 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00072000 P02:00018500 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00002730 P03:00000000 P04:00001300 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00078972 +PROCESSIDENT: 17 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00163000 P02:00022192 P03:00000000 P04:00001400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00059510 +PROCESSIDENT: 18 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 117 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00324510 +HEIGHT: 00010000 +WIDTH: 00157500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207187 +TRANSFORMATION: OX:00000000 OY:00010000 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00157500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00157500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00309510 P02:00080494 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00265000 P02:00020000 P03:00000000 P04:00000600 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00059510 P13:00000000 P14:00007000 +PROCESSIDENT: 10 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 19 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00212500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207190 +TRANSFORMATION: OX:00000000 OY:00010000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00019750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00019750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00030250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00030250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00082250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00082250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00101750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00101750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00144750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00144750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00155250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00155250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00212500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00212500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00167210 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00047210 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00321250 P13:00000000 P14:00007000 +PROCESSIDENT: 20 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 20 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00099734 +HEIGHT: 00010000 +WIDTH: 00071250 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207203 +TRANSFORMATION: OX:00542500 OY:00010000 OZ:00245000 XX:-1000000 XY:00000000 XZ:00000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00020000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00026750 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00026750 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00037250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00037250 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00047750 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00047750 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00099734 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00099734 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00053255 P02:00015000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00025000 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00046250 +PROCESSIDENT: 13 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00092734 P02:00025000 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00046250 +PROCESSIDENT: 14 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 21 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207207 +TRANSFORMATION: OX:00212500 OY:00010000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00019734 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00019734 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00030234 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00030234 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00082250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00082250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00092750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00092750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00128250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00128250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00155250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00155250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00207250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00207250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00217750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00217750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00186706 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00066706 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00243000 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00321250 P13:00000000 P14:00007000 +PROCESSIDENT: 24 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00111500 P13:00000000 P14:00007000 +PROCESSIDENT: 25 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00250000 P02:00019734 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00046250 P13:00000000 P14:00007000 +PROCESSIDENT: 27 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 22 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00111500 +HEIGHT: 00010000 +WIDTH: 00060000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207214 +TRANSFORMATION: OX:00462500 OY:00010000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00111500 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00111500 P02:00060000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00060000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00096500 P02:00030000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00053000 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00111500 P13:00000000 P14:00007000 +PROCESSIDENT: 7 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00111500 P13:00000000 P14:00007000 +PROCESSIDENT: 8 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 23 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00672952 +HEIGHT: 00010000 +WIDTH: 00142500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207217 +TRANSFORMATION: OX:00665000 OY:00010000 OZ:00667952 XX:00000000 XY:00000000 XZ:-1000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00003500 P02:00009750 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00371702 P02:00009750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00371702 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00422952 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00422952 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00672952 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00672952 P02:00142500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00422952 P02:00142500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00422952 P02:00128500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00172952 P02:00128500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00172952 P02:00108500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00003500 P02:00108500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00003500 P02:00089809 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00016952 P02:00089809 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00016952 P02:00079309 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00003500 P02:00079309 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00003500 P02:00025691 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00016952 P02:00025691 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00016952 P02:00015191 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00003500 P02:00015191 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00003500 P02:00009750 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00018500 P02:00068565 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00561452 P02:00000000 P03:00000000 P04:00000600 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00111500 P13:00000000 P14:00007000 +PROCESSIDENT: 26 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00021952 P02:00009750 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00349750 P13:00000000 P14:00007000 +PROCESSIDENT: 27 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00376702 P02:00020000 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00046250 P13:00000000 P14:00007000 +PROCESSIDENT: 28 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00021952 P02:00101500 P03:00000000 P04:00000800 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00151000 P13:00000000 P14:00007000 +PROCESSIDENT: 29 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00172952 P02:00121500 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00250000 P13:00000000 P14:00007000 +PROCESSIDENT: 30 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 24 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00339000 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207220 +TRANSFORMATION: OX:00990000 OY:00010000 OZ:00245000 XX:-1000000 XY:00000000 XZ:00000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00339000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00339000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00169500 P02:00015000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00332000 P02:00000000 P03:00000000 P04:00001400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00250000 +PROCESSIDENT: 7 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00001300 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00250000 +PROCESSIDENT: 8 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 118 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00379000 +HEIGHT: 00010000 +WIDTH: 00172952 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207257 +TRANSFORMATION: OX:01010000 OY:00010000 OZ:00495000 XX:-1000000 XY:00000000 XZ:00000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00022192 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00033735 P02:00022192 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00033735 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00077103 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00077103 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00087603 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00087603 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00141221 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00141221 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00151721 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00151721 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00205338 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00205338 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00215838 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00215838 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00269456 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00269456 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00279956 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00279956 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00333574 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00333574 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00344074 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00344074 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00379000 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00379000 P02:00172952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00172952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00022192 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00191123 P02:00018500 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00022192 P03:00000000 P04:00001300 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00150760 +PROCESSIDENT: 29 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00372000 P02:00021952 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00151000 +PROCESSIDENT: 30 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 119 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00346702 +HEIGHT: 00010000 +WIDTH: 00244750 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207266 +TRANSFORMATION: OX:00287500 OY:00010000 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00048177 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00048177 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00058677 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00058677 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00112294 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00112294 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00122794 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00122794 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00176412 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00176412 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00186912 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00186912 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00224750 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00224750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00244750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00244750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00328202 P02:00150786 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00328202 P02:00090786 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00324750 P13:00000000 P14:00007000 +PROCESSIDENT: 22 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00265000 P02:00217750 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00078972 P13:00000000 P14:00007000 +PROCESSIDENT: 24 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 25 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00820302 +HEIGHT: 00010000 +WIDTH: 00190000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207291 +TRANSFORMATION: OX:01140000 OY:00357500 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00030000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00030000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00022750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00326250 P02:00022750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00326250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00779527 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00782764 P02:00009250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00744452 P02:00009250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00744452 P02:00025750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00788539 P02:00025750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00820302 P02:00116500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00803327 P02:00165000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00165000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00190000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00190000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00794728 P02:00088838 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00326250 P02:00000000 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00413202 P13:00000000 P14:00007000 +PROCESSIDENT: 22 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00250000 P02:00158000 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00555777 P13:00000000 P14:00007000 +PROCESSIDENT: 23 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00250000 P02:00030000 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00071250 P13:00000000 P14:00007000 +PROCESSIDENT: 24 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 26 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00240000 +HEIGHT: 00010000 +WIDTH: 00071250 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207298 +TRANSFORMATION: OX:01140000 OY:00517500 OZ:00316250 XX:00000000 XY:01000000 XZ:00000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00240000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00240000 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00023750 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00023750 P02:00051250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00007250 P02:00051250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00007250 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00121884 P02:00056250 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00233000 P02:00000000 P03:00000000 P04:00001400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00071250 +PROCESSIDENT: 11 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00001300 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00071250 +PROCESSIDENT: 12 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 27 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00114500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207302 +TRANSFORMATION: OX:01140000 OY:00852000 OZ:00316250 XX:00000000 XY:00000000 XZ:-1000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00020000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00071250 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00071250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00114500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00114500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00015000 P02:00059265 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00020000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00071250 P13:00000000 P14:00007000 +PROCESSIDENT: 10 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 120 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00386777 +HEIGHT: 00010000 +WIDTH: 00114500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207304 +TRANSFORMATION: OX:01140000 OY:00737500 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00006250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00348889 P02:00006250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00386777 P02:00114500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00114500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00351014 P02:00057728 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00107500 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00386777 P13:00000000 P14:00007000 +PROCESSIDENT: 9 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 121 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00453277 +HEIGHT: 00010000 +WIDTH: 00190000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207307 +TRANSFORMATION: OX:01140000 OY:00547500 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00386777 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00453277 P02:00190000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00190000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00405010 P02:00097501 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00389227 P13:00000000 P14:00007000 +PROCESSIDENT: 7 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00183000 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00413202 P13:00000000 P14:00007000 +PROCESSIDENT: 8 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 28 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00141031 +HEIGHT: 00010000 +WIDTH: 00098450 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207341 +TRANSFORMATION: OX:00141031 OY:00852000 OZ:00316250 XX:-1000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00141031 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00141031 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00083781 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00083781 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00073281 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00073281 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00021281 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00021281 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00010781 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00010781 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00064814 P02:00083450 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00073450 +PROCESSIDENT: 15 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 30 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00142750 +HEIGHT: 00010000 +WIDTH: 00071250 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207351 +TRANSFORMATION: OX:00380250 OY:00852000 OZ:00316250 XX:-1000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00142750 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00142750 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00135500 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00135500 P02:00051250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00125000 P02:00051250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00125000 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00073000 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00073000 P02:00051250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00062500 P02:00051250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00062500 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00010500 P02:00071250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00010500 P02:00051250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00051250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00081618 P02:00056250 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00046250 +PROCESSIDENT: 17 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00135750 P02:00000000 P03:00000000 P04:00000600 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00046250 +PROCESSIDENT: 18 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 31 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00136469 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207369 +TRANSFORMATION: OX:00257500 OY:00852000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00222800 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00222800 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00061219 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00061219 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00071719 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00071719 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00116469 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00116469 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00136469 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00136469 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00098806 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00038806 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00129469 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00111500 P13:00000000 P14:00007000 +PROCESSIDENT: 18 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00250000 P02:00109469 P03:00000000 P04:00000800 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00046250 P13:00000000 P14:00007000 +PROCESSIDENT: 19 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00222800 P02:00020000 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00073450 P13:00000000 P14:00007000 +PROCESSIDENT: 20 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 32 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00111500 +HEIGHT: 00010000 +WIDTH: 00100000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207372 +TRANSFORMATION: OX:00357500 OY:00852000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00111500 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00111500 P02:00100000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00100000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00096500 P02:00050000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00093000 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00111500 P13:00000000 P14:00007000 +PROCESSIDENT: 7 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00111500 P13:00000000 P14:00007000 +PROCESSIDENT: 8 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 33 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00152334 +HEIGHT: 00010000 +WIDTH: 00098450 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207379 +TRANSFORMATION: OX:00584600 OY:00852000 OZ:00316250 XX:-1000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00152334 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00152334 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00141834 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00141834 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00115850 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00115850 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00105350 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00105350 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00089850 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00089850 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00079350 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00079350 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00027350 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00027350 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00016850 P02:00078450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00016850 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00098450 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00068267 P02:00083450 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00073450 +PROCESSIDENT: 21 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00145334 P02:00000000 P03:00000000 P04:00000600 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00073450 +PROCESSIDENT: 22 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 34 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00102900 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207383 +TRANSFORMATION: OX:00460400 OY:00852000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00250000 P02:00022750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00022750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00074766 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00222800 P02:00074766 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00222800 P02:00102900 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00102900 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00050362 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00111500 P13:00000000 P14:00007000 +PROCESSIDENT: 13 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00222800 P02:00067766 P03:00000000 P04:00000800 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00073450 P13:00000000 P14:00007000 +PROCESSIDENT: 14 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00250000 P02:00022750 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00046250 P13:00000000 P14:00007000 +PROCESSIDENT: 15 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 35 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00106250 +HEIGHT: 00010000 +WIDTH: 00207750 +COLOUR: R:180 G: 30 B: 30 A:100 +UID: 2207402 +TRANSFORMATION: OX:01005250 OY:00852000 OZ:00210000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00106250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00106250 P02:00009750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00086250 P02:00009750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00086250 P02:00020250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00106250 P02:00020250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00106250 P02:00072250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00086250 P02:00072250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00086250 P02:00082750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00106250 P02:00082750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00106250 P02:00134750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00086250 P02:00134750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00086250 P02:00145250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00106250 P02:00145250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00106250 P02:00197250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00086250 P02:00197250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00086250 P02:00207750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00207750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00091250 P02:00103680 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00200750 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00081250 P13:00000000 P14:00007000 +PROCESSIDENT: 21 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00081250 P13:00000000 P14:00007000 +PROCESSIDENT: 22 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 36 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00257900 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207406 +TRANSFORMATION: OX:00822500 OY:00852000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00222800 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00222800 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00055150 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00055150 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00065650 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00065650 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00117650 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00117650 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00128150 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00128150 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00141150 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00141150 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00151650 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00151650 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00180150 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00180150 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00190650 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00190650 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00232900 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00215000 P02:00232900 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00215000 P02:00257900 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00257900 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00157599 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00097599 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00250900 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00146500 P13:00000000 P14:00007000 +PROCESSIDENT: 28 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00215000 P02:00225900 P03:00000000 P04:00000800 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00081250 P13:00000000 P14:00007000 +PROCESSIDENT: 31 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00222800 P02:00020000 P03:00000000 P04:00000400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00073450 P13:00000000 P14:00007000 +PROCESSIDENT: 32 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 37 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00146500 +HEIGHT: 00010000 +WIDTH: 00160000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207409 +TRANSFORMATION: OX:00982500 OY:00852000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00146500 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00146500 P02:00160000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00160000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00131500 P02:00080000 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00153000 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00146500 P13:00000000 P14:00007000 +PROCESSIDENT: 7 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00146500 P13:00000000 P14:00007000 +PROCESSIDENT: 8 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 122 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00346702 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207413 +TRANSFORMATION: OX:01150000 OY:00852000 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00022397 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00022397 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00032897 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00032897 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00076265 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00076265 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00309510 P02:00124322 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00343972 P13:00000000 P14:00007000 +PROCESSIDENT: 13 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 123 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00346702 +HEIGHT: 00010000 +WIDTH: 00087500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207415 +TRANSFORMATION: OX:00900000 OY:00852000 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00046029 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00046029 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00056279 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00056279 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00087500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00087500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00328202 P02:00038670 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00080500 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00343972 P13:00000000 P14:00007000 +PROCESSIDENT: 11 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00324750 P13:00000000 P14:00007000 +PROCESSIDENT: 12 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 124 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00140000 +HEIGHT: 00010000 +WIDTH: 00081702 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207426 +TRANSFORMATION: OX:00442500 OY:00852000 OZ:00586250 XX:01000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00003500 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00031074 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00031074 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00041574 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00041574 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00095191 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00095191 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00105691 P02:00016952 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00105691 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00140000 P02:00003500 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00140000 P02:00081702 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00081702 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00003500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00070049 P02:00018500 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00002730 P03:00000000 P04:00001300 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00078972 +PROCESSIDENT: 15 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00133000 P02:00002730 P03:00000000 P04:00001400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00078972 +PROCESSIDENT: 16 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 125 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00346702 +HEIGHT: 00010000 +WIDTH: 00250000 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207430 +TRANSFORMATION: OX:00812500 OY:00852000 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00265000 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00020000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00039309 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00039309 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00049809 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00049809 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00103427 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00103427 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00113927 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00113927 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00167544 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00167544 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00178044 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00178044 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00231662 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00231662 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00329750 P02:00242162 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00242162 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00250000 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00250000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00328202 P02:00126792 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00243000 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00324750 P13:00000000 P14:00007000 +PROCESSIDENT: 26 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00126500 P13:00000000 P14:00007000 +PROCESSIDENT: 27 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00265000 P02:00020000 P03:00000000 P04:00000600 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00078972 P13:00000000 P14:00007000 +PROCESSIDENT: 28 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 126 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00100000 +HEIGHT: 00010000 +WIDTH: 00126500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207433 +TRANSFORMATION: OX:00562500 OY:00852000 OZ:00447750 XX:-1000000 XY:00000000 XZ:00000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00100000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00100000 P02:00126500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00126500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00049951 P02:00111500 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00001300 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00126500 +PROCESSIDENT: 7 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00093000 P02:00000000 P03:00000000 P04:00001400 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00007000 P13:00000000 P14:00126500 +PROCESSIDENT: 8 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 127 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00346702 +HEIGHT: 00010000 +WIDTH: 00217103 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2207436 +TRANSFORMATION: OX:00217103 OY:00852000 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00324510 P02:00173735 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00173735 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00343202 P02:00217103 P03:00000000 P06:000-1929 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00217103 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00309510 P02:00108897 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00210103 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00324750 P13:00000000 P14:00007000 +PROCESSIDENT: 9 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 38 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00553327 +HEIGHT: 00010000 +WIDTH: 00240000 +COLOUR: R:180 G: 30 B: 30 A:100 +UID: 2218945 +TRANSFORMATION: OX:01140000 OY:00142500 OZ:00245000 XX:00000000 XY:00000000 XZ:01000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00553327 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00538452 P02:00042500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00512160 P02:00042500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00512160 P02:00059250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00480327 P02:00059250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00480327 P02:00076000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00526727 P02:00076000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00469327 P02:00240000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00240000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00496363 P02:00117349 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00553327 P13:00000000 P14:00007000 +PROCESSIDENT: 13 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00233000 P03:00000000 P04:00001100 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00471777 P13:00000000 P14:00007000 +PROCESSIDENT: 14 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 128 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00370327 +HEIGHT: 00010000 +WIDTH: 00067500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2244504 +TRANSFORMATION: OX:00382500 OY:00010000 OZ:00321250 XX:00000000 XY:00000000 XZ:01000000 YX:01000000 YY:00000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00370327 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00346702 P02:00067500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00067500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00342500 P02:00034098 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000700 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00370327 P13:00000000 P14:00007000 +PROCESSIDENT: 7 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 39 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00185500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2252117 +TRANSFORMATION: OX:00787000 OY:00535000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:-1000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00025500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00025500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00185500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00185500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00091287 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00088292 P02:00079000 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00033731 +PROCESSIDENT: 9 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00107250 P02:00106731 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00033731 +PROCESSIDENT: 10 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00126208 P02:00134462 P03:00000000 P04:00000000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00033731 +PROCESSIDENT: 11 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00145167 P02:00162192 P03:00000000 P04:00000800 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00007000 P12:00010000 P13:00000000 P14:00023308 +PROCESSIDENT: 12 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00178500 P03:00000000 P04:00000900 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00125167 P13:00000000 P14:00007000 +PROCESSIDENT: 13 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00194125 P02:00178500 P03:00000000 P04:00001000 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00127125 P13:00000000 P14:00007000 +PROCESSIDENT: 14 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +[PART] +SINGLEMEMBERNUMBER: 40 +ASSEMBLYNUMBER: " " +ORDERNUMBER: 0 +DESIGNATION: " " +ANNOTATION: " " +STOREY: " " +GROUP: " " +PACKAGE: " " +MATERIAL: " " +TIMBERGRADE: " " +QUALITYGRADE: " " +COUNT: 1 +LENGTH: 00321250 +HEIGHT: 00010000 +WIDTH: 00185500 +COLOUR: R:168 G:115 B: 0 A:100 +UID: 2405733 +TRANSFORMATION: OX:00972500 OY:00535000 OZ:000-5000 XX:00000000 XY:00000000 XZ:01000000 YX:00000000 YY:01000000 YZ:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000000 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00020250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00020250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00030750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00030750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00082750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00082750 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00093250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00093250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00321250 P02:00145250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00145250 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00301250 P02:00185500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00185500 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +OUTLINE: SIDE: 3 PROCESS: YES P01:00000000 P02:00000000 P03:00000000 P06:00000000 P08:00000100 P10:00000000 P11:00000000 P12:00000000 +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00122601 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 1 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-040-3 +PROCESSPARAMETERS: P01:00306250 P02:00062601 P03:00000000 P06:00009000 P07:00009000 P11:00010000 P12:00004000 +PROCESSIDENT: 2 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Foro" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00000000 P02:00000000 P03:00000000 P04:00000500 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00125167 P13:00000000 P14:00007000 +PROCESSIDENT: 18 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" +PROCESSKEY: 4-030-3 +PROCESSPARAMETERS: P01:00194125 P02:00000000 P03:00000000 P04:00000600 P06:00009000 P07:00009000 P08:00000000 P09:00000000 P10:00000000 P11:00002200 P12:00127125 P13:00000000 P14:00007000 +PROCESSIDENT: 19 +PROCESSINGQUALITY: AUTOMATIC +COMMENT: "Mezzolegno" diff --git a/ProgramData/EgtBeamWall/Projs/MacroTemplate.ini b/ProgramData/EgtBeamWall/Projs/MacroTemplate.ini new file mode 100644 index 0000000..4959064 --- /dev/null +++ b/ProgramData/EgtBeamWall/Projs/MacroTemplate.ini @@ -0,0 +1,19 @@ +-- %MACRO_NAME%.lua by EgalTech s.r.l. %DATE_TIME% +-- Macro + +-- Variabili predefinite +-- MACRO.W = beam width +-- MACRO.H = beam height +-- MACRO.L = beam length + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +print( 'Macro %MACRO_NAME% started') + +local vPar = {%vPar%} +local sPar = %sPar% + +MACRO.FEATUREID = EgtBeamAddProcess( %AddFeature%, vPar, sPar) \ No newline at end of file diff --git a/ProgramData/EgtBeamWall/Resources/Features/L010.png b/ProgramData/EgtBeamWall/Resources/Features/L010.png new file mode 100644 index 0000000..c19276f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L010.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L012.png b/ProgramData/EgtBeamWall/Resources/Features/L012.png new file mode 100644 index 0000000..88cc6a9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L012.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L012_.png b/ProgramData/EgtBeamWall/Resources/Features/L012_.png new file mode 100644 index 0000000..3ecc5da Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L012_.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L013.png b/ProgramData/EgtBeamWall/Resources/Features/L013.png new file mode 100644 index 0000000..b98a6f0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L013.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L016.png b/ProgramData/EgtBeamWall/Resources/Features/L016.png new file mode 100644 index 0000000..a4d6c4c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L016.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L017.png b/ProgramData/EgtBeamWall/Resources/Features/L017.png new file mode 100644 index 0000000..01b4852 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L017.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L020.png b/ProgramData/EgtBeamWall/Resources/Features/L020.png new file mode 100644 index 0000000..1a89458 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L020.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L030.png b/ProgramData/EgtBeamWall/Resources/Features/L030.png new file mode 100644 index 0000000..dd26f83 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L030.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L031.png b/ProgramData/EgtBeamWall/Resources/Features/L031.png new file mode 100644 index 0000000..9a0d107 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L031.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L032.png b/ProgramData/EgtBeamWall/Resources/Features/L032.png new file mode 100644 index 0000000..a71576d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L032.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L033.png b/ProgramData/EgtBeamWall/Resources/Features/L033.png new file mode 100644 index 0000000..5301f63 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L033.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L034.png b/ProgramData/EgtBeamWall/Resources/Features/L034.png new file mode 100644 index 0000000..f872022 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L034.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L036.png b/ProgramData/EgtBeamWall/Resources/Features/L036.png new file mode 100644 index 0000000..032775a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L036.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L037.png b/ProgramData/EgtBeamWall/Resources/Features/L037.png new file mode 100644 index 0000000..547280d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L037.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L038.png b/ProgramData/EgtBeamWall/Resources/Features/L038.png new file mode 100644 index 0000000..530331d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L038.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L039.png b/ProgramData/EgtBeamWall/Resources/Features/L039.png new file mode 100644 index 0000000..93986df Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L039.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L040.png b/ProgramData/EgtBeamWall/Resources/Features/L040.png new file mode 100644 index 0000000..a59bf04 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L040.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L050.png b/ProgramData/EgtBeamWall/Resources/Features/L050.png new file mode 100644 index 0000000..dad5bb0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L050.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L051.png b/ProgramData/EgtBeamWall/Resources/Features/L051.png new file mode 100644 index 0000000..86b1532 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L051.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L052.png b/ProgramData/EgtBeamWall/Resources/Features/L052.png new file mode 100644 index 0000000..9faf853 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L052.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L053.png b/ProgramData/EgtBeamWall/Resources/Features/L053.png new file mode 100644 index 0000000..c3f5708 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L053.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L055.png b/ProgramData/EgtBeamWall/Resources/Features/L055.png new file mode 100644 index 0000000..1eb76b0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L055.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L056.png b/ProgramData/EgtBeamWall/Resources/Features/L056.png new file mode 100644 index 0000000..e7c35f5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L056.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L060.png b/ProgramData/EgtBeamWall/Resources/Features/L060.png new file mode 100644 index 0000000..48081da Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L060.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L080.png b/ProgramData/EgtBeamWall/Resources/Features/L080.png new file mode 100644 index 0000000..f2f1da3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L080.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L090.png b/ProgramData/EgtBeamWall/Resources/Features/L090.png new file mode 100644 index 0000000..2a24594 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L090.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L100.png b/ProgramData/EgtBeamWall/Resources/Features/L100.png new file mode 100644 index 0000000..096fa0a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L100.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L101.png b/ProgramData/EgtBeamWall/Resources/Features/L101.png new file mode 100644 index 0000000..ae51843 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L101.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L102.png b/ProgramData/EgtBeamWall/Resources/Features/L102.png new file mode 100644 index 0000000..0ecf62a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L102.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L103.png b/ProgramData/EgtBeamWall/Resources/Features/L103.png new file mode 100644 index 0000000..0a8df0a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L103.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L104.png b/ProgramData/EgtBeamWall/Resources/Features/L104.png new file mode 100644 index 0000000..fa0a0cb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L104.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L106.png b/ProgramData/EgtBeamWall/Resources/Features/L106.png new file mode 100644 index 0000000..7956be4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L106.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L136.png b/ProgramData/EgtBeamWall/Resources/Features/L136.png new file mode 100644 index 0000000..4e5aeab Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L136.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L138.png b/ProgramData/EgtBeamWall/Resources/Features/L138.png new file mode 100644 index 0000000..179091b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L138.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L250M.png b/ProgramData/EgtBeamWall/Resources/Features/L250M.png new file mode 100644 index 0000000..3099d05 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L250M.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/L251M.png b/ProgramData/EgtBeamWall/Resources/Features/L251M.png new file mode 100644 index 0000000..7efeaeb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/L251M.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P001.png b/ProgramData/EgtBeamWall/Resources/Features/P001.png new file mode 100644 index 0000000..354c1db Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P001.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P002.png b/ProgramData/EgtBeamWall/Resources/Features/P002.png new file mode 100644 index 0000000..f6dc857 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P002.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P003.png b/ProgramData/EgtBeamWall/Resources/Features/P003.png new file mode 100644 index 0000000..b5fab08 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P003.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P004.png b/ProgramData/EgtBeamWall/Resources/Features/P004.png new file mode 100644 index 0000000..303c318 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P004.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P005.png b/ProgramData/EgtBeamWall/Resources/Features/P005.png new file mode 100644 index 0000000..ee6b0b5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P005.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P006.png b/ProgramData/EgtBeamWall/Resources/Features/P006.png new file mode 100644 index 0000000..ac411e9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P006.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P008.png b/ProgramData/EgtBeamWall/Resources/Features/P008.png new file mode 100644 index 0000000..f870467 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P008.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P009.png b/ProgramData/EgtBeamWall/Resources/Features/P009.png new file mode 100644 index 0000000..331642e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P009.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P010.png b/ProgramData/EgtBeamWall/Resources/Features/P010.png new file mode 100644 index 0000000..bbb03c6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P010.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P011.png b/ProgramData/EgtBeamWall/Resources/Features/P011.png new file mode 100644 index 0000000..4e468a0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P011.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P012.png b/ProgramData/EgtBeamWall/Resources/Features/P012.png new file mode 100644 index 0000000..2c95541 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P012.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P013.png b/ProgramData/EgtBeamWall/Resources/Features/P013.png new file mode 100644 index 0000000..dad5bb0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P013.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P014.png b/ProgramData/EgtBeamWall/Resources/Features/P014.png new file mode 100644 index 0000000..7345d7d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P014.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P015.png b/ProgramData/EgtBeamWall/Resources/Features/P015.png new file mode 100644 index 0000000..1e896e4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P015.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P016.png b/ProgramData/EgtBeamWall/Resources/Features/P016.png new file mode 100644 index 0000000..b7b5dee Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P016.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P017.png b/ProgramData/EgtBeamWall/Resources/Features/P017.png new file mode 100644 index 0000000..07ab520 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P017.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P018.png b/ProgramData/EgtBeamWall/Resources/Features/P018.png new file mode 100644 index 0000000..f23fcb7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P018.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P019.png b/ProgramData/EgtBeamWall/Resources/Features/P019.png new file mode 100644 index 0000000..ab12ace Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P019.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P020.png b/ProgramData/EgtBeamWall/Resources/Features/P020.png new file mode 100644 index 0000000..d886305 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P020.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P021.png b/ProgramData/EgtBeamWall/Resources/Features/P021.png new file mode 100644 index 0000000..7f86a37 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P021.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P022.png b/ProgramData/EgtBeamWall/Resources/Features/P022.png new file mode 100644 index 0000000..0882e18 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P022.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P023.png b/ProgramData/EgtBeamWall/Resources/Features/P023.png new file mode 100644 index 0000000..d18e040 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P023.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P024.png b/ProgramData/EgtBeamWall/Resources/Features/P024.png new file mode 100644 index 0000000..82ca0e3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P024.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P025.png b/ProgramData/EgtBeamWall/Resources/Features/P025.png new file mode 100644 index 0000000..300e708 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P025.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P027.png b/ProgramData/EgtBeamWall/Resources/Features/P027.png new file mode 100644 index 0000000..691442b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P027.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P028.png b/ProgramData/EgtBeamWall/Resources/Features/P028.png new file mode 100644 index 0000000..d796c60 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P028.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/P029.png b/ProgramData/EgtBeamWall/Resources/Features/P029.png new file mode 100644 index 0000000..f931593 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/P029.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T010.png b/ProgramData/EgtBeamWall/Resources/Features/T010.png new file mode 100644 index 0000000..087e199 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T010.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T011.png b/ProgramData/EgtBeamWall/Resources/Features/T011.png new file mode 100644 index 0000000..a6083c8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T011.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T030.png b/ProgramData/EgtBeamWall/Resources/Features/T030.png new file mode 100644 index 0000000..672ac7f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T030.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T035.png b/ProgramData/EgtBeamWall/Resources/Features/T035.png new file mode 100644 index 0000000..d0c20ca Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T035.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T050.png b/ProgramData/EgtBeamWall/Resources/Features/T050.png new file mode 100644 index 0000000..a0e4c68 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T050.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T055.png b/ProgramData/EgtBeamWall/Resources/Features/T055.png new file mode 100644 index 0000000..76915dd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T055.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T070.png b/ProgramData/EgtBeamWall/Resources/Features/T070.png new file mode 100644 index 0000000..6643f8c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T070.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T071.png b/ProgramData/EgtBeamWall/Resources/Features/T071.png new file mode 100644 index 0000000..510313c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T071.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T080.png b/ProgramData/EgtBeamWall/Resources/Features/T080.png new file mode 100644 index 0000000..69a99a2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T080.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T136.png b/ProgramData/EgtBeamWall/Resources/Features/T136.png new file mode 100644 index 0000000..e7eb146 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T136.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Features/T138.png b/ProgramData/EgtBeamWall/Resources/Features/T138.png new file mode 100644 index 0000000..73fb34d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Features/T138.png differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P01_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P01_0.gif new file mode 100644 index 0000000..b1002da Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P01_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P01_3.GIF new file mode 100644 index 0000000..b1002da Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P01_4.GIF new file mode 100644 index 0000000..b1002da Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P02_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P02_0.gif new file mode 100644 index 0000000..ab536e8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P02_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P02_3.GIF new file mode 100644 index 0000000..5d01d63 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P02_4.GIF new file mode 100644 index 0000000..331703e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P04_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P04_0.gif new file mode 100644 index 0000000..2f13ce5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P04_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P04_3.gif new file mode 100644 index 0000000..62dfaee Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P04_4.gif new file mode 100644 index 0000000..2f13ce5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P07_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P07_0.gif new file mode 100644 index 0000000..885fc80 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P07_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P07_3.GIF new file mode 100644 index 0000000..885fc80 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P07_4.GIF new file mode 100644 index 0000000..885fc80 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P11_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P11_0.gif new file mode 100644 index 0000000..44fc8f4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P11_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P11_3.GIF new file mode 100644 index 0000000..44fc8f4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P11_4.GIF new file mode 100644 index 0000000..44fc8f4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P12_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P12_0.gif new file mode 100644 index 0000000..8673cc7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P12_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P12_3.GIF new file mode 100644 index 0000000..8673cc7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P12_4.GIF new file mode 100644 index 0000000..8673cc7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P13_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P13_0.gif new file mode 100644 index 0000000..5811ac5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P13_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P13_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P13_3.gif new file mode 100644 index 0000000..5811ac5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P13_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P13_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P13_4.gif new file mode 100644 index 0000000..5811ac5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P13_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P14_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P14_0.gif new file mode 100644 index 0000000..e8ff68b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P14_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P14_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P14_3.gif new file mode 100644 index 0000000..e8ff68b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P14_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L010_P14_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P14_4.gif new file mode 100644 index 0000000..e8ff68b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L010_P14_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P01_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P01_0.gif new file mode 100644 index 0000000..0a867a2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P01_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P02_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P02_0.gif new file mode 100644 index 0000000..b12d214 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P02_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P04_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P04_0.gif new file mode 100644 index 0000000..f34b1ed Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P04_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P07_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P07_0.gif new file mode 100644 index 0000000..a83f43b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P07_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P09_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P09_0.gif new file mode 100644 index 0000000..e59d4cc Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P09_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P11_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P11_0.gif new file mode 100644 index 0000000..3a2328a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P11_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P12_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P12_0.gif new file mode 100644 index 0000000..eef9083 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P12_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P13_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P13_0.gif new file mode 100644 index 0000000..3ea62bf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P13_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P14_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P14_0.gif new file mode 100644 index 0000000..18c750f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P14_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P15_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P15_0.gif new file mode 100644 index 0000000..966b937 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P15_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L012_P16_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P16_0.gif new file mode 100644 index 0000000..03599c5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L012_P16_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P01_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P01_0.gif new file mode 100644 index 0000000..cbd3812 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P01_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P01_3.GIF new file mode 100644 index 0000000..cbd3812 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P01_4.GIF new file mode 100644 index 0000000..cbd3812 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P02_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P02_0.gif new file mode 100644 index 0000000..2c8cf25 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P02_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P02_3.GIF new file mode 100644 index 0000000..2c8cf25 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P02_4.GIF new file mode 100644 index 0000000..2c8cf25 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P03_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P03_0.gif new file mode 100644 index 0000000..359c42f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P03_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P03_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P03_3.GIF new file mode 100644 index 0000000..359c42f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P03_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P03_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P03_4.gif new file mode 100644 index 0000000..359c42f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P03_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P06_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P06_0.gif new file mode 100644 index 0000000..a5ff1d3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P06_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P06_3.GIF new file mode 100644 index 0000000..a5ff1d3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P06_4.GIF new file mode 100644 index 0000000..a5ff1d3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P07_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P07_0.gif new file mode 100644 index 0000000..93c79a0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P07_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P07_3.GIF new file mode 100644 index 0000000..93c79a0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P07_4.GIF new file mode 100644 index 0000000..93c79a0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P08_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P08_0.gif new file mode 100644 index 0000000..774d9d1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P08_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P08_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P08_3.GIF new file mode 100644 index 0000000..774d9d1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P08_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P08_4.GIF new file mode 100644 index 0000000..774d9d1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P11_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P11_0.gif new file mode 100644 index 0000000..b0bd7f0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P11_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P11_3.GIF new file mode 100644 index 0000000..b0bd7f0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P11_4.GIF new file mode 100644 index 0000000..b0bd7f0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P12_0.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P12_0.gif new file mode 100644 index 0000000..5d3203a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P12_0.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P12_3.GIF new file mode 100644 index 0000000..5d3203a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L013_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P12_4.GIF new file mode 100644 index 0000000..5d3203a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L013_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P01_3.GIF new file mode 100644 index 0000000..9fc7b9e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P01_4.GIF new file mode 100644 index 0000000..2755549 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P02_3.GIF new file mode 100644 index 0000000..c2d6ed6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P02_4.GIF new file mode 100644 index 0000000..a191f8a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P03_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P03_3.GIF new file mode 100644 index 0000000..21cd966 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P03_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P03_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P03_4.GIF new file mode 100644 index 0000000..9a1331b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P03_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P04_3.gif new file mode 100644 index 0000000..1471bfe Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P04_4.gif new file mode 100644 index 0000000..1471bfe Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P06_3.GIF new file mode 100644 index 0000000..a2eab21 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P06_4.GIF new file mode 100644 index 0000000..79b7f63 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P07_3.GIF new file mode 100644 index 0000000..39b895d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P07_4.GIF new file mode 100644 index 0000000..41aacdf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P08_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P08_3.GIF new file mode 100644 index 0000000..affc993 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P08_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P08_4.GIF new file mode 100644 index 0000000..affc993 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P09_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P09_3.GIF new file mode 100644 index 0000000..8412779 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P09_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P09_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P09_4.GIF new file mode 100644 index 0000000..8412779 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P09_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P10_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P10_3.GIF new file mode 100644 index 0000000..57a0c88 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P10_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P10_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P10_4.GIF new file mode 100644 index 0000000..57a0c88 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P10_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P11_3.GIF new file mode 100644 index 0000000..806f42d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P11_4.GIF new file mode 100644 index 0000000..806f42d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P12_3.GIF new file mode 100644 index 0000000..b709fc5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P12_4.GIF new file mode 100644 index 0000000..b709fc5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P13_3.GIF new file mode 100644 index 0000000..e14e5f6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P13_4.GIF new file mode 100644 index 0000000..e14e5f6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P14_3.GIF new file mode 100644 index 0000000..9c82258 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P14_4.GIF new file mode 100644 index 0000000..9c82258 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P15_3.GIF new file mode 100644 index 0000000..148aca0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L016_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P15_4.GIF new file mode 100644 index 0000000..148aca0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L016_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P01_3.GIF new file mode 100644 index 0000000..e0f7dad Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P01_4.GIF new file mode 100644 index 0000000..e7fce42 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P02_3.GIF new file mode 100644 index 0000000..d4b0784 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P02_4.GIF new file mode 100644 index 0000000..c2d28a6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P03_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P03_3.GIF new file mode 100644 index 0000000..8205234 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P03_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P03_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P03_4.GIF new file mode 100644 index 0000000..1b6fd00 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P03_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P06_3.GIF new file mode 100644 index 0000000..1e416fc Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P06_4.GIF new file mode 100644 index 0000000..426040e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P07_3.GIF new file mode 100644 index 0000000..6c2b0fa Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P07_4.GIF new file mode 100644 index 0000000..5f18013 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P08_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P08_3.GIF new file mode 100644 index 0000000..59ecd98 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P08_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P08_4.GIF new file mode 100644 index 0000000..6a26837 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P11_3.GIF new file mode 100644 index 0000000..ab81c35 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P11_4.GIF new file mode 100644 index 0000000..37633fa Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P12_3.GIF new file mode 100644 index 0000000..1c355c7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P12_4.GIF new file mode 100644 index 0000000..efe3baf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P13_3.GIF new file mode 100644 index 0000000..e0139be Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L017_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P13_4.GIF new file mode 100644 index 0000000..0241177 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L017_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P01_3.GIF new file mode 100644 index 0000000..87f21a1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P01_4.GIF new file mode 100644 index 0000000..87f21a1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P02_3.GIF new file mode 100644 index 0000000..060a525 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P02_4.GIF new file mode 100644 index 0000000..060a525 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P05_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P05_3.gif new file mode 100644 index 0000000..95cc5c8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P05_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P05_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P05_4.gif new file mode 100644 index 0000000..95cc5c8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P05_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P06_3.GIF new file mode 100644 index 0000000..7faf087 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P06_4.GIF new file mode 100644 index 0000000..9924290 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P07_3.GIF new file mode 100644 index 0000000..6ca011d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P07_4.GIF new file mode 100644 index 0000000..3ac203c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P08_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P08_3.GIF new file mode 100644 index 0000000..81caf69 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P08_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P08_4.GIF new file mode 100644 index 0000000..7725fe0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P09_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P09_3.GIF new file mode 100644 index 0000000..b611194 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P09_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P09_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P09_4.GIF new file mode 100644 index 0000000..0a2720d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P09_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P10_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P10_3.GIF new file mode 100644 index 0000000..b611194 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P10_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P10_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P10_4.GIF new file mode 100644 index 0000000..0a2720d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P10_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P11_3.GIF new file mode 100644 index 0000000..8109af3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P11_4.GIF new file mode 100644 index 0000000..10e89a2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P12_3.GIF new file mode 100644 index 0000000..b455827 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P12_4.GIF new file mode 100644 index 0000000..b455827 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P13_3.GIF new file mode 100644 index 0000000..ddce8dd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P13_4.GIF new file mode 100644 index 0000000..ddce8dd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P14_3.GIF new file mode 100644 index 0000000..2be3d53 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P14_4.GIF new file mode 100644 index 0000000..b55db4b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P15_3.GIF new file mode 100644 index 0000000..746a947 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L020_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P15_4.GIF new file mode 100644 index 0000000..b4d911f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L020_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P01_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P01_3.gif new file mode 100644 index 0000000..7cf12ad Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P01_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P01_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P01_4.gif new file mode 100644 index 0000000..d8da210 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P01_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P02_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P02_3.gif new file mode 100644 index 0000000..fc091f8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P02_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P02_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P02_4.gif new file mode 100644 index 0000000..d148739 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P02_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P05_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P05_3.gif new file mode 100644 index 0000000..95cc5c8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P05_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P05_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P05_4.gif new file mode 100644 index 0000000..c762bcc Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P05_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P06_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P06_3.gif new file mode 100644 index 0000000..fedce32 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P06_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P06_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P06_4.gif new file mode 100644 index 0000000..1330684 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P06_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P07_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P07_3.gif new file mode 100644 index 0000000..bf26350 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P07_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P07_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P07_4.gif new file mode 100644 index 0000000..71a5f17 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P07_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P08_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P08_3.gif new file mode 100644 index 0000000..4dbf455 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P08_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P08_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P08_4.gif new file mode 100644 index 0000000..73880fc Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P08_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P11_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P11_3.gif new file mode 100644 index 0000000..3cf5c2a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P11_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P11_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P11_4.gif new file mode 100644 index 0000000..7cc51db Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P11_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P14_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P14_3.gif new file mode 100644 index 0000000..169998a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P14_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P14_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P14_4.gif new file mode 100644 index 0000000..6c4a7d5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P14_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P15_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P15_3.gif new file mode 100644 index 0000000..5bb0919 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P15_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L025_P15_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P15_4.gif new file mode 100644 index 0000000..41794f3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L025_P15_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P01_3.GIF new file mode 100644 index 0000000..ad0bf8e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P01_4.GIF new file mode 100644 index 0000000..f95ab65 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P02_3.GIF new file mode 100644 index 0000000..0a74282 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P02_4.GIF new file mode 100644 index 0000000..8a5128c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P03_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P03_3.GIF new file mode 100644 index 0000000..37a06a9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P03_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P03_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P03_4.GIF new file mode 100644 index 0000000..52751ce Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P03_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P04_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P04_3.GIF new file mode 100644 index 0000000..597c8ef Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P04_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P04_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P04_4.GIF new file mode 100644 index 0000000..ba10c28 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P04_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P06_3.GIF new file mode 100644 index 0000000..fc52774 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P06_4.GIF new file mode 100644 index 0000000..fba1afb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P07_3.GIF new file mode 100644 index 0000000..e9a6417 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P07_4.GIF new file mode 100644 index 0000000..a9466ce Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P08_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P08_3.GIF new file mode 100644 index 0000000..ed911e2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P08_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P08_4.GIF new file mode 100644 index 0000000..364c36d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P09_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P09_3.GIF new file mode 100644 index 0000000..326d1be Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P09_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P09_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P09_4.GIF new file mode 100644 index 0000000..4c7c77e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P09_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P10_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P10_3.GIF new file mode 100644 index 0000000..55472a6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P10_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P10_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P10_4.GIF new file mode 100644 index 0000000..55183af Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P10_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P11_3.GIF new file mode 100644 index 0000000..5a195fc Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P11_4.GIF new file mode 100644 index 0000000..a5a80eb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P12_3.GIF new file mode 100644 index 0000000..c37899e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P12_4.GIF new file mode 100644 index 0000000..80d25ea Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P13_3.GIF new file mode 100644 index 0000000..1d48558 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P13_4.GIF new file mode 100644 index 0000000..619d8db Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P14_3.GIF new file mode 100644 index 0000000..8cccfce Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L030_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P14_4.GIF new file mode 100644 index 0000000..ebc1dd9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L030_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P01_3.GIF new file mode 100644 index 0000000..a82b4f5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P01_4.GIF new file mode 100644 index 0000000..02823ea Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P02_3.GIF new file mode 100644 index 0000000..961396e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P02_4.GIF new file mode 100644 index 0000000..4d1e5f1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P04_3.gif new file mode 100644 index 0000000..597c8ef Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P04_4.gif new file mode 100644 index 0000000..809c56d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P11_3.GIF new file mode 100644 index 0000000..aefc61d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P11_4.GIF new file mode 100644 index 0000000..2af0ad7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P12_3.GIF new file mode 100644 index 0000000..a804a5f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P12_4.GIF new file mode 100644 index 0000000..4180c1d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P13_3.GIF new file mode 100644 index 0000000..e70d189 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L032_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P13_4.GIF new file mode 100644 index 0000000..4180c1d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L032_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L033_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P01_3.GIF new file mode 100644 index 0000000..a3c0ceb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L033_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P01_4.GIF new file mode 100644 index 0000000..a3c0ceb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L033_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P06_3.GIF new file mode 100644 index 0000000..3a11889 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L033_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P06_4.GIF new file mode 100644 index 0000000..af39f1e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L033_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P11_3.GIF new file mode 100644 index 0000000..c7a5487 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L033_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P11_4.GIF new file mode 100644 index 0000000..c7a5487 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L033_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P12_3.GIF new file mode 100644 index 0000000..642bbd4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L033_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P12_4.GIF new file mode 100644 index 0000000..642bbd4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L033_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P13_3.GIF new file mode 100644 index 0000000..120c134 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L033_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P13_4.GIF new file mode 100644 index 0000000..120c134 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L033_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L034_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P01_3.GIF new file mode 100644 index 0000000..dbdc8b8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L034_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P01_4.GIF new file mode 100644 index 0000000..a7e749d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L034_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P11_3.GIF new file mode 100644 index 0000000..c696998 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L034_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P11_4.GIF new file mode 100644 index 0000000..6083ed7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L034_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P12_3.GIF new file mode 100644 index 0000000..a65a8ae Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L034_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P12_4.GIF new file mode 100644 index 0000000..5a1012c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L034_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L036_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P01_3.GIF new file mode 100644 index 0000000..1d60568 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L036_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P01_4.GIF new file mode 100644 index 0000000..b1b7060 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L036_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P04_3.gif new file mode 100644 index 0000000..e3fefcb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L036_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P04_4.gif new file mode 100644 index 0000000..e3fefcb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L036_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P11_3.GIF new file mode 100644 index 0000000..a429ad0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L036_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P11_4.GIF new file mode 100644 index 0000000..497dc6b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L036_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P12_3.GIF new file mode 100644 index 0000000..e4b8869 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L036_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P12_4.GIF new file mode 100644 index 0000000..b78fb9d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L036_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P15_3.GIF new file mode 100644 index 0000000..1b9ce8b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L036_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P15_4.GIF new file mode 100644 index 0000000..c6e4391 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L036_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P01_4.GIF new file mode 100644 index 0000000..a9bee03 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P03_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P03_4.gif new file mode 100644 index 0000000..4c4a07c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P03_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P04_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P04_4.GIF new file mode 100644 index 0000000..fc3cf35 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P04_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P05_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P05_4.gif new file mode 100644 index 0000000..687daeb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P05_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P08_4.GIF new file mode 100644 index 0000000..df0d5cf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P09_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P09_4.GIF new file mode 100644 index 0000000..d124b95 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P09_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P10_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P10_4.GIF new file mode 100644 index 0000000..60ddf4d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P10_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P11_4.GIF new file mode 100644 index 0000000..57da1fd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P12_4.GIF new file mode 100644 index 0000000..fa3ec72 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P13_4.GIF new file mode 100644 index 0000000..5e3460e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P14_4.GIF new file mode 100644 index 0000000..183c8d8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P15_4.GIF new file mode 100644 index 0000000..dbac2ff Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P16_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P16_4.gif new file mode 100644 index 0000000..082f32b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P16_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P17_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P17_4.gif new file mode 100644 index 0000000..d5624cd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P17_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P18_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P18_4.gif new file mode 100644 index 0000000..642b901 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P18_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L037_P19_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P19_4.gif new file mode 100644 index 0000000..0039307 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L037_P19_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P01_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P01_3.gif new file mode 100644 index 0000000..ef0b132 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P01_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P01_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P01_4.gif new file mode 100644 index 0000000..015adae Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P01_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P04_3.gif new file mode 100644 index 0000000..3c74537 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P04_4.gif new file mode 100644 index 0000000..d962dc6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P06_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P06_3.gif new file mode 100644 index 0000000..06c5d04 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P06_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P06_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P06_4.gif new file mode 100644 index 0000000..e60fc8d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P06_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P11_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P11_3.gif new file mode 100644 index 0000000..6456203 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P11_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P11_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P11_4.gif new file mode 100644 index 0000000..c4cb690 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P11_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P12_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P12_3.gif new file mode 100644 index 0000000..c33bcd4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P12_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P12_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P12_4.gif new file mode 100644 index 0000000..e668603 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P12_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P13_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P13_3.gif new file mode 100644 index 0000000..822ea2c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P13_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P13_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P13_4.gif new file mode 100644 index 0000000..5c0917e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P13_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P15_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P15_3.gif new file mode 100644 index 0000000..e14598b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P15_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L038_P15_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P15_4.gif new file mode 100644 index 0000000..59f7241 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L038_P15_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L039_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P01_4.GIF new file mode 100644 index 0000000..e41f202 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L039_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P02_4.GIF new file mode 100644 index 0000000..8c07937 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L039_P04_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P04_4.GIF new file mode 100644 index 0000000..5db6f43 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P04_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L039_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P06_4.GIF new file mode 100644 index 0000000..b87c1c2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L039_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P07_4.GIF new file mode 100644 index 0000000..898419c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L039_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P08_4.GIF new file mode 100644 index 0000000..32c3cbc Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L039_P10_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P10_4.GIF new file mode 100644 index 0000000..2de03fe Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P10_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L039_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P11_4.GIF new file mode 100644 index 0000000..0c15616 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L039_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P12_4.GIF new file mode 100644 index 0000000..28fb662 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L039_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P13_4.GIF new file mode 100644 index 0000000..2a731ad Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L039_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P01_3.GIF new file mode 100644 index 0000000..0c27255 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P01_4.GIF new file mode 100644 index 0000000..ca1e2c6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P02_3.GIF new file mode 100644 index 0000000..b4f7810 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P02_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P02_4.gif new file mode 100644 index 0000000..6f404c0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P02_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P03_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P03_3.GIF new file mode 100644 index 0000000..c3e31b8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P03_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P03_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P03_4.GIF new file mode 100644 index 0000000..3c3c32f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P03_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P06_3.GIF new file mode 100644 index 0000000..728d8f9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P06_4.GIF new file mode 100644 index 0000000..5804110 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P07_3.GIF new file mode 100644 index 0000000..828504a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P07_4.GIF new file mode 100644 index 0000000..1b670e6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P11_3.GIF new file mode 100644 index 0000000..2b013a6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P11_4.GIF new file mode 100644 index 0000000..f9af83b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P12_3.GIF new file mode 100644 index 0000000..0f50a6e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P12_4.GIF new file mode 100644 index 0000000..0f50a6e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_Q1_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_Q1_4.GIF new file mode 100644 index 0000000..265df15 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_Q1_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_Q3_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_Q3_3.GIF new file mode 100644 index 0000000..c39be24 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_Q3_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L040_Q3_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L040_Q3_4.GIF new file mode 100644 index 0000000..fac7b53 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L040_Q3_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P01_3.GIF new file mode 100644 index 0000000..a539e04 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P01_4.GIF new file mode 100644 index 0000000..3ee807c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P02_3.GIF new file mode 100644 index 0000000..dfb19a3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P02_4.GIF new file mode 100644 index 0000000..ea236c3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P03_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P03_3.GIF new file mode 100644 index 0000000..2bf883b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P03_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P03_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P03_4.gif new file mode 100644 index 0000000..06c48a4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P03_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P04_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P04_3.GIF new file mode 100644 index 0000000..4cc2f8b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P04_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P04_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P04_4.GIF new file mode 100644 index 0000000..4cc2f8b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P04_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P06_3.GIF new file mode 100644 index 0000000..344bf05 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P06_4.GIF new file mode 100644 index 0000000..999cf09 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P07_3.GIF new file mode 100644 index 0000000..fb14f53 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P07_4.GIF new file mode 100644 index 0000000..40bf9d5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P08_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P08_3.GIF new file mode 100644 index 0000000..751aae9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P08_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P08_4.GIF new file mode 100644 index 0000000..7be1d66 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P10_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P10_3.GIF new file mode 100644 index 0000000..35341e2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P10_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P10_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P10_4.GIF new file mode 100644 index 0000000..206c68d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P10_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P11_3.GIF new file mode 100644 index 0000000..da3b3a1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P11_4.GIF new file mode 100644 index 0000000..321ee71 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P12_3.GIF new file mode 100644 index 0000000..cfcd008 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P12_4.GIF new file mode 100644 index 0000000..bb38fc1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P13_3.GIF new file mode 100644 index 0000000..fb68ced Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P13_4.GIF new file mode 100644 index 0000000..bf119a6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P14_3.GIF new file mode 100644 index 0000000..88a74b8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P14_4.GIF new file mode 100644 index 0000000..42447be Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P15_3.GIF new file mode 100644 index 0000000..d2dbeff Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P15_4.GIF new file mode 100644 index 0000000..3440f16 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P16_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P16_3.GIF new file mode 100644 index 0000000..a9418a0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P16_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L050_P16_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P16_4.GIF new file mode 100644 index 0000000..af4c5f5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L050_P16_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P01_3.GIF new file mode 100644 index 0000000..ac14fe7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P01_4.GIF new file mode 100644 index 0000000..80decdc Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P02_3.GIF new file mode 100644 index 0000000..a5df1d3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P02_4.GIF new file mode 100644 index 0000000..1ddf778 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P04_3.gif new file mode 100644 index 0000000..4cc2f8b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P04_4.gif new file mode 100644 index 0000000..4cc2f8b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P06_3.GIF new file mode 100644 index 0000000..8912fc3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P06_4.GIF new file mode 100644 index 0000000..1496903 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P07_3.GIF new file mode 100644 index 0000000..5a44e2a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P07_4.GIF new file mode 100644 index 0000000..8bcc258 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P08_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P08_3.GIF new file mode 100644 index 0000000..5f017c0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P08_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P08_4.GIF new file mode 100644 index 0000000..2214165 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P10_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P10_3.gif new file mode 100644 index 0000000..35341e2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P10_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P10_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P10_4.gif new file mode 100644 index 0000000..35341e2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P10_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P11_3.GIF new file mode 100644 index 0000000..82f58a4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P11_4.GIF new file mode 100644 index 0000000..2204ae7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P12_3.GIF new file mode 100644 index 0000000..6583a47 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P12_4.GIF new file mode 100644 index 0000000..d9c11eb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P14_3.GIF new file mode 100644 index 0000000..2bc3048 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P14_4.GIF new file mode 100644 index 0000000..da56481 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P15_3.GIF new file mode 100644 index 0000000..349ab25 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L051_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P15_4.GIF new file mode 100644 index 0000000..1316ed3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L051_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L052_P05_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L052_P05_3.gif new file mode 100644 index 0000000..2856358 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L052_P05_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L052_P05_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L052_P05_4.gif new file mode 100644 index 0000000..2856358 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L052_P05_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L052_P09_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L052_P09_3.gif new file mode 100644 index 0000000..2856358 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L052_P09_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L052_P09_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L052_P09_4.gif new file mode 100644 index 0000000..2856358 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L052_P09_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L053_P09_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L053_P09_3.gif new file mode 100644 index 0000000..2856358 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L053_P09_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L053_P09_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L053_P09_4.gif new file mode 100644 index 0000000..2856358 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L053_P09_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P01_3.GIF new file mode 100644 index 0000000..762ace8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P01_4.GIF new file mode 100644 index 0000000..2b3390d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P02_3.GIF new file mode 100644 index 0000000..b91860b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P02_4.GIF new file mode 100644 index 0000000..4c50b85 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P03_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P03_3.GIF new file mode 100644 index 0000000..c9d8a00 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P03_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P03_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P03_4.GIF new file mode 100644 index 0000000..1a176b1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P03_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P04_3.gif new file mode 100644 index 0000000..2e28dde Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P04_4.gif new file mode 100644 index 0000000..2e28dde Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P05_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P05_3.GIF new file mode 100644 index 0000000..c23b97c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P05_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P05_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P05_4.GIF new file mode 100644 index 0000000..c23b97c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P05_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P06_3.GIF new file mode 100644 index 0000000..d0cb130 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P06_4.GIF new file mode 100644 index 0000000..002a39b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P07_3.GIF new file mode 100644 index 0000000..64414d0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P07_4.GIF new file mode 100644 index 0000000..9b282d9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P09_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P09_3.GIF new file mode 100644 index 0000000..9c2b8e2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P09_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P09_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P09_4.GIF new file mode 100644 index 0000000..9c2b8e2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P09_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P10_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P10_3.GIF new file mode 100644 index 0000000..2eae701 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P10_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P10_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P10_4.GIF new file mode 100644 index 0000000..2eae701 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P10_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P11_3.GIF new file mode 100644 index 0000000..a15e8ea Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P11_4.GIF new file mode 100644 index 0000000..a7316a1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P12_3.GIF new file mode 100644 index 0000000..85c71a0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P12_4.GIF new file mode 100644 index 0000000..1ac18e2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P13_3.GIF new file mode 100644 index 0000000..f519210 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P13_4.GIF new file mode 100644 index 0000000..103d6d8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P14_3.GIF new file mode 100644 index 0000000..9efd08f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P14_4.GIF new file mode 100644 index 0000000..79a67cf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P15_3.GIF new file mode 100644 index 0000000..72edf47 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L055_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P15_4.GIF new file mode 100644 index 0000000..72edf47 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L055_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P01_3.GIF new file mode 100644 index 0000000..4510f02 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P01_4.GIF new file mode 100644 index 0000000..7f56c5b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P02_3.GIF new file mode 100644 index 0000000..b98b054 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P02_4.GIF new file mode 100644 index 0000000..1f785a5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P03_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P03_3.gif new file mode 100644 index 0000000..f4790be Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P03_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P03_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P03_4.gif new file mode 100644 index 0000000..f4790be Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P03_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P04_3.gif new file mode 100644 index 0000000..6f97a25 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P04_4.gif new file mode 100644 index 0000000..2e28dde Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P05_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P05_3.gif new file mode 100644 index 0000000..c23b97c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P05_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P05_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P05_4.gif new file mode 100644 index 0000000..c23b97c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P05_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P06_3.GIF new file mode 100644 index 0000000..981b611 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P06_4.GIF new file mode 100644 index 0000000..228d60d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P07_3.GIF new file mode 100644 index 0000000..355af13 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P07_4.GIF new file mode 100644 index 0000000..233dede Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P08_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P08_3.GIF new file mode 100644 index 0000000..2eae701 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P08_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P08_4.GIF new file mode 100644 index 0000000..f6c5476 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P09_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P09_3.GIF new file mode 100644 index 0000000..9c2b8e2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P09_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P09_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P09_4.GIF new file mode 100644 index 0000000..97bbccb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P09_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P10_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P10_3.GIF new file mode 100644 index 0000000..2eae701 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P10_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P10_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P10_4.GIF new file mode 100644 index 0000000..2eae701 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P10_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P11_3.GIF new file mode 100644 index 0000000..1bc65c3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P11_4.GIF new file mode 100644 index 0000000..fda4a1c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P12_3.GIF new file mode 100644 index 0000000..85c71a0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P12_4.GIF new file mode 100644 index 0000000..85c71a0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P14_3.GIF new file mode 100644 index 0000000..9efd08f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P14_4.GIF new file mode 100644 index 0000000..9efd08f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P15_3.GIF new file mode 100644 index 0000000..82ec6c5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L056_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P15_4.GIF new file mode 100644 index 0000000..72edf47 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L056_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P01_3.GIF new file mode 100644 index 0000000..f8a1a3b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P01_4.GIF new file mode 100644 index 0000000..816b1b4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P02_3.GIF new file mode 100644 index 0000000..318ebc7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P02_4.GIF new file mode 100644 index 0000000..0893522 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P04_3.gif new file mode 100644 index 0000000..39d6ac1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P04_4.gif new file mode 100644 index 0000000..781fcd9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P06_3.GIF new file mode 100644 index 0000000..6672254 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P06_4.GIF new file mode 100644 index 0000000..c4eba52 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P07_3.GIF new file mode 100644 index 0000000..707f1c4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P07_4.GIF new file mode 100644 index 0000000..96d5474 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P11_3.GIF new file mode 100644 index 0000000..4bc8fb6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P11_4.GIF new file mode 100644 index 0000000..ff4f19a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P12_3.GIF new file mode 100644 index 0000000..437d100 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P12_4.GIF new file mode 100644 index 0000000..496520d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P13_3.GIF new file mode 100644 index 0000000..fb0b606 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P13_4.GIF new file mode 100644 index 0000000..7c78bb4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P15_3.GIF new file mode 100644 index 0000000..e616614 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L060_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P15_4.GIF new file mode 100644 index 0000000..e616614 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L060_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P01_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P01_3.gif new file mode 100644 index 0000000..9473040 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P01_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P01_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P01_4.gif new file mode 100644 index 0000000..9473040 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P01_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P02_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P02_3.gif new file mode 100644 index 0000000..9a4d18a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P02_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P02_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P02_4.gif new file mode 100644 index 0000000..9a4d18a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P02_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P03_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P03_3.gif new file mode 100644 index 0000000..f13d91a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P03_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P03_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P03_4.gif new file mode 100644 index 0000000..f13d91a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P03_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P06_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P06_3.gif new file mode 100644 index 0000000..ca22d2c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P06_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P06_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P06_4.gif new file mode 100644 index 0000000..ca22d2c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P06_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P09_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P09_3.gif new file mode 100644 index 0000000..7aa9d5e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P09_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P09_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P09_4.gif new file mode 100644 index 0000000..7aa9d5e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P09_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P10_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P10_3.gif new file mode 100644 index 0000000..e0a2f18 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P10_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P10_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P10_4.gif new file mode 100644 index 0000000..e0a2f18 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P10_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P11_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P11_3.gif new file mode 100644 index 0000000..4465da3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P11_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P11_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P11_4.gif new file mode 100644 index 0000000..4465da3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P11_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P12_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P12_3.gif new file mode 100644 index 0000000..5bf856f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P12_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P12_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P12_4.gif new file mode 100644 index 0000000..5bf856f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P12_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P13_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P13_3.gif new file mode 100644 index 0000000..f59bc23 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P13_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P13_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P13_4.gif new file mode 100644 index 0000000..f59bc23 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P13_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P15_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P15_3.gif new file mode 100644 index 0000000..82a3562 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P15_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L061_P15_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P15_4.gif new file mode 100644 index 0000000..82a3562 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L061_P15_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P01_3.GIF new file mode 100644 index 0000000..ad85ef9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P01_4.GIF new file mode 100644 index 0000000..bbad63e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P02_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P02_3.gif new file mode 100644 index 0000000..74b1c3a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P02_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P02_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P02_4.gif new file mode 100644 index 0000000..b31d09a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P02_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P04_3.gif new file mode 100644 index 0000000..139ceba Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P04_4.gif new file mode 100644 index 0000000..13b1b84 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P07_3.GIF new file mode 100644 index 0000000..b6cc1bd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P07_4.GIF new file mode 100644 index 0000000..bd88733 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P10_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P10_3.GIF new file mode 100644 index 0000000..8300335 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P10_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P10_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P10_4.GIF new file mode 100644 index 0000000..a0c2a9d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P10_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P11_3.GIF new file mode 100644 index 0000000..2c4d53e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P11_4.GIF new file mode 100644 index 0000000..301e9e1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P12_3.GIF new file mode 100644 index 0000000..2d2e925 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P12_4.GIF new file mode 100644 index 0000000..2412928 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P13_3.GIF new file mode 100644 index 0000000..4adca31 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P13_4.GIF new file mode 100644 index 0000000..f243a82 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P14_3.GIF new file mode 100644 index 0000000..2f7002a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P14_4.GIF new file mode 100644 index 0000000..2f7002a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P15_3.GIF new file mode 100644 index 0000000..deb8c30 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L080_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P15_4.GIF new file mode 100644 index 0000000..deb8c30 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L080_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L090_P01_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P01_3.gif new file mode 100644 index 0000000..2458416 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P01_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L090_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P01_4.GIF new file mode 100644 index 0000000..2dbf82d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L090_P04_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P04_3.GIF new file mode 100644 index 0000000..ab267cd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P04_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L090_P04_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P04_4.GIF new file mode 100644 index 0000000..7db684e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P04_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L090_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P11_3.GIF new file mode 100644 index 0000000..8988d25 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L090_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P11_4.GIF new file mode 100644 index 0000000..8988d25 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L090_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P12_3.GIF new file mode 100644 index 0000000..37f0f61 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L090_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P12_4.GIF new file mode 100644 index 0000000..37f0f61 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L090_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P01_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P01_3.gif new file mode 100644 index 0000000..490e16e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P01_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P01_4.GIF new file mode 100644 index 0000000..6d26797 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P03_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P03_3.GIF new file mode 100644 index 0000000..8ff25c8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P03_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P03_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P03_4.GIF new file mode 100644 index 0000000..eaa23e8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P03_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P06_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P06_3.GIF new file mode 100644 index 0000000..2d23478 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P06_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P06_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P06_4.GIF new file mode 100644 index 0000000..438e8b2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P06_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P07_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P07_3.GIF new file mode 100644 index 0000000..5c7a73d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P07_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P07_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P07_4.GIF new file mode 100644 index 0000000..ef0eca2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P07_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P08_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P08_3.GIF new file mode 100644 index 0000000..cd22095 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P08_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P08_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P08_4.GIF new file mode 100644 index 0000000..47fa3ce Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P08_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P11_3.GIF new file mode 100644 index 0000000..1086c35 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P11_4.GIF new file mode 100644 index 0000000..ffe9206 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P12_3.GIF new file mode 100644 index 0000000..656c7da Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L100_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P12_4.GIF new file mode 100644 index 0000000..82d516e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L100_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P01_3.GIF new file mode 100644 index 0000000..cf35dde Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P01_4.GIF new file mode 100644 index 0000000..ff2d1e0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P11_3.GIF new file mode 100644 index 0000000..8c75d83 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P11_4.GIF new file mode 100644 index 0000000..00d9848 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P12_3.GIF new file mode 100644 index 0000000..b9fdd50 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P12_4.GIF new file mode 100644 index 0000000..5f95c7f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P13_3.GIF new file mode 100644 index 0000000..185bf49 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P13_4.GIF new file mode 100644 index 0000000..63cb047 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P14_3.GIF new file mode 100644 index 0000000..2f4bbb0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P14_4.GIF new file mode 100644 index 0000000..6cc7710 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P15_3.GIF new file mode 100644 index 0000000..761464d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L101_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P15_4.GIF new file mode 100644 index 0000000..35be6d5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L101_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P01_3.GIF new file mode 100644 index 0000000..4121421 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P01_4.GIF new file mode 100644 index 0000000..26220b9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P11_3.GIF new file mode 100644 index 0000000..79a126b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P11_4.GIF new file mode 100644 index 0000000..36b1cf8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P12_3.GIF new file mode 100644 index 0000000..7439f25 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P12_4.GIF new file mode 100644 index 0000000..ffe98fc Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P13_3.GIF new file mode 100644 index 0000000..7a6ecfb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P13_4.GIF new file mode 100644 index 0000000..eaf1e03 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P14_3.GIF new file mode 100644 index 0000000..a9cd98e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P14_4.GIF new file mode 100644 index 0000000..58facdf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P15_3.GIF new file mode 100644 index 0000000..24dd646 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L102_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P15_4.GIF new file mode 100644 index 0000000..0f11521 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L102_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P01_3.GIF new file mode 100644 index 0000000..c818269 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P01_4.GIF new file mode 100644 index 0000000..275a7ca Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P10_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P10_3.GIF new file mode 100644 index 0000000..260fb86 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P10_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P10_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P10_4.GIF new file mode 100644 index 0000000..8810b56 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P10_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P11_3.GIF new file mode 100644 index 0000000..357dc61 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P11_4.GIF new file mode 100644 index 0000000..f8d39b2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P12_3.GIF new file mode 100644 index 0000000..e149c8d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P12_4.GIF new file mode 100644 index 0000000..2441454 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P13_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P13_3.GIF new file mode 100644 index 0000000..ef35645 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P13_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P13_4.GIF new file mode 100644 index 0000000..9c16f86 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P14_3.GIF new file mode 100644 index 0000000..225653d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P14_4.GIF new file mode 100644 index 0000000..074afa5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P15_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P15_3.gif new file mode 100644 index 0000000..3dd4fc9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P15_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L103_P15_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P15_4.gif new file mode 100644 index 0000000..e93560f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L103_P15_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L104_P01_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P01_3.gif new file mode 100644 index 0000000..42d6cf4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P01_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L104_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P01_4.GIF new file mode 100644 index 0000000..42d6cf4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L104_P11_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P11_3.gif new file mode 100644 index 0000000..f700d52 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P11_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L104_P11_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P11_4.gif new file mode 100644 index 0000000..f700d52 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P11_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L104_P12_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P12_3.gif new file mode 100644 index 0000000..bed025b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P12_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L104_P12_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P12_4.gif new file mode 100644 index 0000000..bed025b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L104_P12_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P01_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P01_3.gif new file mode 100644 index 0000000..7cdc94d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P01_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P01_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P01_4.gif new file mode 100644 index 0000000..163639c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P01_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P04_3.gif new file mode 100644 index 0000000..973400e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P04_4.gif new file mode 100644 index 0000000..f8a51a6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P09_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P09_3.gif new file mode 100644 index 0000000..662b1de Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P09_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P09_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P09_4.gif new file mode 100644 index 0000000..33cd980 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P09_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P10_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P10_3.gif new file mode 100644 index 0000000..ed0bd4a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P10_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P10_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P10_4.gif new file mode 100644 index 0000000..db7164a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P10_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P11_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P11_3.gif new file mode 100644 index 0000000..e1c6e4b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P11_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P11_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P11_4.gif new file mode 100644 index 0000000..ab30fba Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P11_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P12_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P12_3.gif new file mode 100644 index 0000000..5ead558 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P12_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P12_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P12_4.gif new file mode 100644 index 0000000..6470436 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P12_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P13_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P13_3.gif new file mode 100644 index 0000000..be0401c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P13_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P13_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P13_4.gif new file mode 100644 index 0000000..069e6ed Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P13_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P14_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P14_3.gif new file mode 100644 index 0000000..3f8e7b7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P14_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P14_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P14_4.gif new file mode 100644 index 0000000..86697fa Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P14_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P15_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P15_3.gif new file mode 100644 index 0000000..3f8ad33 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P15_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P15_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P15_4.gif new file mode 100644 index 0000000..2c26217 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P15_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P16_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P16_3.gif new file mode 100644 index 0000000..7922fd7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P16_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P16_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P16_4.gif new file mode 100644 index 0000000..0d03885 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P16_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P17_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P17_3.gif new file mode 100644 index 0000000..7d5c5d9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P17_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P17_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P17_4.gif new file mode 100644 index 0000000..3c6dbb5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P17_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P18_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P18_3.gif new file mode 100644 index 0000000..bfbea8c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P18_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P18_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P18_4.gif new file mode 100644 index 0000000..df07b5a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P18_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P19_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P19_3.gif new file mode 100644 index 0000000..70c7456 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P19_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P19_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P19_4.gif new file mode 100644 index 0000000..3eb2799 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P19_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P20_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P20_3.gif new file mode 100644 index 0000000..5af95fc Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P20_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P20_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P20_4.gif new file mode 100644 index 0000000..171b820 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P20_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P21_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P21_3.gif new file mode 100644 index 0000000..e7643d6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P21_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P21_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P21_4.gif new file mode 100644 index 0000000..e3dc22d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P21_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P22_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P22_3.gif new file mode 100644 index 0000000..ee83a92 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P22_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L106_P22_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P22_4.gif new file mode 100644 index 0000000..5d4227b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L106_P22_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P01_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P01_3.gif new file mode 100644 index 0000000..92116a2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P01_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P01_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P01_4.gif new file mode 100644 index 0000000..cabcf4b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P01_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P02_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P02_3.gif new file mode 100644 index 0000000..d9ec216 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P02_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P02_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P02_4.gif new file mode 100644 index 0000000..6ab7693 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P02_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P03_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P03_3.gif new file mode 100644 index 0000000..56e4a53 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P03_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P03_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P03_4.gif new file mode 100644 index 0000000..2de3136 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P03_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P11_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P11_3.gif new file mode 100644 index 0000000..908dd24 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P11_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P11_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P11_4.gif new file mode 100644 index 0000000..6e88b64 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P11_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P12_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P12_3.gif new file mode 100644 index 0000000..91e4232 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P12_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P12_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P12_4.gif new file mode 100644 index 0000000..0a0e271 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P12_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P13_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P13_3.gif new file mode 100644 index 0000000..e063832 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P13_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L107_P13_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P13_4.gif new file mode 100644 index 0000000..f2e464f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L107_P13_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L120_P01_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P01_4.gif new file mode 100644 index 0000000..dd0c0b3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P01_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L120_P02_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P02_4.gif new file mode 100644 index 0000000..6355d3c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P02_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L120_P03_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P03_4.gif new file mode 100644 index 0000000..809487c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P03_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L120_P10_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P10_4.gif new file mode 100644 index 0000000..2215699 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P10_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L120_P11_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P11_4.gif new file mode 100644 index 0000000..d19bcc9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P11_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L120_P12_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P12_4.gif new file mode 100644 index 0000000..2c2b56b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P12_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L120_P13_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P13_4.gif new file mode 100644 index 0000000..af39af0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P13_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L120_P14_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P14_4.gif new file mode 100644 index 0000000..da908de Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P14_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L120_P15_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P15_4.gif new file mode 100644 index 0000000..6a9b174 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P15_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L120_P16_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P16_4.gif new file mode 100644 index 0000000..2856358 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L120_P16_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P01_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P01_3.gif new file mode 100644 index 0000000..10065b4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P01_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P01_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P01_4.gif new file mode 100644 index 0000000..ec5368c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P01_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P02_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P02_3.gif new file mode 100644 index 0000000..7780086 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P02_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P02_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P02_4.gif new file mode 100644 index 0000000..ad0c35c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P02_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P03_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P03_3.gif new file mode 100644 index 0000000..6555155 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P03_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P03_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P03_4.gif new file mode 100644 index 0000000..effc647 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P03_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P04_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P04_3.gif new file mode 100644 index 0000000..7f09914 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P04_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P04_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P04_4.gif new file mode 100644 index 0000000..1410cfb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P04_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P05_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P05_3.gif new file mode 100644 index 0000000..9a87c13 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P05_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P05_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P05_4.gif new file mode 100644 index 0000000..943f636 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P05_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P06_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P06_3.gif new file mode 100644 index 0000000..4fca689 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P06_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P06_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P06_4.gif new file mode 100644 index 0000000..7c9aeb5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P06_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P07_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P07_3.gif new file mode 100644 index 0000000..f62b9d4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P07_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P07_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P07_4.gif new file mode 100644 index 0000000..ec2fe43 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P07_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P08_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P08_3.gif new file mode 100644 index 0000000..b6b7c33 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P08_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P08_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P08_4.gif new file mode 100644 index 0000000..1e5a2b3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P08_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P09_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P09_3.gif new file mode 100644 index 0000000..3726899 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P09_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P09_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P09_4.gif new file mode 100644 index 0000000..442239a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P09_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P11_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P11_3.gif new file mode 100644 index 0000000..6555155 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P11_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P11_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P11_4.gif new file mode 100644 index 0000000..25c3039 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P11_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P12_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P12_3.gif new file mode 100644 index 0000000..c6c4b54 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P12_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P12_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P12_4.gif new file mode 100644 index 0000000..c6c4b54 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P12_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P13_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P13_3.gif new file mode 100644 index 0000000..30db759 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P13_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P13_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P13_4.gif new file mode 100644 index 0000000..30db759 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P13_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P14_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P14_3.gif new file mode 100644 index 0000000..ba92cdd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P14_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P14_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P14_4.gif new file mode 100644 index 0000000..ba92cdd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P14_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P15_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P15_3.gif new file mode 100644 index 0000000..3745870 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P15_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P15_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P15_4.gif new file mode 100644 index 0000000..cf15d17 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P15_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P16_3.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P16_3.gif new file mode 100644 index 0000000..83c37f6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P16_3.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L136_P16_4.gif b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P16_4.gif new file mode 100644 index 0000000..83c37f6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L136_P16_4.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P01_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P01_3.GIF new file mode 100644 index 0000000..bc04011 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P01_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P01_4.GIF new file mode 100644 index 0000000..e2cf251 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P02_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P02_3.GIF new file mode 100644 index 0000000..802647e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P02_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P02_4.GIF new file mode 100644 index 0000000..da14092 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P03_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P03_3.GIF new file mode 100644 index 0000000..c4093a9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P03_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P03_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P03_4.GIF new file mode 100644 index 0000000..f75a306 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P03_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P04_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P04_3.GIF new file mode 100644 index 0000000..9fad432 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P04_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P04_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P04_4.GIF new file mode 100644 index 0000000..c465322 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P04_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P05_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P05_3.GIF new file mode 100644 index 0000000..039fd7d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P05_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P05_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P05_4.GIF new file mode 100644 index 0000000..30de9eb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P05_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P09_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P09_3.GIF new file mode 100644 index 0000000..c769dea Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P09_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P09_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P09_4.GIF new file mode 100644 index 0000000..42c8abb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P09_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P11_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P11_3.GIF new file mode 100644 index 0000000..eae42a4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P11_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P11_4.GIF new file mode 100644 index 0000000..0ec6843 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P12_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P12_3.GIF new file mode 100644 index 0000000..156a005 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P12_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P12_4.GIF new file mode 100644 index 0000000..453d93c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P14_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P14_3.GIF new file mode 100644 index 0000000..4ea11db Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P14_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P14_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P14_4.GIF new file mode 100644 index 0000000..dca8468 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P14_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P15_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P15_3.GIF new file mode 100644 index 0000000..1647218 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P15_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P15_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P15_4.GIF new file mode 100644 index 0000000..2e1d759 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P15_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P16_3.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P16_3.GIF new file mode 100644 index 0000000..a10f671 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P16_3.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/L138_P16_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P16_4.GIF new file mode 100644 index 0000000..a10f671 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/L138_P16_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P019_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P01_1.GIF new file mode 100644 index 0000000..17557d4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P019_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P01_2.GIF new file mode 100644 index 0000000..402d253 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P019_P02_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P02_1.GIF new file mode 100644 index 0000000..942e32f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P02_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P019_P02_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P02_2.GIF new file mode 100644 index 0000000..fb49750 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P02_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P019_P03_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P03_1.GIF new file mode 100644 index 0000000..2b04477 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P03_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P019_P03_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P03_2.GIF new file mode 100644 index 0000000..b880d30 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P03_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P019_P06_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P06_1.GIF new file mode 100644 index 0000000..a82b12a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P06_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P019_P06_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P06_2.GIF new file mode 100644 index 0000000..a72f4a4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P06_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P019_P07_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P07_1.GIF new file mode 100644 index 0000000..62927fa Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P07_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P019_P07_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P07_2.GIF new file mode 100644 index 0000000..0f2544f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P019_P07_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P025_P01_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P01_4.GIF new file mode 100644 index 0000000..02823ea Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P01_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P025_P02_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P02_4.GIF new file mode 100644 index 0000000..4d1e5f1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P02_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P025_P03_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P03_4.GIF new file mode 100644 index 0000000..710e46e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P03_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P025_P04_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P04_4.GIF new file mode 100644 index 0000000..a888ce7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P04_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P025_P11_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P11_4.GIF new file mode 100644 index 0000000..2af0ad7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P11_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P025_P12_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P12_4.GIF new file mode 100644 index 0000000..f76c9df Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P12_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P025_P13_4.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P13_4.GIF new file mode 100644 index 0000000..4180c1d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P025_P13_4.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P01_1.GIF new file mode 100644 index 0000000..a2be64d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P01_2.GIF new file mode 100644 index 0000000..1f2770c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P02_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P02_1.GIF new file mode 100644 index 0000000..4eb5205 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P02_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P02_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P02_2.GIF new file mode 100644 index 0000000..70be1f6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P02_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P03_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P03_1.GIF new file mode 100644 index 0000000..4c37073 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P03_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P03_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P03_2.GIF new file mode 100644 index 0000000..e04f61f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P03_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P04_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P04_1.GIF new file mode 100644 index 0000000..94661bf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P04_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P04_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P04_2.GIF new file mode 100644 index 0000000..1655987 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P04_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P05_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P05_1.GIF new file mode 100644 index 0000000..ba51689 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P05_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P05_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P05_2.GIF new file mode 100644 index 0000000..8c99244 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P05_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P11_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P11_1.GIF new file mode 100644 index 0000000..77146d3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P11_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P11_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P11_2.GIF new file mode 100644 index 0000000..1581773 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P11_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P12_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P12_1.GIF new file mode 100644 index 0000000..2263ed4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P12_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P12_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P12_2.GIF new file mode 100644 index 0000000..fd8ecb8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P12_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P13_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P13_1.GIF new file mode 100644 index 0000000..4db9b5c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P13_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P13_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P13_2.GIF new file mode 100644 index 0000000..ae0244a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P13_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P14_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P14_1.GIF new file mode 100644 index 0000000..2a5155c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P14_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P14_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P14_2.GIF new file mode 100644 index 0000000..66f6a17 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P14_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P15_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P15_1.GIF new file mode 100644 index 0000000..42e7089 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P15_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/P028_P15_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P15_2.GIF new file mode 100644 index 0000000..b82b3ad Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/P028_P15_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T010_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P01_1.GIF new file mode 100644 index 0000000..17557d4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T010_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P01_2.GIF new file mode 100644 index 0000000..402d253 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T010_P02_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P02_1.GIF new file mode 100644 index 0000000..942e32f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P02_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T010_P02_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P02_2.GIF new file mode 100644 index 0000000..fb49750 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P02_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T010_P03_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P03_1.GIF new file mode 100644 index 0000000..2b04477 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P03_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T010_P03_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P03_2.GIF new file mode 100644 index 0000000..b880d30 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P03_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T010_P06_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P06_1.GIF new file mode 100644 index 0000000..a82b12a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P06_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T010_P06_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P06_2.GIF new file mode 100644 index 0000000..a72f4a4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P06_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T010_P07_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P07_1.GIF new file mode 100644 index 0000000..62927fa Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P07_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T010_P07_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P07_2.GIF new file mode 100644 index 0000000..0f2544f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T010_P07_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P01_1.GIF new file mode 100644 index 0000000..fdb6785 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P01_2.GIF new file mode 100644 index 0000000..0c567f8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P02_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P02_1.GIF new file mode 100644 index 0000000..0107102 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P02_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P02_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P02_2.GIF new file mode 100644 index 0000000..bf3579c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P02_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P06_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P06_1.GIF new file mode 100644 index 0000000..d1b4c84 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P06_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P06_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P06_2.GIF new file mode 100644 index 0000000..12ac862 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P06_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P07_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P07_1.GIF new file mode 100644 index 0000000..521c68d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P07_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P07_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P07_2.GIF new file mode 100644 index 0000000..ab4b185 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P07_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P08_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P08_1.GIF new file mode 100644 index 0000000..e1bdcc1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P08_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P08_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P08_2.GIF new file mode 100644 index 0000000..104b58f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P08_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P09_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P09_1.GIF new file mode 100644 index 0000000..f786e87 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P09_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T011_P09_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P09_2.GIF new file mode 100644 index 0000000..02a16bb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T011_P09_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T030_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P01_2.GIF new file mode 100644 index 0000000..3433888 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T030_P02_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P02_2.GIF new file mode 100644 index 0000000..0ed104d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P02_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T030_P06_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P06_1.GIF new file mode 100644 index 0000000..4993545 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P06_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T030_P06_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P06_2.GIF new file mode 100644 index 0000000..fbc79c9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P06_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T030_P11_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P11_1.GIF new file mode 100644 index 0000000..c05c202 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P11_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T030_P11_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P11_2.GIF new file mode 100644 index 0000000..3927321 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P11_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T030_P12_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P12_1.GIF new file mode 100644 index 0000000..8519e5b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P12_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T030_P12_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P12_2.GIF new file mode 100644 index 0000000..abb02b2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P12_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T030_P13_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P13_1.GIF new file mode 100644 index 0000000..2ce5e16 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P13_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T030_P13_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P13_2.GIF new file mode 100644 index 0000000..96554be Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T030_P13_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T035_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P01_1.GIF new file mode 100644 index 0000000..761432a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T035_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P01_2.GIF new file mode 100644 index 0000000..2ecca8b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T035_P02_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P02_1.GIF new file mode 100644 index 0000000..321d1f2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P02_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T035_P02_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P02_2.GIF new file mode 100644 index 0000000..559ee65 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P02_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T035_P06_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P06_1.GIF new file mode 100644 index 0000000..defbdda Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P06_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T035_P06_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P06_2.GIF new file mode 100644 index 0000000..899efbf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P06_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T035_P13_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P13_1.GIF new file mode 100644 index 0000000..d8faab3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P13_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T035_P13_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P13_2.GIF new file mode 100644 index 0000000..d8faab3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T035_P13_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P01_1.GIF new file mode 100644 index 0000000..1e9ec53 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P01_2.GIF new file mode 100644 index 0000000..726f256 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P02_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P02_1.GIF new file mode 100644 index 0000000..72f1f95 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P02_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P02_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P02_2.GIF new file mode 100644 index 0000000..8bb53e3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P02_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P04_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P04_1.GIF new file mode 100644 index 0000000..d696c56 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P04_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P04_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P04_2.GIF new file mode 100644 index 0000000..d696c56 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P04_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P05_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P05_1.GIF new file mode 100644 index 0000000..153ec2f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P05_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P05_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P05_2.GIF new file mode 100644 index 0000000..153ec2f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P05_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P06_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P06_1.GIF new file mode 100644 index 0000000..6e20853 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P06_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P06_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P06_2.GIF new file mode 100644 index 0000000..b5579bf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P06_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P07_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P07_1.GIF new file mode 100644 index 0000000..3336c61 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P07_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P07_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P07_2.GIF new file mode 100644 index 0000000..966e2e8 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P07_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P08_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P08_1.GIF new file mode 100644 index 0000000..134c5c9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P08_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P08_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P08_2.GIF new file mode 100644 index 0000000..3359dfb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P08_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P10_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P10_1.GIF new file mode 100644 index 0000000..94bb561 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P10_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P10_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P10_2.GIF new file mode 100644 index 0000000..620ed89 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P10_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P11_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P11_1.GIF new file mode 100644 index 0000000..d100c29 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P11_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P11_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P11_2.GIF new file mode 100644 index 0000000..9316523 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P11_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P12_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P12_1.GIF new file mode 100644 index 0000000..3a08c6a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P12_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P12_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P12_2.GIF new file mode 100644 index 0000000..a5cf101 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P12_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P14_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P14_1.GIF new file mode 100644 index 0000000..177e8f7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P14_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P14_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P14_2.GIF new file mode 100644 index 0000000..26fc3ac Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P14_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P15_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P15_1.GIF new file mode 100644 index 0000000..7767e31 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P15_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T050_P15_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P15_2.GIF new file mode 100644 index 0000000..669b6ed Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T050_P15_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P01_1.GIF new file mode 100644 index 0000000..fc84a68 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P01_2.GIF new file mode 100644 index 0000000..818a8e0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P02_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P02_1.GIF new file mode 100644 index 0000000..9d025c7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P02_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P02_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P02_2.GIF new file mode 100644 index 0000000..3538210 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P02_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P04_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P04_1.gif new file mode 100644 index 0000000..e4620a2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P04_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P04_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P04_2.gif new file mode 100644 index 0000000..e4620a2 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P04_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P06_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P06_1.GIF new file mode 100644 index 0000000..ffef3c3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P06_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P06_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P06_2.GIF new file mode 100644 index 0000000..b0b127e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P06_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P07_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P07_1.GIF new file mode 100644 index 0000000..094fa92 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P07_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P07_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P07_2.GIF new file mode 100644 index 0000000..7d7a3bf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P07_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P08_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P08_1.GIF new file mode 100644 index 0000000..bb6778c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P08_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P08_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P08_2.GIF new file mode 100644 index 0000000..cd8a7bf Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P08_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P09_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P09_1.GIF new file mode 100644 index 0000000..97bbccb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P09_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P09_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P09_2.GIF new file mode 100644 index 0000000..97bbccb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P09_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P10_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P10_1.GIF new file mode 100644 index 0000000..2eae701 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P10_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P10_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P10_2.GIF new file mode 100644 index 0000000..2eae701 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P10_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P11_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P11_1.GIF new file mode 100644 index 0000000..d7771f6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P11_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P11_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P11_2.GIF new file mode 100644 index 0000000..9ae31c7 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P11_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P12_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P12_1.GIF new file mode 100644 index 0000000..85c71a0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P12_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P12_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P12_2.GIF new file mode 100644 index 0000000..85c71a0 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P12_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P14_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P14_1.GIF new file mode 100644 index 0000000..9efd08f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P14_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P14_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P14_2.GIF new file mode 100644 index 0000000..9efd08f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P14_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P15_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P15_1.GIF new file mode 100644 index 0000000..72edf47 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P15_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T055_P15_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P15_2.GIF new file mode 100644 index 0000000..72edf47 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T055_P15_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P01_1.GIF new file mode 100644 index 0000000..dd5e6ae Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P01_2.GIF new file mode 100644 index 0000000..74dec8d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P11_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P11_1.GIF new file mode 100644 index 0000000..3e59222 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P11_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P11_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P11_2.GIF new file mode 100644 index 0000000..e9340b9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P11_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P12_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P12_1.GIF new file mode 100644 index 0000000..ae57f54 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P12_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P12_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P12_2.GIF new file mode 100644 index 0000000..89de610 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P12_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P13_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P13_1.GIF new file mode 100644 index 0000000..4f17d94 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P13_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P13_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P13_2.GIF new file mode 100644 index 0000000..0be0ee1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P13_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P14_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P14_1.GIF new file mode 100644 index 0000000..0f56677 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P14_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P14_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P14_2.GIF new file mode 100644 index 0000000..4901602 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P14_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P15_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P15_1.GIF new file mode 100644 index 0000000..d2533ca Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P15_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T070_P15_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P15_2.GIF new file mode 100644 index 0000000..d2533ca Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T070_P15_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P01_1.GIF new file mode 100644 index 0000000..6d52168 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P01_2.GIF new file mode 100644 index 0000000..300f6a9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P07_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P07_1.GIF new file mode 100644 index 0000000..c6210d6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P07_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P07_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P07_2.GIF new file mode 100644 index 0000000..67463a9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P07_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P09_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P09_1.GIF new file mode 100644 index 0000000..18f6893 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P09_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P09_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P09_2.GIF new file mode 100644 index 0000000..95eb060 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P09_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P10_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P10_1.GIF new file mode 100644 index 0000000..01672cd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P10_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P10_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P10_2.GIF new file mode 100644 index 0000000..36b358f Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P10_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P11_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P11_1.GIF new file mode 100644 index 0000000..8e6db3e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P11_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P11_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P11_2.GIF new file mode 100644 index 0000000..6f3d074 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P11_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P12_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P12_1.GIF new file mode 100644 index 0000000..7b8873d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P12_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P12_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P12_2.gif new file mode 100644 index 0000000..706c272 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P12_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P13_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P13_1.GIF new file mode 100644 index 0000000..2493171 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P13_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P13_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P13_2.GIF new file mode 100644 index 0000000..51c342e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P13_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P14_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P14_1.GIF new file mode 100644 index 0000000..0f56677 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P14_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P14_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P14_2.GIF new file mode 100644 index 0000000..0f56677 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P14_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P15_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P15_1.GIF new file mode 100644 index 0000000..d2533ca Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P15_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T071_P15_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P15_2.GIF new file mode 100644 index 0000000..d2533ca Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T071_P15_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P01_1.GIF new file mode 100644 index 0000000..2104b56 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P01_2.GIF new file mode 100644 index 0000000..128ef31 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P04_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P04_1.gif new file mode 100644 index 0000000..6a7c90b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P04_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P04_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P04_2.gif new file mode 100644 index 0000000..6a7c90b Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P04_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P07_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P07_1.GIF new file mode 100644 index 0000000..df89c06 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P07_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P07_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P07_2.GIF new file mode 100644 index 0000000..193906e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P07_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P11_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P11_1.GIF new file mode 100644 index 0000000..4d29f88 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P11_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P11_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P11_2.GIF new file mode 100644 index 0000000..16667fb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P11_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P12_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P12_1.GIF new file mode 100644 index 0000000..33ee2db Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P12_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P12_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P12_2.GIF new file mode 100644 index 0000000..4106d74 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P12_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P14_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P14_1.GIF new file mode 100644 index 0000000..4c795b4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P14_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P14_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P14_2.GIF new file mode 100644 index 0000000..4c795b4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P14_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P15_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P15_1.GIF new file mode 100644 index 0000000..a247789 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P15_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T080_P15_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P15_2.GIF new file mode 100644 index 0000000..e723ff1 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T080_P15_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P01_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P01_1.gif new file mode 100644 index 0000000..10065b4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P01_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P01_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P01_2.gif new file mode 100644 index 0000000..ec5368c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P01_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P02_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P02_1.gif new file mode 100644 index 0000000..7780086 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P02_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P02_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P02_2.gif new file mode 100644 index 0000000..ad0c35c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P02_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P03_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P03_1.gif new file mode 100644 index 0000000..6555155 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P03_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P03_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P03_2.gif new file mode 100644 index 0000000..effc647 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P03_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P04_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P04_1.gif new file mode 100644 index 0000000..7f09914 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P04_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P04_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P04_2.gif new file mode 100644 index 0000000..1410cfb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P04_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P05_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P05_1.gif new file mode 100644 index 0000000..9a87c13 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P05_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P05_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P05_2.gif new file mode 100644 index 0000000..943f636 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P05_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P06_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P06_1.gif new file mode 100644 index 0000000..4fca689 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P06_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P06_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P06_2.gif new file mode 100644 index 0000000..7c9aeb5 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P06_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P07_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P07_1.gif new file mode 100644 index 0000000..f62b9d4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P07_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P07_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P07_2.gif new file mode 100644 index 0000000..ec2fe43 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P07_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P08_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P08_1.gif new file mode 100644 index 0000000..b6b7c33 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P08_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P08_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P08_2.gif new file mode 100644 index 0000000..1e5a2b3 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P08_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P09_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P09_1.gif new file mode 100644 index 0000000..3726899 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P09_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P09_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P09_2.gif new file mode 100644 index 0000000..442239a Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P09_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P11_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P11_1.gif new file mode 100644 index 0000000..6555155 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P11_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P11_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P11_2.gif new file mode 100644 index 0000000..25c3039 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P11_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P12_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P12_1.gif new file mode 100644 index 0000000..c6c4b54 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P12_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P12_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P12_2.gif new file mode 100644 index 0000000..c6c4b54 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P12_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P13_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P13_1.gif new file mode 100644 index 0000000..30db759 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P13_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P13_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P13_2.gif new file mode 100644 index 0000000..30db759 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P13_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P14_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P14_1.gif new file mode 100644 index 0000000..ba92cdd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P14_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P14_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P14_2.gif new file mode 100644 index 0000000..ba92cdd Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P14_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P15_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P15_1.gif new file mode 100644 index 0000000..3745870 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P15_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P15_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P15_2.gif new file mode 100644 index 0000000..cf15d17 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P15_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P16_1.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P16_1.gif new file mode 100644 index 0000000..83c37f6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P16_1.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T136_P16_2.gif b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P16_2.gif new file mode 100644 index 0000000..83c37f6 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T136_P16_2.gif differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P01_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P01_1.GIF new file mode 100644 index 0000000..bc04011 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P01_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P01_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P01_2.GIF new file mode 100644 index 0000000..e2cf251 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P01_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P02_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P02_1.GIF new file mode 100644 index 0000000..802647e Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P02_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P02_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P02_2.GIF new file mode 100644 index 0000000..da14092 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P02_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P03_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P03_1.GIF new file mode 100644 index 0000000..c4093a9 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P03_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P03_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P03_2.GIF new file mode 100644 index 0000000..f75a306 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P03_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P04_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P04_1.GIF new file mode 100644 index 0000000..9fad432 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P04_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P04_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P04_2.GIF new file mode 100644 index 0000000..c465322 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P04_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P05_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P05_1.GIF new file mode 100644 index 0000000..039fd7d Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P05_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P05_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P05_2.GIF new file mode 100644 index 0000000..30de9eb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P05_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P09_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P09_1.GIF new file mode 100644 index 0000000..c769dea Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P09_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P09_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P09_2.GIF new file mode 100644 index 0000000..42c8abb Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P09_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P11_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P11_1.GIF new file mode 100644 index 0000000..eae42a4 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P11_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P11_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P11_2.GIF new file mode 100644 index 0000000..0ec6843 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P11_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P12_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P12_1.GIF new file mode 100644 index 0000000..156a005 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P12_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P12_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P12_2.GIF new file mode 100644 index 0000000..453d93c Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P12_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P14_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P14_1.GIF new file mode 100644 index 0000000..4ea11db Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P14_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P14_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P14_2.GIF new file mode 100644 index 0000000..dca8468 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P14_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P15_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P15_1.GIF new file mode 100644 index 0000000..1647218 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P15_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P15_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P15_2.GIF new file mode 100644 index 0000000..2e1d759 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P15_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P16_1.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P16_1.GIF new file mode 100644 index 0000000..a10f671 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P16_1.GIF differ diff --git a/ProgramData/EgtBeamWall/Resources/Parameters/T138_P16_2.GIF b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P16_2.GIF new file mode 100644 index 0000000..a10f671 Binary files /dev/null and b/ProgramData/EgtBeamWall/Resources/Parameters/T138_P16_2.GIF differ diff --git a/ProgramData/EgtBeamWall/Temp/EgtBEAMWALL.ViewerOptimizerLog1.txt b/ProgramData/EgtBeamWall/Temp/EgtBEAMWALL.ViewerOptimizerLog1.txt new file mode 100644 index 0000000..46577f8 --- /dev/null +++ b/ProgramData/EgtBeamWall/Temp/EgtBEAMWALL.ViewerOptimizerLog1.txt @@ -0,0 +1,63 @@ +2022/05/19 12:02:02 Init +User DESKTOP-933NOPU\carlo (1) +EgtBEAMWALL.ViewerOptimizerR32.exe ver. 2.4e1 +EgtUILib.dll ver. 2.4e1 +EgtInterfaceR32.dll ver. 2.4d4 +EgtExecutorR32.dll ver. 2.4d4 +EgtGeneralR32.dll ver. 2.4d4 +EgtNumKernelR32.dll ver. 2.4d4 +EgtGeomKernelR32.dll ver. 2.4d4 +EgtGraphicsR32.dll ver. 2.4d4 +EgtExchangeR32.dll ver. 2.4e1 +EgtMachKernelR32.dll ver. 2.4d4 +EgtNestingR32.dll ver. 2.4d4 +Key 000335 (28620) +OS Ms Windows 8 64-bit +CPU Intel(R) Core(TM)2 Duo CPU T9400 @ 2.53GHz - 2 threads - MMX+SSE+SSE2 +Memory 4083 MB (virtual 6899 MB) +UserObj Managers : +EXePicture +EGkDefault +EXePhoto +EMkAxis +EMkDrilling +EMkDisposition +EMkCamData +EMkChiseling +EMkExit +EMkGenMachining +EMkMilling +EMkPocketing +EMkMortising +EMkSawFinishing +EMkSawing +EMkSawRoughing +EMkHead +EMkSurfFinishing +EMkTable +EMkTcPos +EMkWaterJetting +Lua 5.3 interpreter started +Require Library = EgtBase +EgtBase started +EgtConst started +EgtVector3d started +EgtPoint3d started +EgtFrame3d started +EgtBBox3d started +EgtColor3d started +KeyOptions : True 11 +Context 1 started +OpenGL 3.3.0 (Nw) NVIDIA Corporation Quadro FX 1700M/PCIe/SSE2 +GLSL 3.30 NVIDIA via Cg compiler +PixFmt 7 ICD BUFF2 RGBA32 Z24 +BeamMgr started +MachMgr started (C:\EgtData\Machines) +Exec File = C:\EgtData\Machines\Essetre-90480027\Wall\GetTs3Data.lua +cannot open C:\EgtData\Machines\Essetre-90480027\Wall\GetTs3Data.lua: No such file or directory +Error executing Ts3Data file C:\EgtData\Machines\Essetre-90480027\Wall\Ts3Data.lua +Exec File = C:\ProgramData\Egaltech\Progetto Restyling Wall\Wall\GetWallData.lua +cannot open C:\ProgramData\Egaltech\Progetto Restyling Wall\Wall\GetWallData.lua: No such file or directory +Error executing GetWallData script C:\ProgramData\Egaltech\Progetto Restyling Wall\Wall\GetWallData.lua +EvalExpr(number): Error not a number +EvalExpr(number): Error not a number diff --git a/ProgramData/EgtBeamWall/Warehouse/Basic.ini b/ProgramData/EgtBeamWall/Warehouse/Basic.ini new file mode 100644 index 0000000..18f19c3 --- /dev/null +++ b/ProgramData/EgtBeamWall/Warehouse/Basic.ini @@ -0,0 +1,29 @@ +; Commento per evitare BOM con UTF-8 +; Magazzino semplice +; L1 = L (Beam) +; S1 = W, L (Wall) + +[Beam] +CurrentL=4 +StartOffset=20 +Offset=8 +Quantity=112 +L1=3000 +L2=1100 +L3=3500 +L4=12000 +L5=6550 +L6=5400 + +[Wall] +CurrentS=7 +Kerf=120 +Offset=50 +Quantity=125 +S1=11000,1500 +S2=23,4 +S3=5,6 +S4=7,8 +S5=9,10 +S6=32,23 +S7=22,11 diff --git a/ProgramData/EgtBeamWall/Warehouse/Medium.ini b/ProgramData/EgtBeamWall/Warehouse/Medium.ini new file mode 100644 index 0000000..ffa4ea5 --- /dev/null +++ b/ProgramData/EgtBeamWall/Warehouse/Medium.ini @@ -0,0 +1,282 @@ +; Commento per evitare BOM con UTF-8 +; Magazzino intermedio +; 1 = W, H, Material (Beam) +; L1 = 1, L (Beam) +; 1 = H, Material (Wall) +; S1 = 1, W, L (Wall) + +[Beam_List] +1=160,300, +2=200,200, +3=400,400, +4=200,200, +5=400,400, +6=500,400, +7=600,280, +8=200,200, +9=400,400, +10=600,290, +11=200,200, +12=400,400, +13=600,300, +14=200,200, +15=400,400, +16=200,200, +17=400,400, +18=600,295, +19=196,200, +20=140,240, +21=100,180, +22=160,240, +23=480,200, +24=160,280, +25=100,140, +26=100,200, +27=320,200, +28=240,180, +29=200,180, +30=60,200, +31=200,60, +32=520,200, +33=200,520, +34=60,80, +35=99.9,80, +36=80,80, +37=60,120, +38=160,120, +39=100,240, +40=20,240, +41=240,200, +42=160,200, +43=60,160, +44=160,160, +45=65,80, +46=120,200, +47=200,240, +48=200,480, +49=60,155, +50=60,240, +51=100,160, +52=45,160, +53=76.2,50.8,Douglas fir +54=76.2,152.4,Douglas fir +55=76.2,203.2,Douglas fir +56=76.2,254,Douglas fir +57=76.2,289.13,Douglas fir +58=101.6,152.4,Douglas fir +59=101.6,254,Douglas fir +60=101.6,304.8,Douglas fir +61=101.6,355.6,Douglas fir +62=190.5,190.5,Douglas fir +63=203.2,203.2,Douglas fir +64=304.8,304.8,Douglas fir +65=140,200,GL24h +66=100,160,GL24h +67=880,240,GL24h +68=200,480,GL24h +69=140,200,BIL +70=140,180,BIL +71=140,180,BIL +72=140,180,BIL +73=140,180,BIL +74=140,180,BIL +75=140,180,BIL +76=140,180,BIL +77=140,180,BIL +78=140,180,BIL +79=140,180,BIL +80=140,180,BIL +81=140,180,BIL +82=140,180,BIL +83=140,180,BIL +84=140,180,BIL +85=140,180,BIL +86=140,180,BIL +87=140,180,BIL +88=140,180,BIL +89=140,180,BIL +90=140,180,BIL +91=140,180,BIL +92=140,180,BIL +93=140,180,BIL +94=140,180,BIL +95=140,180,BIL +96=160,200,BIL +97=300,100,CLT-X-Lam +98=797.12,100,CLT-X-Lam +99=975,100,CLT-X-Lam +100=850,100,CLT-X-Lam +101=275,100,CLT-X-Lam +102=400,100,CLT-X-Lam +103=605,100,CLT-X-Lam +104=506.86,100,CLT-X-Lam +105=864.88,100,CLT-X-Lam +106=254,254,Lamellare +107=101.6,254,Lamellare +108=76.2,152.4,Lamellare +109=76.2,76.2,Lamellare +110=120,120,UT- Abete Rosso +111=120,120, +112=390,400, +113=690,300, +114=350,250, +115=220,280,GL24h +116=254,127,Douglas fir +117=127,127,Douglas fir +118=127,254,Douglas fir + +[Beam] +StartOffset=10 +Offset=5.4 +L1=1,4000,20,1 +L2=20,12000,100,1 +L3=30,12000,100,1 +L4=55,12000,100,1 +L5=65,14000,100,1 +L6=65,12000,100,0 +L7=66,15000,100,1 +L8=107,15000,20,1 +L9=108,15000,10,1 +L10=109,15000,30,1 +L11=106,15000,5,1 +L12=116,8000,10,1 + +[Wall_List] +1=145,Fire +2=160,KVH +3=155,Fire3 +4=220,KVH;GL24h +5=240,GL24h;KVH-NSi +6=140,KVH +7=100,KVH +8=320,GL24h +9=80,KVH +10=120,KVH +11=400,GL24h +12=200,KVH +13=240,KVH;GL24h +14=160,GL24h +15=260,GL24h +16=280,GL24h +17=300,KVH +18=380,KVH +19=380,GL24h +20=360,GL24h +21=220,KVH-NSi +22=280,KVH +23=100,OSB +24=125,OSB +25=75,OSB +26=150,OSB +27=175,OSB +28=25,OSB +29=100,Triply +30=75,Triply +31=180,A_180 +32=100,Sapin +33=100,Lamellare +34=60,Douglas fir +35=150,Sheetrock +36=250,Sheetrock +37=100,Magnumboard-WALL +38=200,Magnumboard-FLOOR +39=75,Magnumboard-WALL +40=100,Magnumboard-FLOOR +41=65,Magnumboard-WALL +42=90,Magnumboard-WALL +43=25,WBP-plaat +44=50,WBP-plaat +45=75,WBP-plaat +46=200,Magnumboard-WALL +47=100,Magnumboard +48=200,Magnumboard +49=75,Magnumboard +50=100, +51=88, +52=200, +53=100,CLT-X-Lam +54=100,CLT-X-Lam +55=100,CLT-X-Lam +56=100,CLT-X-Lam +57=100,CLT-X-Lam +58=100,CLT-X-Lam +59=100,CLT-X-Lam +60=100,CLT-X-Lam +61=100,CLT-X-Lam +62=100,CLT-X-Lam +63=50.8,MPP Panel +64=100,CLT-X-Lam +65=100,CLT-X-Lam +66=100,CLT-X-Lam +67=100,CLT-X-Lam +68=100,CLT-X-Lam +69=100,CLT-X-Lam +70=100,CLT-X-Lam +71=100,CLT-X-Lam +72=100,CLT-X-Lam +73=250,CLT +74=115,CLT + +[Wall] +Kerf=10 +Offset=30 +S1=1,3200,10,130,1 +S2=2,1110,20,0,1 +S3=3,100,18500,0,1 +S4=4,4100,216000,0,1 +S5=5,30,30,0,1 +S6=6,30,30,10,1 +S7=7,30,30,23,1 +S8=8,30,30,44,1 +S9=9,230,130,0,1 +S10=10,30,30,0,1 +S11=11,30,30,0,1 +S12=12,30,30,0,1 +S13=13,30,330,0,1 +S14=14,3,30,0,1 +S15=15,5,4,0,1 +S16=16,30,30,0,1 +S17=17,30,30,2,1 +S18=18,30,30,0,1 +S19=19,30,30,0,1 +S20=20,33,44,0,1 +S21=21,12,30,0,1 +S22=5,122,30,0,1 +S23=5,123,30,0,1 +S24=16,127,30,0,1 +S25=3,2,3,0,1 +S26=8,33,44,1,1 +S27=5,1,2,3,1 +S28=9,3,2,1,1 +S29=23,2800,13000,20,1 +S30=24,2800,15000,10,1 +S31=25,2800,13000,20,1 +S32=26,2800,13000,20,1 +S33=27,3500,13000,20,1 +S34=28,35000,13000,20,1 +S35=29,1500,2780,10,1 +S36=30,1500,2780,10,1 +S37=31,2800,13000,10,1 +S38=32,2800,10000,10,1 +S39=33,2800,13000,99,1 +S40=34,2800,13000,99,1 +S41=35,2800,13000,99,1 +S42=44,2800,13000,20,1 +S43=45,2800,13000,30,1 +S44=43,2800,13000,10,1 +S45=47,2800,13000,100,1 +S46=48,2800,13000,100,1 +S47=49,2800,13000,100,1 +S48=47,2800,6500,100,1 +S49=48,2800,6500,100,1 +S50=49,2800,6500,100,1 +S51=47,2800,15000,100,1 +S52=48,2800,15000,100,1 +S53=49,2800,15000,100,1 +S54=53,1220,13500,20,1 +S55=50,2700,13000,100,1 +S56=63,2700,13000,20,1 +S57=74,2700,13000,100,1 +S58=50,2700,15000,100,1 +S59=50,2700,6500,100,1 +S60=73,2700,13000,100,1 diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/BatchProcess.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/BatchProcess.lua new file mode 100644 index 0000000..8e67674 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/BatchProcess.lua @@ -0,0 +1,512 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2020/06/12 +-- Gestione calcolo batch disposizione e lavorazioni per Travi +-- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. +-- 2019/07/16 Aggiunta gestione modalità oltre 10 per impostazione macchina e uscita. +-- 2019/07/19 Aggiunta gestione collisioni. +-- 2019/07/24 Aggiunta gestione extra-corse. +-- 2019/08/29 Aggiunta possibilità di processare file NGE. +-- 2019/10/04 Migliorato log dei parametri ricevuti. +-- 2019/10/07 Aggiunta gestione Flag 4 = Check+Generate. +-- 2019/10/09 In ImportBtl aggiunto flag per usare UserAttr. +-- 2019/12/09 Gestione conservazione modifiche su barre. +-- 2019/12/20 Gestione LOAD90 tramite file ausiliario (btm). +-- 2019/12/28 Tolta uscita in caso di errore su features. +-- 2020/01/08 Aggiunta seconda sezione limite (BD.MAX_WIDTH2 x BD.MAX_HEIGHT2). +-- 2020/01/14 Si carica ultimo gruppo di lavoro. Corretto problema con nome non definito in segnalazione errore in generazione o stima. +-- 2020/01/30 File Diff con nome del btl. +-- 2020/02/12 Migliorie nella gestione degli errori. +-- 2020/06/12 Si esegue sempre Processing se parametri macchina TS3 successivi al btl. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--BEAM = {} +--BEAM.FILE = 'c:\\EgtData\\Varie\\TestEssetreFast\\TestFabio\\BTL_TS37\\Bar_25_2.btl' +--BEAM.MACHINE = 'FAST' +--BEAM.FLAG = 3 + +-- Log dati in input +local sFlag = '' +if BEAM.FLAG == 0 then + sFlag = 'GENERATE' +elseif BEAM.FLAG == 1 then + sFlag = 'MODIFY' +elseif BEAM.FLAG == 2 then + sFlag = 'SIMULATE' +elseif BEAM.FLAG == 3 then + sFlag = 'CHECK' +elseif BEAM.FLAG == 4 then + sFlag = 'CHECK+GENERATE' +elseif BEAM.FLAG == 11 then + sFlag = 'TOOLS' +elseif BEAM.FLAG == 12 then + sFlag = 'JOBS' +else + sFlag = 'FLAG='..tostring( BEAM.FLAG) +end +local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. BEAM.MACHINE .. ', ' .. sFlag +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( BEAM.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 ( BEAM.FLAG == 1 or BEAM.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 ( BEAM.FLAG == 1 or BEAM.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-' .. BEAM.MACHINE +if not EgtSetCurrMachine( sMachine) then + BEAM.ERR = 11 + BEAM.MSG = 'Error selecting machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + BEAM.ERR = 12 + BEAM.MSG = 'Error not configured for beams machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Se modalità visualizzazione finestre per DB esco +if BEAM.FLAG > 10 then + BEAM.ERR = 0 + return +end + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Dati del file +local sDir, sTitle, sExt = EgtSplitPath( BEAM.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( BEAM.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( BEAM.FILE, EIB_FL.TS3_POS + EIB_FL.USEUATTR) then + BEAM.ERR = 13 + BEAM.MSG = 'Error importing BTL file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + -- faccio copia del file btl originale + EgtCopyFile( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + -- altrimenti Nge, lo apro + else + if not EgtOpenFile( BEAM.FILE) then + BEAM.ERR = 13 + BEAM.MSG = 'Error opening NGE file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + -- faccio copia del file originale + EgtCopyFile( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + end + + -- Aggiorno eventuali dati ausiliari + UpdateAuxData( sBtmFile) + + -- Recupero l'elenco ordinato delle travi + local vBeam = {} + local nPartId = EgtGetFirstPart() + while nPartId do + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + nPartId = EgtGetNextPart( nPartId) + end + if #vBeam == 0 then + BEAM.ERR = 14 + BEAM.MSG = 'Error no beams in the file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) + end + + -- Ne recupero le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + BEAM.ERR = 15 + BEAM.MSG = 'Box undefined for beam ' .. vBeam[i].Name + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + vBeam[i].Box = b3Solid + end + end + + -- Ne recupero la posizione + for i = 1, #vBeam do + local PosX = EgtGetInfo( vBeam[i].Id, 'POSX', 'd') + vBeam[i].PosX = PosX + end + + -- Eseguo eventuali rotazioni e inversioni testa-coda + for i = 1, #vBeam do + local b3Solid = vBeam[i].Box + -- rotazione + local dRotAng = EgtGetInfo( vBeam[i].Id, 'ROTATED', 'd') + if dRotAng and abs( dRotAng) > GEO.EPS_ANG_SMALL then + local ptRotCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptRotCen, X_AX(), dRotAng, GDB_RT.GLOB) + b3Solid:rotate( ptRotCen, X_AX(), dRotAng) + end + -- inversione + local dInvAng = 180 - ( EgtGetInfo( vBeam[i].Id, 'INVERTED', 'd') or 0) + if abs( dInvAng) > GEO.EPS_ANG_SMALL then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptInvCen, Z_AX(), dInvAng, GDB_RT.GLOB) + end + end + + -- Ne verifico le dimensioni + local dRawW = vBeam[1].Box:getDimY() + local dRawH = vBeam[1].Box:getDimZ() + local vBeamErr = {} + for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end + end + if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + table.remove( vBeam, vBeamErr[i]) + end + BEAM.ERR = 16 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Verifico sezione barra non troppo grande + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) and + ( dRawW > BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' .. + 'e (' .. EgtNumToString( BD.MAX_WIDTH2, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT2, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Verifico sezione barra non troppo piccola + if dRawW < BD.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < BD.MIN_HEIGHT - 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'sotto i limiti della macchina (' .. EgtNumToString( BD.MIN_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MIN_HEIGHT, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Lunghezza della barra + local dRawL = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'BARLEN', 'd') or 12000) + 0.1 + -- Sovramateriale di testa + local dOvmHead = vBeam[1].PosX or 0 + + -- Sistemo le travi nel grezzo + local bPbOk, sPbErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) + if not bPbOk then + BEAM.ERR = 18 + BEAM.MSG = sPbErr + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Imposto Nome file CN + local _, sName, _ = EgtSplitPath( BEAM.FILE) + EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + + -- Abilito Vmill + EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + + -- Lavoro le features + local bPfOk, Stats = BE.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 + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = 19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = -19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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 + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = 0 + BEAM.CUTID = nCutId + BEAM.TASKID = nTaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + end + -- Salvo il progetto + EgtSaveFile( sNgeFile) +end + +-- *** Eseguo simulazione con verifica collisione in cieco *** +if ( BEAM.FLAG == 0 and ( bToProcess or bToRecalc)) or BEAM.FLAG == 3 or BEAM.FLAG == 4 then + EgtOutLog( ' +++ Simulating with collision check >>>') + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.INIT then + BEAM.ERR = 19 + BEAM.MSG = 'Error in clamps disposition' + elseif nErr == MCH_SHE.COLLISION then + BEAM.ERR = 22 + BEAM.MSG = 'Head-part collision' + elseif nErr == MCH_SHE.OUTSTROKE then + BEAM.ERR = 23 + BEAM.MSG = 'Axis outstroke ' .. sErr + elseif nErr == MCH_SHE.SPECIAL then + BEAM.ERR = 24 + BEAM.MSG = 'Clamp move error ' .. sErr + else + BEAM.ERR = 25 + BEAM.MSG = 'General failure (contact supplier)' + end + BEAM.ROT = 0 + BEAM.CUTID = 0 + BEAM.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 + BEAM.CUTID = EgtGetVal( vItem[i], 'CUTID', 'i') or 0 + elseif string.find( vItem[i], 'TASKID', 1, true) then + BEAM.TASKID = EgtGetVal( vItem[i], 'TASKID', 'i') or 0 + end + end + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + return + end +end + +-- *** Genero programma CN *** ( se richiesto) +if BEAM.FLAG == 0 or BEAM.FLAG == 4 then + EgtOutLog( ' +++ Generating NC part program >>>') + if not EgtGenerate( '', 'EgtCAM5 - ' .. sNgeFile) then + BEAM.ERR = 20 + local _, sName, _ = EgtSplitPath( BEAM.FILE) + BEAM.MSG = 'Error generating NC part program : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end +end + +-- *** Eseguo stima tempi *** +EgtOutLog( ' +++ Estimating T&L >>>') +if not EgtEstimate( '', 'EgtCAM5 - ' .. sNgeFile) then + + BEAM.ERR = 21 + local _, sName, _ = EgtSplitPath( BEAM.FILE) + BEAM.MSG = 'Error estimating production time : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.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 BEAM.FLAG == 1 or BEAM.FLAG == 2 then + EgtSetView( SCE_VD.ISO_SW, false) +end + +-- Completamento senza errori e avvisi +if nWarnCnt == 0 then + BEAM.ERR = 0 + BEAM.MSG = '---' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) +end + +-- Scrittura tempo totale stimato di lavorazione +WriteTimeToLogFile( Ttot) + +EgtOutLog( ' +++ BatchProcess completed') diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/Beam.ini b/ProgramData/EgtCAM5/Beam 2020.08.14/Beam.ini new file mode 100644 index 0000000..bc2ede0 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/Beam.ini @@ -0,0 +1,8 @@ +[Beam] +BtlEnable=1 +BaseDir=C:\EgtData\Beam +BtlExec=BatchProcess.lua +Button1=Process.lua,Images\Process.png,Lavora Travi +Button2=Swap.lua,Images\Swap.png,Scambia estremi trave +Button3=Rotate.lua,Images\Rotate.png,Ruota trave +Button4=BeamMachinings,Images\BeamMachinings.png,Lista lavorazioni diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/Images/BeamMachinings.png b/ProgramData/EgtCAM5/Beam 2020.08.14/Images/BeamMachinings.png new file mode 100644 index 0000000..5ab6b0c Binary files /dev/null and b/ProgramData/EgtCAM5/Beam 2020.08.14/Images/BeamMachinings.png differ diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/Images/Process.png b/ProgramData/EgtCAM5/Beam 2020.08.14/Images/Process.png new file mode 100644 index 0000000..13070d5 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam 2020.08.14/Images/Process.png differ diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/Images/Rotate.png b/ProgramData/EgtCAM5/Beam 2020.08.14/Images/Rotate.png new file mode 100644 index 0000000..bd1532e Binary files /dev/null and b/ProgramData/EgtCAM5/Beam 2020.08.14/Images/Rotate.png differ diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/Images/Swap.png b/ProgramData/EgtCAM5/Beam 2020.08.14/Images/Swap.png new file mode 100644 index 0000000..04fa8f8 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam 2020.08.14/Images/Swap.png differ diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/BeamExec.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/BeamExec.lua new file mode 100644 index 0000000..f926b98 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/BeamExec.lua @@ -0,0 +1,1138 @@ +-- BeamExec.lua by Egaltech s.r.l. 2020/07/29 +-- Libreria esecuzione lavorazioni per Travi +-- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. +-- 2019/09/04 Corretto controllo feature di testa e coda con sovramateriale di testa elevato. +-- 2019/09/25 Aggiunta gestione StepJoint e StepJointNotch. +-- 2020/01/21 Aggiunta gestione ScarfJoint. +-- 2020/02/10 Aggiunta gestione FrenchRidgeLap. +-- 2020/02/11 Aggiunta gestione BlockHausFront. +-- 2020/04/02 Fori di testa dal basso non danno errore e fanno ribaltare la trave. +-- 2020/04/07 Aggiunta gestione TyroleanDovetail. +-- 2020/04/14 Aggiunta gestione Dovetail. +-- 2020/05/16 Migliorie ordinamento fori. +-- 2020/05/16 Gestione rotazione di 90deg. +-- 2020/05/21 Correzione rotazione di 90deg (caso DY > DZ). +-- 2020/05/25 Correzione rotazione di 90deg dopo scarico su carico. +-- 2020/06/02 Per dati foro si chiama funzione GetData di ProcessDrill (per gestire variazioni di diametro da UserParams). +-- 2020/07/25 Ricalcolati flag head e tail della prima parte del foro dopo lo split. +-- 2002/07/27 Modifica a ordinamento fori. + +-- Tabella per definizione modulo +local BeamExec = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali e libero tutti gli altri +_G.package.loaded.BeamData = nil +_G.package.loaded.CutData = nil +_G.package.loaded.MillingData = nil +_G.package.loaded.PocketingData = nil +_G.package.loaded.DrillData = nil +_G.package.loaded.SawingData = nil +local BD = require( 'BeamData') + +-- Carico le librerie +_G.package.loaded.MachiningLib = nil +local BM = require( 'MachiningLib') +_G.package.loaded.BeamLib = nil +local BL = require( 'BeamLib') +_G.package.loaded.DiceCut = nil +local DC = require( 'DiceCut') +_G.package.loaded.FacesBySaw = nil +local Fbs = require( 'FacesBySaw') +_G.package.loaded.ProcessHeadCut = nil +local Hcut= require( 'ProcessHeadCut') +_G.package.loaded.ProcessSplit = nil +local Split = require( 'ProcessSplit') +_G.package.loaded.ProcessCut = nil +local Cut = require( 'ProcessCut') +_G.package.loaded.ProcessDoubleCut = nil +local DoubleCut = require( 'ProcessDoubleCut') +_G.package.loaded.ProcessLongCut = nil +local LongCut = require( 'ProcessLongCut') +_G.package.loaded.ProcessLongDoubleCut = nil +local Long2Cut = require( 'ProcessLongDoubleCut') +_G.package.loaded.ProcessSawCut = nil +local SawCut = require( 'ProcessSawCut') +_G.package.loaded.ProcessRidgeLap = nil +local RidgeLap = require( 'ProcessRidgeLap') +_G.package.loaded.ProcessLapJoint = nil +local LapJoint = require( 'ProcessLapJoint') +_G.package.loaded.ProcessChamfer = nil +local Chamfer = require( 'ProcessChamfer') +_G.package.loaded.ProcessDrill = nil +local Drill = require( 'ProcessDrill') +_G.package.loaded.ProcessFrenchRidgeLap = nil +local FrenchRidgeLap = require( 'ProcessFrenchRidgeLap') +_G.package.loaded.ProcessBlockHausFront = nil +local BlockHausFront = require( 'ProcessBlockHausFront') +_G.package.loaded.ProcessTenon = nil +local Tenon = require( 'ProcessTenon') +_G.package.loaded.ProcessMortise = nil +local Mortise = require( 'ProcessMortise') +_G.package.loaded.ProcessDtTenon = nil +local DtTenon = require( 'ProcessDtTenon') +_G.package.loaded.ProcessDtMortise = nil +local DtMortise = require( 'ProcessDtMortise') +_G.package.loaded.ProcessMark = nil +local Mark = require( 'ProcessMark') +_G.package.loaded.ProcessText = nil +local Text = require( 'ProcessText') +_G.package.loaded.ProcessScarfJoint = nil +local ScarfJoint = require( 'ProcessScarfJoint') +_G.package.loaded.ProcessSimpleScarf = nil +local Scarf = require( 'ProcessSimpleScarf') +_G.package.loaded.ProcessStepJoint = nil +local StepJoint = require( 'ProcessStepJoint') +_G.package.loaded.ProcessStepJointNotch = nil +local StJoNotch = require( 'ProcessStepJointNotch') +_G.package.loaded.ProcessProfFront = nil +local ProfFront = require( 'ProcessProfFront') +_G.package.loaded.ProcessProfConcave = nil +local ProfConcave = require( 'ProcessProfConcave') +_G.package.loaded.ProcessProfConvex = nil +local ProfConvex = require( 'ProcessProfConvex') +_G.package.loaded.ProcessProfCamb = nil +local ProfCamb = require( 'ProcessProfCamb') +_G.package.loaded.ProcessProfHead = nil +local ProfHead = require( 'ProcessProfHead') +_G.package.loaded.ProcessRoundArch = nil +local RoundArch = require( 'ProcessRoundArch') +_G.package.loaded.ProcessTyroleanDovetail = nil +local TyroleanDovetail = require( 'ProcessTyroleanDovetail') +_G.package.loaded.ProcessDovetail = nil +local Dovetail = require( 'ProcessDovetail') +_G.package.loaded.ProcessFreeContour = nil +local FreeContour = require( 'ProcessFreeContour') +_G.package.loaded.ProcessDecor = nil +local Decor = require( 'ProcessDecor') + +EgtOutLog( ' BeamExec started', 1) +EgtMdbSetGeneralParam( MCH_GP.MAXDEPTHSAFE, BD.COLL_SIC) +EgtMdbSave() + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle travi nel grezzo *** +------------------------------------------------------------------------------------------------------------- +function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) + + -- Determinazione minimo grezzo scaricabile + BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) + + -- Creazione nuovo gruppo di lavoro + local sMgName = EgtGetMachGroupNewName( 'Mach_1') + 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 + BD.OriTR = Point3d( b3Tab:getDimX(), b3Tab:getDimY(), 0) + + -- Impostazione dell'attrezzaggio di default + EgtImportSetup() + + -- Inserimento dei pezzi con il loro grezzo + local Cnt = 0 + local Len = dRawL + local DeltaS = dOvmHead + local DeltaE = BD.OVM_MID + for i = 1, #vBeam do + -- assegno identificativo pezzo + local Pz = vBeam[i].Id + -- dati del pezzo + local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT) + local b3Solid = vBeam[i].Box + if b3Part:isEmpty() or b3Solid:isEmpty() then break end + EgtOutLog( 'PartSez=' .. EgtNumToString( b3Part:getDimY(), 1) .. 'x' .. EgtNumToString( b3Part:getDimZ(), 1), 3) + -- se sezione compatibile e lunghezza disponibile sufficiente + local PartLen = b3Solid:getDimX() + local PartWidth = b3Solid:getDimY() + local PartHeight = b3Solid:getDimZ() + local NextLen = Len - DeltaS - PartLen - DeltaE + if (( abs( PartWidth - dRawW) < 10 * GEO.EPS_SMALL and abs( PartHeight - dRawH) < 10 * GEO.EPS_SMALL) or + ( abs( PartHeight - dRawW) < 10 * GEO.EPS_SMALL and abs( PartWidth - dRawH) < 10 * GEO.EPS_SMALL)) and + NextLen + DeltaE >= 0 then + -- eventuale sovramateriale di testa + if vBeam[i].PosX then + DeltaS = max( vBeam[i].PosX - ( dRawL - Len), 0) + end + -- dimensioni del grezzo + local CrawLen = min( PartLen + DeltaS + DeltaE, Len) + local Delta = CrawLen - PartLen - DeltaS + -- creo e posiziono il grezzo + local nRaw = EgtAddRawPart( Point3d(0,0,0), CrawLen, dRawW, dRawH, BD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, BD.OriTR, MCH_CR.TR) + EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) + -- assegno ordine in lavorazione + Cnt = Cnt + 1 + EgtSetInfo( nRaw, 'ORD', Cnt) + -- creo o pulisco gruppo geometrie aggiuntive + if not BL.CreateOrEmptyAddGroup( Pz) then + local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz) + return false, sOut + end + -- aggiungo faccia per taglio iniziale al pezzo + BL.AddPartStartFace( Pz, b3Solid) + -- se sovramateriale di testa, lo notifico + if DeltaS > 0.09 then + EgtSetInfo( nRaw, 'HOVM', DeltaS) + end + -- aggiungo faccia per taglio finale al pezzo + BL.AddPartEndFace( Pz, b3Solid) + -- inserisco il pezzo nel grezzo + EgtDeselectPartObjs( Pz) + local ptPos = b3Part:getMin() - b3Solid:getMin() + Vector3d( Delta, ( dRawW - PartWidth) / 2, ( dRawH - PartHeight) / 2) + EgtAddPartToRawPart( Pz, ptPos, nRaw) + if abs( PartWidth - dRawW) > 10 * GEO.EPS_SMALL then + -- rotazione attorno a centro geometria complessiva del pezzo + EgtRotatePartInRawPart( Pz, X_AX(), 90) + -- correggo per eccentricità solido rispetto a geometria complessiva del pezzo + local vtEccOri = b3Solid:getCenter() - b3Part:getCenter() + local vtEccRot = Vector3d( vtEccOri) + vtEccRot:rotate( X_AX(), 90) + EgtMovePartInRawPart( Pz, ( vtEccOri - vtEccRot)) + end + -- aggiorno la lunghezza residua della barra + Len = Len - CrawLen + end + -- se rimasto troppo poco grezzo, esco + --if Len < BD.MinRaw then break end + DeltaS = 0 + end + + -- Se rimasto materiale aggiungo grezzo dell'avanzo + if Len > 10 then + local nRaw = EgtAddRawPart( Point3d(0,0,0), Len, dRawW, dRawH, BD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, BD.OriTR, MCH_CR.TR) + EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) + -- assegno ordine in lavorazione + Cnt = Cnt + 1 + EgtSetInfo( nRaw, 'ORD', Cnt) + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) + local H_S = 200 + local H_L = 400 + -- Determinazione minimo grezzo scaricabile + if dRawH <= H_S then + BD.MinRaw = BD.MINRAW_S + elseif dRawH <= H_L then + local Coeff = ( dRawH - H_S) / ( H_L - H_S) + BD.MinRaw = ( 1 - Coeff) * BD.MINRAW_S + Coeff * BD.MINRAW_L + else + BD.MinRaw = BD.MINRAW_L + end +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function Verify90DegRotation( nRawId) + if not nRawId then return false end + -- dimensioni sezione trave in posizione normale (rotazione 0°) + local dRawW = EgtGetRawPartBBox( nRawId):getDimY() + local dRawH = EgtGetRawPartBBox( nRawId):getDimZ() + -- verifica dell'altezza rispetto alla massima larghezza + return ( dRawH < BD.MAX_WIDTH + 10 * GEO.EPS_SMALL and dRawW < BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) or + ( dRawH < BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL and dRawW < BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) +end + +------------------------------------------------------------------------------------------------------------- +local function IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- feature sempre di testa o coda per il gruppo + if Proc.Grp == 1 or Proc.Grp == 2 then + return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- feature sempre di testa o coda nonostante il gruppo + if ( Proc.Grp == 3 or Proc.Grp == 4) and + ( Proc.Prc == 38 or Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then + return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- gestioni speciali + if LapJoint.Identify( Proc) then + return LapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if Drill.Identify( Proc) then + return Drill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if RoundArch.Identify( Proc) then + return RoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if Dovetail.Identify( Proc) then + return Dovetail.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if FreeContour.Identify( Proc) then + return FreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + -- non è di testa + return false +end + +------------------------------------------------------------------------------------------------------------- +local function IsTailFeature( Proc, b3Raw, dCurrOvmH) + -- feature sempre di testa o coda per il gruppo + if Proc.Grp == 1 or Proc.Grp == 2 then + return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- feature sempre di testa o coda nonostante il gruppo + if ( Proc.Grp == 3 or Proc.Grp == 4) and + ( Proc.Prc == 38 or Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then + return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- gestioni speciali + if LapJoint.Identify( Proc) then + return LapJoint.IsTailFeature( Proc, b3Raw) + end + if Drill.Identify( Proc) then + return Drill.IsTailFeature( Proc, b3Raw) + end + if DtMortise.Identify( Proc) then + return DtMortise.IsTailFeature( Proc, b3Raw) + end + if RoundArch.Identify( Proc) then + return RoundArch.IsTailFeature( Proc, b3Raw) + end + if Dovetail.Identify( Proc) then + return Dovetail.IsTailFeature( Proc, b3Raw) + end + if FreeContour.Identify( Proc) then + return FreeContour.IsTailFeature( Proc, b3Raw) + end + -- non è di coda + return false +end + +------------------------------------------------------------------------------------------------------------- +local function CollectFeatures( PartId, b3Raw, dCurrOvmH) + -- recupero le feature + local vProc = {} + local LayerId = {} + LayerId[1] = BL.GetAddGroup( PartId) + LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings') + for nInd = 1, 2 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.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 + Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH) + Proc.Tail = IsTailFeature( Proc, b3Raw, dCurrOvmH) + table.insert( vProc, Proc) + -- se foro + if Drill.Identify( Proc) then + -- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento) + Proc.Diam, Proc.Fcs, Proc.Fce = Drill.GetData( Proc, b3Raw) + -- verifico se necessaria seconda lavorazione da parte opposta per foro più lungo della punta + if Drill.Split( Proc, b3Raw) then + -- aggiorno flags prima parte foro (dati tabelle sempre per riferimento) + Proc.Flg = 2 + Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH) + Proc.Tail = IsTailFeature( Proc, b3Raw, dCurrOvmH) + -- definisco dati seconda parte + local Proc2 = {} + Proc2.Id = ProcId + Proc2.Grp = nGrp + Proc2.Prc = nPrc + Proc2.Flg = -2 + Proc2.Box = BBox3d( Proc.Box) + Proc2.Fct = Proc.Fct + Proc2.Diam = Proc.Diam + Proc2.Head = Proc.Head + Proc2.Tail = Drill.IsTailFeature( Proc2, b3Raw, dCurrOvmH) + Proc2.Fcs = Proc.Fce + Proc2.Fce = Proc.Fcs + Proc2.CutId = Proc.CutId + Proc2.TaskId = Proc.TaskId + table.insert( vProc, Proc2) + end + end + else + EgtOutLog( ' Feature ' .. tostring( Proc.Id) .. ' is empty (no geometry)') + end + end + end + ProcId = EgtGetNext( ProcId) + end + end + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function OrderFeatures( vProc, b3Raw) + + local dSmallDrillRange = EgtIf( b3Raw:getDimX() < BD.LEN_SHORT_PART, 200, 600) + + -- funzione di confronto + -- secondo centro box in X (taglio di intestazione prima di altri tagli di testa e taglio di separazione però prima di altri tagli di coda) + local function CompareFeatures( B1, B2) + -- se primo è intestazione va sempre prima + if Hcut.Identify( B1) then + return true + end + -- se l'altro è intestazione va sempre prima + if Hcut.Identify( B2) then + return false + end + -- se uno di testa e non l'altro, privilegio quello di testa + if B1.Head ~= B2.Head then + return B1.Head + end + -- se entrambi di testa e primo è scasso o mortasa va messo dopo + if B1.Head and B2.Head and ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1)) then + return false + end + -- se entrambi di testa e secondo è scasso o mortasa va messo dopo + if B1.Head and B2.Head and ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2)) then + return true + end + -- se primo è feature di coda e l'altro è separazione o non è feature di coda + if B1.Tail and ( Split.Identify( B2) or not B2.Tail) then + return false + end + -- se secondo è feature di coda e l'altro è separazione o non è feature di coda + if B2.Tail and ( Split.Identify( B1) or not B1.Tail) then + return true + end + -- se primo è scasso o mortasa di coda, sempre dopo tutto + if B1.Tail and ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1)) then + return false + end + -- se secondo è scasso o mortasa di coda, sempre dopo tutto + if B2.Tail and ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2)) then + return true + end + -- se primo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda + if abs( B1.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + -- se anche l'altra è lunga, faccio prima quello a Zmax + if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + return B1.Box:getMax():getZ() > B2.Box:getMax():getZ() + else + return B1.Box:getMin():getX() + 50 > B2.Box:getCenter():getX() + end + end + -- se secondo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda + if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + return B1.Box:getCenter():getX() > B2.Box:getMin():getX() + 50 + end + -- se primo è foro e l'altro no, lo penalizzo + if B1.Prc == 40 and B2.Prc ~= 40 then + return B1.Box:getCenter():getX() - 100 > B2.Box:getMax():getX() + end + -- se primo è altro e secondo è foro, lo premio + if B1.Prc ~= 40 and B2.Prc == 40 then + return B1.Box:getMax():getX() + 100 > B2.Box:getCenter():getX() + end + -- se entrambi fori con posizione praticamente uguale ordino secondo diametro e faccia di inizio (Fcs) + if B1.Prc == 40 and B2.Prc == 40 and abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) < dSmallDrillRange then + if abs( B1.Diam - B2.Diam) < 1.0 then + if B1.Fcs == B2.Fcs then + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + else + return B1.Fcs > B2.Fcs + end + else + return ( B1.Diam > B2.Diam) + end + end + -- se entrambi tenoni e si intersecano, metto prima tenone vero e poi base tenone + if Tenon.Identify( B1) and Tenon.Identify( B2) and + B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then + return ( B1.Prc == 50 and B2.Prc == 52) + end + -- confronto standard + if abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) > 0.4 * ( B1.Box:getDimX() + B2.Box:getDimX()) then + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + elseif abs( B1.Box:getCenter():getY() - B2.Box:getCenter():getY()) > 0.2 * ( B1.Box:getDimY() + B2.Box:getDimY()) then + return B1.Box:getCenter():getY() > B2.Box:getCenter():getY() + elseif abs( B1.Box:getCenter():getZ() - B2.Box:getCenter():getZ()) > 0.1 * ( B1.Box:getDimZ() + B2.Box:getDimZ()) then + return B1.Box:getCenter():getZ() > B2.Box:getCenter():getZ() + else + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + end + end + + -- eseguo ordinamento + table.sort( vProc, CompareFeatures) + + -- riunisco fori con lo stesso diametro e non troppo lontani + local dDrillRange = EgtIf( BD.GO_FAST == 2, 6000, dSmallDrillRange) + for i = 1, #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 40 then + for j = i + 1, #vProc do + local ProcJ = vProc[j] + if ProcJ.Prc == 40 and ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and + abs( ProcJ.Diam - ProcI.Diam) < 1.0 and abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < dDrillRange then + if j > i + 1 then + local ProcK = vProc[i+1] + if ProcK.Prc ~= 40 or abs( ProcK.Diam - ProcJ.Diam) > 1.0 then + table.insert( vProc, i + 1, table.remove( vProc, j)) + end + end + end + end + end + end + -- riunisco marcature, testi e decori non troppo lontani + local dMarkRange = 300 + for i = 1, #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 60 or ProcI.Prc == 61 or ProcI.Prc == 959 then + for j = i + 1, #vProc do + local ProcJ = vProc[j] + if ( ProcJ.Prc == 60 or ProcJ.Prc == 61 or ProcJ.Prc == 959) and + ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and + abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < dMarkRange then + if j > i + 1 then + table.insert( vProc, i + 1, table.remove( vProc, j)) + end + break + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +local function ClassifyFeatures( vProc, b3Raw, Stats) + local bAllOk = true + local bSomeDown = false + local bSomeSide = false + local bSplitRot = false + local nHeading + local nSplitting + for i = 1, #vProc do + local Proc = vProc[i] + local bOk = true + local bDown = false + local bSide = false + local bDownSideOnHeadOk = false + -- se intestatura + if Hcut.Identify( Proc) then + nHeading = i + -- se separazione + elseif Split.Identify( Proc) then + nSplitting = i + -- se taglio + elseif Cut.Identify( Proc) then + bOk, bDown = Cut.Classify( Proc, b3Raw) + -- se doppio taglio + elseif DoubleCut.Identify( Proc) then + bOk, bDown = DoubleCut.Classify( Proc) + -- se taglio longitudinale + elseif LongCut.Identify( Proc) then + bOk, bDown = LongCut.Classify( Proc) + -- se doppio taglio longitudinale + elseif Long2Cut.Identify( Proc) then + bOk, bDown = Long2Cut.Classify( Proc) + -- se taglio con lama + elseif SawCut.Identify( Proc) then + bOk, bDown = SawCut.Classify( Proc) + -- se mezzo-legno di testa + elseif RidgeLap.Identify( Proc) then + bOk, bDown = RidgeLap.Classify( Proc, b3Raw) + -- se scanalatura, scanalatura frontale, tacca, tacca cantonale, mezzo-legno, scanalatura-battuta, + -- mezzolegno tipo chalet-tavola di chiusura, rivestimento, mezzolegno chalet, tasca, taglio triangolato + elseif LapJoint.Identify( Proc) then + bOk, bDown = LapJoint.Classify( Proc, b3Raw) + -- se foratura + elseif Drill.Identify( Proc) then + bOk, bDown, bSide = Drill.Classify( Proc, b3Raw) + bDownSideOnHeadOk = true + -- se tenone + elseif Tenon.Identify( Proc) then + bOk, bDown = Tenon.Classify( Proc, b3Raw) + -- se giunzione francese + elseif FrenchRidgeLap.Identify( Proc) then + bOk, bDown = FrenchRidgeLap.Classify( Proc) + -- se block house front + elseif BlockHausFront.Identify( Proc) then + bOk, bDown = BlockHausFront.Classify( Proc) + -- se mortasa (anche frontale) + elseif Mortise.Identify( Proc) then + bOk, bDown = Mortise.Classify( Proc) + -- se tenone a coda di rondine + elseif DtTenon.Identify( Proc) then + bOk, bDown = DtTenon.Classify( Proc, b3Raw) + -- se mortasa a coda di rondine (anche frontale) + elseif DtMortise.Identify( Proc) then + bOk, bDown = DtMortise.Classify( Proc) + -- se marcatura + elseif Mark.Identify( Proc) then + bOk, bDown = Mark.Classify( Proc) + -- se testo + elseif Text.Identify( Proc) then + bOk, bDown = Text.Classify( Proc) + -- se giunto Gerber + elseif ScarfJoint.Identify( Proc) then + bOk, bDown = ScarfJoint.Classify( Proc) + -- se giunto Gerber + elseif Scarf.Identify( Proc) then + bOk, bDown = Scarf.Classify( Proc) + -- se giunto a gradino + elseif StepJoint.Identify( Proc) then + bOk, bDown = StepJoint.Classify( Proc) + -- se tacca a gradino + elseif StJoNotch.Identify( Proc) then + bOk, bDown = StJoNotch.Classify( Proc) + -- se arco + elseif RoundArch.Identify( Proc) then + bOk, bDown = RoundArch.Classify( Proc) + -- se incastro tirolo + elseif TyroleanDovetail.Identify( Proc) then + bOk, bDown = TyroleanDovetail.Classify( Proc, b3Raw) + -- se giunto coda di rondine + elseif Dovetail.Identify( Proc) then + bOk, bDown = Dovetail.Classify( Proc, b3Raw) + -- se profilo front + elseif ProfFront.Identify( Proc) then + bOk, bDown, bSide = ProfFront.Classify( Proc, b3Raw) + -- se profilo concavo + elseif ProfConcave.Identify( Proc) then + bOk, bDown, bSide = ProfConcave.Classify( Proc, b3Raw) + -- se profilo convesso + elseif ProfConvex.Identify( Proc) then + bOk, bDown, bSide = ProfConvex.Classify( Proc, b3Raw) + -- se profilo caudato + elseif ProfCamb.Identify( Proc) then + bOk, bDown, bSide = ProfCamb.Classify( Proc, b3Raw) + -- se profilo head + elseif ProfHead.Identify( Proc) then + bOk, bDown, bSide = ProfHead.Classify( Proc, b3Raw) + -- se contorno libero + elseif FreeContour.Identify( Proc) then + bOk, bDown, bSide = FreeContour.Classify( Proc, b3Raw) + -- se decorazione + elseif Decor.Identify( Proc) then + bOk, bDown = Decor.Classify( Proc) + end + -- assegno risultato + if bOk then + -- non ammessa feature di testa da lavorare ribaltata o ruotata + if Proc.Head and ( bDown or bSide) and not bDownSideOnHeadOk then + Proc.Flg = 0 + Proc.Down = true + bAllOk = false + table.insert( Stats, {Err = 1, Msg='Error : impossible to machine by orientation', CutId=Proc.CutId, TaskId=Proc.TaskId}) + -- gestione feature di coda da lavorare ribaltata + elseif Proc.Tail and bDown then + Proc.Down = true + bSomeDown = true + bSplitRot = true + -- gestione feature di coda da lavorare ruotata + elseif Proc.Tail and bSide then + Proc.Side = true + bSomeSide = true + bSplitRot = true + -- caso normale + else + Proc.Down = bDown + Proc.Side = bSide + if bDown then bSomeDown = true end + if bSide then bSomeSide = true end + end + else + Proc.Flg = 0 + bAllOk = false + table.insert( Stats, {Err = 1, Msg='Error : impossible to machine', CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + end + -- se necessario ribaltamento, assegno intestatura alla fase ribaltata + if bSomeDown and nHeading then + vProc[nHeading].Down = true + -- se altrimenti necessaria rotazione (senza ribaltamento), assegno intestatura alla fase ribaltata (creata ad hoc) + elseif bSomeSide and nHeading then + vProc[nHeading].Down = true + bSomeDown = true + end + -- se necessaria separazione del ribaltato o ruotato, la assegno sempre alla fase ribaltata + if bSplitRot and nSplitting then + vProc[nSplitting].Down = true + bSomeDown = true + end + return bAllOk, bSomeDown, bSomeSide, bSplitRot +end + +------------------------------------------------------------------------------------------------------------- +local function PrintFeatures( vProc, b3Raw) + EgtOutLog( ' RawBox=' .. tostring( b3Raw)) + for i = 1, #vProc do + local Proc = vProc[i] + local sOut = string.format( ' Proc=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s', + Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId, + Proc.Flg, EgtIf( Proc.Down, 'T', 'F'), EgtIf( Proc.Side, 'T', 'F'), EgtIf( Proc.Head, 'T', 'F'), EgtIf( Proc.Tail, 'T', 'F'), + Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, tostring( Proc.Box)) + EgtOutLog( sOut) + end +end + +------------------------------------------------------------------------------------------------------------- +local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut, b3Raw) + local bOk = true + local sErr = '' + local bNewPhase = false + -- se intestatura ( 1-340-X ) + EgtOutLog( ' * Process ' .. tostring( Proc.Id) .. ' *', 1) + if Hcut.Identify( Proc) then + -- esecuzione taglio di testa + bOk, sErr = Hcut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut) + -- se separazione ( 2-350-X ) + elseif Split.Identify( Proc) then + -- esecuzione separazione o eliminazione grezzo residuo + bOk, _, sErr = Split.Make( Proc, nPhase, nRawId, nPartId) + -- richiedo il passaggio alla seconda fase di lavorazione di questa trave + bNewPhase = true + -- se taglio ( 1/2-010-X) + elseif Cut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se doppio taglio ( 1/2-011-X) + elseif DoubleCut.Identify( Proc) then + -- se due facce, eseguo doppio taglio + if Proc.Fct == 2 then + bOk, sErr = DoubleCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- altrimenti eseguo singolo taglio + else + bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + end + -- se taglio longitudinale ( 0/3/4-010-X) + elseif LongCut.Identify( Proc) then + -- esecuzione taglio longitudinale + bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) + -- se doppio taglio longitudinale ( 0-012-X) + elseif Long2Cut.Identify( Proc) then + -- se due facce longitudinali, eseguo doppio taglio longitudinale + if Long2Cut.GetLongFacesCount( Proc) == 2 then + bOk, sErr = Long2Cut.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti eseguo singolo taglio longitudinale + else + bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) + end + -- se taglio con lama ( 0/3/4-013-X) + elseif SawCut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = SawCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mezzo-legno di testa ( 1/2-030-X) + elseif RidgeLap.Identify( Proc) then + -- esecuzione mezzo-legno di testa + bOk, sErr = RidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se fessura ( 3/4-016-X) o se fessura frontale ( 3/4-017-X) o se tacca ( 3/4-020-X) o se tacca cantonale ( 3/4-025-X) + -- o se mezzo-legno ( 3/4-030-X) o se scanalatura/battuta ( 3/4-032-X) o se mezzo legno tipo chalet/tavola di chiusura ( 3/4-033-X) + -- o se rivestimento ( 3/4-034-X) o se mezzolegno chalet ( 4-037-X) o se tasca ( 4-039-X) o se taglio triangolato ( 4-120-X) + elseif LapJoint.Identify( Proc) then + -- esecuzione mezzo-legno o scanalatura + bOk, sErr = LapJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se smusso ( 3/4-036-X) + elseif Chamfer.Identify( Proc) then + -- esecuzione smusso + bOk, sErr = Chamfer.Make( Proc, nPhase, nRawId, nPartId) + -- se foratura ( 3/4-040-X) + elseif Drill.Identify( Proc) then + -- esecuzione foratura + bOk, sErr = Drill.Make( Proc, nPhase, nRawId, nPartId) + -- se giunzione francese ( 1/2-035-X) + elseif FrenchRidgeLap.Identify( Proc) then + -- esecuzione giunzione francese + bOk, sErr = FrenchRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se block house front ( 3/4-038-X) + elseif BlockHausFront.Identify( Proc) then + -- esecuzione giunzione francese + bOk, sErr = BlockHausFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se tenone ( 1/2-050-X) + elseif Tenon.Identify( Proc) then + -- esecuzione tenone + bOk, sErr = Tenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mortasa ( 3/4-050-X) anche frontale ( 3/4-051-X) + elseif Mortise.Identify( Proc) then + -- esecuzione mortasa + bOk, sErr = Mortise.Make( Proc, nPhase, nRawId, nPartId) + -- se tenone a coda di rondine ( 1/2-055-X) + elseif DtTenon.Identify( Proc) then + -- esecuzione tenone + bOk, sErr = DtTenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mortasa a coda di rondine ( 3/4-055-X) anche frontale ( 3/4-056-X) + elseif DtMortise.Identify( Proc) then + -- esecuzione mortasa + bOk, sErr = DtMortise.Make( Proc, nPhase, nRawId, nPartId) + -- se marcatura ( 3/4-060-X) + elseif Mark.Identify( Proc) then + -- esecuzione marcatura + bOk, sErr = Mark.Make( Proc, nPhase, nRawId, nPartId) + -- se testo ( 4-061-X) + elseif Text.Identify( Proc) then + -- esecuzione testo + bOk, sErr = Text.Make( Proc, nPhase, nRawId, nPartId) + -- se giunto Gerber ( 1/2-071-X) + elseif ScarfJoint.Identify( Proc) then + -- esecuzione giunto Gerber + bOk, sErr = ScarfJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se giunto Gerber ( 1/2-070-X) + elseif Scarf.Identify( Proc) then + -- esecuzione giunto Gerber + bOk, sErr = Scarf.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se giunto a gradino ( 1/2-080-X) + elseif StepJoint.Identify( Proc) then + -- esecuzione giunto a gradino + bOk, sErr = StepJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se tacca a gradino ( 3/4-080-X) + elseif StJoNotch.Identify( Proc) then + -- esecuzione tacca a gradino + bOk, sErr = StJoNotch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo Front ( 3/4-100-X) + elseif ProfFront.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo concavo ( 3/4-101-X) + elseif ProfConcave.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo convesso ( 3/4-102-X) + elseif ProfConvex.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo caudato ( 3/4-103-X) + elseif ProfCamb.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se arco ( 4-104-X) + elseif RoundArch.Identify( Proc) then + -- esecuzione arco + bOk, sErr = RoundArch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo Head ( 3/4-106-X) + elseif ProfHead.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se incastro tirolo ( 1/2/3/4-136-X) + elseif TyroleanDovetail.Identify( Proc) then + bOk, sErr = TyroleanDovetail.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se giunto coda di rondine ( 1/2/3/4-138-X) + elseif Dovetail.Identify( Proc) then + bOk, sErr = Dovetail.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se contorno libero ( 0/3/4-250-X) + elseif FreeContour.Identify( Proc) then + -- esecuzione contorno + bOk, sErr = FreeContour.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se decorazione ( 0/3/4-959-X) + elseif Decor.Identify( Proc) then + -- esecuzione decorazione + bOk, sErr = Decor.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti feature sconosciuta + else + sErr = 'Error on process ' .. tostring( Proc.Id) .. ' unknown type (' .. tonumber( Proc.Grp) .. '-' .. tonumber( Proc.Prc) .. ')' + EgtOutLog( sErr) + bOk = false + end + return bOk, sErr, bNewPhase +end + +------------------------------------------------------------------------------------------------------------- +local function VerifyNeedForHeadCut( vProc, bSomeDown, bSomeSide) + -- verifico se necessaria la rotazione di 90 gradi + if not bSomeSide then + return false + end + -- verifico se viene dopo un pezzo diviso quando ruotato (quindi con rimanenza scaricata sul carico) + local nPrevPhase = EgtGetCurrPhase() - 1 + local nPrevDispId = EgtGetPhaseDisposition( nPrevPhase) or GDB_ID.NULL + local nPrevType = EgtGetInfo( nPrevDispId, 'TYPE') + if nPrevType ~= 'MID2' and nPrevType ~= 'END2' then + return false + end + -- verifico se c'è una sola lavorazione ribaltata (quindi è il taglio di testa) + local nDownCnt = 0 + for i = 1, #vProc do + if vProc[i].Down then + nDownCnt = nDownCnt + 1 + end + end + return ( nDownCnt == 1) +end + +------------------------------------------------------------------------------------------------------------- +local function MoveDrillsOnTenon( vProc) + -- se non richiesto spostamento fori su tenone, esco + if not BD.OFFSET_DRILL_TENON or abs( BD.OFFSET_DRILL_TENON) < 0.1 then return end + -- ciclo sulle feature + for i = 1, #vProc do + if Tenon.Identify( vProc[i]) then + for j = 1, #vProc do + if Drill.Identify( vProc[j]) then + -- se esiste intersezione tra tenone e foro + if vProc[i].Box:getMin():getX() < vProc[j].Box:getMax():getX() + 100 * GEO.EPS_SMALL and + vProc[j].Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL then + -- verifico se foro già spostato + if not EgtExistsInfo( vProc[j].Id, 'MOV') then + -- recupero curva ausiliaria del foro + local AuxDriId = EgtGetInfo( vProc[j].Id, 'AUXID', 'i') + AuxDriId = EgtIf( AuxDriId, AuxDriId + vProc[j].Id, nil) + -- recupero versore normale del tenone + local AuxTenId = EgtGetInfo( vProc[i].Id, 'AUXID', 'i') + AuxTenId = EgtIf( AuxTenId, AuxTenId + vProc[i].Id, GDB_ID.NULL) + local vtExtr = EgtCurveExtrusion( AuxTenId, GDB_RT.GLOB) + -- se tutto ok, eseguo spostamento + if AuxDriId and vtExtr then + local vtMove = -vtExtr * BD.OFFSET_DRILL_TENON + EgtMove( AuxDriId, vtMove, GDB_RT.GLOB) + EgtSetInfo( vProc[j].Id, 'MOV', vtMove) + end + end + end + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamExec.ProcessFeatures() + -- verifica se possibile rotazione di 90 gradi + BD.ROT90 = BD.ROT90 and Verify90DegRotation( EgtGetFirstRawPart()) + -- ciclo sui pezzi + local nTotErr = 0 + local Stats = {} + local nOrd = 1 + local nRawId = EgtGetFirstRawPart() + while nRawId do + -- verifico che il grezzo contenga pezzi oppure sia abbastanza lungo da essere scaricato coi carrelli + local nPartId = EgtGetFirstPartInRawPart( nRawId) + if not nPartId and EgtGetRawPartBBox( nRawId):getDimX() < BD.MinRaw then break end + -- aggiungo la fase, se non è la prima + if nOrd == 1 then + EgtSetCurrPhase( 1) + else + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) + end + local nPhase = EgtGetCurrPhase() + local nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', EgtIf( nPartId, 'START', 'REST')) + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( nRawId) .. ' Part=' .. tostring( nPartId) .. ' ***', 1) + -- ingombro del grezzo e sovramateriale di testa + local b3Raw = EgtGetRawPartBBox( nRawId) + local dCurrOvmH = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 + -- recupero le feature di lavorazione della trave + local vProc = CollectFeatures( nPartId, b3Raw, dCurrOvmH) + -- le ordino lungo X + OrderFeatures( vProc, b3Raw) + -- le classifico + local bAllOk, bSomeDown, bSomeSide, bSplitRot = ClassifyFeatures( vProc, b3Raw, Stats) + if not bAllOk then + nTotErr = nTotErr + 1 + end + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc, b3Raw) + end + -- verifico se comunque necessario taglio di testa + local bNeedHCut = VerifyNeedForHeadCut( vProc, bSomeDown, bSomeSide) + -- eventuale spostamento fori sui tenoni + MoveDrillsOnTenon( vProc) + -- se richiesto ribaltamento (oppure rotazione) + if bSomeDown or bSomeSide then + -- ribalto le travi della fase corrente + local nRId = nRawId + while nRId do + EgtRotateRawPart( nRId, X_AX(), 180) + nRId = EgtGetNextRawPart( nRId) + end + EgtSetInfo( nDispId, 'ROT', -2) + -- inserisco le lavorazioni da lavorare ribaltate + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and Proc.Down then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut, b3Raw) + if not bOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + elseif sMsg and #sMsg > 0 then + table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + else + table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + EgtRotateRawPart( nRawId, X_AX(), 180) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'MID2') + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtSetInfo( nDispId, 'ROT', -2) + end + end + end + -- se separazione non ancora effettuata, aggiungo nuova fase con le travi in posizione standard + if not bSplitRot then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) + -- altrimenti + else + -- aggiungo nuova fase con le travi in posizione standard + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + local nType = 'MID' + if bSplitRot then nType = EgtIf( bSomeSide, 'MID2', 'END2') end + EgtSetInfo( nDispId, 'TYPE', nType) + EgtSetInfo( nDispId, 'ORD', nOrd) + end + -- se richiesta rotazione + if bSomeSide then + -- vettore movimento grezzi per rotazione di 90deg + local dDeltaYZ = EgtGetRawPartBBox( nRawId):getDimY() - EgtGetRawPartBBox( nRawId):getDimZ() + local vtMove = Vector3d( 0, dDeltaYZ / 2, dDeltaYZ / 2) + local bPreMove = ( dDeltaYZ < 0) + -- ruoto le travi della fase corrente + local nRId = nRawId + while nRId do + if bPreMove then EgtMoveRawPart( nRId, vtMove) end + EgtRotateRawPart( nRId, X_AX(), 90) + if not bPreMove then EgtMoveRawPart( nRId, vtMove) end + nRId = EgtGetNextRawPart( nRId) + end + EgtSetInfo( nDispId, 'ROT', -1) + -- inserisco le lavorazioni da lavorare ruotate + local nSideMchOk = 0 + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and Proc.Side then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, false, b3Raw) + if not bOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + elseif sMsg and #sMsg > 0 then + table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + else + table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + if bOk then nSideMchOk = nSideMchOk + 1 end + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + if bPreMove then EgtMoveRawPart( nRawId, vtMove) end + EgtRotateRawPart( nRawId, X_AX(), 90) + if not bPreMove then EgtMoveRawPart( nRawId, vtMove) end + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'MID2') + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtSetInfo( nDispId, 'ROT', -1) + end + end + end + -- se non sono state inserite lavorazioni di fianco, elimino la fase perchè inutile e dannosa + if nSideMchOk == 0 then + EgtRemoveLastPhase() + end + -- se separazione non ancora effettuata, aggiungo nuova fase con le travi in posizione standard + if not bSplitRot then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) + -- altrimenti + else + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', EgtIf( not bSplitRot, 'MID', 'END2')) + EgtSetInfo( nDispId, 'ORD', nOrd) + end + -- inserisco le lavorazioni non ribaltate della trave + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and not ( Proc.Down or Proc.Side) then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, false, 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 + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'END') + EgtSetInfo( nDispId, 'ORD', nOrd) + end + end + end + -- passo al grezzo successivo + nOrd = nOrd + 1 + nRawId = EgtGetNextRawPart( nRawId) + end + + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + local bApplOk, sApplErrors = EgtApplyAllMachinings() + if not bApplOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err = 1, Msg=sApplErrors, Rot=0, CutId=0, TaskId=0}) + end + + return ( nTotErr == 0), Stats +end + +------------------------------------------------------------------------------------------------------------- +return BeamExec diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/BeamLib.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/BeamLib.lua new file mode 100644 index 0000000..803c067 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/BeamLib.lua @@ -0,0 +1,876 @@ +-- BeamLib.lua by Egaltech s.r.l. 2020/08/18 +-- Libreria globale per Travi +-- 2020/07/28 Corretto calcolo attacchi e uscite di lame per non uscire dalla faccia sotto. +-- 2020/08/18 Aggiunto a GetNearestParalOpposite e GetNearestOrthoOpposite parametro opzionale vtNorm. + +-- Tabella per definizione modulo +local BeamLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' BeamLib started', 1) + +------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetAddGroup( PartId) + -- recupero il nome del gruppo di lavoro corrente + local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL) + if not sMchGrp then return nil, nil end + -- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco + local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp) + -- restituisco Id e Nome + return AddGrpId, sMchGrp +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.CreateOrEmptyAddGroup( PartId) + -- recupero i dati del gruppo aggiuntivo + local AddGrpId, sMchGrp = BeamLib.GetAddGroup( PartId) + if not sMchGrp then return false end + -- se esiste lo svuoto + if AddGrpId then + return EgtEmptyGroup( AddGrpId) + end + -- altrimenti lo creo + AddGrpId = EgtGroup( PartId or GDB_ID.NULL) + if not AddGrpId then return false end + -- assegno nome, flag di layer per gruppo di lavoro e colore + EgtSetName( AddGrpId, sMchGrp) + EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup()) + EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 50)) + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPartStartFace( PartId, b3Solid) + -- recupero gruppo per geometria aggiuntiva + local AddGrpId = BeamLib.GetAddGroup( PartId) + if not AddGrpId then + local sErr = 'Error on process StartFace impossible to find AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo nuovo taglio iniziale + local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMax(), X_AX(), b3Solid, GDB_RT.GLOB) + if not nStmId then + local sErr = 'Error on process StartFace impossible to create Face' + EgtOutLog( sErr) + return false, sErr + end + -- applico gli opportuni attributi di feature + EgtSetName( nStmId, 'StartCut') + EgtSetInfo( nStmId, 'GRP', 1) + EgtSetInfo( nStmId, 'PRC', 340) + -- verifico se sostituisce un taglio di testa già presente + local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PartId, 'Processings') or GDB_ID.NULL) + while nProcId do + local nGrp = EgtGetInfo( nProcId, 'GRP', 'i') or 0 + local nProc = EgtGetInfo( nProcId, 'PRC', 'i') or 0 + if ( nGrp == 1 or nGrp == 2) and nProc == 10 then + local ptC, vtN = EgtSurfTmFacetCenter( nProcId, 0, GDB_ID.ROOT) + if ptC and vtN and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL then + EgtSetInfo( nStmId, 'ORI', nProcId) + end + end + nProcId = EgtGetNext( nProcId) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPartEndFace( PartId, b3Solid) + -- recupero gruppo per geometria aggiuntiva + local AddGrpId = BeamLib.GetAddGroup( PartId) + if not AddGrpId then + local sErr = 'Error on process EndFace impossible to find AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo nuovo taglio finale + local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMin(), -X_AX(), b3Solid, GDB_RT.GLOB) + if not nStmId then + local sErr = 'Error on process EndFace impossible to create Face' + EgtOutLog( sErr) + return false, sErr + end + -- applico gli opportuni attributi di feature + EgtSetName( nStmId, 'EndCut') + EgtSetInfo( nStmId, 'GRP', 2) + EgtSetInfo( nStmId, 'PRC', 350) + -- verifico se sostituisce un taglio di coda già presente + local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PartId, 'Processings') or GDB_ID.NULL) + while nProcId do + local nGrp = EgtGetInfo( nProcId, 'GRP', 'i') or 0 + local nProc = EgtGetInfo( nProcId, 'PRC', 'i') or 0 + if ( nGrp == 1 or nGrp == 2) and nProc == 10 then + local ptC, vtN = EgtSurfTmFacetCenter( nProcId, 0, GDB_ID.ROOT) + if ptC and vtN and AreSameVectorApprox( vtN, -X_AX()) and abs( ptC:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL then + EgtSetInfo( nStmId, 'ORI', nProcId) + end + end + nProcId = EgtGetNext( nProcId) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPhaseWithRawParts( nFirstRawId, OriTR, dDeltaSucc) + EgtAddPhase() + local nRawId = nFirstRawId + local dRawMove = 0 + while nRawId do + EgtKeepRawPart( nRawId) + EgtMoveToCornerRawPart( nRawId, OriTR, MCH_CR.TR) + EgtMoveRawPart( nRawId, Vector3d( - dRawMove, 0, 0)) + if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end + dRawMove = dRawMove + EgtGetRawPartBBox( nRawId):getDimX() + nRawId = EgtGetNextRawPart( nRawId) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartOnTop( nCrvId) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- cerco l'estremo più alto e lo imposto come inizio + local dUmax = 0 + local dZmax = - GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf, 0.5 do + local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) + if ptP and ptP:getZ() > dZmax + GEO.EPS_SMALL then + dZmax = ptP:getZ() + dUmax = dU + end + end + if abs( dUmax - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUmax) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartOnLonger( nCrvId) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- cerco l'entità più lunga e la imposto come inizio + local dUmax = 0 + local dLmax = - GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf - 1 do + local ptP1 = EgtUP( nCrvId, dU, GDB_ID.ROOT) + local ptP2 = EgtUP( nCrvId, dU + 0.5, GDB_ID.ROOT) + local ptP3 = EgtUP( nCrvId, dU + 1.0, GDB_ID.ROOT) + local dL = dist( ptP1, ptP2) + dist( ptP2, ptP3) + if dL > dLmax + GEO.EPS_SMALL then + dLmax = dL + dUmax = dU + end + end + if abs( dUmax - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUmax) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- recupero il versore normale al piano di lavoro o estrusione + local vtN = EgtCurveExtrusion( nCrvId, GDB_ID.ROOT) + -- coefficienti per riportare la distanza nel piano di lavoro + local dCoeffX = 1 / ( sqrt( 1 - vtN:getX() * vtN:getX())) + local dCoeffY = 1 / ( sqrt( 1 - vtN:getY() * vtN:getY())) + local dCoeffZ = 1 / ( sqrt( 1 - vtN:getZ() * vtN:getZ())) + -- cerco l'estremo più vicino al box e lo imposto come inizio (escluso Zmin) + local dUopt = 0 + local dDopt = GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf, 0.5 do + local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) + if ptP then + local vtMin = ptP - b3Raw:getMin() + local vtMax = ptP - b3Raw:getMax() + local dD = abs( vtMin:getX()) * dCoeffX + dD = min( abs( vtMax:getX()) * dCoeffX, dD) + dD = min( abs( vtMin:getY()) * dCoeffY, dD) + dD = min( abs( vtMax:getY()) * dCoeffY, dD) + dD = min( abs( vtMax:getZ()) * dCoeffZ, dD) + if dD < dDopt + GEO.EPS_SMALL then + dDopt = dD + dUopt = dU + end + end + end + if abs( dUopt - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUopt) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetPointDirDepth( nPartId, ptP, vtDir) + -- recupero il solido del grezzo + local nSolId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, 'Box') + if not nSolId then return end + -- interseco con la retta + local bOk, vType, vPar = EgtLineSurfTmInters( ptP, vtDir, nSolId, GDB_RT.GLOB) + if not bOk then return end + if not vPar or #vPar == 0 then return -2 end + local dLenIn, dLenOut + for i = 1, #vPar do + if vPar[i] < 0 then + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = -1 + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN then + dLenIn = -2 + end + else + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = vPar[i] + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN or vType[i] == GDB_SLT.TOUCH then + dLenOut = vPar[i] + end + end + end + return dLenIn, dLenOut +end + +--------------------------------------------------------------------- +function BeamLib.GetNearestParalOpposite( vtRef, vtNorm) + -- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa + local vtMyRef = Vector3d( vtRef) + if vtNorm then + vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm + vtMyRef:normalize() + end + -- devo confrontare la componente orizzontale con quella verticale + local dHorSq = vtMyRef:getX() * vtMyRef:getX() + vtMyRef:getY() * vtMyRef:getY() + local dVertSq =vtMyRef:getZ() * vtMyRef:getZ() + -- se prevalente la componente orizzontale + if dHorSq >= dVertSq then + if abs( vtMyRef:getX()) > abs( vtMyRef:getY()) then + if vtMyRef:getX() > 0 then + return MCH_MILL_FU.PARAL_LEFT + else + return MCH_MILL_FU.PARAL_RIGHT + end + else + if vtMyRef:getY() > 0 then + return MCH_MILL_FU.PARAL_FRONT + else + return MCH_MILL_FU.PARAL_BACK + end + end + -- altrimenti prevale la verticale + else + if vtMyRef:getZ() > 0 then + return MCH_MILL_FU.PARAL_DOWN + else + return MCH_MILL_FU.PARAL_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetNearestOrthoOpposite( vtRef, vtNorm) + -- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa + local vtMyRef = Vector3d( vtRef) + if vtNorm then + vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm + vtMyRef:normalize() + end + -- devo confrontare la componente orizzontale con quella verticale + local dHorSq = vtMyRef:getX() * vtMyRef:getX() + vtMyRef:getY() * vtMyRef:getY() + local dVertSq = vtMyRef:getZ() * vtMyRef:getZ() + -- se prevalente la componente orizzontale + if dHorSq >= dVertSq then + if abs( vtMyRef:getX()) >= abs( vtMyRef:getY()) then + if vtMyRef:getX() > 0 then + return MCH_MILL_FU.ORTHO_LEFT + else + return MCH_MILL_FU.ORTHO_RIGHT + end + else + if vtMyRef:getY() > 0 then + return MCH_MILL_FU.ORTHO_FRONT + else + return MCH_MILL_FU.ORTHO_BACK + end + end + -- altrimenti prevale la verticale + else + if vtMyRef:getZ() > 0 then + return MCH_MILL_FU.ORTHO_DOWN + else + return MCH_MILL_FU.ORTHO_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetOrtupOpposite( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return MCH_MILL_FU.ORTUP_LEFT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return MCH_MILL_FU.ORTUP_RIGHT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return MCH_MILL_FU.ORTUP_FRONT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return MCH_MILL_FU.ORTUP_BACK + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return MCH_MILL_FU.ORTUP_DOWN + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return MCH_MILL_FU.ORTUP_TOP + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetVersRef( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return X_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return -X_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return Y_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return -Y_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return Z_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return -Z_AX() + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetBoxFaceNorm( b3Box, ptP, vtV) + local vtNx = V_NULL() + if abs( ptP:getX() - b3Box:getMin():getX()) < 10 * GEO.EPS_SMALL then + vtNx = -X_AX() + elseif abs( ptP:getX() - b3Box:getMax():getX()) < 10 * GEO.EPS_SMALL then + vtNx = X_AX() + end + local vtNy = V_NULL() + if abs( ptP:getY() - b3Box:getMin():getY()) < 10 * GEO.EPS_SMALL then + vtNy = -Y_AX() + elseif abs( ptP:getY() - b3Box:getMax():getY()) < 10 * GEO.EPS_SMALL then + vtNy = Y_AX() + end + local vtNz = V_NULL() + if abs( ptP:getZ() - b3Box:getMin():getZ()) < 10 * GEO.EPS_SMALL then + vtNz = -Z_AX() + elseif abs( ptP:getZ() - b3Box:getMax():getZ()) < 10 * GEO.EPS_SMALL then + vtNz = Z_AX() + end + local dNxDotV = vtNx * vtV + local dNyDotV = vtNy * vtV + local dNzDotV = vtNz * vtV + if dNxDotV > dNyDotV and dNxDotV > dNzDotV then + return vtNx + elseif dNyDotV > dNzDotV and dNyDotV > dNxDotV then + return vtNy + else + return vtNz + end +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceElevation( nSurfId, nFac, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFac, GDB_ID.ROOT) + if not ptC or not vtN then return 0 end + local frOCS = Frame3d( ptC, vtN) ; + local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS) + local dElev = b3Box:getDimZ() + if nPartId then + local _, dCenElev = BeamLib.GetPointDirDepth( nPartId, ptC, vtN) + if dCenElev and dCenElev > dElev then + dElev = dCenElev + end + end + return dElev +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc, dCosSideAng) + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nSurfId) + if not dCosSideAng then + dCosSideAng = -0.09 + end + -- recupero le normali delle facce + local vvtN = {} + for i = 1, nFacCnt do + local _, vtN = EgtSurfTmFacetCenter( nSurfId, i - 1, GDB_ID.ROOT) + vvtN[i] = vtN ; + end + -- adiacenze e sottosquadra delle facce + local vAdj = {} + local vUcut = {} + local vOrtho = {} + for i = 1, nFacCnt do + -- recupero le adiacenze del loop esterno + local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + vAdj[i] = nCount + -- ne determino eventuale sottosquadra ( dal valore passato o - 3deg) e ortogonalità + local bUcut = false + local bOrtho = true + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + local vtN = vvtN[i] + local vtN2 = vvtN[vFacAdj[j]+1] + local dResV = vtN * vtN2 + if dResV < dCosSideAng - GEO.EPS_SMALL then + bUcut = true + end + if abs( dResV) > 2 * GEO.EPS_SMALL then + bOrtho = false + end + end + end + vUcut[i] = bUcut + vOrtho[i] = bOrtho + end + -- se 4 facce tutte con adiacenza 2, allora è un tunnel + if nFacCnt == 4 then + if vAdj[1] == 2 and vAdj[2] == 2 and vAdj[3] == 2 and vAdj[4] == 2 then + -- se tutte le facce sono ortogonali tra loro esco con un flag che ne indica questa propietà + if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true and vOrtho[4] == true then + return -1, GEO.INFINITO, true + else + return -1, GEO.INFINITO + end + end + end + -- se 3 facce con una che ha 2 adiacenze e le altre hanno 1 adiacenza, allora è una semi-fessura + if bCompare3Fc and nFacCnt == 3 then + local nCount2Adc = 0 + local nCount1Adc = 0 + -- ottengo il numero di facce con due adiacenze e il numero di facce con una adiacenza + for i = 1, #vAdj do + if vAdj[i] == 2 then + nCount2Adc = nCount2Adc + 1 + elseif vAdj[i] == 1 then + nCount1Adc = nCount1Adc + 1 + end + end + -- se il numero di adiacenze corrisponde + if nCount2Adc == 1 and nCount1Adc == 2 then + if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true then + return -1, GEO.INFINITO, true + else + return -1, GEO.INFINITO + end + end + end + -- recupero le facce non in sottosquadra e con il maggior numero di adiacenze + local nFacInd = {} + local nMaxAdj = -1 + local nSupAdj = -1 + for i = 1, nFacCnt do + if not vUcut[i] then + if vAdj[i] > nMaxAdj then + nFacInd = {} + nFacInd[1] = i - 1 + nMaxAdj = vAdj[i] + elseif vAdj[i] == nMaxAdj and nMaxAdj > 0 then + table.insert( nFacInd, i - 1) + end + end + if vAdj[i] > nSupAdj then + nSupAdj = vAdj[i] + end + end + -- verifico non ci sia una faccia in sottosquadra con adiacenza superiore + if nSupAdj > nMaxAdj then + return -2, GEO.INFINITO + end + -- premio la faccia con minore elevazione + local nFacOpt, nFacOpt2 + local dMinElev, dMinElev2 = GEO.INFINITO, GEO.INFINITO + for i = 1, #nFacInd do + local dElev = BeamLib.GetFaceElevation( nSurfId, nFacInd[i], nPartId) + if dElev < dMinElev then + if dMinElev < dMinElev2 then + nFacOpt2 = nFacOpt + dMinElev2 = dMinElev + end + nFacOpt = nFacInd[i] + dMinElev = dElev + elseif dElev < dMinElev2 then + nFacOpt2 = nFacInd[i] + dMinElev2 = dElev + end + end + return nFacOpt, dMinElev, nFacOpt2, dMinElev2 +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceHvRefDim( nSurfId, nFacet) + -- recupero centro e normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + if not ptC or not vtN then return end + -- riferimento tipo OCS della faccia (X orizz, Y max pendenza, Z normale) + local frHV = Frame3d( ptC, vtN) + if frHV:getVersY():getZ() < 0 then + frHV:rotate( ptC, vtN, 180) + end + -- determino l'ingombro in questo riferimento + local b3HV = EgtSurfTmGetFacetBBoxRef( nSurfId, nFacet, GDB_BB.STANDARD, frHV) + -- restituisco i valori calcolati + return frHV, b3HV:getDimX(), b3HV:getDimY() +end + +--------------------------------------------------------------------- +function BeamLib.CalcLeadInOutGeom( ptP1, ptP2, vtV1, vtV2, vtN, dRad, vtRef, dCutExtra, b3Box) + -- Mi assicuro che i vettori ingresso/uscita giacciano nel piano + vtV1 = vtV1 - vtV1 * vtN * vtN ; vtV1:normalize() + vtV2 = vtV2 - vtV2 * vtN * vtN ; vtV2:normalize() + -- Versore tangente al taglio + local vtTg = ptP2 - ptP1 ; + vtTg = vtTg - vtTg * vtN * vtN ; vtTg:normalize() + -- Sistema di riferimento intrinseco al taglio + local vtX = vtTg ^ vtN + local frFace = Frame3d( ptP1, vtX, vtTg, vtN) + EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Versori di attacco e uscita + local dCos1 = vtV1 * vtRef + local dCos2 = vtV2 * vtRef + local vtLi, vtLo + if dCos1 > dCos2 then + vtLi = vtV1 + vtLo = vtV1 + else + vtLi = vtV2 + vtLo = vtV2 + end + local bRight = ( vtX * vtLi > 0) + -- Versori di attacco e uscita nel riferimento intrinseco al taglio + local vtLiL = Vector3d( vtLi) ; vtLiL:toLoc( frFace) + local vtLoL = Vector3d( vtLo) ; vtLoL:toLoc( frFace) + -- Spostamento punti per effetto dell'extra o della deficienza di taglio + ptP1 = ptP1 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) + ptP2 = ptP2 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) + -- Non va considerata l'uscita dalla faccia sotto, pertanto va abbassata + local b3MyBox = BBox3d( b3Box) ; b3MyBox:Add( b3MyBox:getMin() - 1000 * Z_AX()) + -- Attacco + local dLiTang = 10000 + local dLiPerp = 10000 + local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtLi, b3MyBox) + if bLiOk and #vLiPar > 0 then + -- con la prima faccia di uscita + local dLen = vLiPar[#vLiPar] + local ptInt = ptP1 + vtLi * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3MyBox, ptInt, vtLi) + EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLi * vtFN) + local dLiLen = dLen + dAddLen + EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) + dLiTang = - dLiLen * vtLiL:getY() + dLiPerp = EgtIf( bRight, dLiLen, - dLiLen) * vtLiL:getX() + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtLi, b3Mod) + if bLiOk2 and #vLiPar2 > 0 then + local dLen2 = vLiPar2[#vLiPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP1 + vtLi * dLen2, vtLi) + EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLi * vtFN2) + local dLiLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) + local dLiTang2 = - dLiLen2 * vtLiL:getY() + local dLiPerp2 = EgtIf( bRight, dLiLen2, - dLiLen2) * vtLiL:getX() + if dLiLen2 < dLiLen then + dLiTang = dLiTang2 + dLiPerp = dLiPerp2 + end + end + end + -- Lunghezza di uscita + local dLoTang = 10000 + local dLoPerp = 10000 + local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtLo, b3MyBox) + if bLoOk and #vLoPar > 0 then + -- con la prima faccia di uscita + local dLen = vLoPar[#vLoPar] + local ptInt = ptP2 + vtLo * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3MyBox, ptInt, vtLo) + EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLo * vtFN) + local dLoLen = dLen + dAddLen + EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) + dLoTang = dLoLen * vtLoL:getY() + dLoPerp = EgtIf( bRight, dLoLen, - dLoLen) * vtLoL:getX() + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtLo, b3Mod) + if bLoOk2 and #vLoPar2 > 0 then + local dLen2 = vLoPar2[#vLoPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP2 + vtLo * dLen2, vtLo) + EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLo * vtFN2) + local dLoLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) + local dLoTang2 = dLoLen2 * vtLoL:getY() + local dLoPerp2 = EgtIf( bRight, dLoLen2, - dLoLen2) * vtLoL:getX() + if dLoLen2 < dLoLen then + dLoTang = dLoTang2 + dLoPerp = dLoPerp2 + end + end + end + return dLiTang, dLiPerp, dLoTang, dLoPerp +end + +--------------------------------------------------------------------- +function BeamLib.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dRad, vtRef, dCutExtra, b3Box) + -- Versore tangente al taglio + local vtTg = ptP2 - ptP1 ; + vtTg = vtTg - vtTg * vtN * vtN ; vtTg:normalize() + -- Sistema di riferimento intrinseco al taglio + local vtX = vtTg ^ vtN + local frFace = Frame3d( ptP1, vtX, vtTg, vtN) + if ( vtX * vtRef < 0) then + vtX = - vtX + end + EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Spostamento punti per effetto dell'extra o della deficienza di taglio + ptP1 = ptP1 - vtX * dCutExtra + ptP2 = ptP2 - vtX * dCutExtra + -- Non va considerata l'uscita dalla faccia sotto, pertanto va abbassata + local b3MyBox = BBox3d( b3Box) ; b3MyBox:Add( b3MyBox:getMin() - 1000 * Z_AX()) + -- Attacco + local dLiTang = 10000 + local dLiPerp = 0 + local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtTg, b3MyBox) + if bLiOk and #vLiPar > 0 then + local dLen = vLiPar[1] + local ptInt = ptP1 + vtTg * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3MyBox, ptInt, -vtTg) + EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) + local dLiLen = dLen + dAddLen + EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) + dLiTang = - dLiLen + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtTg, b3Mod) + if bLiOk2 and #vLiPar2 > 0 then + local dLen2 = vLiPar2[1] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP1 + vtTg * dLen2, -vtTg) + EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) + local dLiLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) + if -dLiLen2 < -dLiLen then + dLiTang = - dLiLen2 + end + end + end + -- Lunghezza di uscita + local dLoTang = 10000 + local dLoPerp = 0 + local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtTg, b3MyBox) + if bLoOk and #vLoPar > 0 then + local dLen = vLoPar[#vLoPar] + local ptInt = ptP2 + vtTg * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3MyBox, ptInt, vtTg) + EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) + local dLoLen = dLen + dAddLen + EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) + dLoTang = dLoLen + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtTg, b3Mod) + if bLoOk2 and #vLoPar2 > 0 then + local dLen2 = vLoPar2[#vLoPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP2 + vtTg * dLen2, vtTg) + EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) + local dLoLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) + if dLoLen2 < dLoLen then + dLoTang = dLoLen2 + end + end + end + return dLiTang, dLiPerp, dLoTang, dLoPerp +end + +--------------------------------------------------------------------- +function BeamLib.MakeOneFaceBySaw( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDwnUp, dCutExtra, dCutSic, dCutOffset, dAccStart, sNotes, b3Raw) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + -- risolvo parametro ambiguo + local nOrthoOpposite + local vtOrthO + if isVector3d( Par5) then + nOrthoOpposite = BeamLib.GetNearestOrthoOpposite( Par5, vtN) + vtOrthO = Vector3d( Par5) + else + nOrthoOpposite = Par5 + vtOrthO = BeamLib.GetVersRef( Par5) + end + -- linea o bilinea di lavorazione (qui uso nOrthoOpposite per ripetere esattamente il calcolo del Mach) + local ptP1, ptPm, ptP2, vtV1, vtV2, dLen, dWidth = EgtSurfTmFacetOppositeSide( nSurfId, nFacet, BeamLib.GetVersRef( nOrthoOpposite), GDB_ID.ROOT) + if not dLen or dLen < 1.1 or not dWidth or dWidth < 1.1 then + local sWarn = 'Face ' .. string.format( '%d,%d', nSurfId, nFacet) .. ' skipped : too small' + EgtOutLog( sWarn, 1) + return true, '' + end + vtV1 = - vtV1 + local bInvert = ( ptP2:getZ() < ptP1:getZ() - 100 * GEO.EPS_SMALL) + if bInvert then + ptP1, ptP2 = ptP2, ptP1 + vtV1, vtV2 = vtV2, vtV1 + end + local vtTg = ptP2 - ptP1 ; vtTg:normalize() + local dAllStart = 0 + local dAllEnd = 0 + -- se bilinea, scarto la parte più allineata con la direzione ortogonale + if ( ( ptPm - ptP1) - ( ptPm - ptP1) * vtTg * vtTg):len() > 100 * GEO.EPS_SMALL then + local vtTg1 = ptPm - ptP1 ; vtTg1:normalize() + local vtTg2 = ptP2 - ptPm ; vtTg2:normalize() + local dDist1 = dist( ptP1, ptPm) + local dDist2 = dist( ptP2, ptPm) + --if dDist1 * ( vtTg1 ^ vtOrthO):len() > dDist2 * ( vtTg2 ^ vtOrthO):len() then + if abs( vtTg1 * vtOrthO) < abs( vtTg2 * vtOrthO) then + ptP2 = Point3d( ptPm) + dAllEnd = - dDist2 - 10 * GEO.EPS_SMALL + else + ptP1 = Point3d( ptPm) + dAllStart = - dDist1 - 10 * GEO.EPS_SMALL + end + vtTg = ptP2 - ptP1 ; vtTg:normalize() + end + -- verifico se lavorazione con lama sotto e testa sopra + if not dVzLimDwnUp then dVzLimDwnUp = -0.5 end + local bDownUp = ( vtN:getZ() < dVzLimDwnUp) + local nFaceUse = nOrthoOpposite + if bDownUp then nFaceUse = BeamLib.GetOrtupOpposite( nOrthoOpposite) end + local bWsRight = ( bInvert ~= bDownUp) + local nWorkSide = EgtIf( bWsRight, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) + -- Versore di riferimento + local vtRef = Vector3d( vtTg) + vtRef:rotate( vtN, EgtIf( bInvert, -90, 90)) + -- Versore esterno + local vtOut = vtRef - vtRef * vtTg * vtTg ; vtOut:normalize() + -- Versore ausiliario (direzione braccio) + local vtAux = Vector3d( vtN:getX(), vtN:getY(), 0) ; vtAux:normalize() + vtAux:rotate( Z_AX(), EgtIf( bWsRight, 90, -90)) + if vtAux:isSmall() then + vtAux = Vector3d( vtOut:getX(), vtOut:getY(), 0) ; vtAux:normalize() + else + if abs( vtAux * vtOut) < GEO.EPS_SMALL then + if abs( vtTg:getZ()) > 0.5 then + if vtAux * vtRef < 0 then + vtAux = - vtAux + end + elseif vtAux * vtTg > 0 then + vtAux = - vtAux + end + elseif vtAux * vtOut < 0 then + vtAux = - vtAux + end + end + -- parametri di attacco/uscita + local b3Box = BBox3d( b3Raw) + b3Box:expand( dCutSic) + local dLiTang, dLiPerp, dLoTang, dLoPerp + local ptP1act = ptP1 + vtN * dCutOffset + local ptP2act = ptP2 + vtN * dCutOffset + if ( vtV1:getZ() > -0.5 or vtV2:getZ() > -0.5) and ( abs( vtV1:getY()) > 0.707 or abs( vtV2:getY()) > 0.707 or vtN:getZ() < 0.95) then + dLiTang, dLiPerp, dLoTang, dLoPerp = BeamLib.CalcLeadInOutGeom( ptP1act, ptP2act, vtV1, vtV2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + else + dLiTang, dLiPerp, dLoTang, dLoPerp = BeamLib.CalcLeadInOutTangGeom( ptP1act, ptP2act, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + end + -- posizione braccio + EgtOutLog( 'vtN=' .. tostring( vtN) .. ' vtRef=' .. tostring( vtRef) .. ' vtOut=' .. tostring( vtOut) .. ' vtAux=' .. tostring( vtAux), 3) + local nSCC = MCH_SCC.NONE + if abs( vtAux:getX()) > abs( vtAux:getY()) then + nSCC = EgtIf( ( vtAux:getX() > 0), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + else + nSCC = EgtIf( ( vtAux:getY() > 0), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + -- inserisco la lavorazione di taglio + local sName = 'Cut_' .. ( EgtGetName( nSurfId) or tostring( nSurfId)) .. '_' .. tostring( nFacet + 1) + local nMchFId = EgtAddMachining( sName, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + sName = EgtGetOperationName( nMchFId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nSurfId, nFacet}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, bInvert) + EgtSetMachiningParam( MCH_MP.WORKSIDE, nWorkSide) + -- affondamento aggiuntivo + EgtSetMachiningParam( MCH_MP.OFFSR, -dCutExtra) + -- offset longitudinale + EgtSetMachiningParam( MCH_MP.OFFSL, EgtIf( bDownUp, -dCutOffset, dCutOffset)) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLiTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLiPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLoTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLoPerp) + -- imposto allungamenti iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAllStart - dAccStart) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAllEnd) + -- eventuali note + if sNotes and #sNotes > 0 then EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, sName, nMchFId +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.UpdateHCING( nRawId, dHCI, dDist) + local dOldHCI = EgtGetInfo( nRawId, 'HCING', 'd') or 0 + if dDist and dDist > dOldHCI + 10 then + return + end + if dHCI > dOldHCI then + EgtSetInfo( nRawId, 'HCING', dHCI) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.UpdateTCING( nRawId, dTCI) + local dOldTCI = EgtGetInfo( nRawId, 'TCING', 'd') or 0 + if dTCI > dOldTCI then + EgtSetInfo( nRawId, 'TCING', dTCI) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetNzLimDownUp( b3Raw) + return EgtIf( b3Raw:getDimZ() < 200, -0.5, -0.258) +end + +------------------------------------------------------------------------------------------------------------- +return BeamLib diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/DiceCut.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/DiceCut.lua new file mode 100644 index 0000000..6a8f6f4 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/DiceCut.lua @@ -0,0 +1,625 @@ +-- DiceCut.lua by Egaltech s.r.l. 2020/04/21 +-- Gestione dei piano paralleli nei tagli lunghi: equidistanziamento dei piani paralleli + +-- Tabella per definizione modulo +local DiceCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' DiceCut started', 1) + +-- Dati +local BD = require( 'BeamData') + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- creo i piani paralleli +-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptC: il punto centrale del piano della feature +-- vtN: il versore normale del piano della feature +-- nCopyPlane: 0 => genera una copia del piano passato, 1=> non genera una copia del piano passato +-- dOffset: offset dei piani paralleli +-- nStep: numero massimo di step +-- Color: colre del fascio di piani +-- dTolerance*: distanza tra i piani paralleli e i piani di taglio (se non esistono altre superfici può essere omesso) +-- bNoTolOnFirstCut*: elimina la tolleranza per il primo piano del fascio (se non esistono altre superfici può essere omesso) +-- ptCCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +local function GetParallelPlanes( nParent, BBoxRawPart, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) + local ptMyCCut + local AreaMin = 5*5 + if ptCCut and vtNCut then + if dTolerance then + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + local ptMyCCut1 + if ptCCut1 and vtNCut1 then + ptMyCCut1 = Point3d( ptCCut1 + 0 * vtNCut1) + end + local TabellaTmSurfParallel = {} + local i = nCopyPlane + while i < nStep do + local SurfId = EgtSurfTmPlaneInBBox( nParent, ptC + ( i * dOffset) * vtN, vtN, BBoxRawPart, GDB_RT.GLOB) + local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL) + if nFacet > 0 and vtNCut and ptMyCCut and EgtSurfArea(SurfId) > AreaMin then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut, -vtNCut, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut, -vtNCut, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and vtNCut1 and ptMyCCut1 and EgtSurfArea(SurfId) > AreaMin then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut1, -vtNCut1, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut1, -vtNCut1, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and EgtSurfArea(SurfId) > AreaMin then + table.insert( TabellaTmSurfParallel, SurfId) + EgtSetColor( SurfId, Color) + else + EgtErase( SurfId) + break + end + if dOffset == 0 then + break + end + i = i + 1 + end + return TabellaTmSurfParallel +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrderedCutTable: +-- nParent: il layer +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function GetOrderedCutTable( nParent, TabParallelPlanes, TabOrtoPlanes) + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + local TabellaOrderParallelCut1 = {} + + for IndexTmP=1, StepParallel do + TabellaOrderParallelCut1[IndexTmP] = {} + for IndexOrto=1, StepOrto do + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT) + local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + if Copy1Id and ptOrtoN then + EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB) + EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + local nFacet1 = EgtSurfTmFacetCount( Copy1Id) + local nFacet2 = EgtSurfTmFacetCount( Copy2Id) + if nFacet1 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + elseif nFacet2 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + break + else + table.insert( TabellaOrderParallelCut1[IndexTmP], Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + end + end + end + table.insert(TabellaOrderParallelCut1[IndexTmP], TabParallelPlanes[IndexTmP]) + end + return TabellaOrderParallelCut1 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrtoCutCenter: +-- idFacet: l'id della faccia +-- ptC: il punto centrale della faccia +-- vtN: il versore normale della faccia +-- vtO: il versore dei piani ortogonali +-- dOffsetEff: offset della distanza dal punto centrale +-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset +local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dNzLimDwnUp) + local FrameLocal = Frame3d( EgtSurfTmFacetCenter( FacetId, 0, GDB_ID.ROOT)) + EgtSetGridFrame(FrameLocal) + local IdAuxLocal = EgtGroup(EgtGetParent( FacetId), FrameLocal) + EgtSetName( IdAuxLocal, "AuxLocal") + local BoxLocal = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, FrameLocal) + local ptS = EgtGP( EgtSurfTmBBox( IdAuxLocal, BoxLocal, GDB_RT.GRID), GDB_ID.ROOT) + EgtErase( IdAuxLocal) + EgtSetGridFrame(Frame3d()) + -- riferimento intrinseco + local asseX = vtO + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + -- ingombro della faccia secondo questo riferimento + local Box = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, Frame) + local dLen = Box:getDimX() + local dWidth = Box:getDimY() + + -- se faccia con un lato piccolo e non diretta troppo verso il basso, non servono dice + if ( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > dNzLimDwnUp then + return nil, nil, nil + end + + local N = ceil( dLen / dOffsetEff) + local dOffsetRel = dLen / N + local dCopyPlane + local dCenOffs = ( Box:getMax():getX() + Box:getMin():getX()) / 2 + + if dLen <= dOffsetRel then + --dOffsetRel = 0 + dCopyPlane = 1 + elseif dLen <= 2 * dOffsetRel then + dOffsetRel = dOffsetEff + dCopyPlane = 0 + else + if N % 2 == 0 then + dCopyPlane = 0 + elseif N % 2 == 1 then + dCopyPlane = 0.5 + end + end + + + return dOffsetRel, dCopyPlane, dCenOffs, ptS +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- TableMesh: +-- TableOrto: tabella delle superfici dei piani ortogonali +-- TableParallel: tabella delle superfici dei piani paralleli +-- Forma una tabella unica delle superfici di taglio inserendo strati di tagli ortogonali alternati da strati di taglio parallelo +local function TableMesh( TableOrto, TableParallel) + local TableUnited = {} + for i=1, #TableOrto do + table.insert( TableUnited, TableOrto[i]) + table.insert( TableUnited, TableParallel[i]) + end + return TableUnited +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- FindValue: +-- tab: tabella da scansionare +-- val: valore da cercare +-- Verifica se tab contiene val, a supporto della funzione SortOrtoCutsByNormalMethod +local function FindValue( tab, val) + for index, value in ipairs( tab) do + if value == val then + return true + end + end + return false +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- SortOrtoCutsByNormalMethod: +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio sfruttando il prodotto dei versori normali (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function SortOrtoCutsByNormalMethod( TabParallelPlanes, TabOrtoPlanes) + -- tabella dei tagli ordinati + local TabOrderOrtoCut = {} + -- tabella ausiliaria dei dati inseriti nell'ordine + local TabAux = {} + -- ciclo di ordinamento + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + for IndexTmP=1, StepParallel do + TabOrderOrtoCut[IndexTmP] = {} + local ptParalN, vtNParalN = EgtSurfTmFacetCenter( TabParallelPlanes[IndexTmP][1], 0, GDB_ID.ROOT) + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- controlla che l'elemento da valutare non sia gia' stato inserito nella tabella + if not FindValue( TabAux, OrtoPlaneId) then + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( OrtoPlaneId, 0, GDB_ID.ROOT) + local scalarProduct = ( ptOrtoN - ptParalN) * vtNParalN + if scalarProduct > 0 then + table.insert( TabOrderOrtoCut[IndexTmP], OrtoPlaneId) + table.insert( TabAux, OrtoPlaneId) + end + end + end + end + end + -- cancello dal DB geometrico i tagli non inseriti + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- ricerco il taglio tra gli inseriti + if not FindValue( TabAux, OrtoPlaneId) then + EgtErase( OrtoPlaneId) + end + end + end + return TabOrderOrtoCut +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- VerifyFirstOrthoCut : +-- CutTable: tabella dei tagli +-- OffsetP: offset della distanza dal punto centrale +-- BBoxRawPart: il grezzo della barra +-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua +local function VerifyFirstOrthoCut( CutTable, OffsetP, BBoxRawPart, dNzLimDwnUp) + + if not CutTable[1] or not CutTable[2] then return end + + local CutOId = CutTable[1][1] + local Cut1Id = CutTable[2][1] + local Cut2Id = CutTable[2][2] + + if CutOId and Cut1Id and Cut2Id then + -- centri e normali delle due semifacce + local ptC1, vtN1 = EgtSurfTmFacetCenter( Cut1Id, 0, GDB_ID.ROOT) + local ptC2, vtN2 = EgtSurfTmFacetCenter( Cut2Id, 0, GDB_ID.ROOT) + -- normale alla faccia ortogonale + local _, vtO = EgtSurfTmFacetCenter( CutOId, 0, GDB_ID.ROOT) + vtO = vtO - vtO * vtN1 * vtN1 ; vtO:normalize() + -- calcolo lunghezza prima semi-faccia + local asseX1 = vtO + local asseY1 = vtN1 ^ asseX1 + local Frame1 = Frame3d( ptC1, ptC1+asseX1, ptC1+asseY1) + local Box1 = EgtGetBBoxRef( Cut1Id, GDB_BB.STANDARD, Frame1) + local x1 = Box1:getDimX() + -- calcolo lunghezza seconda semi-faccia + local asseX2 = vtO + local asseY2 = vtN2 ^ asseX2 + local Frame2 = Frame3d( ptC2, ptC2+asseX2, ptC2+asseY2) + local Box2 = EgtGetBBoxRef( Cut2Id, GDB_BB.STANDARD, Frame2) + local x2 = Box2:getDimX() + -- lunghezza totale faccia + local dLongSize = x1 + x2 + -- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti + if dLongSize <= OffsetP + 1.0 and vtN1:getZ() > dNzLimDwnUp then + local nParent = EgtGetParent( Cut1Id) + local SurfId = EgtSurfTmBySewing( nParent, { Cut1Id, Cut2Id}) + EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) + EgtErase( CutOId) + table.remove( CutTable[1], 1) + table.remove( CutTable[2], 1) + table.remove( CutTable[2], 1) + table.insert( CutTable[2], 1, SurfId) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- ricavo i vertici del box +local function CalcolaPuntiEstremiBox( BBoxRawPart) + local ptMin = BBoxRawPart:getMin() + local ptMax = BBoxRawPart:getMax() + local TBoxPoint = {} + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMin:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMin:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMax:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMax:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMin:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMin:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMax:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMax:getY(), ptMax:getZ()), On = true}) + return TBoxPoint +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- restituisce i punti che devono essere presi in considerazione per la costruzione del BoundingBox +local function VerificaEstremiGrezzo( ptC, vtN, TPoint) + for i = 1, #TPoint do + if ( TPoint[i].P - ptC) * vtN < 0 then + TPoint[i].On = false + end + end + return TPoint +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature +-- le funzioni commentate permettono di vedere la creazione di BoundingBox +local function DistanzaMassima( nParent, ptC1, vtN1, ptC2, vtN2, BBoxRawPart, TPoint) + -- calcolo il riferimento nel piano 1 + local Frame1 = Frame3d( ptC1, vtN1) + -- determino l'ingombro in questo riferimento della parte di trave compresa nel o nei piani + local BB1 = BBox3d() + -- punti di vertice della trave compresi + for i = 1, #TPoint do + if TPoint[i].On then + local ptP = Point3d( TPoint[i].P) + ptP:toLoc( Frame1) + BB1:Add( ptP) + end + end + -- eventuale altra faccia + if ptC2 and vtN2 then + local IdAux = EgtGroup( nParent) + local IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, ptC2, vtN2, BBoxRawPart, GDB_RT.GLOB) + EgtCutSurfTmPlane( IdSurf2, ptC1, -vtN1, false, GDB_RT.GLOB) + if IdSurf2 then + local BB2 = EgtGetBBoxRef( IdSurf2, GDB_BB.STANDARD, Frame1) + BB1:Add( BB2) + end + EgtErase( IdAux) + end + if not BB1:isEmpty() then + return ( BB1:getMax():getZ() + 0.1) + end + + return 0 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- DiceCut.GetDice : +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptCPlanes: il punto centrale del piano della feature +-- vtNPlanes: il versore normale del piano della feature +-- bGetOrtoPlanes*: se voglio calcolare i piani ortogonali al piano passato (se non esistono altre superfici può essere omesso) +-- ptCBond*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNBond*: il versore normale della superfice limitante (se non esistono altre superfici può essere omesso) +-- dOrthoMaxDim : massima profondità taglio se faccia singola perpendicolare facce laterali trave +-- dCustMaxDimDice: dimensione massima customizzata, sostituisce il parametro BD.MAX_DIM_DICE +---------------------------------------------------------------------------------------------------------------------------------------------------- +function DiceCut.GetDice( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, bGetOrtoPlanes, ptCBond, vtNBond, dOrthoMaxDim, dCustMaxDimDice) + + local dMaxDimDice = ( dCustMaxDimDice and dCustMaxDimDice < BD.MAX_DIM_DICE) or BD.MAX_DIM_DICE + local dTolerance = 0 -- distanza di sicurezza per i tagli ortogonali + local OffsetP = dMaxDimDice -- distanza tra i piani paralleli + local StepP = 20 -- numero massimo di piani paralleli da generare + local OffsetO = dMaxDimDice -- distanza tra i piani ortogonali + local StepO = 20 -- numero massimo di piani ortogonali da generare + + --Ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo + local TBoxPoint = CalcolaPuntiEstremiBox( BBoxRawPart) + TBoxPoint = VerificaEstremiGrezzo( ptCPlanes, vtNPlanes, TBoxPoint) + if ptCBond and vtNBond then + TBoxPoint = VerificaEstremiGrezzo( ptCBond, vtNBond, TBoxPoint) + end + local dElevP = DistanzaMassima( nParent, ptCPlanes, vtNPlanes, ptCBond, vtNBond, BBoxRawPart, TBoxPoint) + local dElevO + if ptCBond and vtNBond then + dElevO = DistanzaMassima( nParent, ptCBond, vtNBond, ptCPlanes, vtNPlanes, BBoxRawPart, TBoxPoint) + end + + -- inclinazione limite per taglio da sotto + local dNzLimDwnUp = BL.GetNzLimDownUp( BBoxRawPart) + + -- se normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda + if abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then + OffsetO = dOrthoMaxDim or BD.MAX_DIM_HTCUT + end + + -- aggiungo piccolo extra agli offset + OffsetP = OffsetP + 10 * GEO.EPS_SMALL + OffsetO = OffsetO + 10 * GEO.EPS_SMALL + + -- se seconda faccia non definita, forzo calcolo piani ortogonali + if not ptCBond or not vtNBond then + bGetOrtoPlanes = true + end + + -- se piani non ortogonali, diminuisco la distanza di offset opportunamente + local originalOffsetP = OffsetP + if not bGetOrtoPlanes then + local dCoeff = ( vtNPlanes ^ vtNBond):len() + OffsetP = OffsetP * dCoeff + OffsetO = OffsetO * dCoeff + end + + local n = ceil( dElevP / OffsetP) + OffsetP = dElevP / n + if dElevO then + local m = ceil( dElevO / OffsetO) + OffsetO = dElevO / m + end + + -- elenco di tutte le superfici generate dai tagli + local TabFUCHSIA = {} + local TabGREEN = {} + + -- PIANI PARALLELI alla faccia di taglio + local TabellaTmSurfP = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, 0, OffsetP, StepP, Color3d( FUCHSIA(), 60), dTolerance, true, ptCBond, vtNBond) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfP, TabFromIn[i]) + end + + -- PIANI ORTOGONALI alla faccia di taglio + -- orientamento definito da seconda faccia + if not bGetOrtoPlanes then + local TabellaTmSurfOrto = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCBond, vtNBond, 0, OffsetO, StepO, Color3d( GREEN(), 60), dTolerance, false, ptCPlanes, vtNPlanes) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfOrto, TabFromIn[i]) + end + local TabellaOrderParallelCut = GetOrderedCutTable( nParent, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati + local TabellaOrderOrtoCut = GetOrderedCutTable( nParent, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato + + TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato + TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati + + -- orientamento da definire + else + for PlnInd = 1, #TabellaTmSurfP do + -- piano interno + local ptCInner, vtNInner = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd], 0, GDB_ID.ROOT) + -- eventuale piano esterno + local ptCOuter, vtNOuter = nil, nil + if PlnInd > 1 then + ptCOuter, vtNOuter = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd-1], 0, GDB_ID.ROOT) + vtNOuter = -vtNOuter + end + -- calcolo la direzione dei piani ortogonali + local vtO = VectorFromUprightOrtho( vtNInner) + if vtNInner:getZ() > -0.0175 or vtNInner:getZ() < dNzLimDwnUp or abs( vtNInner:getY()) > 0.8 then + vtO:rotate( vtNInner, 90) + -- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente + if abs( vtO:getY()) > 2 * abs( vtO:getX()) and vtNInner:getZ() > dNzLimDwnUp then + vtO:rotate( vtNInner, 90) + -- se faccia principale verso il basso (almeno -3deg), lo inverto per iniziare da sopra + if vtNInner:getZ() < -0.05 then + vtO = -vtO + end + else + if ptCInner:getX() > BBoxRawPart:getCenter():getX() then + if vtO:getX() < 0 then vtO = - vtO end + else + if vtO:getX() > 0 then vtO = - vtO end + end + end + end + -- calcolo le dimensioni dell'offset e dove posizionare la prima faccia: + -- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato + -- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato + -- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero + local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, OffsetO, dNzLimDwnUp) + + if OffsetRel and CopyPlane and dCenOffs then + ptCInner = ptCInner + dCenOffs * vtO + local TabRight = GetParallelPlanes( nParent, BBoxRawPart, ptCStart, vtO, CopyPlane, -OffsetRel, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + if CopyPlane == 0 then + CopyPlane = 1 + end + local TabLeft = GetParallelPlanes( nParent, BBoxRawPart, ptCStart, vtO, CopyPlane, OffsetRel, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + -- carico la tabella con gli indici riordinati + local TempOrtoTab = {} + for i = #TabLeft, 1, -1 do + table.insert( TempOrtoTab, TabLeft[i]) + end + for i = 1, #TabRight do + table.insert( TempOrtoTab, TabRight[i]) + end + -- creo una tabella per ogni piano per generare i tagli sulla Inner + local TempParTab = GetOrderedCutTable( nParent, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) + for i = 1, #TempParTab do + table.insert( TabFUCHSIA, TempParTab[i]) + end + table.insert( TabGREEN, TempOrtoTab) + else + table.insert( TabFUCHSIA, {TabellaTmSurfP[PlnInd]}) + table.insert( TabGREEN, {}) + end + end + end + + -- Se sono state costruite non più di una faccia parallela e una faccia perpendicolare, allora non servono e tengo le originali + if #TabGREEN == 1 and #TabGREEN[1] <= 1 and #TabFUCHSIA == 1 and #TabFUCHSIA[1] <= 1 then + if #TabGREEN[1] == 1 then + EgtErase( TabGREEN[1][1]) + end + TabGREEN = {} + if #TabFUCHSIA[1] == 1 then + EgtErase( TabFUCHSIA[1][1]) + end + TabFUCHSIA = {} + end + + -- Si uniscono le tabelle dei tagli ortogonali e paralleli in una sola tabella + local UltimateTable = TableMesh( TabGREEN, TabFUCHSIA) + + -- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato + if not bGetOrtoPlanes then + VerifyFirstOrthoCut( UltimateTable, originalOffsetP, BBoxRawPart, dNzLimDwnUp) + end + + return UltimateTable +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- PrintOrderCut: +-- TabellaOrderCut: tabella delle superfici di taglio +-- stampo l'ordine dei piani di taglio ricevendo una tabella con gli strati parallelo/ortogonali già ordinati +function DiceCut.PrintOrderCut( TabellaOrderCut) + local Step = #TabellaOrderCut + if Step > 0 then + EgtOutLog( " L'ordine delle superfici da tagliare è il seguente:") + else + EgtOutLog( ' Non sono necessarie superfici aggiuntive di taglio.') + end + for i = 1, Step do + if i % 2 == 1 then + EgtOutLog( ' *** Strato di taglio ' .. EgtNumToString( ( i + 1) / 2, 0)) + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli ortogonali: ') + else + EgtOutLog( ' Tagli ortogonali assenti') + end + else + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli paralleli: ') + else + EgtOutLog( ' Tagli paralleli assenti') + end + end + for j=1, #TabellaOrderCut[i] do + EgtOutLog( ' Indice faccia ' .. (TabellaOrderCut[i][j] or 0)) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +local function DiceCutTest() + + -- salvo l'indice del layer Trimesh selezionato + local SelectedIndex = EgtGetFirstSelectedObj() + -- verifico che sia selezionato un elemento + if not SelectedIndex then return end + + -- salvo l'indice del layer Processing + local nParent = EgtGetParent( SelectedIndex) + -- salvo l'indice del layer Part + local nRawPart = EgtGetParent( nParent) + local nBox = EgtGetFirstNameInGroup( nRawPart, 'Box') + -- carico il bounding box della trave + -- local BBoxRawPart = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD ) + local BBoxRawPart = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD ) + -- seleziono il Part e il Layer di destinazione + EgtSetCurrPartLayer( nRawPart, nParent) + + -- conto il numero di facce da processare + local nFacet = EgtSurfTmFacetCount( SelectedIndex) + EgtOutLog( ' Numero facce ' .. nFacet, 1) + + -- salvo + local TabPlanesFeatures = {} + for i = 1, nFacet do + local ptC, vtN = EgtSurfTmFacetCenter( SelectedIndex, i - 1, GDB_ID.ROOT) + table.insert( TabPlanesFeatures, { ptC = ptC, vtN = vtN}) + end + local ptC1 = Point3d( TabPlanesFeatures[1].ptC) + local vtN1 = Vector3d( TabPlanesFeatures[1].vtN) + + local CutTable = {} + if nFacet == 1 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, true) + elseif nFacet == 2 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN) + end + + if EgtGetDebugLevel() > 1 then + DiceCut.PrintOrderCut( CutTable) + end + + EgtDeselectAll() + + EgtDraw() +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +--DiceCutTest() + +return DiceCut diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/DiceCut.nik.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/DiceCut.nik.lua new file mode 100644 index 0000000..b63cf27 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/DiceCut.nik.lua @@ -0,0 +1,657 @@ +-- DiceCut.lua by Egaltech s.r.l. 2020/02/07 +-- Gestione dei piano paralleli nei tagli lunghi: equidistanziamento dei piani paralleli + +-- Tabella per definizione modulo +local DiceCut = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' DiceCut started', 1) + +-- Dati +local BD = require( 'BeamData') + +local bHew = false +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- creo i piani paralleli +-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptC: il punto centrale del piano della feature +-- vtN: il versore normale del piano della feature +-- nCopyPlane: 0 => genera una copia del piano passato, 1=> non genera una copia del piano passato +-- dOffset: offset dei piani paralleli +-- nStep: numero massimo di step +-- Color: colre del fascio di piani +-- dTolerance*: distanza tra i piani paralleli e i piani di taglio (se non esistono altre superfici può essere omesso) +-- bNoTolOnFirstCut*: elimina la tolleranza per il primo piano del fascio (se non esistono altre superfici può essere omesso) +-- ptCCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +local function GetParallelPlanes( nParent, BBoxRawPart, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) + local ptMyCCut + local AreaMin = 5*5 + if ptCCut and vtNCut then + if dTolerance then + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + local ptMyCCut1 + if ptCCut1 and vtNCut1 then + ptMyCCut1 = Point3d( ptCCut1 + 0 * vtNCut1) + end + local TabellaTmSurfParallel = {} + local i = nCopyPlane + while i < nStep do + local SurfId = EgtSurfTmPlaneInBBox( nParent, ptC + ( i * dOffset) * vtN, vtN, BBoxRawPart, GDB_RT.GLOB) + local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL) + if nFacet > 0 and vtNCut and ptMyCCut and EgtSurfArea(SurfId) > AreaMin then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut, -vtNCut, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut, -vtNCut, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and vtNCut1 and ptMyCCut1 and EgtSurfArea(SurfId) > AreaMin then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut1, -vtNCut1, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut1, -vtNCut1, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and EgtSurfArea(SurfId) > AreaMin then + table.insert( TabellaTmSurfParallel, SurfId) + EgtSetColor( SurfId, Color) + else + EgtErase( SurfId) + break + end + if dOffset == 0 then + break + end + i = i + 1 + end + return TabellaTmSurfParallel +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrderedCutTable: +-- nParent: il layer +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function GetOrderedCutTable( nParent, TabParallelPlanes, TabOrtoPlanes) + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + local TabellaOrderParallelCut1 = {} + + for IndexTmP=1, StepParallel do + TabellaOrderParallelCut1[IndexTmP] = {} + for IndexOrto=1, StepOrto do + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT) + local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + if Copy1Id and ptOrtoN then + EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB) + EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + local nFacet1 = EgtSurfTmFacetCount( Copy1Id) + local nFacet2 = EgtSurfTmFacetCount( Copy2Id) + if nFacet1 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + elseif nFacet2 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + break + else + table.insert( TabellaOrderParallelCut1[IndexTmP], Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + end + end + end + table.insert(TabellaOrderParallelCut1[IndexTmP], TabParallelPlanes[IndexTmP]) + end + return TabellaOrderParallelCut1 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrtoCutCenter: +-- idFacet: l'id della faccia +-- ptC: il punto centrale della faccia +-- vtN: il versore normale della faccia +-- vtO: il versore dei piani ortogonali +-- dOffsetEff: offset della distanza dal punto centrale +-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset +local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff) + local FrameLocal = Frame3d( EgtSurfTmFacetCenter( FacetId, 0, GDB_ID.ROOT)) + EgtSetGridFrame(FrameLocal) + local IdAuxLocal = EgtGroup(EgtGetParent( FacetId), FrameLocal) + EgtSetName( IdAuxLocal, "AuxLocal") + local BoxLocal = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, FrameLocal) + local ptS = EgtGP( EgtSurfTmBBox( IdAuxLocal, BoxLocal, GDB_RT.GRID), GDB_ID.ROOT) + EgtErase( IdAuxLocal) + EgtSetGridFrame(Frame3d()) + -- riferimento intrinseco + local asseX = vtO + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + -- ingombro della faccia secondo questo riferimento + local Box = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, Frame) + local dLen = Box:getDimX() + local dWidth = Box:getDimY() + + -- se faccia con un lato piccolo e non diretta troppo verso il basso, non servono dice + if ( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > -0.5 then + return nil, nil, nil + end + + local N = ceil( dLen / dOffsetEff) + local dOffsetRel = dLen / N + local dCopyPlane + local dCenOffs = ( Box:getMax():getX() + Box:getMin():getX()) / 2 + + if dLen <= dOffsetRel then + --dOffsetRel = 0 + dCopyPlane = 1 + elseif dLen <= 2 * dOffsetRel then + dOffsetRel = dOffsetEff + dCopyPlane = 0 + else + if N % 2 == 0 then + dCopyPlane = 0 + elseif N % 2 == 1 then + dCopyPlane = 0.5 + end + end + + + return dOffsetRel, dCopyPlane, dCenOffs, ptS +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- TableMesh: +-- TableOrto: tabella delle superfici dei piani ortogonali +-- TableParallel: tabella delle superfici dei piani paralleli +-- Forma una tabella unica delle superfici di taglio inserendo strati di tagli ortogonali alternati da strati di taglio parallelo +local function TableMesh( TableOrto, TableParallel) + local TableUnited = {} + for i=1, #TableOrto do + table.insert( TableUnited, TableOrto[i]) + table.insert( TableUnited, TableParallel[i]) + end + return TableUnited +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- FindValue: +-- tab: tabella da scansionare +-- val: valore da cercare +-- Verifica se tab contiene val, a supporto della funzione SortOrtoCutsByNormalMethod +local function FindValue( tab, val) + for index, value in ipairs( tab) do + if value == val then + return true + end + end + return false +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- SortOrtoCutsByNormalMethod: +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio sfruttando il prodotto dei versori normali (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function SortOrtoCutsByNormalMethod( TabParallelPlanes, TabOrtoPlanes) + -- tabella dei tagli ordinati + local TabOrderOrtoCut = {} + -- tabella ausiliaria dei dati inseriti nell'ordine + local TabAux = {} + -- ciclo di ordinamento + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + for IndexTmP=1, StepParallel do + TabOrderOrtoCut[IndexTmP] = {} + local ptParalN, vtNParalN = EgtSurfTmFacetCenter( TabParallelPlanes[IndexTmP][1], 0, GDB_ID.ROOT) + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- controlla che l'elemento da valutare non sia gia' stato inserito nella tabella + if not FindValue( TabAux, OrtoPlaneId) then + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( OrtoPlaneId, 0, GDB_ID.ROOT) + local scalarProduct = ( ptOrtoN - ptParalN) * vtNParalN + if scalarProduct > 0 then + table.insert( TabOrderOrtoCut[IndexTmP], OrtoPlaneId) + table.insert( TabAux, OrtoPlaneId) + end + end + end + end + end + -- cancello dal DB geometrico i tagli non inseriti + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- ricerco il taglio tra gli inseriti + if not FindValue( TabAux, OrtoPlaneId) then + EgtErase( OrtoPlaneId) + end + end + end + return TabOrderOrtoCut +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- VerifyFirstOrthoCut : +-- CutTable: tabella dei tagli +-- OffsetP: offset della distanza dal punto centrale +-- BBoxRawPart: il grezzo della barra +-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua +local function VerifyFirstOrthoCut( CutTable, OffsetP, BBoxRawPart) + + if not CutTable[1] or not CutTable[2] then return end + + local CutOId = CutTable[1][1] + local Cut1Id = CutTable[2][1] + local Cut2Id = CutTable[2][2] + + if CutOId and Cut1Id and Cut2Id then + -- centri e normali delle due semifacce + local ptC1, vtN1 = EgtSurfTmFacetCenter( Cut1Id, 0, GDB_ID.ROOT) + local ptC2, vtN2 = EgtSurfTmFacetCenter( Cut2Id, 0, GDB_ID.ROOT) + -- normale alla faccia ortogonale + local _, vtO = EgtSurfTmFacetCenter( CutOId, 0, GDB_ID.ROOT) + vtO = vtO - vtO * vtN1 * vtN1 ; vtO:normalize() + -- calcolo lunghezza prima semi-faccia + local asseX1 = vtO + local asseY1 = vtN1 ^ asseX1 + local Frame1 = Frame3d( ptC1, ptC1+asseX1, ptC1+asseY1) + local Box1 = EgtGetBBoxRef( Cut1Id, GDB_BB.STANDARD, Frame1) + local x1 = Box1:getDimX() + -- calcolo lunghezza seconda semi-faccia + local asseX2 = vtO + local asseY2 = vtN2 ^ asseX2 + local Frame2 = Frame3d( ptC2, ptC2+asseX2, ptC2+asseY2) + local Box2 = EgtGetBBoxRef( Cut2Id, GDB_BB.STANDARD, Frame2) + local x2 = Box2:getDimX() + -- lunghezza totale faccia + local dLongSize = x1 + x2 + -- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti + if dLongSize <= OffsetP + 1.0 and vtN1:getZ() > -0.5 then + local nParent = EgtGetParent( Cut1Id) + local SurfId = EgtSurfTmBySewing( nParent, { Cut1Id, Cut2Id}) + EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) + EgtErase( CutOId) + table.remove( CutTable[1], 1) + table.remove( CutTable[2], 1) + table.remove( CutTable[2], 1) + table.insert( CutTable[2], 1, SurfId) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- ricavo i vertici del box +local function CalcolaPuntiEstremiBox( BBoxRawPart) + local ptMin = BBoxRawPart:getMin() + local ptMax = BBoxRawPart:getMax() + local TBoxPoint = {} + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMin:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMin:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMax:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMax:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMin:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMin:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMax:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMax:getY(), ptMax:getZ()), On = true}) + return TBoxPoint +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- restituisce i punti che devono essere presi in considerazione per la costruzione del BoundingBox +local function VerificaEstremiGrezzo( ptC, vtN, TPoint) + for i = 1, #TPoint do + if ( TPoint[i].P - ptC) * vtN < 0 then + TPoint[i].On = false + end + end + return TPoint +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature +-- le funzioni commentate permettono di vedere la creazione di BoundingBox +local function DistanzaMassima( nParent, ptC1, vtN1, ptC2, vtN2, BBoxRawPart, TPoint) + -- calcolo il riferimento nel piano 1 + local Frame1 = Frame3d( ptC1, vtN1) + -- determino l'ingombro in questo riferimento della parte di trave compresa nel o nei piani + local BB1 = BBox3d() + -- punti di vertice della trave compresi + for i = 1, #TPoint do + if TPoint[i].On then + local ptP = Point3d( TPoint[i].P) + ptP:toLoc( Frame1) + BB1:Add( ptP) + end + end + -- eventuale altra faccia + if ptC2 and vtN2 then + local IdAux = EgtGroup( nParent) + local IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, ptC2, vtN2, BBoxRawPart, GDB_RT.GLOB) + EgtCutSurfTmPlane( IdSurf2, ptC1, -vtN1, false, GDB_RT.GLOB) + if IdSurf2 then + local BB2 = EgtGetBBoxRef( IdSurf2, GDB_BB.STANDARD, Frame1) + BB1:Add( BB2) + end + EgtErase( IdAux) + end + if not BB1:isEmpty() then + return ( BB1:getMax():getZ() + 0.1) + end + + return 0 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- DiceCut.GetDice : +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptCPlanes: il punto centrale del piano della feature +-- vtNPlanes: il versore normale del piano della feature +-- bGetOrtoPlanes*: se voglio calcolare i piani ortogonali al piano passato (se non esistono altre superfici può essere omesso) +-- ptCBond*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNBond*: il versore normale della superfice limitante (se non esistono altre superfici può essere omesso) +---------------------------------------------------------------------------------------------------------------------------------------------------- +function DiceCut.GetDice( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, bGetOrtoPlanes, ptCBond, vtNBond, IdTmSurf) + + local dTolerance = 0 -- distanza di sicurezza per i tagli ortogonali + local OffsetP = BD.MAX_DIM_DICE -- distanza tra i piani paralleli + local StepP = 20 -- numero massimo di piani paralleli da generare + local OffsetO = BD.MAX_DIM_DICE -- distanza tra i piani ortogonali + local StepO = 20 -- numero massimo di piani ortogonali da generare + + --Ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo + local TBoxPoint = CalcolaPuntiEstremiBox( BBoxRawPart) + TBoxPoint = VerificaEstremiGrezzo( ptCPlanes, vtNPlanes, TBoxPoint) + if ptCBond and vtNBond then + TBoxPoint = VerificaEstremiGrezzo( ptCBond, vtNBond, TBoxPoint) + end + local dElevP = DistanzaMassima( nParent, ptCPlanes, vtNPlanes, ptCBond, vtNBond, BBoxRawPart, TBoxPoint) + local dElevO + if ptCBond and vtNBond then + dElevO = DistanzaMassima( nParent, ptCBond, vtNBond, ptCPlanes, vtNPlanes, BBoxRawPart, TBoxPoint) + end + + -- se normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda + if abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then + --OffsetP = BD.MAX_DIM_HTCUT + OffsetO = BD.MAX_DIM_HTCUT + end + + -- aggiungo piccolo extra agli offset + OffsetP = OffsetP + 10 * GEO.EPS_SMALL + OffsetO = OffsetO + 10 * GEO.EPS_SMALL + + -- se seconda faccia non definita, forzo calcolo piani ortogonali + if not ptCBond or not vtNBond then + bGetOrtoPlanes = true + end + + -- se piani non ortogonali, diminuisco la distanza di offset opportunamente + local originalOffsetP = OffsetP + if not bGetOrtoPlanes then + local dCoeff = ( vtNPlanes ^ vtNBond):len() + OffsetP = OffsetP * dCoeff + OffsetO = OffsetO * dCoeff + end + + local n = ceil( dElevP / OffsetP) + OffsetP = dElevP / n + if dElevO then + local m = ceil( dElevO / OffsetO) + OffsetO = dElevO / m + end + + -- elenco di tutte le superfici generate dai tagli + local TabFUCHSIA = {} + local TabGREEN = {} + + -- eseguo eventuale sgrossatura + local IdHewSurf + local ptHew, vtHew + local HewTable = {} + if IdTmSurf and vtNPlanes*vtNBond >=0.9 then + IdHewSurf = EgtSurfTmConvexHullInBBox( nParent, IdTmSurf, BBoxRawPart, GDB_RT.GLOB) + if IdHewSurf then + bHew = true + ptHew, vtHew = EgtSurfTmFacetCenter( IdHewSurf, 0, GDB_ID.ROOT) + HewTable = DiceCut.GetDice( nParent, BBoxRawPart, ptHew, vtHew, true) + vtHew = -vtHew + EgtErase( IdHewSurf) + end + else + IdTmSurf = nil + end + bHew = false + -- PIANI PARALLELI alla faccia di taglio + local TabellaTmSurfP = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, 0, OffsetP, StepP, Color3d( FUCHSIA(), 60), dTolerance, bTolOnHew, ptCBond, vtNBond, ptHew, vtHew) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfP, TabFromIn[i]) + end + + -- PIANI ORTOGONALI alla faccia di taglio + -- orientamento definito da seconda faccia + if not bGetOrtoPlanes then + local TabellaTmSurfOrto = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCBond, vtNBond, 0, OffsetO, StepO, Color3d( GREEN(), 60), dTolerance, false, ptCPlanes, vtNPlanes, ptHew, vtHew) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfOrto, TabFromIn[i]) + end + local TabellaOrderParallelCut = GetOrderedCutTable( nParent, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati + local TabellaOrderOrtoCut = GetOrderedCutTable( nParent, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato + + TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato + TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati + + -- orientamento da definire + else + for PlnInd = 1, #TabellaTmSurfP do + -- piano interno + local ptCInner, vtNInner = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd], 0, GDB_ID.ROOT) + -- eventuale piano esterno + local ptCOuter, vtNOuter = nil, nil + if PlnInd > 1 then + ptCOuter, vtNOuter = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd-1], 0, GDB_ID.ROOT) + vtNOuter = -vtNOuter + end + -- calcolo la direzione dei piani ortogonali + local vtO = VectorFromUprightOrtho( vtNInner) + if vtNInner:getZ() > 0.05 or vtNInner:getZ() < -0.5 or abs( vtNInner:getY()) > 0.5 then + vtO:rotate( vtNInner, 90) + -- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente + if abs( vtO:getY()) > abs( vtO:getX()) and vtNInner:getZ() > -0.5 then + vtO:rotate( vtNInner, 90) + else + if ptCInner:getX() > BBoxRawPart:getCenter():getX() then + if vtO:getX() < 0 then vtO = - vtO end + else + if vtO:getX() > 0 then vtO = - vtO end + end + end + end + -- calcolo le dimensioni dell'offset e se dove posizionare la prima faccia: + -- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato + -- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato + -- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero + local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, OffsetO) + + if OffsetRel and CopyPlane and dCenOffs then + ptCInner = ptCInner + dCenOffs * vtO + local TabRight = GetParallelPlanes( nParent, BBoxRawPart, ptCStart, vtO, CopyPlane, -OffsetRel, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + if CopyPlane == 0 then + CopyPlane = 1 + end + local TabLeft = GetParallelPlanes( nParent, BBoxRawPart, ptCStart, vtO, CopyPlane, OffsetRel, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + -- carico la tabella con gli indici riordinati + local TempOrtoTab = {} + for i = #TabLeft, 1, -1 do + table.insert( TempOrtoTab, TabLeft[i]) + end + for i = 1, #TabRight do + table.insert( TempOrtoTab, TabRight[i]) + end + -- creo una tabella per ogni piano per generare i tagli sulla Inner + local TempParTab = GetOrderedCutTable( nParent, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) + for i = 1, #TempParTab do + table.insert( TabFUCHSIA, TempParTab[i]) + end + table.insert( TabGREEN, TempOrtoTab) + else + table.insert( TabFUCHSIA, {TabellaTmSurfP[PlnInd]}) + table.insert( TabGREEN, {}) + end + end + end + + -- Se sono state costruite non più di una faccia parallela e una faccia perpendicolare, allora non servono e tengo le originali + if #TabGREEN == 1 and #TabGREEN[1] <= 1 and #TabFUCHSIA == 1 and #TabFUCHSIA[1] <= 1 then + if #TabGREEN[1] == 1 then + EgtErase( TabGREEN[1][1]) + TabGREEN = {} + end + if #TabFUCHSIA[1] == 1 and not bHew then + EgtErase( TabFUCHSIA[1][1]) + TabFUCHSIA = {} + end + end + + -- Si uniscono le tabelle dei tagli ortogonali e paralleli in una sola tabella + local UltimateTable = TableMesh( TabGREEN, TabFUCHSIA) + + -- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato + if not bGetOrtoPlanes then + VerifyFirstOrthoCut( UltimateTable, originalOffsetP, BBoxRawPart) + end + + return UltimateTable +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- PrintOrderCut: +-- TabellaOrderCut: tabella delle superfici di taglio +-- stampo l'ordine dei piani di taglio ricevendo una tabella con gli strati parallelo/ortogonali già ordinati +function DiceCut.PrintOrderCut( TabellaOrderCut) + local Step = #TabellaOrderCut + if Step > 0 then + EgtOutLog( " L'ordine delle superfici da tagliare è il seguente:") + else + EgtOutLog( ' Non sono necessarie superfici aggiuntive di taglio.') + end + for i = 1, Step do + if i % 2 == 1 then + EgtOutLog( ' *** Strato di taglio ' .. EgtNumToString( ( i + 1) / 2, 0)) + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli ortogonali: ') + else + EgtOutLog( ' Tagli ortogonali assenti') + end + else + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli paralleli: ') + else + EgtOutLog( ' Tagli paralleli assenti') + end + end + for j=1, #TabellaOrderCut[i] do + EgtOutLog( ' Indice faccia ' .. (TabellaOrderCut[i][j] or 0)) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +local function DiceCutTest() + + -- salvo l'indice del layer Trimesh selezionato + local SelectedIndex = EgtGetFirstSelectedObj() + -- verifico che sia selezionato un elemento + if not SelectedIndex then return end + + -- salvo l'indice del layer Processing + local nParent = EgtGetParent( SelectedIndex) + -- salvo l'indice del layer Part + local nRawPart = EgtGetParent( nParent) + local nBox = EgtGetFirstNameInGroup( nRawPart, 'Box') + -- carico il bounding box della trave + -- local BBoxRawPart = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD ) + local BBoxRawPart = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD ) + -- seleziono il Part e il Layer di destinazione + EgtSetCurrPartLayer( nRawPart, nParent) + + -- conto il numero di facce da processare + local nFacet = EgtSurfTmFacetCount( SelectedIndex) + EgtOutLog( ' Numero facce ' .. nFacet, 1) + + -- salvo + local TabPlanesFeatures = {} + for i = 1, nFacet do + local ptC, vtN = EgtSurfTmFacetCenter( SelectedIndex, i - 1, GDB_ID.ROOT) + table.insert( TabPlanesFeatures, { ptC = ptC, vtN = vtN}) + end + local ptC1 = Point3d( TabPlanesFeatures[1].ptC) + local vtN1 = Vector3d( TabPlanesFeatures[1].vtN) + + local CutTable = {} + if nFacet == 1 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, true) + elseif nFacet == 2 then + --local IdHewSurf + --local HewTable = {} + --if vtN1*TabPlanesFeatures[2].vtN >= 0.9 then + -- if SelectedIndex then + -- IdHewSurf = EgtSurfTmConvexHullInBBox( nParent, SelectedIndex, BBoxRawPart, GDB_RT.GLOB) + -- if IdHewSurf then + -- bHew = true + -- local ptHew, vtHew = EgtSurfTmFacetCenter( IdHewSurf, 0, GDB_ID.ROOT) + -- HewTable = DiceCut.GetDice( nParent, BBoxRawPart, ptHew, vtHew, true) + -- EgtErase( IdHewSurf) + -- end + -- end + --else + -- SelectedIndex = nil + --end + --bHew = false + --CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN, SelectedIndex) + --if HewTable and CutTable then + -- for i = 1, #CutTable, 1 do + -- table.insert( HewTable, CutTable[i]) + -- end + -- CutTable = HewTable + --end + + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN, SelectedIndex) + end + + if EgtGetDebugLevel() > 1 then + DiceCut.PrintOrderCut( CutTable) + end + + EgtDeselectAll() + + EgtDraw() +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +--DiceCutTest() + +return DiceCut diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/FacesBySaw.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/FacesBySaw.lua new file mode 100644 index 0000000..72ecc59 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/FacesBySaw.lua @@ -0,0 +1,158 @@ +-- FacesBySaw.lua by Egaltech s.r.l. 2020/04/20 +-- Gestione taglio con lama di feature con una, due o tre facce + +-- Tabella per definizione modulo +local FacesBySaw = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' FacesBySaw started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +function FacesBySaw.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, sCutName) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico il numero di facce della tacca + if Proc.Fct < 2 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw facet number not supported' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero dati su giunzione tra facce + local bTouch, ptT1, ptT2, dAngT = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if not bTouch then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw faces not touching' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo direzione di lavoro + local vtRef = {} + local vtTg = ptT2 - ptT1 ; + vtRef[1] = vtN[1] ^ vtTg + if vtRef[1] * vtN[2] < 0 then vtRef[1] = - vtRef[1] end + vtRef[2] = vtN[2] ^ vtTg + if vtRef[2] * vtN[1] < 0 then vtRef[2] = - vtRef[2] end + -- determino quale faccia è più grande + local ptPs = ( ptT1 + ptT2) / 2 + local dSqDim1 = ( ptC[1] - ptPs):sqlen() + local dSqDim2 = ( ptC[2] - ptPs):sqlen() + local nBigInd = EgtIf( dSqDim1 >= dSqDim2, 1, 2) + local nSmaInd = 3 - nBigInd + local nUpInd = EgtIf( vtN[1]:getZ() >= vtN[2]:getZ(), 1, 2) + local nOtInd = 3 - nUpInd + -- recupero la lavorazione + local sCutting = ML.FindCutting( sCutName) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 5 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- calcolo extra taglio + local dCutExtra = 0 + if dAngT < -92 and dAngT > -178 then + dCutExtra = - dSawThick / tan( 180 + dAngT) + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nUpInd], vtN[nUpInd], false, ptC[nOtInd], vtN[nOtInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- assegno il modo di tagliare + local vtOrthO = EgtIf( ( i % 2) == 1, vtRef[nOtInd], vtRef[nUpInd]) + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthO, nil, dCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- lavoro la prima faccia + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, vtRef[1], nil, dCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + -- lavoro seconda faccia + bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 1, sCutting, dSawDiam, vtRef[2], nil, dCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + elseif Proc.Box:getCenter():getX() > b3Solid:getCenter():getX() then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + local dDist = b3Solid:getMax():getX() - Proc.Box:getMax():getX() + BL.UpdateHCING( nRawId, dOffs, dDist) + end + end + return true +end + +--------------------------------------------------------------------- +function FacesBySaw.MakeThree( Proc, nPhase, nRawId, nPartId, sCutName) + return false +end + +return FacesBySaw \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/MachiningLib.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/MachiningLib.lua new file mode 100644 index 0000000..4aa1878 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/MachiningLib.lua @@ -0,0 +1,108 @@ +-- MachiningLib.lua by Egaltech s.r.l. 2020/05/16 +-- Libreria ricerca lavorazioni per Travi + +-- Tabella per definizione modulo +local MachiningLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' MachiningLib started', 1) + +-- Dati +local BD = require( 'BeamData') +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 - BD.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/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessBlockHausFront.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessBlockHausFront.lua new file mode 100644 index 0000000..b3cd74d --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessBlockHausFront.lua @@ -0,0 +1,306 @@ +-- ProcessBlockHausFront.lua by Egaltech s.r.l. 2020/08/03 +-- Gestione calcolo giunzione block house in testa + +-- Tabella per definizione modulo +local ProcessBlockHausFront = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessBlockHausFront started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessBlockHausFront.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 38) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessBlockHausFront.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + -- do errore perchè non è ancora gestita la rotazione di 90° + -- considerazioni: al momento non è possibile sapere se ci sono due rastremature o una quindi se è rivolta verso il basso + -- viene dato errore, altrimenti si potrebbe imporre la rotazione di 180 (ovviamente con una sola rastrematura rivolta verso il basso) + if abs(vtN:getZ()) > abs(vtN:getX()) and abs(vtN:getZ()) > abs(vtN:getY()) and vtN:getZ() < -0.5 then + return false + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessBlockHausFront.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + local dMinZedFace = 1 + for i = 1, nFacetCnt do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinZedFace then + dMinZedFace = dXVal + vFaceOrd[3] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + bHead = ( vtN[vFaceOrd[1]]:getX() > 0) + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- recupero la geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato + local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), 'b') + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + local dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < (#vCuts-1) or (i == #vCuts) then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 00 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + -- altrimenti di fianco + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + -- altrimenti di fianco + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessBlockHausFront diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessChamfer.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessChamfer.lua new file mode 100644 index 0000000..6e6a4a8 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessChamfer.lua @@ -0,0 +1,190 @@ +-- ProcessChamfer.lua by Egaltech s.r.l. 2020/06/09 +-- Gestione calcolo profilo libero per Travi + +-- Tabella per definizione modulo +local ProcessChamfer = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessChamfer started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessChamfer.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 36) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessChamfer.Make( Proc, nPhase, nRawId, nPartId) + -- verifico se ha geometria ausiliaria (onde) + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Chamfer') + 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 dMillDiam = 10 + local dMaxMat = 20 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + end + + -- se onde + if AuxId then + -- inserisco la lavorazione + local sName = 'Chm_' .. ( 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 + -- impongo lavorazione dall'alto + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- lavoro tenendo l'utensile a sinistra + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto lavorazione a metà tagliente e senza step + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat / 2) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto attacchi e uscite + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, 3) + EgtSetMachiningParam( MCH_MP.LITANG, 6) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + + -- altrimenti smusso standard + else + -- normale ed elevazione della faccia principale + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local _, dElev = BL.GetPointDirDepth( nPartId, ptC, vtN) + local bFront = ( vtN:getY() < 0) + -- limitazioni su inizio e fine derivanti da altre facce + local bLimXmin = false + local bLimXmax = false + if Proc.Fct >= 3 then + bLimXmin = true + bLimXmax = true + elseif Proc.Fct >= 2 then + local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if vtN1:getX() > 0 then + bLimXmin = true + else + bLimXmax = true + end + end + -- calcolo eventuali accorciamenti per facce limitanti + local dAllExtr + if dElev < dMillDiam / 2 then + dAllExtr = -sqrt( dMillDiam * dElev - dElev * dElev) + else + dAllExtr = -dMillDiam / 2 + end + local dStartAll = 0 + local dEndAll = 0 + if vtN:getY() < 0 then + if bLimXmax then dStartAll = dAllExtr end + if bLimXmin then dEndAll = dAllExtr end + else + if bLimXmax then dEndAll = dAllExtr end + if bLimXmin then dStartAll = dAllExtr end + end + -- determino numero di parti + local dLen = Proc.Box:getDimX() + local dStartAccDist = BD.LONGCUT_ENDLEN + local dEndAccDist = BD.LONGCUT_ENDLEN + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + dC = dLen / ( nC + 2) + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + dC = dLen / 2 + else + nC = 1 + dC = 0 + end + end + -- eseguo le diverse parti + for i = 1, nC do + -- inserisco la lavorazione + local sName = 'Chm_' .. ( 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 + -- lavoro tenendo l'utensile a sinistra + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto lavorazione un poco sotto + local sDepth = 'TH+'..EgtNumToString( BD.CUT_EXTRA) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, sDepth) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- imposto attacchi e uscite + local dSal, dEal + if bFront then + dSal = EgtIf( i == 1, dStartAll, -( i - 1) * dC) + dEal = EgtIf( i == nC, dEndAll, -( nC - i) * dC) + else + dSal = EgtIf( i == nC, dStartAll, -( nC - i) * dC) + dEal = EgtIf( i == 1, dEndAll, -( i - 1) * dC) + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.LIPERP, dMillDiam / 4) + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + local nSCC = EgtIf( ( BD.C_SIMM or i == 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + + return true +end + +--------------------------------------------------------------------- +return ProcessChamfer diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessCut.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessCut.lua new file mode 100644 index 0000000..1500315 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessCut.lua @@ -0,0 +1,374 @@ +-- ProcessCut.lua by Egaltech s.r.l. 2020/07/29 +-- Gestione calcolo singoli tagli di lama per Travi + +-- Tabella per definizione modulo +local ProcessCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessCut.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessCut.Classify( Proc, b3Raw) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN:getZ() <= - 0.5 and abs( vtN:getY()) > 0.1 then + local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0) + if DimH > BD.MAX_DIM_DICE then + return true, true + end + end + -- verifico se c'è un taglio da sotto e se è nei limiti + local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw) + local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) + if bDownCut then + local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0) + -- confronto anche qua la distanza maggiore della faccia con la massima distanza del DiceCut + -- e se il rapporto supera il 2 (implica che genera 3 tagli) dichiaro impossibile la lavorazione + if DimH and BD.MAX_DIM_DICE and abs(BD.MAX_DIM_DICE) > 20 * GEO.EPS_SMALL and + abs( DimH / BD.MAX_DIM_DICE) > 2 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) +local function VerifyCurveForChamfer( AuxId) + if not AuxId then + return -2 + end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + return -1 + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- va bene solo se direzione estrusione orizzontale + if abs( vtExtr:getZ()) > 0.1 then + return 0 + end + return 1 +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico le entità curva associate (max 2) + local sVal = EgtGetInfo( Proc.Id, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local AuxId, Aux2Id + if vsAuxId and #vsAuxId >=1 then + AuxId = tonumber( vsAuxId[1]) + end + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if AuxId then AuxId = AuxId + Proc.Id end + if Aux2Id then Aux2Id = Aux2Id + Proc.Id end + local nRes = VerifyCurveForChamfer( AuxId) + if nRes == 0 and Aux2Id then + AuxId = Aux2Id + nRes = VerifyCurveForChamfer( AuxId) + end + if nRes == -2 then + return true + end + if nRes == -1 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + if nRes == 0 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true, nil +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) + -- se taglio di testa + if Proc.Head then + -- se coincide con il taglio di separazione precedente, non va fatto + if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- altrimenti taglio di coda + else + -- se coincide con taglio di separazione, non va fatto + if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + end + -- se vero taglio, eventuale inserimento smussi + if Proc.Prc == 10 then + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( Proc.Head, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 2 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- determino la direzione di taglio preferenziale + local _, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0) + local bHorizCut = (( dCutV < dMaxDepth - BD.CUT_EXTRA and dCutH > dMaxDepth - BD.CUT_EXTRA) and not bDownCut) + -- verifico se necessari tagli supplementari + EgtOutLog( string.format( 'MaxDepth=%.1f CutH=%.1f CutV=%.1f', dMaxDepth, dCutH, dCutV), 3) + local vCuts = {} + if dCutH > dMaxDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC or dCutV > dMaxDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, true, nil, nil, dMaxDepth - BD.CUT_EXTRA) + end + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + local bOrthInv = false + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + if ( i % 2) == 1 then + local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) + if ( vtN:getY() > 0.707 and vtO:getY() < -0.05) or + ( vtN:getY() < -0.707 and vtO:getY() > 0.05) then + EgtInvertSurf( vCuts[i][j]) + bOrthInv = true + end + end + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local vtOrthoO + local bNoPerpCuts = false + if i % 2 == 1 then + vtOrthoO = Vector3d( vtN) + else + local vtO + if #vCuts[i-1] > 0 then + vtO = EgtSurfTmFacetNormVersor( vCuts[i-1][1], 0, GDB_ID.ROOT) + elseif vCuts[i+1] and #vCuts[i+1] > 0 then + vtO = EgtSurfTmFacetNormVersor( vCuts[i+1][1], 0, GDB_ID.ROOT) + else + bNoPerpCuts = true + end + if vtO then + vtOrthoO = Vector3d( vtO) * EgtIf( bOrthInv, -1, 1) + else + if bHorizCut then + vtOrthoO = Z_AX() + elseif vtN:getY() > -0.02 then + vtOrthoO = Y_AX() + else + vtOrthoO = -Y_AX() + end + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se taglio dal basso + if bDownCut then + -- se strato pari composto da 1 o 2 elementi + if ( i % 2) == 0 and #vCuts[i] <= 2 then + -- il primo elemento prende la direzione prevista, il secondo quella opposta + local vtNewOrthoO = Vector3d( vtOrthoO) + local dVzLimDwnUp = dNzLimDwnUp + if j ~= 1 then + vtNewOrthoO = -vtOrthoO + dVzLimDwnUp = -0.707 + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtNewOrthoO, dVzLimDwnUp, BD.CUT_EXTRA_MIN, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- tutti gli altri casi vengono saltati + -- caso generale + else + -- in generale sta sollevato di pochissimo + local dExtraCut = -0.1 + -- se tagli paralleli + if ( i % 2) == 0 then + -- se non ci sono tagli ortogonali devo affondare + if bNoPerpCuts then + dExtraCut = BD.CUT_EXTRA + -- se altrimenti tagli ortogonali invertiti, devo approfondire dello spessore lama + elseif bOrthInv then + dExtraCut = dSawThick + end + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, dNzLimDwnUp, dExtraCut, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + end + -- altrimenti tagli diretti della faccia + else + -- lavoro la faccia + local vtOrthoO + if bFromBottom and dCutV < dMaxDepth - BD.CUT_EXTRA and vtN:getZ() > 0 then + vtOrthoO = -Z_AX() + elseif bHorizCut then + vtOrthoO = Z_AX() + elseif Proc.Head and abs( vtN:getY()) > 0.259 and vtN:getZ() > -0.174 and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then + vtOrthoO = X_AX() + elseif Proc.Tail and abs( vtN:getY()) > 0.259 and vtN:getZ() > -0.174 and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then + vtOrthoO = -X_AX() + elseif vtN:getY() > -0.02 then + vtOrthoO = Y_AX() + else + vtOrthoO = -Y_AX() + end + -- tagli molto di lato e inclinati sono permessi fino a -45deg + if abs( vtN:getX()) < 0.5 then dNzLimDwnUp = -0.707 end + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, dNzLimDwnUp, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if abs( vtN:getZ()) > 0.5 then + dOffs = dOffs - 0.6 * Proc.Box:getDimX() + elseif ( abs( vtN:getY()) > 0.9 and vtN:getZ() > 0.2) then + dOffs = dOffs - 0.3 * Proc.Box:getDimX() + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if abs( vtN:getZ()) > 0.5 then + dOffs = dOffs - 0.6 * Proc.Box:getDimX() + elseif ( abs( vtN:getY()) > 0.9 and vtN:getZ() > 0.2) then + dOffs = dOffs - 0.3 * Proc.Box:getDimX() + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessCut diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDecor.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDecor.lua new file mode 100644 index 0000000..4a7ecd8 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDecor.lua @@ -0,0 +1,81 @@ +-- ProcessDecor.lua by Egaltech s.r.l. 2018/04/18 +-- Gestione calcolo decoro per Travi + +-- Tabella per definizione modulo +local ProcessDecor = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDecor started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDecor.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 959) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDecor.Classify( Proc) + -- recupero i dati della decorazione + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico sia una decorazione + if not vtExtr then + return false + end + -- verifico se la decorazione è lavorabile solo da sotto + local bDown = (( vtExtr:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDecor.Make( Proc, nPhase, nRawId, nPartId) + -- recupero i dati della decorazione + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico che la decorazione non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Decor from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sToFind = EgtGetInfo( Proc.Id, 'P15') + local sMilling = ML.FindMilling( sToFind) + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessDecor diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDoubleCut.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDoubleCut.lua new file mode 100644 index 0000000..150a847 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDoubleCut.lua @@ -0,0 +1,286 @@ +-- ProcessDoubleCut.lua by Egaltech s.r.l. 2020/08/18 +-- Gestione calcolo doppi tagli di lama per Travi + +-- Tabella per definizione modulo +local ProcessDoubleCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessDoubleCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDoubleCut.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 11) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDoubleCut.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- se due facce, verifico se convesso + local bConvex = true + if nFacetCnt == 2 then + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + bConvex = not bAdj or ( dAng > 0) + end + -- verifico le normali delle facce + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if not bConvex and ( vtN:getZ() < - 0.72 or ( vtN:getZ() < - 0.259 and Proc.Box:getDimX() > BD.MAX_DIM_DICE)) then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId then return true end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDoubleCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- se convesso, lo tratto come due tagli singoli + if bConvex then + -- lavoro per prima la faccia più diretta in alto + local vOrd = { 1, 2} + if vtN[2]:getZ() > vtN[1]:getZ() then + vOrd = { 2, 1} + end + -- creo piano di taglio coincidente con la prima faccia e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[1]], vtN[vOrd[1]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- creo piano di taglio coincidente con la seconda faccia e lo lavoro + AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[2]], vtN[vOrd[2]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- altrimenti + else + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- aggiorno nome e info + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local vtOrthOpp = vtN[nBigInd] + local vtNorm = vtN[nSmaInd] + if ( i % 2) ~= 1 then vtOrthOpp, vtNorm = vtNorm, vtOrthOpp end + if not bOnY then vtOrthOpp[2] = 0 end + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtOrthOpp, vtNorm) + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, EgtIf( bHead, 'HeadSide', 'TailSide')) + if not bOk then + return bOk, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.4 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.4 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + return true +end + +--------------------------------------------------------------------- +return ProcessDoubleCut diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDovetail.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDovetail.lua new file mode 100644 index 0000000..b2d6014 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDovetail.lua @@ -0,0 +1,1777 @@ +-- ProcessDovetail.lua by Egaltech s.r.l. 2020/08/04 +-- Gestione calcolo giunzione coda di rondine + +-- Tabella per definizione modulo +local ProcessDovetail = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessDovetail started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sUseRoughTool = '' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDovetail.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 138) +end + +--------------------------------------------------------------------- +local function AssignQValues( Proc) + + -- reset delle variabili assegnazione parametri Q + sUseRoughTool = '' + + if Proc.Prc == 138 then + sUseRoughTool = 'Q02' -- d + end +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc, sUseRoughTool) + + local bForceUseRough = false + -- verifico se devo usare il truciolatore + -- 2020-03-20 forzata disabilitazione uso truciolatore se parametro Q non è presente + if #sUseRoughTool == 0 or EgtGetInfo( Proc.Id, sUseRoughTool, 'i') == 2 then + bForceUseRough = true + end + + return bForceUseRough +end + +--------------------------------------------------------------------- +local function OrderFaces( Proc, vtN) + + local dMinXFace = 0.99 + local dPosXFace = 0 + local dNegXFace = 0 + local vFaceOrd = { 0, 0, 0} + + -- se 2 facce : ordine (1=0, 2=interna, 3=intermedia) + if #vtN <= 2 then + for i = 1, #vtN do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinXFace then + dMinXFace = dXVal + vFaceOrd[3] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, #vtN do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- se 3 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia) + elseif #vtN == 3 then + for i = 1, #vtN do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinXFace then + dMinXFace = dXVal + vFaceOrd[3] = i + end + if dXVal > dPosXFace then + dPosXFace = dXVal + vFaceOrd[2] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + if vFaceOrd[2] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing internal face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, #vtN do + if i ~= vFaceOrd[3] and i ~= vFaceOrd[2] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + vFaceOrd[1] = i + end + end + end + -- se 4 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia, 4=esterna) + else + for i = 1, #vtN do + if vtN[i]:getX() > dPosXFace then + dPosXFace = vtN[i]:getX() + vFaceOrd[2] = i + end + if vtN[i]:getX() < dNegXFace then + dNegXFace = vtN[i]:getX() + vFaceOrd[4] = i + end + end + if vFaceOrd[2] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing internal face' + EgtOutLog( sErr) + return false, sErr + end + if vFaceOrd[4] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing external face' + EgtOutLog( sErr) + return false, sErr + end + local nMidFace = 3 + for i = 1, #vtN do + if i ~= vFaceOrd[2] and i ~= vFaceOrd[4] then + vFaceOrd[nMidFace] = i + nMidFace = 1 + end + end + if vFaceOrd[1] == 0 or vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing middle face' + EgtOutLog( sErr) + return false, sErr + end + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[1] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' wrong angle between middle faces' + EgtOutLog( sErr) + return false, sErr + end + end + return true, '', vFaceOrd +end + +--------------------------------------------------------------------- +local function VerifyIfRoughMill( dLargeFace, vtN, bCalcElev, dAngOnSide) + local bUseRoughMill = false + local sMilling + -- recupero la lavorazione + if dAngOnSide then + if bCalcElev then + local dCollSic = BD.COLL_SIC + -- se direzione tende verso una delle 3 direzioni azzero l'altezza extra + if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end + sMilling = ML.FindMilling( 'ProfTCone', dLargeFace + dCollSic) + else + sMilling = ML.FindMilling( 'ProfTCone') + end + else + if bCalcElev then + local dCollSic = BD.COLL_SIC + -- se direzione tende verso una delle 3 direzioni azzero l'altezza extra + if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end + sMilling = ML.FindMilling( 'Long2Cut', dLargeFace + dCollSic) + else + sMilling = ML.FindMilling( 'Long2Cut') + end + dAngOnSide = 0 + end + if sMilling then + -- recupero i dati dell'utensile + local dToolDiam = 100 + local dToolLength = 0 + local dMaxDepth = 0 + local dMaxMat = 50 + local dSideAngle = 0 + local dMachStep = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + -- ottengo il passo della lavorazione + dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep + end + end + if dMachStep <= 0.1 then + dMachStep = dMaxMat * 0.5 + end + -- se ho già fatto la ricerca lavorazione considerando l'elevazione controllo solo l'angolo + if bCalcElev then + -- se angolo spoglia compatibile + if abs( dSideAngle - dAngOnSide) < GEO.EPS_SMALL then + return true, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep + end + else + -- se altezza taglio utensile maggiore altezza faccia e angolo spoglia compatibile + if ( dMaxDepth > dLargeFace + 10 * GEO.EPS_SMALL) and ( abs( dSideAngle - dAngOnSide) < GEO.EPS_SMALL) then + return true, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep + end + end + end + + return false +end + +--------------------------------------------------------------------- +local function AddFaceToSurf( Proc, nPartId, b3Solid) + + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + -- punto medio sulla faccia + local ptN = Point3d( b3Solid:getMin():getX(), ( b3Solid:getMin():getY() + b3Solid:getMax():getY())/2, ( b3Solid:getMin():getZ() + b3Solid:getMax():getZ())/2) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN, -X_AX(), b3Solid, GDB_ID.ROOT) + -- se esiste la superfice aggiunta, la ritaglio la superficie con le facce + if nSurfInt then + -- inverto la normale + EgtInvertSurf( nSurfInt) + for i = 1, Proc.Fct do + local ptN, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) + end + -- unisco la nuova superfice + if nSurfInt then + local bOk = EgtSurfTmAdd( nNewProc, nSurfInt) + if bOk then + EgtErase( nSurfInt) + Proc.Id = nNewProc + Proc.Fct = EgtSurfTmFacetCount( nNewProc) + end + end + end +end + +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessDovetail.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() > 0.1 then + return true + end + end + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 *b3Raw:getDimX()) then + return false + end + -- se una o due facce ora è sicuramente di testa + if Proc.Fct <= 2 then + return true + end + -- deve avere la normale principale diretta verso la testa + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN:getX() < 0.499 then + return false + elseif Proc.Fct >= 5 then + return true + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDovetail.IsTailFeature( Proc, b3Raw) + -- recupero identificativo del pezzo + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() < -0.1 then + -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione + if b3Solid:getDimX() > BD.LEN_SHORT_PART then + return true + else + -- aggiungo faccia + AddFaceToSurf( Proc, nPartId, b3Solid) + return false + end + end + end + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then + return false + end + -- se due facce e interessa veramente la coda, allora di coda + if Proc.Fct <= 2 then + if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then + -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione + if b3Solid:getDimX() > BD.LEN_SHORT_PART then + return true + else + -- aggiungo faccia + AddFaceToSurf( Proc, nPartId, b3Solid) + return false + end + end + end + -- deve avere la normale principale diretta verso la coda + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN:getX() > -0.499 then + return false + else + -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione + if b3Solid:getDimX() > BD.LEN_SHORT_PART then + return true + else + -- aggiungo faccia + AddFaceToSurf( Proc, nPartId, b3Solid) + return false + end + end +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDovetail.Classify( Proc, b3Raw) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- verifico se sono presenti i parametri Q per l'uso forzato del truciolatore + local bForceUseRough = EvaluateQParam( Proc, sUseRoughTool) + -- verifico le normali delle facce + local nFlatFaceNeg + local bDown = false + -- individuo se c'è faccia rivolta verso Z- + for i = 1, Proc.Fct do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < -0.99 then + nFlatFaceNeg = i - 1 + break + end + end + -- se trovata faccia rivolta verso Z- + if nFlatFaceNeg then + -- se 3 o più facce sicuramente è in mezzo, setto il ribaltamento senza ulteriori controlli + if Proc.Fct >= 3 then + bDown = true + -- altrimenti è in testa o coda e verifico se lavorabile da sotto + else + -- prendo le dimensioni della faccia + local nOtherFace = 1 - nFlatFaceNeg + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT) + -- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama e non fattibile con truciolatore + if dAng > -89.99 and dAng < 0 then + bDown = true + -- altrimenti, verifico se lunghezza faccia piatta è compatibile con il taglio di lama + else + local dLargeFace = Proc.Box:getDimX() + local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeFace, -Z_AX(), true) + -- se forzato uso truciolatore + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + end + end + -- altrimenti controllo la componente in Z delle facce + else + local vtN = {} + for i = 1, Proc.Fct do + vtN[i] = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT) + end + for i = 1, Proc.Fct do + local nFacet = i - 1 + -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + if abs( vtN[i]:getZ()) > abs( vtN[i]:getX()) and abs( vtN[i]:getZ()) > abs( vtN[i]:getY()) and vtN[i]:getZ() < -0.5 then + -- se ho due facce e feature agli estremi verifico che la lunghezza faccia sia compatibile col taglio di lama + -- o con truciolatore in base al valore del Q + if Proc.Fct == 2 and ( Proc.Head or Proc.Tail) then + -- prendo le dimensioni della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local nOtherFace = EgtIf( nFacet == 0, nFacet + 1, nFacet - 1) + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) + -- se angolo interno acuto + if dAng < 0 and dAng < -90 - 5 * GEO.EPS_SMALL then + -- se forzato truciolatore allora controllo se posso fare con utensile tronco di cono + local dLargeface = Proc.Box:getDimX() + local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true, (90+dAng)) + -- se forzato uso truciolatore + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + -- altrimenti angolo interno a 90 + else + local dDist = dist( ptP1, ptP2) + local dLargeface + local dDeltadH = abs( dDist - dH) + local dDeltadV = abs( dDist - dV) + -- prendo la dimensione diversa dalla lunghezza di adiacenza + if dDeltadH < dDeltadV then + dLargeface = dV + else + dLargeface = dH + end + -- se (anche) la direzione in z dell'altra faccia è negativa verifico se posso farla di fresa (in base alle impostazioni del Q) + if vtN[nOtherFace+1]:getZ() < -0.001 then + -- se forzato uso truciolatore verifico se posso fare di truciolatore + if bForceUseRough then + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) + bDown = not bUseRough + -- altrimenti posso usare lama, ma (anche) la direzione in z dell'altra faccia è negativa, quindi non è lavorabile, setto il ribaltamento + else + bDown = true + end + else + local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) + -- se forzato uso truciolatore + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + end + end + elseif Proc.Fct == 3 and ( Proc.Head or Proc.Tail) then + -- ordino le 3 facce: (1=altra intermedia, 2=interna, 3=intermedia) + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1 end + -- se le due facce intermedie sono compatibili con la lunghezza lama da sotto + -- prendo le dimensioni della facce + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vFaceOrd[3]-1, GDB_ID.ROOT) + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3]-1, vFaceOrd[1]-1, GDB_ID.ROOT) + -- prendo la dimensione uguale dalla lunghezza di adiacenza + local dLargeface = dist( ptP1, ptP2) + local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) + -- se forzato uso truciolatore e non riesco a farlo + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + elseif not Proc.Head and not Proc.Tail then + bDown = true + end + end + end + end + return true, bDown +end + +--------------------------------------------------------------------- +local function MakeCutsByDice( Proc, b3Raw, vCuts, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) + + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + vtOrthoO = Vector3d( vtRef2) + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( i == ( #vCuts - 1) or i == #vCuts) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < ( #vCuts - 1) or i == #vCuts then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -( dTrim + dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + + return true +end + +--------------------------------------------------------------------- +local function MachChainFacesByBlade( Proc, nCFaceSide, nCFaceInt1, nCFaceInt2, sCutting, bHead, vtRef, dTrim, dDepth) + + -- inserisco la lavorazione di taglio per la laterale negativa + local sName = 'Cut_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. EgtIf( nCFaceSide > 0, tostring( nCFaceSide) .. '_', '') .. tostring( nCFaceInt1) .. '-' .. tostring( nCFaceInt2) + local nMchFId = EgtAddMachining( sName, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nCFaceInt1 - 1},{ Proc.Id, nCFaceInt2 - 1}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) + local nSCC = EgtIf( vtRef:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + -- imposto posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- affondamento aggiuntivo + EgtSetMachiningParam( MCH_MP.OFFSR, -dTrim) + -- offset longitudinale + EgtSetMachiningParam( MCH_MP.OFFSL, 0) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto affondamento + if dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + else + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + end + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, 180) + EgtSetMachiningParam( MCH_MP.LOTANG, 0) + EgtSetMachiningParam( MCH_MP.LOPERP, 180) + local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nCFaceInt1 - 1, GDB_ID.ROOT) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nCFaceInt2 - 1, GDB_ID.ROOT) + local dNyMax = EgtIf( abs( vtN1:getY()) > abs( vtN2:getY()), vtN1:getY(), vtN2:getY()) + local dNzMax = EgtIf( abs( vtN1:getZ()) > abs( vtN2:getZ()), vtN1:getZ(), vtN2:getZ()) + if dNzMax < 0 and bHead == ( dNyMax < 0) then + EgtSetMachiningParam( MCH_MP.LITANG, 340) + EgtSetMachiningParam( MCH_MP.LIPERP, -100) + elseif dNzMax < 0 and bHead == ( dNyMax > 0) then + EgtSetMachiningParam( MCH_MP.LOTANG, 340) + EgtSetMachiningParam( MCH_MP.LOPERP, -100) + end + -- imposto allungamenti iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 50) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 50) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + + return true +end + +--------------------------------------------------------------------- +local function MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1, sErr1 end + ---- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + local vtRef2nd + if Proc.Fct > 2 and vFaceOrd[1] ~= 0 then + vtRef2nd = Vector3d( 0, vtN[vFaceOrd[1]]:getY(), vtN[vFaceOrd[1]]:getZ()) + vtRef2nd:normalize() + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + + -- calcolo la distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 and dAng > -89.9 then + dTrim = 0 + else + dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + end + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) + if not bOk then return false, sErr end + end + if vFaceOrd[1] ~= 0 then + bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[1] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 and dAng > -89.9 then + dTrim = 0 + else + dTrim = ((dToolThick* vtN[vFaceOrd[1]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + end + end + + -- se esistono faccia interna ed altra intermedia, verifico se richiedono taglio a cubetti + local vCuts2 = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[1] ~= 0 then + vCuts2 = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[1] ~= 0 then + vCuts2 = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], true) + end + if #vCuts2 > 0 then + local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts2, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) + if not bOk then return false, sErr end + end + + -- se non ha fatto nessun taglio a cubetti e ho 3 facce + if #vCuts == 0 and #vCuts2 == 0 and Proc.Fct > 2 then + -- lavoro la faccia interna (di fondo) indirettamente lavorando le due facce intermedie + local bOk, sErr = MachChainFacesByBlade( Proc, 0, vFaceOrd[3], vFaceOrd[1], sCutting, bHead, vtRef, ( dTrim + dFinalExtraTrim)) + if not bOk then return false, sErr end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- taglio sulla seconda faccia intermedia + if vFaceOrd[1] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- se altrimenti non ha fatto una parte dei tagli a cubetti + elseif #vCuts == 0 and #vCuts2 == 0 then + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nDirVect = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr + bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nDirVect, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeMillCut( Proc, i, j, k, sMilling, + nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut, bHead, vtRef) + local sWarn = '' + local bUnderCut = bUCut + -- inserisco la lavorazione di fresatura + -- per evitare nomi lavorazioni coincidenti, concateno anche il Proc.Id se il nome (del Proc.Id) è presente + local s2ndName = EgtGetName( Proc.Id) or '' + local sName = EgtIf( bUnderCut, 'MillTCone_', 'Mill_') .. ( EgtIf( #s2ndName > 0, s2ndName, tostring( Proc.Id))) .. ( EgtIf( #s2ndName > 0, '_' .. tostring( Proc.Id), '')) .. '_' .. tostring(i) .. '_' .. tostring(j) + local kStep = k or 0 + if kStep > 0 then + sName = sName .. '_' .. tostring(k) + end + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + local vtDirRef + -- imposto i parametri lavorazione in base alle facce lavorate + if vFaceOrd and #vFaceOrd > 0 then + -- aggiungo geometria e imposto uso faccia + EgtSetMachiningGeometry( {{ Proc.Id, vFaceOrd[3]-1},{ Proc.Id, vFaceOrd[1]-1}}) + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) + -- setto vettore direzione per posizione braccio porta testa + vtDirRef = vtRef + -- imposto lato corezione e inversione percorso + if kStep % 2 == 1 then + -- imposto lato sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + -- imposto lato destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- tolgo inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + -- imposto affondamento + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH' .. EgtIf( dOffs < 0, '', '-') .. EgtNumToString( dOffs, 4)) + else + -- aggiungo geometria e imposto uso faccia + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + local nFaceUse = BL.GetNearestOrthoOpposite( TabNAD[j][1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- setto vettore direzione per posizione braccio porta testa + vtDirRef = rfFac:getVersZ() + -- imposto lato corezione e inversione percorso + if kStep % 2 == 1 then + -- imposto lato destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + -- imposto lato sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- tolgo inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + -- imposto affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dOffs) + end + -- imposto posizione braccio porta testa + local nSCC = EgtIf( vtDirRef:getY() > (100 * GEO.EPS_ZERO), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + --imposto passo 0 + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto offset radiale in base all'angolo tra le due facce e alla posizione in Z + il passo laterale + dOffrRad = dOffrRad + dAddOffsRad + -- per le passate intermedie aggiungo un delta sull'offset radiale perchè c'è già il taglio di lama precedente + EgtSetMachiningParam( MCH_MP.OFFSR, dOffrRad + EgtIf( bPrevByBlade and ( i < nStep) and ( kStep < 1), 0.5, 0)) + -- imposto offset longotudinale a 0 + EgtSetMachiningParam( MCH_MP.OFFSL, 0) + -- imposto gli attacchi + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( 60 + 0.5 * dToolDiam)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( 60 + 0.5 * dToolDiam)) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill solo in ultima passata in Z locale + local sUserNotes + if i < nStep then + sUserNotes = 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + else + sUserNotes = 'VMRS=0;' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + _, sWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, + bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces, + vFaceOrd, bHead, sMillingMaster, dToolDiamMaster, dMaxMatMaster, + dSideAngleMaster, dMachStepMaster, nMainFace, dElevMain) + local sWarn = '' + local sMilling + local dToolDiam = 100 + local dSideAngle = 0 + local dMaxMat = 50 + local dMaxDepth = 50 + local dMachStep = 0 + local bUCutMax + -- dati della facce + local vtN = {} + local ptC = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + end + -- se non ho passato la lavorazione ( già verificata) + if not sMillingMaster then + -- se il flag del sottosquadra è nil, cerco se tra le facce c'è un angolo sottosquadra + if bUCut == nil then + for i = 1, nFacetCnt do + for j = i + 1, nFacetCnt do + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, (i-1), (j-1), GDB_ID.ROOT) + if bAdj and dAng and dAng < -90.1 then + bUCut = true + break + end + end + end + end + -- recupero l'angolo di spoglia dell'utensile a tronco di cono + -- recupero la lavorazione + local sMchFind = 'Long2Cut' + if bUCut then + sMchFind = 'ProfTCone' + end + sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep + end + end + if dMachStep <= 0.1 then + dMachStep = dMaxMat * 0.5 + end + else + sMilling = sMillingMaster + dToolDiam = dToolDiamMaster + dMaxMat = dMaxMatMaster + dSideAngle = dSideAngleMaster + dMachStep = dMachStepMaster + end + local nFacInd, dFacElev + if nMainFace and dElevMain then + nFacInd = nMainFace + dFacElev = dElevMain + else + -- se devo lavorare facce concatenate + if bJoinFaces then + nFacInd = vFaceOrd[2] - 1 + -- calcolo l'elevazione + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + if dLenIn > 0 then + dFacElev = dLenIn + elseif dLenOut then + dFacElev = dLenOut + end + else + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, sin(dSideAngle)) + if not nFacInd or nFacInd < 0 then + -- provo eliminando i sottosquadra + nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, -2) + if not nFacInd or nFacInd < 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MachSideFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + else + bUCutMax = true + end + end + end + end + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local TabNAD = {} + local bPrevByBlade = false + -- se non ho la forzatura a usare solo truciolatore e tagli lama consentiti + -- inserisco tagli di lama come antischeggia sulle altre facce + if not bForceUseRough and bUseBlade then + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dToolThick + end + end + -- controllo versore faccia di riferimento, è lungo l'asse trave + local vtRef = Vector3d( vtN[nFacInd+1]) + if not AreSameVectorApprox( vtN[nFacInd+1], X_AX()) and not AreSameVectorApprox( vtN[nFacInd+1], -X_AX()) then + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[nFacInd+1]:getY(), vtN[nFacInd+1]:getZ()) + end + vtRef:normalize() + -- ciclo inserimento tagli antischeggia sulle facce + for i = 1, nFacetCnt do + if ( i - 1) == nFacInd then + TabNAD[i] = { vtN[i]} + else + local dExtraZed = EgtIf( bForceMakeMill, 1, 0.1) + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) + if dAng then + TabNAD[i] = { vtN[i], dAng, dist( ptP1, ptP2)} + end + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + dExtraZed = 0.1 + else + dTrim = ((dToolThick* vtN[nFacInd+1]) * vtN[i] * vtN[i]):len() + end + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, ( i - 1), sCutting, dSawDiam, nOrthoOpposite, nil, -( dTrim + dExtraZed), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + bPrevByBlade = true + end + end + -- altrimenti solo taglio truciolatore + else + for i = 1, nFacetCnt do + if ( i - 1) == nFacInd then + TabNAD[i] = { vtN[i]} + else + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) + if dAng then + TabNAD[i] = { vtN[i], dAng, dist( ptP1, ptP2)} + end + end + end + end + local vtRef + -- se devo lavorare facce concatenate + if bJoinFaces then + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + end + -- creo percorsi di lavorazione + local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dMachStep) + local dStep = dFacElev / nStep + local dLargeVal + local nLenSideMax + -- se non devo fare fresature + if not bForceMakeMill then nStep = 0 end + for i = 1, nStep do + local dOffs = ( i * dStep) - dFacElev + if i == nStep then dOffs = 0 end + local dOffsSide = 0 + local dDelta = 100000 + local dElevface + for j = 1, nFacetCnt do + if ( j - 1) ~= nFacInd then + local dParzElev = dOffs + -- calcolo la larghezza (solo 1 volta) + if i == 1 then + -- se ho un sottosquadra maggiore dell'angolo di spoglia utensile + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dParzElev = dFacElev + end + if bJoinFaces then + -- calcolo l'elevazione di ogni singola faccia dal punto medio + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[j], vtN[j]) + if dLenIn > 0 then + dElevface = dLenIn + elseif dLenOut then + dElevface = dLenOut + end + if not dLargeVal or dElevface > dLargeVal then + dLargeVal = dElevface + end + else + local dDeltadH = abs( TabNAD[j][3] - dH) + local dDeltadV = abs( TabNAD[j][3] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + nLenSideMax = j + end + else + if dDeltadV < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + nLenSideMax = j + end + end + end + end + -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) + dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) + end + end + local dRefLarge + -- se ho facce concatenate verifico che la massima larghezza sia comunque superiore al diametro utensile + if bJoinFaces then + dRefLarge = dToolDiam + dLargeVal = EgtIf( dLargeVal > ( dToolDiam + dOffsSide), dLargeVal, dToolDiam + dOffsSide) + else + dRefLarge = EgtIf( nFacetCnt == 2, dToolDiam, ( 2 * dToolDiam)) + end + -- se ho 2 facce o la larghezza è più grande dell'utensile allora posso lavorare il passo + if nFacetCnt == 2 or ( dLargeVal - dOffsSide) >= dToolDiam then + -- se ho facce concatenate + if bJoinFaces then + local dOffrRad = 0 + -- se larghezza faccia consente passi laterali extra + if ( dLargeVal - dOffsSide) > dRefLarge then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) + local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide + for k = nStepSide, 1, -1 do + local dAddOffsRad = ( k * dStepSide) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, 1, k, sMilling, + nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut, bHead, vtRef) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- inserisco la lavorazione di fresatura a contatto con la faccia + local bOk, sErr = MakeMillCut( Proc, i, 1, nil, sMilling, + nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, + dOffrRad, 0, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut, bHead, vtRef) + if not bOk then + return false, sErr + end + sWarn = sErr + else + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + -- calcolo l'offset radiale in base all'affondamento e all'angolo spoglia + local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dOffrRad = -( tan( 90 + TabNAD[j][2]) * dFacElev) + end + -- se lato lavorato è il più lungo e la larghezza cava consente passi laterali extra + if j == nLenSideMax and ( dLargeVal - dOffsSide) > dRefLarge then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / ( dToolDiam * 0.5)) + local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide + for k = nStepSide, 1, -1 do + local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- inserisco la lavorazione di fresatura a contatto con la faccia + local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, 0, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + end + -- altrimenti passo saltato esco con errore + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' + EgtOutLog( sErr) + return false, sErr + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +local function Make2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) + -- verifico le normali delle facce + -- individuo se c'è faccia rivolta verso Z- + local nFlatFaceNeg + local vtN = {} + local ptC = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + if vtN[i]:getZ() < -0.99 then + nFlatFaceNeg = i - 1 + end + end + -- se trovata faccia rivolta verso Z- faccio controllo di lavorabilità da sotto + if nFlatFaceNeg then + -- prendo le dimensioni della faccia + local dLargeFace = Proc.Box:getDimX() + local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough, sMilling = VerifyIfRoughMill( dLargeFace, -Z_AX(), true) + -- se non forzato truciolatore provo la lama + if not bForceUseRough and bUseBlade then + return MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + -- altrimenti provo con il truciolatore + else + -- se non ho la lavorazione esco + if not sMilling then + local sErr = 'Error, machining or tool not found ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- Calcolo uso faccia + local nOtherInd = 2 - nFlatFaceNeg + local nFaceUse = BL.GetNearestParalOpposite( vtN[nOtherInd]) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFlatFaceNeg}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- annullo offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- applico allungamento iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YP + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- altrimenti non ho faccia (antivento) da sotto + else + for i = 1, Proc.Fct do + local nFacet = i - 1 + -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + if abs( vtN[i]:getZ()) > abs( vtN[i]:getX()) and abs( vtN[i]:getZ()) > abs( vtN[i]:getY()) and vtN[i]:getZ() < -0.5 then + -- lavoro con lama o truciolatore in base al Q + -- prendo le dimensioni della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local nOtherFace = 1 - nFacet + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) + local dLargeFace = Proc.Box:getDimX() + local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUCut = ( dAng < 0) and ( dAng < -90 - 5 * GEO.EPS_SMALL) + local bOCut = ( dAng < 0) and ( dAng > -90 + 5 * GEO.EPS_SMALL) + local bForceMakeMill = bUCut or bForceUseRough + -- 2020.04.18 da indicazioni di Fabio Sq. : se angolo interno acuto lo lavoro con utensile a tronco di cono + -- e, se consentito uso lama, preceduto anche due tagli antischeggia (solo in caso di 3 facce, con 2 facce disattivo gli antischeggia) + local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, X_AX(), true, EgtIf( bUCut, ( 90 + dAng), nil)) + -- se devo farlo con fresatura + if bForceMakeMill then + -- se non ho lavorazione (se per esempio l'angolo di spoglia utensile non è uguale a quello tra le due facce) do errore + if not sMilling then + local sErr = 'Error, machining or tool not found ' .. sName + EgtOutLog( sErr) + return false, sErr + end + -- genero lavorazioni + local bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + bUseBlade, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, nOtherFace, dLargeFace) + if not bOk then return false, sErr end + elseif bUseBlade then + local bOk, sErr = MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + -- se fallita di lama e di fresa è fattibile, eseguo con la fresa + if not bOk and sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + bUseBlade, true, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, nOtherFace, dLargeFace) + if not bOk then return false, sErr end + else + return false, sErr + end + end + return true + -- altrimenti non in Z negativa + else + -- se nessuna entità ha z negativa + if i == Proc.Fct then + -- verifico angolo tra le facce + local nOtherFace = nFacet - 1 + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) + local dLargeFace = Proc.Box:getDimX() + -- ordino le facce, se 2 facce: (1=0, 2=interna, 3=intermedia) + local bOk, sErr, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk then return bOk, sErr end + local bUCut = ( dAng < 0) and ( dAng < -90 - 5 * GEO.EPS_SMALL) + local bOCut = ( dAng < 0) and ( dAng > -90 + 5 * GEO.EPS_SMALL) + local bForceMakeMill = bUCut or bForceUseRough + -- 2020.04.18 da indicazioni di Fabio Sq. : se angolo interno acuto lo lavoro con utensile a tronco di cono + -- e, se consentito uso lama, preceduto anche due tagli antischeggia (solo in caso di 3 facce, con 2 facce disattivo gli antischeggia) + -- se devo farlo con fresatura + if bForceMakeMill then + local bOk, sErr + bOk = false + -- se angolo ( tra le due facce è) ottuso + if bOCut then + local ptPs = ( ptP1 + ptP2) / 2 + -- calcolo l'elevazione di ogni singola faccia dal punto medio della linea di adiacenza + -- prendo l'elevazione sul punto medio della prima faccia + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[vFaceOrd[2]]) + if dLenIn > 0 then + dLargeFace = dLenIn + elseif dLedOut then + dLargeFace = dLedOut + end + -- verifico la possibilità di lavorare con utensile + local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, vtN[vFaceOrd[2]], true) + -- se ho trovato lavorazione applicata a faccia definita + if sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, vFaceOrd[2]-1, dLargeFace) + end + -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima + if not bOk then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false) + end + if not bOk then return false, sErr end + + -- prendo l'elevazione sul punto medio della seconda faccia + dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[vFaceOrd[3]]) + if dLenIn > 0 then + dLargeFace = dLenIn + elseif dLedOut then + dLargeFace = dLedOut + end + -- verifico la possibilità di lavorare con utensile + bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, vtN[vFaceOrd[3]], true) + -- se ho trovato lavorazione applicata a faccia definita + if sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, vFaceOrd[3]-1, dLargeFace) + end + -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima + if not bOk then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false) + end + if not bOk then return false, sErr end + else + -- verifico la possibilità di lavorare con utensile (orizzontale) + local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, X_AX(), true, EgtIf( bUCut, ( 90 + dAng), nil)) + -- se ho trovato lavorazione applicata a faccia definita + if sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, vFaceOrd[2]-1, dLargeFace) + end + -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima + if not bOk then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false) + end + if not bOk then return false, sErr end + end + else + return MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + end + end + end + end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + + -- recupero la geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return true end + AuxId = AuxId + Proc.Id + -- recupero il centro e la normale della faccia ausiliaria + local ptC, vtN = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + if not vtN then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' wrong Normal of AuxSurface' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se di testa o coda + local bHead = ( vtN:getX() > 0) + -- recupero la lavorazione per la geometria ausiliaria + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se già fatto con altro componente della stessa feature + local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring( AuxId), 'b') + if bAuxMachined then return true end + -- verifico se coincide con taglio di testa + if bHead and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- verifico se coincide con taglio di coda + if not bHead and AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + -- inserisco la lavorazione + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + -- imposto la nota nel gruppo aggiuntivo di lavorazione per evitare di tagliare una seconda volta + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + return true +end + +--------------------------------------------------------------------- +local function MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, nSidePosFct, nMiddleFct, nSideNegFct, vtRef, nFacetCnt) + + local sWarn = '' + -- recupero la lavorazione + local sMchFind = 'Long2Cut' + local sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 100 + local dMaxMat = 50 + local dSideAngle = 0 + local dMachStep = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + -- ottengo il passo della lavorazione + dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep + end + end + if dMachStep <= 0.1 then + dMachStep = dMaxMat * 0.5 + end + local nFacInd = nMiddleFct - 1 + local dFacElev + -- calcolo elevazione + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[nMiddleFct], vtN[nMiddleFct]) + if dLenIn > 0 then + dFacElev = dLenIn + elseif dLenOut then + dFacElev = dLenOut + end + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local TabNAD = {} + TabNAD[nMiddleFct] = { vtN[nMiddleFct]} + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, ( nSideNegFct or 0) - 1, GDB_ID.ROOT) + if dAng then + TabNAD[nSideNegFct] = { vtN[nSideNegFct], dAng, dist( ptP1, ptP2)} + end + bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (nSidePosFct-1), GDB_ID.ROOT) + if dAng then + TabNAD[nSidePosFct] = { vtN[nSidePosFct], dAng, dist( ptP1, ptP2)} + end + -- creo percorsi di lavorazione + local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dMachStep) + local dStep = dFacElev / nStep + local dLargeVal + local nLenSideMax + for i = 1, nStep do + local dOffs = ( i * dStep) - dFacElev + if i == nStep then dOffs = 0 end + local dOffsSide = 0 + local dDelta = 100000 + local dElevface + for j = 1, nFacetCnt do + if j == nSideNegFct or j == nSidePosFct then + local dParzElev = dOffs + -- calcolo la larghezza (solo 1 volta) + if i == 1 then + local dDeltadH = abs( TabNAD[j][3] - dH) + local dDeltadV = abs( TabNAD[j][3] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + nLenSideMax = j + end + else + if dDeltadV < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + nLenSideMax = j + end + end + end + -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) + dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) + end + end + local dRefLarge = EgtIf( nSideNegFct, ( 2 * dToolDiam), dToolDiam) + -- se la larghezza è più grande dell'utensile allora posso lavorare il passo + if ( dLargeVal - dOffsSide) >= dToolDiam then + for j = 1, nFacetCnt do + if j == nSideNegFct or j == nSidePosFct then + -- calcolo l'offset radiale in base all'affondamento e all'angolo spoglia + local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) + -- se lato lavorato è il più lungo e la larghezza cava consente passi laterali extra + if j == nLenSideMax and ( dLargeVal - dOffsSide) > dRefLarge then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * EgtIf( nSideNegFct, 0.5, 1)) + local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide + for k = nStepSide, 1, -1 do + local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + true, false) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- inserisco la lavorazione di fresatura a contatto con la faccia + local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, 0, nStep, dToolDiam, dStep, + true, false) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- altrimenti passo saltato esco con errore + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' + EgtOutLog( sErr) + return false, sErr + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bUseBlade) + + local ptC = {} + local vtN = {} + -- dati delle facce e ordinamento facce { } + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le 4 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia, 4=esterna) + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1, sErr1 end + -- vettori di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + local vtRef2nd = Vector3d( 0, vtN[vFaceOrd[1]]:getY(), vtN[vFaceOrd[1]]:getZ()) + vtRef2nd:normalize() + -- se non forzato uso truciolatore e abilitato il taglio di lama faccio le due pareti con antischeggia + -- lavoro le facce laterali indirettamente lavorando le due facce intermedie + if not bForceUseRough and bUseBlade then + -- recupero la lavorazione con lama + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + local dTrim = -0.3 + -- se ho la faccia laterale negativa + if vFaceOrd[4] ~= 0 then + -- inserisco la lavorazione di taglio per la faccia laterale negativa, faccio in modo che la testa rimanga nella stessa posizione per entrambe i tagli + local bOk, sErr = MachChainFacesByBlade( Proc, vFaceOrd[4], vFaceOrd[3], vFaceOrd[1], sCutting, true, vtRef, dTrim, dToolThick) + if not bOk then return false, sErr end + end + -- se ho la faccia laterale positiva + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione di taglio per la faccia laterale positiva + local bOk, sErr = MachChainFacesByBlade( Proc, vFaceOrd[2], vFaceOrd[3], vFaceOrd[1], sCutting, true, vtRef, dTrim) + if not bOk then return false, sErr end + end + end + -- lavoro le facce intermedie + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione di fresatura per la faccia intermedia + local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[2], vFaceOrd[3], vFaceOrd[4], vtRef, Proc.Fct) + if not bOk then return false, sErr end + end + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione di fresatura per la faccia intermedia + local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[2], vFaceOrd[1], vFaceOrd[4], vtRef, Proc.Fct) + if not bOk then return false, sErr end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bInMiddle) + -- flag per lavorazioni sulla testa o coda + local bUseBlade = false + local bForceMakeMill = bForceUseRough + local bUCut = false + local bOCut = false + local bJoinFaces = true + -- modifiche ai flag per lavorazione in mezzo + if bInMiddle then + -- abilito la lama per i tagli antischeggia + bUseBlade = true + -- abilito la fresatura + bForceMakeMill = true + -- disabilito il concatenamento delle facce intermedie + bJoinFaces = false + -- annullo il flag del sottosquadra per forzare la ricerca all'interno della funzione + bUCut = nil + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce, se 3 facce: (1=altra intermedia, 2=interna, 3=intermedia) + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1, sErr1 end + -- verifica se di testa o coda + local bHead = false + if not bInMiddle then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + end + -- se non in mezzo può essere necessario lavorare come in mezzo + if not bInMiddle then + -- calcolo l'elevazione + local dSideElev = 0 + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + if dLenIn > 0 then + dSideElev = dLenIn + elseif dLenOut then + dSideElev = dLenOut + end + -- determino il massimo affondamento con l'utensile + local sMchFind = 'Long2Cut' + sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 10 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se l'elevazione supera l'affondamento, lavoro perpendicolare all'asse trave + if dSideElev > dMaxDepth then + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bUseBlade) + end + end + + -- lavoro le restanti facce in modo standard + return MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces, + vFaceOrd, bHead) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- verifico se sono presenti i parametri Q per l'uso forzato del truciolatore + local bForceUseRough = EvaluateQParam( Proc, sUseRoughTool) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + if Proc.Fct < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + + -- se ha due facce ( allora è di testa o coda) + if Proc.Fct == 2 then + -- eventuale taglio di testa o coda + local bAuxOk, sAuxErr = MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + if not bAuxOk then return bAuxOk, sAuxErr end + -- lavorazione della feature + local bOk, sErr = Make2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) + if not bOk then return bOk, sErr end + -- se ha 3 facce ed è di testa o coda + elseif Proc.Fct == 3 and ( Proc.Head or Proc.Tail) then + -- eventuale taglio di testa o coda + local bAuxOk, sAuxErr = MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + if not bAuxOk then return bAuxOk, sAuxErr end + -- lavorazione della feature + if bForceUseRough then + local bOk, sErr = MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) + if not bOk then return bOk, sErr end + else + local bOk, sErr = MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + if not bOk then return bOk, sErr end + end + -- se ha 3 facce (e interna) + elseif Proc.Fct == 3 then + local bOk, sErr = MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, true) + if not bOk then return bOk, sErr end + -- altrimenti 4 facce (e interna) + else + local bOk, sErr = MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, true) + if not bOk then return bOk, sErr end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dTCI) + end + + return true +end + +--------------------------------------------------------------------- +return ProcessDovetail diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDrill.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDrill.lua new file mode 100644 index 0000000..9ba0f11 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDrill.lua @@ -0,0 +1,284 @@ +-- ProcessDrill.lua by Egaltech s.r.l. 2020/07/27 +-- Gestione calcolo forature per Travi + +-- Tabella per definizione modulo +local ProcessDrill = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDrill started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDrill.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 40) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDrill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + return false + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- se entrata principale + if Proc.Flg > 0 then + local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + return ( ( nFcs == 5 or nFcs == 6) and vtExtr:getX() > 0.5) + -- altrimenti entrata opposta + else + local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + return ( ( nFce == 5 or nFce == 6) and vtExtr:getX() < -0.5) + end + +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDrill.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.OVM_MID + BD.MAX_DIST_HTFEA then + return false + end + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + return false + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- se entrata principale + if Proc.Flg == 2 or ( Proc.Flg == 1 and vtExtr:getZ() >= BD.DRILL_VZ_MIN) then + local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + return ( ( nFcs == 5 or nFcs == 6) and vtExtr:getX() < -0.5) + -- altrimenti entrata opposta + else + local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + return ( ( nFce == 5 or nFce == 6) and vtExtr:getX() > 0.5) + end +end + +--------------------------------------------------------------------- +-- Recupero dati foro e adattamento se speciale +function ProcessDrill.GetData( Proc, b3Raw) + -- 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 BD.USER_HOLE_DIAM and BD.USER_HOLE_DIAM > 1 then + EgtModifyArcRadius( AuxId, BD.USER_HOLE_DIAM / 2) + 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 + +--------------------------------------------------------------------- +-- Verifica se da lavorare in due metà +function ProcessDrill.Split( 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 bOpen = ( Proc.Fce ~= 0) + -- recupero flag abilitazione split (0=auto,1=no) + local bTrySplit = ( EgtGetInfo( Proc.Id, 'Q02', 'i') ~= 1) + if not bTrySplit then + return false + end + -- recupero la lavorazione + local sDrilling, _, dMaxMat = ML.FindDrilling( dDiam) + if not sDrilling then dMaxMat = 0 end + -- restituisco se va fatto in doppio (solo fori orizzontali) + local bHoriz = ( abs( vtExtr:getZ()) < abs( BD.DRILL_VZ_MIN) and + ( abs( vtExtr:getY()) * b3Raw:getDimZ() > abs( vtExtr:getZ()) * b3Raw:getDimY() or Proc.Fce == 5 or Proc.Fce == 6)) + local bSlant = ( abs( vtExtr:getX()) > BD.DRILL_VX_MAX) + return ( bOpen and ( bHoriz or BD.ROT90) and not bSlant) +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) + -- se lavorato in doppio, devo considerare il lato più sfavorevole + if Proc.Flg == 2 or Proc.Flg == -2 then + if vtExtr:getZ() > 0 then + vtExtr = - vtExtr + ptCen = ptCen + vtExtr * dLen + end + end + -- 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()) > BD.DRILL_VX_MAX then + return false, false, false + end + local bOpen = ( Proc.Fce ~= 0) + local bFaceDown = ( ptCen:getZ() < b3Raw:getMin():getZ() + 2 and not Proc.Head and not Proc.Tail) + -- verifico se il foro è sotto e quindi va spostato o sopra o sul fianco + if (( vtExtr:getZ() < BD.DRILL_VZ_MIN or bFaceDown) and ( not bOpen or Proc.Flg ~= 1)) then + if not bOpen then + return true, true, false + else + return true, not BD.ROT90, BD.ROT90 + end + else + return true, false, false + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) + -- 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 : 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) + if Proc.Flg == -2 then vtExtr = - vtExtr end + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- verifico che il foro non sia fattibile solo da sotto + local bToInvert = ( vtExtr:getZ() < BD.DRILL_VZ_MIN) + if bToInvert and ( not bOpen or Proc.Flg ~= 1) then + local sErr = 'Error : drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + if Proc.Fcs == 0 then bToInvert = true end + if bToInvert then vtExtr = - vtExtr end + if Proc.Flg == -2 then bToInvert = true end + -- recupero la lavorazione + local sDrilling, nType = ML.FindDrilling( dDiam) + if not sDrilling then + local sErr = 'Error : 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 < BD.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 Proc.Flg == 2 or Proc.Flg == -2 then + dDepth = dLen / 2 + BD.DRILL_OVERLAP + end + 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/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDtMortise.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDtMortise.lua new file mode 100644 index 0000000..c2dc3cb --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDtMortise.lua @@ -0,0 +1,290 @@ +-- ProcessDtMortise.lua by Egaltech s.r.l. 2020/07/27 +-- Gestione calcolo mortase a coda di rondice per Travi + +-- Tabella per definizione modulo +local ProcessDtMortise = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDtMortise started', 1) + +-- Dati +local BL = require( 'BeamLib') +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- settaggi interni ( poi andrà utilizzato parametro ACTIVE_AS proveniente da parametri utente di TechnoEssetre) +local bMakeAntiSplitPath = true +local bMakeAsByArc = true + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDtMortise.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 55) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 56)) +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDtMortise.IsTailFeature( Proc, b3Raw) + -- la mortasa di fronte è già stata classificata nel chiamante + -- controllo la mortasa standard + if Proc.Box:getMin():getX() < b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + -- recupero la curva di profilo + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtStart = EgtSV( AuxId, GDB_ID.ROOT) + local vtEnd = EgtEV( AuxId, GDB_ID.ROOT) + local vtDir = -vtStart + vtEnd ; vtDir:normalize() + return ( vtDir:getX() < -0.5) + end + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDtMortise.Classify( Proc) + -- recupero i dati della curva di contorno della faccia di fondo + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se la mortasa è lavorabile solo da sotto + local bDown = ( vtExtr:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +local function CalcTopPath( nProcId, AuxId, nAddGrpId, dAltMort, dSideAng, b3Solid) + -- copio la curva di base + local NewAuxId = EgtCopyGlob( AuxId, nAddGrpId) + if not NewAuxId then return end + -- ne allungo gli estremi + EgtExtendCurveStartByLen( NewAuxId, 100) + EgtExtendCurveEndByLen( NewAuxId, 100) + -- eseguo traslazione e offset per portarla sul top + local vtMove = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) * ( dAltMort - 10 * GEO.EPS_SMALL) + EgtMove( NewAuxId, vtMove, GDB_RT.GLOB) + local dOffset = dAltMort * tan( dSideAng) + if not EgtOffsetCurve( NewAuxId, dOffset) then return end + -- la limito entro la trave + local refBox = Frame3d( b3Solid:getMin()) + local vtBoxDiag = b3Solid:getMax() - b3Solid:getMin() + local nCount + NewAuxId, nCount = EgtTrimFlatCurveWithBox( NewAuxId, refBox, vtBoxDiag, true, true, GDB_RT.GLOB) + -- se divisa in più parti, le unisco congiungendole con segmenti + if nCount > 1 then + if EgtGetType( NewAuxId) ~= GDB_TY.CRV_COMPO then + NewAuxId = EgtCurveCompo( nAddGrpId, NewAuxId) + end + for i = 2, nCount do + local CrvId = NewAuxId + i - 1 + local ptStart = EgtSP( CrvId, GDB_ID.ROOT) + EgtAddCurveCompoLine( NewAuxId, ptStart, GDB_RT.GLOB) + EgtAddCurveCompoCurve( NewAuxId, CrvId) + end + end + return NewAuxId +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDtMortise.Make( Proc, nPhase, nRawId, nPartId) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') 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') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Missing profile geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del top + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico che la mortasa non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 then + local sErr = 'Machining from bottom impossible : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'DtMortise') + if not sMilling then + local sErr = 'Milling not found in library : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile e l'angolo di spoglia + local dToolDiam = 100 + local dMaxMat = 30 + local dSideAng = 0 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolDiam = max( dToolDiam, 10) + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- verifico se raggio troppo piccolo per l'utensile + local nSt, nEnd = EgtCurveDomain( AuxId) + for i = nSt, nEnd - 1 do + local dRad = EgtCurveCompoRadius( AuxId, i) + if dRad > 0 and dRad < dToolDiam / 2 then + local sErr = 'Radius too small : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + end + -- se parametro interno abilitato e il percorso non è chiuso, aggiungo percorso e lavorazione antischeggia + if bMakeAntiSplitPath and not EgtCurveIsClosed( AuxId) then + -- recupero il riferimento della faccia di fondo + local rfFac0 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + -- ottengo il box con la normale della faccia 0 + local bBoxF0 = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfFac0) + -- recupero l'altezza della mortasa + local dAltMort = bBoxF0:getDimZ() + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo il percorso top mortise + local nAuxId1 = CalcTopPath( Proc.Id, AuxId, nAddGrpId, dAltMort, dSideAng, b3Solid) + -- se esiste il percorso + if nAuxId1 then + -- creo percorso sulla parte alta della mortasa + local dToolRadDelta = dAltMort * tan( dSideAng) + local dTopDiam = dToolDiam + 2 * dToolRadDelta + -- recupero punto iniziale e finale del percorso + local ptStart = EgtSP( nAuxId1, GDB_RT.GLOB) + local ptEnd = EgtEP( nAuxId1, GDB_RT.GLOB) + if ptStart and ptEnd then + local nId1 + -- se richiesti due segmenti di linea + if not bMakeAsByArc then + -- determino il punto comune dei due segmenti + local vtDelta = ( ptEnd - ptStart) / 4 + vtDelta:rotate( vtExtr, -90) + local ptMid = ( ptStart + ptEnd) / 2 + vtDelta + -- creo la spezzata formata dai due segmenti + nId1 = EgtCurveCompoFromPoints( nAddGrpId, { ptStart, ptMid, ptEnd}, GDB_RT.GLOB) + -- altrimenti richiesto arco + else + -- direzione del segmento + local vtDir = ptEnd - ptStart ; + local dLen = vtDir:len() + vtDir:normalize() + -- direzioni tangenti iniziale e finale + local vtStart = EgtSV( nAuxId1, GDB_RT.GLOB) + local vtEnd = EgtEV( nAuxId1, GDB_RT.GLOB) + -- angoli + local dAngStart = acos( vtStart * vtDir) + local dAngEnd = acos( vtEnd * vtDir) + local dMaxAng = min( 30, dAngStart, dAngEnd) + if dLen < dTopDiam then + dMaxAng = min( dMaxAng, asin( dLen / dTopDiam)) + end + local vtTg = vtDir ; vtTg:rotate( vtExtr, -dMaxAng) + -- creo l'arco + nId1 = EgtArc2PV( nAddGrpId, ptStart, ptEnd, vtTg, GDB_RT.GLOB) + end + if not nId1 then + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + EgtModifyCurveExtrusion( nId1, vtExtr, GDB_RT.GLOB) + -- inserisco la lavorazione di contornatura anti splint + local sNameF = 'DtMtAS_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nId1, -1}}) + -- setto affondamento pari all'altezza della mortsasa + EgtSetMachiningParam( MCH_MP.DEPTH, dAltMort) + -- setto offset radiale con aggiunto un ulteriore allargamento di 1mm + EgtSetMachiningParam( MCH_MP.OFFSR, dToolRadDelta - 1) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, false, true)) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dAltMort, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + else + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + else + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + end + -- verifico se necessarie più passate (distanza all'imbocco ortogonale all'asse) + local vtDiff = EgtEP( AuxId, GDB_RT.GLOB) - EgtSP( AuxId, GDB_RT.GLOB) + local vtAx = EgtEV( AuxId, GDB_RT.GLOB) - EgtSV( AuxId, GDB_RT.GLOB) + vtAx:normalize() + local vtOrtDiff = vtDiff - vtDiff * vtAx * vtAx + local dDist = vtOrtDiff:len() + -- calcolo le passate + local nPass = ceil( dDist / ( 1.9 * dToolDiam)) + local dStep = ( dDist - 0.95 * dToolDiam) / ( 2 * nPass) + for i = nPass, 1, -1 do + -- inserisco la lavorazione di contornatura + local sNameF = 'DtMt_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nPass) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto offset + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, false, true)) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessDtMortise diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDtTenon.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDtTenon.lua new file mode 100644 index 0000000..21fb0b7 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessDtTenon.lua @@ -0,0 +1,258 @@ +-- ProcessTenon.lua by Egaltech s.r.l. 2020/04/27 +-- Gestione calcolo tenone a coda di rondine per Travi + +-- Tabella per definizione modulo +local ProcessDtTenon = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTenon started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + + +--------------------------------------------------------------------- +local function VerifyOrientation( Proc, vtN, b3Raw) + -- se trave molto bassa + if b3Raw:getDimZ() <= 120 then + -- se tenone praticamente in asse, accetto fino a -45 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.7072) + -- altrimenti accetto fino a -30deg + else + return ( vtN:getZ() >= -0.51) + end + -- se trave bassa + elseif b3Raw:getDimZ() <= 200 then + -- se tenone praticamente in asse, accetto fino a -30 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.51) + -- altrimenti accetto fino a -20deg + else + return ( vtN:getZ() >= -0.343) + end + -- se trave media + elseif b3Raw:getDimZ() <= 300 then + -- se tenone praticamente in asse, accetto fino a -20 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.343) + -- altrimenti, accetto fino a -10 deg + else + return ( vtN:getZ() >= -0.174) + end + -- altrimenti + else + -- accetto fino a -5deg + return ( vtN:getZ() >= -0.088) + end +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDtTenon.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 55) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDtTenon.Classify( Proc, b3Raw) + -- recupero i dati della curva di contorno della faccia top + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se il tenone è lavorabile solo da sotto + local bDown = not VerifyOrientation( Proc, vtExtr, b3Raw) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDtTenon.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') 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') + 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 + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + -- verifico che il tenone non sia orientato verso il basso + if not VerifyOrientation( Proc, vtExtr, b3Raw) then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' DtTenon from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza del tenone + local frDtTen = Frame3d( ptBC, vtExtr) + local b3DtTen = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frDtTen) + local dDtTenH = b3DtTen:getDimZ() + -- assegno centro e normale della faccia top + local vtN = vtExtr + local ptC = ptBC + vtN * dDtTenH + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- porto inizio curva a Zmax + BL.PutStartOnTop( AuxId) + -- se tenone inclinato o non esattamente alle estremità, necessario taglio di lama sulla testa + if not AreSameOrOppositeVectorApprox( vtN, X_AX()) or + ( Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dOvmHead - 100 * GEO.EPS_SMALL and + Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 100 * GEO.EPS_SMALL) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla testa del tenone e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC, vtN, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- se pezzo piccolo, in coda e piano inclinato attorno a Z applico svuotatura + if b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getX() < 0 and abs( vtExtr:getY()) > 0.173 then + local sPocketing = ML.FindPocketing( 'OpenPocket') + -- 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( {{ AddId, -1}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + local nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- altrimenti applico taglio di lama + else + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getZ() > 0.25) + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0, bFromBottom) + if not bOk then return bOk, sErr end + end + end + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'DtTenon') + 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 dTDiam = 50 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- calcolo distanza massima della curva dal punto più lontano della base tenone Dt (facet 0) + local dMaxDist = 0 + local nLoopId, nLoopCnt = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id)) + if nLoopId then + local dUmin, dUmax = EgtCurveDomain( nLoopId) + for dU = dUmin, dUmax do + local ptP = EgtUP( nLoopId, dU, GDB_ID.ROOT) + local ptNear = EgtNP( AuxId, ptP, GDB_ID.ROOT) + local dDist = dist( ptP, ptNear) + if dDist > dMaxDist then + dMaxDist = dDist + end + end + for i = 1, nLoopCnt do + EgtErase( nLoopId + i - 1) + end + else + local b3DtAux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frDtTen) + dMaxDist = 2 * ( b3DtTen:getRadius() - b3DtAux:getRadius()) + end + EgtOutLog( 'MaxDist=' .. EgtNumToString( dMaxDist, 3), 3) + -- Cicli di lavorazione (max 5) + local MAX_PASS = 5 + local nStep = min( ceil( dMaxDist / ( 0.7 * dTDiam)), MAX_PASS) + local dStep = min( dMaxDist, 0.7 * dTDiam * MAX_PASS) / nStep + for i = nStep, 1, -1 do + -- inserisco la passata di lavorazione + local sNameR = 'DtTn_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchRId = EgtAddMachining( sNameR, sMilling) + if not nMchRId then + local sErr = 'Error adding machining ' .. sNameR .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo i parametri + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dDtTenH, 1) .. ';') + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if abs( vtExtr:getY()) > 0.088 then + nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchRId, false) + return false, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if abs( vtN:getY()) > 0.1 or ( b3Raw:getDimZ() - Proc.Box:getDimZ()) < BD.MIN_HEIGHT then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessDtTenon diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessFreeContour.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessFreeContour.lua new file mode 100644 index 0000000..cbefab4 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessFreeContour.lua @@ -0,0 +1,354 @@ +-- ProcessFreeContour.lua by Egaltech s.r.l. 2020/05/16 +-- Gestione calcolo profilo libero per Travi + +-- Tabella per definizione modulo +local ProcessFreeContour = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessFreeContour started', 1) + +-- Dati +local BD = require( 'BeamData') +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) +end +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessFreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- se pocket, ne verifico la direzione di lavorazione + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + if bPocket then + 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) + return ( vtN:getX() >= 0.5) + end + -- deve occupare una buona parte dell'area + if Proc.Box:getDimY() * Proc.Box:getDimZ() > 0.45 * b3Raw:getDimY() * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessFreeContour.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- se pocket, ne verifico la direzione di lavorazione + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + if bPocket then + 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) + return ( vtN:getX() <= - 0.5) + end + -- deve occupare una buona parte dell'area + if Proc.Box:getDimY() * Proc.Box:getDimZ() > 0.45 * b3Raw:getDimY() * b3Raw:getDimZ() then + return true + end + -- non è di coda + return false +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 true, bDown, false + -- se altrimenti profilo orizzontale + elseif abs( vtN:getZ()) < 0.5 then + return true, false, false + -- se altrimenti profilo verticale che non interessa tutta la sezione + elseif Proc.Box:getDimZ() < 0.9 * b3Raw:getDimZ() then + local bDown = ( vtN:getZ() < - 0.5) + return true, bDown, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'FreeContour') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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) + local bDown = ( b3Aux:getMin():getZ() < b3Raw:getMin():getZ() + 5) + -- 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 + -- ne verifico la lunghezza per eventuale spezzatura e lavorazione in doppio + local nStep = 1 + local dStep = 0 + local dLenMax = BD.LONGCUT_ENDLEN + if b3Aux:getDimX() > dLenMax then + local dCrvLen = EgtCurveLength( AuxId) + nStep = ceil( dCrvLen / dLenMax) + dStep = dCrvLen / nStep + EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) + end + -- eventuale spezzatura sul tratto più lungo se curva chiusa + BL.PutStartOnLonger( AuxId) + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local bCross = false + if abs( vtExtr:getY()) > 0.707 then + if b3Aux:getDimY() > b3Raw:getDimY() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimY()) + end + elseif abs( vtExtr:getZ()) > 0.707 then + if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimZ()) + end + end + local nDouble = 1 + local bCanDouble = abs( vtExtr:getY()) > 0.707 and bCross + local bStripOnSide = false + if bCross then + if nStep > 1 or ( bDown and b3Aux:getDimX() > 0.5 * b3Raw:getDimX()) then + -- devo lasciare un codolo + dDepth = dDepth - BD.DIM_STRIP + bStripOnSide = true + else + -- devo affondare un poco oltre + dDepth = dDepth + BD.CUT_EXTRA + end + end + if dDepth > dMaxDepth then + if bCanDouble then + nDouble = 2 + dDepth = min( 0.5 * dDepth, dMaxDepth) + else + dDepth = dMaxDepth + end + end + -- se utensile orizzontale verso Y+, non in doppio e codolo da lasciare, devo invertire per lavorare sempre da Y- + if vtExtr:getY() > 0.707 and nDouble == 1 and bStripOnSide then + bToolInv = true + end + -- eseguo + for i = 1, nStep do + for j = 1, nDouble do + -- 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}}) + -- eventuale accorciamento di testa + if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then + local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + end + -- eventuale accorciamento di coda + if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then + local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- se estrusione da sotto, inverto direzione fresa + if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- se seconda passata, inverto direzione di lavoro + if j == 2 then + EgtSetMachiningParam( MCH_MP.INVERT, 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 + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByPocket( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- 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, nPhase, nRawId, nPartId, dOvmHead) + -- recupero la tipologia + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- se svuotatura + if bPocket then + return MakeByPocket( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- altrimenti contornatura + else + return MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead) + end +end + +--------------------------------------------------------------------- +return ProcessFreeContour diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessFrenchRidgeLap.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessFrenchRidgeLap.lua new file mode 100644 index 0000000..8d301b2 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessFrenchRidgeLap.lua @@ -0,0 +1,278 @@ +-- ProcessFrenchRidgeLap.lua by Egaltech s.r.l. 2020/02/11 +-- Gestione calcolo giunzione francese + +-- Tabella per definizione modulo +local ProcessFrenchRidgeLap = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessFrenchRidgeLap started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessFrenchRidgeLap.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 35) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessFrenchRidgeLap.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessFrenchRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getX()) > GEO.EPS_SMALL and abs( vtN[i]:getY()) > GEO.EPS_SMALL and abs( vtN[i]:getZ()) > GEO.EPS_SMALL then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + bHead = ( vtN[vFaceOrd[1]]:getX() > 0) + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + local dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < (#vCuts-1) or (i == #vCuts) then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO = Vector3d( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + else + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO = Vector3d( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + -- altrimenti di fianco + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + -- altrimenti di fianco + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessFrenchRidgeLap diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessHeadCut.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessHeadCut.lua new file mode 100644 index 0000000..7a0a34a --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessHeadCut.lua @@ -0,0 +1,215 @@ +-- ProcessSplit.lua by Egaltech s.r.l. 2020/06/16 +-- Gestione calcolo tagli di testa per Travi + +-- Tabella per definizione modulo +local ProcessHeadCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessHeadCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessHeadCut.Identify( Proc) + return ( Proc.Grp == 1 and Proc.Prc == 340) +end + +--------------------------------------------------------------------- +-- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) +local function VerifyCurveForChamfer( AuxId) + if not AuxId then + return -2 + end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + return -1 + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- va bene solo se direzione estrusione orizzontale + if abs( vtExtr:getZ()) > 0.1 then + return 0 + end + return 1 +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( nOriId, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico le entità curva associate (max 2) + local sVal = EgtGetInfo( nOriId, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local AuxId, Aux2Id + if vsAuxId and #vsAuxId >=1 then + AuxId = tonumber( vsAuxId[1]) + end + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if AuxId then AuxId = AuxId + nOriId end + if Aux2Id then Aux2Id = Aux2Id + nOriId end + local nRes = VerifyCurveForChamfer( AuxId) + if nRes == 0 and Aux2Id then + AuxId = Aux2Id + nRes = VerifyCurveForChamfer( AuxId) + end + if nRes == -2 then + return true + end + if nRes == -1 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + if nRes == 0 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true, nil +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessHeadCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bNeedHCut) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- inserimento smussi + local nOriId = EgtGetInfo( Proc.Id, 'ORI', 'i') + if nOriId then + local bOkc, sErrC = MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 50 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- caratteristiche taglio + local bHorizCut = ( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL and b3Raw:getDimZ() < dMaxDepth - BD.CUT_EXTRA) + local dDimYRef = EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, dMaxDepth - BD.CUT_EXTRA, BD.MAX_DIM_HTCUT_HBEAM) + local bDoubleCut = ( not bHorizCut and b3Raw:getDimY() > dDimYRef + 10 * GEO.EPS_SMALL) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- se non obbligatorio e coincide con inizio grezzo, non va fatto + if not bNeedHCut and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX()) < 10 * GEO.EPS_SMALL then + return true + end + -- flag di lavorazione faccia + local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_FRONT) + -- determino se più tagli con offset + local nCuts = max( ceil( dOvmHead / ( BD.MAX_LEN_SCRAP_START or BD.MAX_LEN_SCRAP)), 1) + local dOffsL = dOvmHead / nCuts + -- calcolo extra taglio ed accorciamento + local dCutExtra = 0 + local dAccStart = 0 + if b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL or b3Raw:getDimY() < 2 * BD.MAX_DIM_HTCUT_HBEAM + 10 * GEO.EPS_SMALL then + dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN, BD.CUT_EXTRA) + dAccStart = 0 + else + dCutExtra = - ( b3Raw:getDimY() - dMaxDepth - BD.CUT_EXTRA) + local dSawRad = dSawDiam / 2 + local dKL = dSawRad - dMaxDepth + b3Raw:getDimY() / 2 + BD.CUT_EXTRA_MIN + dAccStart = sqrt( dSawRad * dSawRad - dKL * dKL) + end + -- se necessari tagli in doppio, eseguo gli opposti + if bDoubleCut then + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_BACK, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, '', b3Raw) + if not bOk then return false, sErr end + end + end + -- eseguo i tagli necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, '', b3Raw) + if not bOk then return false, sErr end + end + return true +end + +--------------------------------------------------------------------- +return ProcessHeadCut diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessLapJoint.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessLapJoint.lua new file mode 100644 index 0000000..13d6ffb --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessLapJoint.lua @@ -0,0 +1,3552 @@ +-- ProcessLapJoint.lua by Egaltech s.r.l. 2020/08/20 +-- Gestione calcolo mezzo-legno per Travi +-- 2019/10/08 Agg. gestione OpenPocket. + +-- Tabella per definizione modulo +local ProcessLapJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') +local DoubleCut = require( 'ProcessDoubleCut') +local LongCut = require( 'ProcessLongCut') +local Long2Cut = require( 'ProcessLongDoubleCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessLapJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sForceUseBlade = '' -- i +local sDepthChamferMill = '' -- d +local sPreemptiveChamfer = '' -- i +local sUseMill = '' -- i +local sUseRoughTool = '' -- i +local sUseRoughToolWithBAxis90 = '' -- i +local sUseRoughToolWithBAxis0 = '' -- i +local sInsertBoreOnCorner = '' -- 1 +local sMakeContourWithSmallTool = '' -- i +local sMakeOnlyContourOrFullPocket = '' -- i +local sMakeBySideRoughTool = '' -- i +local sAntisplintMode = '' -- i + +-- Settaggi interni +local bTrySidePocketAtFirst = true + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLapJoint.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 33) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or + ( Proc.Grp == 4 and Proc.Prc == 37) or + ( Proc.Grp == 4 and Proc.Prc == 39) or + ( Proc.Grp == 4 and Proc.Prc == 120)) +end + +--------------------------------------------------------------------- +local function AssignQValues( Proc) + + -- reset delle variabili assegnazione parametri Q + sForceUseBlade = '' + sDepthChamferMill = '' + sPreemptiveChamfer = '' + sUseMill = '' + sUseRoughTool = '' + sUseRoughToolWithBAxis90 = '' + sUseRoughToolWithBAxis0 = '' + sInsertBoreOnCorner = '' + sMakeContourWithSmallTool = '' + sMakeOnlyContourOrFullPocket = '' + sMakeBySideRoughTool = '' + sAntisplintMode = '' + + if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then + sForceUseBlade = 'Q01' -- i + sDepthChamferMill = 'Q04' -- d + sPreemptiveChamfer = 'Q05' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then + sDepthChamferMill = 'Q01' -- d + sPreemptiveChamfer = 'Q02' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then + sDepthChamferMill = 'Q01' -- d + sUseMill = 'Q02' -- i + sUseRoughTool = 'Q03' -- i + sUseRoughToolWithBAxis90 = 'Q04' -- i + sUseRoughToolWithBAxis0 = 'Q05' -- i + sInsertBoreOnCorner = 'Q06' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25 then + sInsertBoreOnCorner = 'Q01' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then + sMakeContourWithSmallTool = 'Q01' -- i + sMakeOnlyContourOrFullPocket = 'Q02' -- i + sMakeBySideRoughTool = 'Q03' -- i + sAntisplintMode = 'Q06' -- i + sDepthChamferMill = 'Q07' -- d + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then + sMakeBySideRoughTool = 'Q01' -- i + end + -- le altre features gestite non hanno parametri Q nei parametri globali +end + +--------------------------------------------------------------------- +local function TestElleShape3( Proc) + -- valida solo nel caso di tre facce + if Proc.Fct ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +local function TestElleShape4( Proc) + -- valida solo nel caso di quattro facce + if Proc.Fct ~= 4 then return false end + -- determino se L con due facce terminali o O + local bIsL = false + local dMinArea3 = GEO.INFINITO + local dMaxArea2 = 0 + for i = 1, 4 do + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, i - 1, GDB_ID.ROOT) + local dArea = dH * dV + if nCount == 2 then + dMaxArea2 = max( dMaxArea2, dArea) + elseif nCount == 3 then + dMinArea3 = min( dMinArea3, dArea) + bIsL = true + end + end + if not bIsL then return false end + -- verifico se L profona oppure lunga + if dMinArea3 < dMaxArea2 then + return 1 + else + return 2 + end +end + +--------------------------------------------------------------------- +local function VerifySawChain( Proc, dMinDim, dMaxDim, vtOrtho) + local bUseSawChain = false + local sMchFind = 'Sawing' + local sSawing = ML.FindSawing(sMchFind) + local dMaxMat = 0 + local dSawCornerRad = 0 + local dSawThick = 0 + local dMaxDepth = 200 + -- se non trova una lavorazione di sawing esco + if not sSawing then + return bUseSawChain + else + -- recupero i dati dell'utensile + local dToolLength = 0 + local dSawWidth = 75 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dSawCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) or dSawCornerRad + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + if dSawThick <= dMinDim and dSawWidth <= dMaxDim then + bUseSawChain = true + end + end + end + return bUseSawChain, sSawing, dMaxMat, dSawCornerRad, dSawThick, dMaxDepth +end + +--------------------------------------------------------------------- +local function VerifyIfPocket( Proc, dDiam, vtOrtho, sMchFindMaster) + local bUsePocketing = false + local sMchFind = 'Pocket' + if sMchFindMaster and #sMchFindMaster > 0 then + sMchFind = sMchFindMaster + end +-- local dCollSic = 2 * BD.COLL_SIC +-- if abs( vtOrtho:getX()) > 0.996 or abs( vtOrtho:getY()) > 0.996 or abs( vtOrtho:getZ()) > 0.996 then dCollSic = BD.COLL_SIC end + local sPocketing = ML.FindPocketing( sMchFind, dDiam) + local dMaxMat = 0 + -- se non trova una svuotatura adatta + if not sPocketing then + return bUsePocketing + else + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + bUsePocketing = true + end + end + return bUsePocketing, sPocketing, dMaxMat +end + +--------------------------------------------------------------------- +local function VerifyIfByBHSideMill( Proc) + local bUseBHSideMill = false + local bHead = true + local sMilling + local dMaxMat = 10 + -- se non feature BlockHausHalfLap e non abilitato parametro Q per lavorarlo di fianco esco + local nUseSideTool = EgtGetInfo( Proc.Id, sMakeBySideRoughTool, 'i') or 0 + if Proc.Prc ~= 37 and nUseSideTool == 0 then + return false + end + -- verifico se U + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) + -- se U e lunghezza non richiede spezzatura + if bIsU and Proc.Box:getDimX() <= BD.LONGCUT_MAXLEN then + -- recupero la lavorazione + sMilling = ML.FindMilling( 'BHSideMill') + if sMilling then + -- recupero i dati dell'utensile + local dToolLength = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + end + -- verifico se la feature è abbastanza vicino a testa/coda da permettere la lavorazione con questo utensile + -- recupero l'ingombro della trave + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if b3Solid then + local dMinXF = Proc.Box:getMin():getX() + local dMaxXF = Proc.Box:getMax():getX() + local dMinT = b3Solid:getMin():getX() + local dMaxT = b3Solid:getMax():getX() + -- determino se è più vicino alla testa o al bordo + bHead = ( dMaxT - dMinXF) < ( dMaxXF - dMinT) + -- determino se è compatibile con il massimo affondamento dell'utensile + bUseBHSideMill = EgtIf( bHead, (dMaxT - dMinXF), (dMaxXF - dMinT)) < dMaxDepth + end + end + end + return bUseBHSideMill, bHead, sMilling, dMaxMat +end + +--------------------------------------------------------------------- +local function GetTunnelDimension( Proc, nPartId) + -- ottengo i versori delle 4 facce e ottengo l'orientamento del tunnel + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( Proc.Id) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- variabili dimensioni fessura e id faccia lunga + local dDimMin + local dDimMax + local nLongIdFace = 0 + -- ottengo il versore ortogonale + local ptN1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + local vtOrtho = vtN1 ^ vtN2 + if vtOrtho:isSmall() then + _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT) + vtOrtho = vtN1 ^ vtN2 + end + -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta la profondità della fessura + local frFc = Frame3d( ptN1, vtOrtho) ; + local bBoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) + local dDepth = bBoxLoc:getDimZ() + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- mi assicuro che la Z del punto utilizzato per creare la superficie sia alla Z media del bounding box locale + local ptN2 = Point3d(ptN1) + ptN2:toLoc(frFc) + ptN2 = Point3d( ptN2:getX(), ptN2:getY(), ( bBoxLoc:getMin():getZ() + bBoxLoc:getMax():getZ())/2) + ptN2:toGlob(frFc) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN2, vtOrtho, b3Solid, GDB_ID.ROOT) + -- ritaglio la superficie con le facce della fessura + for i = 1, nFacCnt do + local ptN, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) + end + local _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT) + dDimMin = min( DimH, DimV) + dDimMax = max( DimH, DimV) + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacCnt-1, GDB_ID.ROOT) + -- se faccia pari alla larghezza fessura + if abs(DimH - dDimMax) < GEO.EPS_SMALL or abs(DimV - dDimMax) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + -- altrimenti faccia pari allo spessore fessura + else + nLongIdFace = nFacCnt-2 + end + if not dDimMax then + return dDimMin, dDimMax, dDepth, nil, nil + end + return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt +end + +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() > 0.1 then + return true + end + end + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 *b3Raw:getDimX()) then + return false + end + -- se una o due facce ora è sicuramente di testa + if Proc.Fct <= 2 then + return true + end + -- deve avere la normale principale diretta verso la testa + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN and vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN and vtN:getX() < 0.499 then + return false + elseif Proc.Fct >= 5 then + return true + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessLapJoint.IsTailFeature( Proc, b3Raw) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() < -0.1 then + return true + end + end + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- se può essere fatto con utensile tipo lama + local bUseBHSideMill, bHead = VerifyIfByBHSideMill( Proc) + if bUseBHSideMill then + return not bHead + end + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then + return false + end + -- recupero identificativo del pezzo + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + -- se due facce e interessa veramente la coda, allora di coda + if Proc.Fct <= 2 then + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then + return true + end + end + -- deve avere la normale principale diretta verso la coda + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN and vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN and vtN:getX() > -0.499 then + return false + else + return true + end +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLapJoint.Classify( Proc, b3Raw) + -- se 1 faccia + if Proc.Fct == 1 then + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + --local bDown = ( vtN:getZ() < BD.NZ_MINA) + --return true, bDown + return true, false + -- se 2 facce + elseif Proc.Fct == 2 then + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bSmall = ( ( Proc.Head or Proc.Tail) and Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) or + ( not ( Proc.Head or Proc.Tail) and Proc.Box:getDimY() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or + ( vtN[1]:getZ() < BD.NZ_MINA and ( vtN[2]:getZ() < -0.1 or not bSmall)) or + ( vtN[2]:getZ() < BD.NZ_MINA and ( vtN[1]:getZ() < -0.1 or not bSmall)) + return true, bDown + -- se più di 2 facce + else + local bClosedOrthoFaces + local nDeletedface + -- recupero la faccia con il maggior numero di adiacenze e minor elevazione + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + else + return false + end + end + -- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche + if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + return false + end + -- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura + for i = 1, Proc.Fct do + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + -- elimino una faccia + nDeletedface = i-1 + if EgtSurfTmRemoveFacet( nNewProc, nDeletedface) then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( nNewProc, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + EgtErase( nNewProc) + break + else + EgtErase( nNewProc) + return false + end + end + -- altrimenti esco + else + EgtErase( nNewProc) + break + end + end + -- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo + if bClosedOrthoFaces then + nFacInd = nDeletedface + -- rendo nulla la faccia opzionale perchè si tratta di una fessura + nFacInd2 = nil + dElev = BL.GetFaceElevation( Proc.Id, nFacInd) + bClosedOrthoFaces = false -- non lo setto come tunnel + end + end + -- se facce formano un tunnel e sono ortogonali + if bClosedOrthoFaces then + -- ottengo le dimensioni del tunnel + local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId) + EgtErase(nSurfInt) + -- verifico se può essere fatto con svuotatura + if VerifyIfPocket( Proc, dDimMin, vtOrtho) then + return true, false + elseif VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho) then + return true, false + else + return false + end + else + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se può essere fatto con utensile tipo lama + local bUseBHSideMill, _, _, dMaxMat = VerifyIfByBHSideMill( Proc) + if bUseBHSideMill and ( dMaxMat <= dV) then + return true, false + -- altrimenti controllo se deve essere ruotato con le altre lavorazioni + else + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bDown = ( vtN:getZ() < BD.NZ_MINA) + -- se verso il basso, verifico se utilizzabile seconda faccia + if bDown then + if nFacInd2 and dElev2 < 2 * dElev then + local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINB) + end + end + return true, bDown + end + end + end +end + +--------------------------------------------------------------------- +-- Lavorazione con fresa +--------------------------------------------------------------------- +local function MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se orientata verso l'alto + local bUp = ( vtN:getZ() >= BD.NZ_MINA) + -- scelta faccia da lavorare + local nFacInd = 0 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'BirdsMouth') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + if vtN:getX() > 0 then + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_LEFT, MCH_MILL_FU.PARAL_LEFT)) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.PARAL_RIGHT)) + end + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + if not bUp then EgtSetMachiningParam( MCH_MP.INVERT, true) end + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- predispongo lavorazione + local sMilling + -- verifico il parametro Q per uso fresa + local nUseRM = EgtGetInfo( Proc.Id, sUseMill, 'i') + if nUseRM and nUseRM == 1 then + sMilling = ML.FindMilling( 'LongSmallCut') + else + sMilling = ML.FindMilling( 'BirdsMouth') + end + -- recupero la lavorazione + local dTDiam = 0 + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + else + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + end + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- dati medi + local ptM = ( ptC[1] + ptC[2]) / 2 + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error : LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- scelta faccia da lavorare + local nFacInd + -- se entrambe possibili + if bFaceOk[1] and bFaceOk[2] then + -- se in testa, scelgo quella orientata verso la testa + if Proc.Head then + if vtN[1]:getX() > vtN[2]:getX() then + nFacInd = 0 + else + nFacInd = 1 + end + -- se altrimenti in coda, scelgo quella orientata verso la coda + elseif Proc.Tail then + if vtN[1]:getX() < vtN[2]:getX() then + nFacInd = 0 + else + nFacInd = 1 + end + -- altrimenti, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+) + else + if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then + if ptM:getX() > b3Raw:getCenter():getX() then + nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1) + else + nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1) + end + else + nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1) + end + end + elseif bFaceOk[1] then + nFacInd = 0 + else + nFacInd = 1 + end + local nOthInd = 1 - nFacInd + local sName + local nMchFId + local nFaceUse + -- se forzato uso fresa controllo se posso fare in una o più passate + if nUseRM and nUseRM == 1 then + -- prendo la larghezza della faccia + local _, pPt1, pPt2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOthInd, GDB_ID.ROOT) + local dDistPoint = dist( pPt1, pPt2) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local dWidth = EgtIf( abs( dDistPoint - dH) < abs( dDistPoint - dV), dV, dH) + -- se larghezza faccia maggiore diametro utensile aggiungo una lavorazione + if dTDiam > 0 and dWidth > dTDiam then + -- inserisco la lavorazione di fresatura + sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_1' + nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- tolgo l'inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- aggiungo offset laterale + EgtSetMachiningParam( MCH_MP.OFFSR , (dTDiam/2)) + -- imposto posizione braccio porta testa + if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + -- inserisco la lavorazione di fresatura + sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- tolgo l'inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- imposto posizione braccio porta testa + if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + elseif Proc.Box:getCenter():getX() > b3Solid:getCenter():getX() then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + local dDist = b3Solid:getMax():getX() - Proc.Box:getMax():getX() + BL.UpdateHCING( nRawId, dOffs, dDist) + end + end + return true +end + +--------------------------------------------------------------------- +local function MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw, nChamfer) + -- se interessa l'intera sezione della trave, necessaria sgrossatura + if nChamfer < 2 and Proc.Box:getDimY() > 0.9 * b3Raw:getDimY() and Proc.Box:getDimZ() > 0.9 * b3Raw:getDimZ() then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo sgrossatura e la lavoro + local AddId = EgtSurfTmConvexHullInBBox( nAddGrpId, Proc.Id, b3Raw, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local nCutFacet = EgtSurfTmFacetCount( AddId) + if nCutFacet == 1 then + return Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + elseif nCutFacet == 2 then + return DoubleCut.Make( CutProc, nPhase, nRawId, nPartId, 0) + end + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev, bSpecialApp, sMillMaster, nFacInd2, dFacElev2) + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Riordino le dimensioni per avere dH > dV + if dH < dV then + dH, dV = dV, dH + end + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > 0.5 * dH then + nFacAdj = vAdj[i] + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) + break + end + end + end + if not nFacAdj then + local sErr = 'Error : main face without long adjacent face' + EgtOutLog( sErr) + return false, sErr + end + -- Determino se estremi aperti o chiusi e faccia adiacente da aggiungere alla lavorazione + local bOpenStart = false + local bOpenEnd = false + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) + local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacAdj, GDB_ID.ROOT) + -- Riordino le dimensioni per avere dH > dV + if dH2 < dV2 then + dH2, dV2 = dV2, dH2 + end + local nFacAdj2 + for j = 1, #vAdj2 do + if vAdj2[j] == nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + -- decommentare questa parte per concatenare due facce + --if bSpecialApp and vAdj2[j] >= 0 then + -- local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacAdj, vAdj2[j], GDB_ID.ROOT) + -- local dLen = dist( ptP1, ptP2) + -- if abs( dLen - dV2) < 10 * GEO.EPS_SMALL then + -- nFacAdj2 = vAdj2[j] + -- end + --end + end + -- Recupero la lavorazione di fresa + local sMilling + if bSpecialApp then + sMilling = sMillMaster + else + sMilling = ML.FindMilling( 'LongSmallCut') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dTDiam = 50 + local dMaxMat = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + end + -- Se massimo materiale utensile è molto inferiore dell'elevazione non faccio la lavorazione e do un warning + if dMaxMat > 0 and dMaxMat + 15 < dElev then + sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' ,skipped milling; elevation bigger than max tool depth' + return true, sWarn, dMaxMat + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + if nFacAdj2 then + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj},{ Proc.Id, nFacAdj2}}) + else + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + end + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + if bSpecialApp then + -- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita + if nFacAdj2 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2)) + -- confronto la faccia applicata nella lavorazione(faccia adiacente) con la seconda faccia passata nella funzione + -- se corrispondono allora aggiungo una estensione nei lati chiusi pari all'elevazione della stessa faccia corrispondente + if nFacAdj == nFacInd2 then + if not bOpenStart then + EgtSetMachiningParam( MCH_MP.LOPERP, dFacElev2) + end + if not bOpenEnd then + EgtSetMachiningParam( MCH_MP.LIPERP, dFacElev2) + end + end + end + -- applico elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, 0, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, 0, - dTDiam / 2)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, '', dTDiam +end + +--------------------------------------------------------------------- +local function ChooseCorner( Proc, nFacInd) + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + local tFacAdj = {} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + for j = i+1, #vAdj do + if vAdj[j] >= 0 then + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vAdj[i], vAdj[j], GDB_ID.ROOT) + if ptP1 and ptP2 and dAng < 0 then + local dLen = dist( ptP1, ptP2) + table.insert( tFacAdj, { vAdj[i], vAdj[j], dLen, ptP1, ptP2, dAng}) + end + end + end + end + end + -- tra le linee prendo quella più lunga + local dMaxLen = 0 + local nIdLine + for i = 1, #tFacAdj do + if tFacAdj[i][3] > dMaxLen then + nIdLine = i + dMaxLen = tFacAdj[i][3] + end + end + + return dMaxLen, nIdLine, tFacAdj +end + +--------------------------------------------------------------------- +local function MakeContourCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam) + + local sMyWarn = '' + local pAuxId = {} + local nAuxId + local AuxId + local ptApPoint + local sMilling + local dTrimDist + local dCollSic = BD.COLL_SIC + + -- ottengo gli angoli dove applicare il percorso con fresa più piccola + local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) + -- se non trovato nessun angolo interno valido esco + if #tFacAdj == 0 then + return true, sMyWarn + end + -- prendo il primo versore + local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra + if abs( vtN1:getX()) > 0.7 or abs( vtN1:getY()) > 0.7 or abs( vtN1:getZ()) > 0.7 then dCollSic = 0 end + + -- se fresatura da sotto salto la lavorazione + if vtN1:getZ() < BD.DRILL_VZ_MIN then + local sErr = 'Error : milling from bottom ' + EgtOutLog( sErr) + return false, sErr + end + + -- ciclo su tutti gli angoli trovati + for i = 1, #tFacAdj do + sMyWarn = '' + -- le 2 facce di contatto devono essere perpendicolari o non sottossquadra rispetto alla faccia di fondo + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][1], GDB_ID.ROOT) + local _, ptP1x, ptP2x, dAngx = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][2], GDB_ID.ROOT) + if ( dAng < 0 and 180 + dAng >= 90 - 10 * GEO.EPS_SMALL) and ( dAngx < 0 and 180 + dAngx >= 90 - 10 * GEO.EPS_SMALL) then + -- prendo la lunghezza di adiacenza delle due linee + local dLen1 = dist( ptP1, ptP2) + local dLen2 = dist( ptP1x, ptP2x) + -- cerco il punto tra le 3 facce: nIdEndPoint + local nIdIniPoint + local nIdEndPoint + if ptP1 and ptP2 then + if ( dist( ptP1, tFacAdj[i][4]) < GEO.EPS_SMALL) or ( dist( ptP2, tFacAdj[i][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptP1, tFacAdj[i][5]) < GEO.EPS_SMALL) or ( dist( ptP2, tFacAdj[i][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- se ho il punto comune + if nIdEndPoint then + -- recupero la lavorazione con elevazione pari all'altezza trovata + sMilling = ML.FindMilling( 'LongSmallCut', tFacAdj[i][3] + dCollSic) + if sMilling then + -- recupero i dati dell'utensile + local dTDiam = 50 + local dMaxMat = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + -- se il diametro trovato è minore della metà del diametro utilizzato in precendenza + if dTDiam < ( dDiam / 2) then + -- calcolo lunghezza minima in base all'angolo tra le due pareti + local dMinDist = (( dDiam / 2) / tan( ( 180 + tFacAdj[i][6]) / 2)) + 2 + -- se entrambe le linee sono maggiori delle lunghezza minima proseguo + if dLen1 >= dMinDist and dLen2 >= dMinDist then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[i][nIdEndPoint], ptP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptP2 + else + ptApPoint = ptP1 + end + -- prima linea + nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[i][nIdEndPoint], GDB_RT.GLOB) + -- calcolo arretramento + dTrimDist = dLen1 - dMinDist + -- se arretramento valido + if dTrimDist > 100 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , - dTrimDist, ptApPoint , GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- se il punto finale corrisponde con il punto comune, uso l'altro + if dist( tFacAdj[i][nIdEndPoint], ptP1x) < 10 * GEO.EPS_SMALL then + ptApPoint = ptP2x + else + ptApPoint = ptP1x + end + -- seconda linea + nAuxId = EgtLine( nAddGrpId, tFacAdj[i][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + -- calcolo arretramento + dTrimDist = dLen2 - dMinDist + -- se arretramento valido + if dTrimDist > 100 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , - dTrimDist, ptApPoint , GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- trasformo in percorso + if #pAuxId > 0 then + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + end + -- se c'è il percorso + if AuxId then + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtN1, GDB_RT.GLOB) + -- inserisco la lavorazione + local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if nMchId then + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN1:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4) + -- allungo inizio e fine di 0mm + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + -- setto affondamento 0 + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- setto non inversione del percorso + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( tFacAdj[i][3], 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + if EgtApplyMachining( true, false) then + _, sMyWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + -- altrimenti lavorazione non applicata + else + _, sMyWarn = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + end + -- altrimenti non è ctata inserita lavorazione + else + sMyWarn = 'warning adding machining ' .. sName .. '-' .. sMilling + end + -- altrimenti non c'è il percorso + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' + end + -- altrimenti + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' + end + -- altrimenti diametro trovato è simile a quello già utilizzato +-- else +-- sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' smaller tool not found' + end + -- altrimenti non è stata trovata lavorazione + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library' + end + -- altrimenti non è stato trovato il punto comune +-- else +-- sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' + end + -- altrimenti pareti sottosquadra o angolo aperto +-- else +-- sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' + end + if #sMyWarn > 0 then + EgtOutLog( sMyWarn) + end + end + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function MakeCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam) + + local sMyWarn = '' + local pAuxId = {} + local nAuxId + local AuxId + local ptApPoint + local dLenTrimExt + local sMilling + local dMaxDepth = 0 + + -- ottengo l'angolo di riferimento dove applicare il percorso di pulitura + local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) + -- se non trovato nessun angolo valido esco + if #tFacAdj == 0 then + return true, sMyWarn + end + -- prendo il primo versore + local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local _, vtN3 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local nIdIniPoint + local nIdEndPoint + if ptLocP1 and ptLocP2 then + if ( dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- versore direzione + local vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] + vtExtr:normalize() + -- inserisco le prime tre linee + if nIdIniPoint and nIdEndPoint then + -- se fresatura da sotto salto la lavorazione + if vtExtr:getZ() < BD.DRILL_VZ_MIN then + local sErr = 'Error : clean corner milling from bottom impossible' + EgtOutLog( sErr) + return false, sErrLX + end + -- sommo i tre versori per avre una direzione media + vtExtr = vtN1 + vtN2 + vtN3 + vtExtr:normalize() + -- recupero la lavorazione non calcolando l'elevazione + sMilling = ML.FindMilling( 'CleanCorner', (dDiam*0.5)) + if not sMilling then + local sErr = 'Error : clean corner milling/tool not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile ( temporaneo, per compensare errore nella lavorazione) + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth + end + -- l'altezza di taglio del tagliente corrisponde al raggio del raccordo che si riesce a coprire + -- quindi confronto l'elevazione con il raggio utensile utilizzato per la svuotatura + if dMaxDepth < (dDiam * 0.5) - 100 * GEO.EPS_SMALL then + sMyWarn = 'Warning : skip clean corner (the cut heigth is smaller to machine the corner radius)' + EgtOutLog( sMyWarn) + return false, sMyWarn + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdIniPoint], tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB) + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- inserisco le ultime tre linee + -- trovo il secondo punto sulla superfice di riferimento + _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][2], GDB_ID.ROOT) + if ptLocP1 and ptLocP2 then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB) + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- ultima linea di risalita + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], tFacAdj[nIdLine][nIdIniPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- trasformo in percorso + if #pAuxId > 0 then + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + end + -- se non c'é il percorso do errore + if not AuxId then + local sErr = 'Error : impossible make clean corner path' + EgtOutLog( sErr) + return false, sErr + end + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- inserisco la lavorazione + local sName = 'Clean_' .. ( 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}}) + -- 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) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4) + -- allungo inizio e fine di 10mm + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- setto affondamento 0 + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + 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 + +--------------------------------------------------------------------- +local function MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam, bSpecialMach) + local sMyWarn = '' + -- ottengo l'angolo dove applicare il foro + local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) + -- se non trovato nessun angolo interno valido esco + if #tFacAdj == 0 then + return true, sMyWarn + end + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local nIdIniPoint + local nIdEndPoint + if ptLocP1 and ptLocP2 then + if ( dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- inserisco foro + if nIdIniPoint and nIdEndPoint then + local vtExtr + if bSpecialMach then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) + vtExtr = vtN0 + vtN1 + vtN2 + else + -- versore direzione + vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] + end + vtExtr:normalize() + -- se foratura da sotto salto la lavorazione + if vtExtr:getZ() < BD.DRILL_VZ_MIN then + local sErr = 'Error : drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sDrilling, nType = ML.FindDrilling( dDiam) + if not sDrilling then + local sErr = 'Error : drilling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 20 + local dDiamTool = 20 + local dDiamTh = 35 + local bIsDrilling + if EgtMdbSetCurrMachining( sDrilling) then + 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 + dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + dDiamTh = EgtTdbGetCurrToolThDiam() + end + end + -- se foro inclinato, limito il massimo affondamento + local CosB = abs( vtExtr:getX()) + if CosB < BD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dMaxDepth = dMaxDepth - dDiamTh / 2 * TgA + else + dMaxDepth = 0 + end + -- setto griglia + if bSpecialMach then + EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdEndPoint], vtExtr)) + else + EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdIniPoint], vtExtr)) + end + -- creo geometria + local AuxId = EgtCircle( nAddGrpId, {0,0,0}, EgtIf( bIsDrilling, dDiamTool/2, ( dDiamTool/2) + 0.1), GDB_RT.GRID) + -- riporto la griglia a globale + EgtSetGridFrame() + -- calcolo spessore + local dDepthBore = dMaxLen + if bSpecialMach then + -- calcolo l'elevazione + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, tFacAdj[nIdLine][nIdEndPoint], vtExtr) + if dLenIn > 0 then + dDepthBore = dLenIn + elseif dLedOut then + dDepthBore = dLedOut + end + EgtModifyCurveThickness( AuxId, dDepthBore) + else + EgtModifyCurveThickness( AuxId, -dMaxLen) + 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}}) + -- 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 dDepth + if bSpecialMach then + dDepth = dDepthBore + else + dDepth = dMaxLen + 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) + end + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione (coincide con affondamento) + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + 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 + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev, bForceUseBlade, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces, nBottomFace) + local sWarn + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Cerco una faccia adiacente alla principale sul lato più lungo + local nFacAdj + local dMaxLen = 0 + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > dMaxLen then + nFacAdj = vAdj[i] + dMaxLen = dLen + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) + end + end + end + if not nFacAdj then + local sErr = 'Error : long adjacent face not found' + EgtOutLog( sErr) + return false, sErr + end + -- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT) + if abs( vtN * rfFac:getVersX()) > abs( vtN * rfFac:getVersY()) then + dH, dV = dV, dH + end + -- Determino se estremi aperti o chiusi + local bOpenStart = false + local bOpenEnd = false + -- se non ho la faccia di fondo ( che comporta essere una fessura) verifico se ho lati aperti + if not nBottomFace then + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) + for j = 1, #vAdj2 do + if vAdj2[j] == nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + end + end + -- Recupero il massimo affondamento possibile con la lama + local dSawMaxDepth = 0 + local sCutting = ML.FindCutting( 'HeadSide') + if sCutting then + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawMaxDepth = EgtTdbGetCurrToolMaxDepth() or dSawMaxDepth + end + end + end + -- Se entrambi gli estremi sono aperti e possibile, lavoro con la lama + if bOpenStart and bOpenEnd and bForceUseBlade and dElev < dSawMaxDepth + 10 * GEO.EPS_SMALL then + -- Recupero la lavorazione di lama + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr, 'MNF' + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 4 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + if dSawThick > dV + 10 * GEO.EPS_SMALL then + local sErr = 'Error : sawblade too thick' + EgtOutLog( sErr) + return false, sErr + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ()) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- Eseguo i tagli + local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + local dOffs = ( i - 1) * dStep + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- altrimenti con sega a catena + else + -- Recupero la lavorazione + local sSawing = ML.FindSawing( 'Sawing') + if not sSawing then + local sErr = 'Error : chainsawing not found in library' + EgtOutLog( sErr) + return false, sErr, 'MNF' + end + -- Recupero i dati dell'utensile + local dSawWidth = 75 + local dSawThick = 8 + local dMaxDepth = 200 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + if dSawThick > dV + 10 * GEO.EPS_SMALL then + local sErr = 'Error : chainsaw too thick' + EgtOutLog( sErr) + return false, sErr + end + local bGoFromHead = true + -- se la lunghezza utensile non riesce ad arrivare sul fondo assegno la possibilità di lavorare di testa o di fianco + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + -- lavora di testa se è un tunnel, lavora di fianco se non è un tunnel + bGoFromHead = not bOrthoFaces + end + -- se continuo a lavorare di testa + if bGoFromHead then + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) + -- Calcolo angolo 3° asse rot (da direz. utensile) + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) + local ptP1, ptP2 = EgtSurfTmFacetOppositeSide( Proc.Id, nFacAdj, rfFac:getVersZ(), GDB_ID.ROOT) + local vtT = vtN ^ (ptP2 - ptP1) + vtT:normalize() + local d3RotAng = EgtIf( abs( vtT:getZ()) < 0.1, 0, 90) + -- Verifico se necessarie più passate + local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- Applico la lavorazione con sega a catena a questa faccia + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=' .. EgtNumToString( d3RotAng)) + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se necessario, limito l'affondamento + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth - dElev + EgtOutLog( sWarn) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH '..EgtNumToString( dDepth, 1)) + end + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 2) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + elseif EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + -- altrimenti segacatena di fianco + else + -- verifico se posso farlo con la sega-catena + local bMakeChainSaw, sSawing2, dMaxMat2, dSawCornerRad2, dSawThick2 = VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho) + if bMakeChainSaw then + -- Verifico se necessarie più passate + local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick2) + local dStep = 0 + if nStep > 1 then + dStep = ( dDimMin - dSawThick2) / ( nStep - 1) + end + for i = 1, nStep do + -- inserisco la lavorazione di sawing + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing2) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing2 + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLundIdFace}}) + -- imposto uso del lato faccia + -- al momento, dato che la fessura è passante da parte a parte, gestisco solo la lavorazione + -- dall'alto e di fronte (da dietro è disabilitata perchè ho exracorsa con la FAST). + -- Questa feature non è applicata su facce di testa e quindi non controllo l'entrata in X + if abs(vtOrtho:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + --elseif abs(vtOrtho:getZ()) < 0.707 and abs(vtOrtho:getY()) > 0.707 then + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + --elseif abs(vtOrtho:getZ()) <= 0.707 and vtOrtho:getY() < -0.707 then + -- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + --elseif abs(vtOrtho:getZ()) < 0.707 and vtOrtho:getX() > 0.707 then + -- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + --else + -- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se possibile aumento l'affondamento pari al raggio corner + 1 + if dMaxMat2 > (dDepth + dSawCornerRad2 + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad2 + 1)) + -- se massimo affondamento supera altezza fessura, uso massimo affondamento + elseif dMaxMat2 > (dDepth + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, (dMaxMat2 - 1)) + -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning + elseif dMaxMat2 < dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat2) + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + elseif EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + end + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw) + -- Recupero la lavorazione di lama + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- eseguo il taglio + local bMadeASbyBld, sWarn, nIdMach = BL.MakeOneFaceBySaw( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + return bMadeASbyBld, sWarn, nIdMach, dSawThick +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc, bMakeVertCham, sDephtCham, sOnlyCham, sUseBlade) + local nChamfer = 0 + local bForceUseBlade = false + local sErr + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- verifico se devo usare lama invece della sega-catena + -- 2020-03-20 forzata abilitazione uso lama se parametro Q non è presente + if #sUseBlade == 0 or EgtGetInfo( Proc.Id, sUseBlade, 'i') == 1 then + bForceUseBlade = true + end + + return nChamfer, dDepth, sErr, bForceUseBlade +end + +--------------------------------------------------------------------- +local function MakePocket( Proc, nPartId, ptPs, tvtN, nFaceRef, sMchFind, nUseRoughTool, sMasterPocket, dPrevFaceElev, tDimAndRef, dAng) + + -- calcolo l'elevazione dal punto medio + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, tvtN[2]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + local dCollSic = 2 * BD.COLL_SIC + -- calcolo il diametro utensile + local dDiamTool + local dFaceDiamTool + if tDimAndRef then + -- prendo il valore dalle dimensioni minime delle facce + dFaceDiamTool = min( tDimAndRef[2][1], tDimAndRef[2][2]) + end + -- se ho lavorazione precedente ricalcolo grossolanamente l'elevazione + if dPrevFaceElev and dPrevFaceElev > 0 and dAng then + dElev = dElev + ( sqrt( ( dElev * dElev) - ( dPrevFaceElev * dPrevFaceElev)) * sin(dAng)) + elseif dPrevFaceElev and dPrevFaceElev > dElev then + dElev = dPrevFaceElev + end + local sPocketing + if sMasterPocket then + sPocketing = sMasterPocket + else + sPocketing = ML.FindPocketing( sMchFind, dFaceDiamTool, dElev + dCollSic) + end + if not sPocketing then + local sErr = 'Error : pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + dDiamTool = 20 + local dMaxDepth = 0 + local sTuuidPk + if EgtMdbSetCurrMachining( sPocketing) then + sTuuidPk = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidPk) or '') then + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- se nome svuotatura non è stato ricalcolato, confronto il diametro utensile utilizzato con il minimo faccia e se non sono compatibili esco + if sMasterPocket and dFaceDiamTool and dDiamTool >= dFaceDiamTool then + return false, '', sTuuidPk, dDiamTool, dElev + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef) + 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( {{ Proc.Id, (nFaceRef)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if tvtN[2]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- se tasca aperta e non lavorata col truciolatore, imposto opportuno attacco + if sMchFind == 'OpenPocket' and nUseRoughTool == 0 then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dElev) + dElev = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn, sTuuidPk, dDiamTool +end + +--------------------------------------------------------------------- +local function MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtN, nBaseFace, nSideFace, ptPs, tDimAndRef, + b3Raw, nDiffWidth, nUseRoughTool, dAng, sPocketing, sTuuidPk, dPrevFaceElev) + + local sMchFind = 'Pocket' + local dAngLimit = 40 + + -- se feature é larga come trave imposto openpocket + if nDiffWidth == 0 then + sMchFind = 'OpenPocket' + -- altrimenti non è passante disabilito il truciolatore + else + nUseRoughTool = 0 + end + -- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto + if ( 180 + dAng) > 90.1 then + -- calcolo l'angolo dalla verticale dall'angolo tra le due facce, perchè la feature potrebbe essere ruotata sulla Z locale della + -- faccia principale e quindi la componente X del versore della faccia potrebbe dare un valore non coerente + local dDiffFromSqAng = dAng + 90 + -- se l'angolo dalla verticale si discosta di più dell'angolo limite impostato, utilizzo la svuotatura + if cos( dDiffFromSqAng) < cos( dAngLimit) then + -- applico la svuotatura + local bOk, sWarn, sTuuidPk, dDiamTool, dElev = MakePocket( Proc, nPartId, ptPs, tvtN, nSideFace, sMchFind, nUseRoughTool, sPocketing, dPrevFaceElev, tDimAndRef, dAng) + if not bOk then + -- se ho id utensile e diametro è perchè non ha fatto svuotatura perchè la faccia è più stretta del diametro utensile + -- e provo ad inserire singola passata di testa + if sTuuidPk and dDiamTool then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2Cut', dElev, sTuuidPk) + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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( {{ Proc.Id, nSideFace}}) + -- imposto uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite(tvtN[1]) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + -- imposto posizione braccio porta testa + if tvtN[2]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + else + return false, sWarn + end + else + return bOk, sWarn + end + -- altrimenti contornatura di fianco + else + local bOpenStart = false + local bOpenEnd = false + if nDiffWidth == 0 then + bOpenStart = true + bOpenEnd = true + else + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBaseFace))[1] + for j = 1, #vAdj2 do + if vAdj2[j] == (nSideFace) then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == (nSideFace) do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == (nSideFace) do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + end + end + local sMilling + if nUseRoughTool > 0 then + sMilling = ML.FindMilling( 'Long2Cut', nil, sTuuidPk) + else + sMilling = ML.FindMilling( 'LongSmallCut', nil, sTuuidPk) + end + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 50 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + end + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( tDimAndRef[1][3]:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, (nSideFace)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- setto inversione del percorso + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- setto a 0 eventuali offset + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- calcolo elevazione per allungamenti attacchi con fianchi chiusi + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, tvtN[2]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + -- applico gli allungamenti o accorciamenti + if bOpenStart then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dTDiam / 2) + if dElev > 0 then + EgtSetMachiningParam( MCH_MP.LIPERP, dElev) + end + end + if bOpenEnd then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dTDiam / 2) + if dElev > 0 then + EgtSetMachiningParam( MCH_MP.LOPERP, dElev) + end + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + return true +end + +--------------------------------------------------------------------- +local function SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId, bStartPoint) + + -- fondo tra loro le curve compatibili + EgtMergeCurvesInCurveCompo( nPathInt) + local nStartIdEnt, nNumEnt = EgtCurveDomain( nPathInt) + local pLastPIni, pLastPEnd + + -- faccio una copia della curva e la esplodo + if nStartIdEnt then + -- prendo i punti + for i = 1, nNumEnt do + local pPini = EgtUP( nPathInt, (i-1), GDB_RT.GLOB) + local pPend = EgtUP( nPathInt, EgtIf( i == nNumEnt, 0, i), GDB_RT.GLOB) + -- Se normale lungo la Z considero il box in X e Y + if abs(vtOrtho:getZ()) > 0.999 then + -- se corrisponde a X + if ( abs( pPini:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Y + elseif ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + -- altrimenti se normale lungo la Y considero il box in X e Z + elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.999 then + -- se corrisponde a X + if ( abs( pPini:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Z + elseif ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + -- caso che non dovrebbe mai capitare ma gestito per completezza + -- altrimenti se normale lungo la X considero il box in Y e Z + elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.999 then + -- se corrisponde a Y + if ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Z + elseif ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + end + end + -- se devo cambiare il punto di partenza + if bStartPoint and pLastPIni and pLastPEnd then + -- calcolo il punto medio con gli ultimi punti utilizzati + local ptPs = ( pLastPIni + pLastPEnd) / 2 + EgtChangeClosedCurveStartPoint( nPathInt, ptPs, GDB_RT.GLOB) + end + end +end + +--------------------------------------------------------------------- +local function ExtractExternalPaths( nPathInt, nNumIdAux, vtOrtho, b3Solid, nAddGrpId) + local nAuxId1, nAuxId2 + if nNumIdAux == 1 then + -- fondo tra loro le curve compatibili + EgtMergeCurvesInCurveCompo( nPathInt) + -- esplodo il percorso in modo da avere entià separate per poterle controllare + local nStartId, nNumIds = EgtExplodeCurveCompo( nPathInt) + if nStartId then + local sDeleteByDir + -- Se normale lungo la Z elimino le entità che hanno differenza in Z + if abs(vtOrtho:getZ()) > 0.7 then + sDeleteByDir = 'Z' + -- altrimenti se normale lungo la Y elimino le entità che hanno variazione in Y +-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.7 then + elseif abs(vtOrtho:getY()) > 0.7 then + sDeleteByDir = 'Y' + -- caso che non dovrebbe mai capitare ma gestito per completezza + -- altrimenti se normale lungo la X elimino le entità che hanno variazione in X +-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.7 then + elseif abs(vtOrtho:getX()) > 0.7 then + sDeleteByDir = 'X' + end + if sDeleteByDir then + for i = 1, nNumIds do + local ptP1 = EgtSP( ( nStartId + i - 1), GDB_RT.GLOB) + local ptP2 = EgtEP( ( nStartId + i - 1), GDB_RT.GLOB) + if sDeleteByDir == 'Z' then + -- se hanno variazione in Z cancello l'entità + if abs( ptP1:getZ() - ptP2:getZ()) > 10 * GEO.EPS_SMALL then + EgtErase( nStartId + i - 1) + end + elseif sDeleteByDir == 'Y' then + -- se hanno variazione in Y cancello l'entità + if abs( ptP1:getY() - ptP2:getY()) > 10 * GEO.EPS_SMALL then + EgtErase( nStartId + i - 1) + end + elseif sDeleteByDir == 'X' then + -- se hanno variazione in X cancello l'entità + if abs( ptP1:getX() - ptP2:getX()) > 10 * GEO.EPS_SMALL then + EgtErase( nStartId + i - 1) + end + end + end + -- ricreo i vari percorsi + local dLocalVal + local tPaths = {} + local nNumPaths + local dMaxVal + local dMinVal + for i = 1, nNumIds do + local ptP1 = EgtSP( ( nStartId + i - 1), GDB_RT.GLOB) + if ptP1 then + if sDeleteByDir == 'Z' then + local bInsTab + for j = 1, #tPaths do + local dLocalVal = tPaths[j][2] + if abs( ptP1:getZ() - dLocalVal) < 10 * GEO.EPS_SMALL then + local tLocIds = tPaths[j][1] + table.insert( tLocIds, ( nStartId + i - 1)) + tPaths[j][1] = tLocIds + bInsTab = true + end + end + -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella + if not bInsTab then + table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getZ()}) + dMaxVal = b3Solid:getMax():getZ() + dMinVal = b3Solid:getMin():getZ() + end + elseif sDeleteByDir == 'Y' then + local bInsTab + for j = 1, #tPaths do + local dLocalVal = tPaths[j][2] + if abs( ptP1:getY() - dLocalVal) < 10 * GEO.EPS_SMALL then + local tLocIds = tPaths[j][1] + table.insert( tLocIds, ( nStartId + i - 1)) + tPaths[j][1] = tLocIds + bInsTab = true + end + end + -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella + if not bInsTab then + table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getY()}) + dMaxVal = b3Solid:getMax():getY() + dMinVal = b3Solid:getMin():getY() + end + elseif sDeleteByDir == 'X' then + local bInsTab + for j = 1, #tPaths do + local dLocalVal = tPaths[j][2] + if abs( ptP1:getX() - dLocalVal) < 10 * GEO.EPS_SMALL then + local tLocIds = tPaths[j][1] + table.insert( tLocIds, ( nStartId + i - 1)) + tPaths[j][1] = tLocIds + bInsTab = true + end + end + -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella + if not bInsTab then + table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getX()}) + dMaxVal = b3Solid:getMax():getX() + dMinVal = b3Solid:getMin():getX() + end + end + end + end + + if tPaths then + local tChamPath = {} + -- elimino quelle che non corrispondono agli estremi + for i = 1, #tPaths do + -- se non corrisponde ai limiti elimino l'elemento + if abs( tPaths[i][2] - dMaxVal) > 10 * GEO.EPS_SMALL and abs( tPaths[i][2] - dMinVal) > 10 * GEO.EPS_SMALL then + tPaths[i] = nil + end + end + + for i = 1, #tPaths do + if tPaths[i] then + local tNoMatch = {} + local tPathLoc = tPaths[i][1] + local pIniLoc = EgtSP( tPathLoc[1], GDB_RT.GLOB) + local pEndLoc = EgtEP( tPathLoc[1], GDB_RT.GLOB) + -- ciclo sui percorsi per trovare i punti non coincidenti (se percorso non chiuso) + for j = 2, #tPathLoc do + -- prendo i punti del percorso successivo + local pAddIni = EgtSP( tPathLoc[j], GDB_RT.GLOB) + local pAddEnd = EgtEP( tPathLoc[j], GDB_RT.GLOB) + -- se consecutivi + if AreSamePointApprox( pEndLoc, pAddIni) then + pEndLoc = pAddEnd + elseif AreSamePointApprox( pIniLoc, pAddEnd) then + pIniLoc = pAddIni + else + table.insert( tNoMatch, tPathLoc[j]) + end + end + -- controllo eventuali percorsi scartati + for j = 1, #tNoMatch do + -- prendo i punti del percorso successivo + local pAddIni = EgtSP( tNoMatch[j], GDB_RT.GLOB) + local pAddEnd = EgtEP( tNoMatch[j], GDB_RT.GLOB) + -- se consecutivi + if AreSamePointApprox( pEndLoc, pAddIni) then + pEndLoc = pAddEnd + elseif AreSamePointApprox( pIniLoc, pAddEnd) then + pIniLoc = pAddIni + end + end + -- creo concatenamento partendo dal punto iniziale + local nIdLoc = EgtCurveCompoByReorder( nAddGrpId, tPathLoc, pIniLoc, true) + if nIdLoc then + table.insert( tChamPath, nIdLoc) + end + end + end + for i = 1, #tChamPath do + local ptP1 = EgtSP( tChamPath[i], GDB_RT.GLOB) + -- modifico estrusione percorso + if sDeleteByDir == 'Z' then + if abs(ptP1:getZ() - dMaxVal) < 10 * GEO.EPS_SMALL then + EgtModifyCurveExtrusion( tChamPath[i], Z_AX(), GDB_RT.GLOB) + else + EgtModifyCurveExtrusion( tChamPath[i], -Z_AX(), GDB_RT.GLOB) + end + elseif sDeleteByDir == 'Y' then + if abs(ptP1:getY() - dMaxVal) < 10 * GEO.EPS_SMALL then + EgtModifyCurveExtrusion( tChamPath[i], Y_AX(), GDB_RT.GLOB) + else + EgtModifyCurveExtrusion( tChamPath[i], -Y_AX(), GDB_RT.GLOB) + end + elseif sDeleteByDir == 'X' then + if abs(ptP1:getX() - dMaxVal) < 10 * GEO.EPS_SMALL then + EgtModifyCurveExtrusion( tChamPath[i], X_AX(), GDB_RT.GLOB) + else + EgtModifyCurveExtrusion( tChamPath[i], -X_AX(), GDB_RT.GLOB) + end + end + end + if #tChamPath == 1 then + return tChamPath[1], 1, nil + elseif #tChamPath == 2 then + return tChamPath[1], 2, tChamPath[2] + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + for i = 1, #tChamPath do + EgtErase( tChamPath[i]) + end + end + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + end + -- altrimenti cancello tutte le emtità e restituisco nil + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + end + end + end + + return nil, 0, nil +end + +--------------------------------------------------------------------- +local function CheckPocketTool( sMchFind, dDiam, dElev) + + local sPocketing = ML.FindPocketing( sMchFind, dDiam, dElev) + if sPocketing then + -- recupero i dati dell'utensile + local dTDiam = 50 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + return true, dTDiam + end + end + return false +end + +--------------------------------------------------------------------- +local function CheckDiamToolByFaces( Proc, nFacInd, dH, dV, bIsU, bIsL, dElev, nUseRoughTool) + local dMaxDimFace = max( dH, dV) + -- verifico che diametro utensile prende con la openpocket con la massima dimensione faccia + local bUseMaxTool, dMaxDiam + -- se è forzato l'uso del truciolatore non passo l'altezza di elevazione + if nUseRoughTool and nUseRoughTool == 1 then + bUseMaxTool, dMaxDiam = CheckPocketTool( 'OpenPocket', dMaxDimFace) + else + bUseMaxTool, dMaxDiam = CheckPocketTool( 'OpenPocket', dMaxDimFace, dElev) + end + -- se non trovato utensile esco + if not bUseMaxTool then + return false + end + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + -- se non ho facce adiacenti esco subito + if not vAdj or #vAdj == 0 then + return false + end + -- Normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- Cerco le facce adiacenti alla principale con angolo concavo >= 90 + local tWidth = {} + local tExtremPt = {} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + -- verifico l'angolo tra le facce ( esco se angolo compreso < 90) + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + if bAdj and dAng < -90 - 20 * GEO.EPS_ANG_SMALL then + return false + end + -- larghezza della faccia ortogonalmente alla adiacente + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT) + local vtX = vtN2 ^ vtN + local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2) + local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, nFacInd, GDB_BB.STANDARD, frRef) + if b3Ref then + table.insert( tWidth, b3Ref:getDimY()) + table.insert( tExtremPt, { ptP1, ptP2}) + end + end + end + -- se le facce di adiacenza non corrispondono con quelle della forma esco + if ( bIsU and #tWidth ~= 2) or ( bIsL and #tWidth ~= 1) then + return false + end + local dLargeVal = 0 + for i = 1, #tWidth do + dLargeVal = max( dLargeVal, tWidth[i]) + end + -- se facce U verifico se le distanze tra i punti sono minori delle distanze tra le facce + if bIsU then + local dLen11 = dist( tExtremPt[1][1], tExtremPt[2][1]) + local dLen12 = dist( tExtremPt[1][1], tExtremPt[2][2]) + local dLen21 = dist( tExtremPt[1][2], tExtremPt[2][1]) + local dLen22 = dist( tExtremPt[1][2], tExtremPt[2][2]) + dLargeVal = min( dLargeVal, dLen11, dLen12, dLen21, dLen22) + end + -- per essere accettabile, il diametro massimo deve essere minore della larghezza della faccia + if dMaxDiam < dLargeVal + 20 * GEO.EPS_SMALL then + return dMaxDiam, 'OpenPocket', nUseRoughTool, dMaxDiam + else + return false, '', 0, dMaxDiam + end +end + +--------------------------------------------------------------------- +local function MakeChamfer( Proc, b3FacesUsed, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : chamfer not found in library' + EgtOutLog( sErr) + return -1, sErr + end + -- ottengo le curve di contorno libero + local nAuxId1, nAuxId2, nNumIdAux + if b3FacesUsed then +-- nAuxId1, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) +-- EgtModifyCurveExtrusion( nAuxId1, vtOrtho, GDB_RT.GLOB) +-- SetOpenSide( nAuxId1, vtOrtho, b3Solid, nAddGrpId, true) +-- nNumIdAux = 2 + + -- estraggo i percorsi + nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId) + -- se percorso creato estraggo solo i percorsi delle facce interessate, non di testa + if nAuxId1 then + nAuxId1, nNumIdAux, nAuxId2 = ExtractExternalPaths( nAuxId1, nNumIdAux, vtOrtho, b3Solid, nAddGrpId) + end + else + nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId) + if not nNumIdAux then nNumIdAux = 0 end + end + + local dExtra = 2 + for i = 1, nNumIdAux do + local AuxId + local vtExtr + if b3FacesUsed then + if i == 1 then + AuxId = nAuxId1 + else + -- faccio la copia del percorso +-- AuxId = EgtCopyGlob( nAuxId1, nAddGrpId) + AuxId = nAuxId2 + end + if AuxId then + vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + end + else + AuxId = nAuxId1 + i - 1 + vtExtr, _, _ = EgtCurveArea( AuxId) + end + if vtExtr then + if not b3FacesUsed then + local fFrCurve = EgtGetGlobFrame( AuxId) + vtExtr:toGlob( fFrCurve) + end +-- if b3FacesUsed and i == nNumIdAux then +-- vtExtr = -vtExtr +-- end + -- Se normale entro certi limiti +-- if vtExtr:getZ() > -0.707 and ( abs(vtOrtho:getX()) > 0.99 or abs(vtOrtho:getY()) > 0.99 or abs(vtOrtho:getZ()) > 0.99) then + if vtExtr:getZ() > -0.707 and ( abs(vtExtr:getX()) > 0.99 or abs(vtExtr:getY()) > 0.99 or abs(vtExtr:getZ()) > 0.99) then + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchId = EgtAddMachining( sNameCh, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sMilling + EgtOutLog( sErr) + return -1, sErr + end + -- modifico estrusione percorso + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto posizione braccio porta testa + if vtExtr:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- assegno affondamento e offset radiale +-- EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra - EgtIf( b3FacesUsed, (dDepth / 2), 0)) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- se opero su 3 facce e sono al secondo e ultimo percorso inverto la lavorazione +-- if b3FacesUsed and i == nNumIdAux then +-- EgtSetMachiningParam( MCH_MP.INVERT, true) +-- end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return -1, sErr + end + -- se non perpendicolare emetto un warning + -- else + -- sWarn = 'Warning : chamfer skipped because not perpendicular to face or from bottom' + -- EgtOutLog( sWarn) + end + --emetto un warning + -- else + -- sWarn = 'Warning : chamfer skipped because not perpendicular to face' + -- EgtOutLog( sWarn) + end + end + + return 0 +end + +--------------------------------------------------------------------- +local function MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFindMaster, b3FacesUsed, b3Solid, bOrthoFacesMaster) + + local bOrthoFaces + local sWarn + local sMchFind = 'Pocket' + local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt + if sMchFindMaster and #sMchFindMaster > 0 then + sMchFind = sMchFindMaster + end + if b3FacesUsed then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, b3FacesUsed) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeByPockets could not find reference face' + EgtOutLog( sErr) + return -1, sErr + end + end + else + bOrthoFaces = bOrthoFacesMaster + end + + -- se è un tunnel provo a vedere se è possibile lavorarlo con la svuotatura + if bOrthoFaces then + -- ottengo le dimensioni del tunnel + dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId) + -- verifico la direzione + -- se devo inserire il chamfer + if nChamfer > 0 then + local nOk, sErr = MakeChamfer( Proc, b3FacesUsed, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return -1, sErr end + end + -- se smusso non è esclusivo + if nChamfer < 2 then + -- verifico se può essere fatto con svuotatura + local bMakePocket, sPocketing, dMaxMat = VerifyIfPocket( Proc, dDimMin, vtOrtho, sMchFind) + if bMakePocket then + -- gestione svuotatura da un solo lato o anche dal lato opposto (se non verticale) + -- estraggo il contorno dalla superfice per evitare i problemi con la svuotatura + -- e assegno l'estrusione + local nPathInt, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) + EgtModifyCurveExtrusion( nPathInt, vtOrtho, GDB_RT.GLOB) + -- se ho 3 facce, ciclo sulle entià del percorso per segnare quelle che sono aperte + if b3FacesUsed then + SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId) + end + -- variabili per parametri lavorazione + local dMachDepth + local dElev = 0 + local bDoubleSide + -- se possibile svuotare completamente da una sola parte + if dMaxMat > ( dDepth + 2) then + dMachDepth = (dDepth / 2) + 2 + dElev = dDepth + else + -- se direzione verso la verticale setto max affondamento possibile ed + -- emetto messaggio di warning perché non lavorabile interamente + if abs(vtOrtho:getZ()) >= 0.707 then + dMachDepth = dMaxMat - (dDepth / 2) + dElev = dMaxMat + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + -- altrimenti setto il flag per fare la svuotatura da due parti + else + if dMaxMat > (dDepth / 2) then + dMachDepth = 1 + dElev = (dDepth / 2) + 1 + else + dMachDepth = dMaxMat - (dDepth / 2) + dElev = dMaxMat + end + bDoubleSide = true + 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 -1, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nPathInt, -1}}) + -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) + local bInvertMach + if vtOrtho:getZ() < BD.NZ_MINA and abs(vtOrtho:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti + elseif not bDoubleSide and vtOrtho:getY() > GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + end + -- imposto posizione braccio porta testa + if vtOrtho:getY() < GEO.EPS_SMALL then + if bInvertMach then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + else + if bInvertMach then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + end + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- inverto il percorso di lavorazione per lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- imposto affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return -1, sErr + end + end + -- se posso applicare la svuotatura sul lato opposto + if bDoubleSide then + -- se anche lavorando dal lato opposto non riesco a svuotare completamente la fessura + -- setto i parametri affondamento ed emetto warning + if dMaxMat*2 < dDepth then + dMachDepth = dMaxMat - (dDepth / 2) + dElev = dMaxMat + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- inserisco la lavorazione di svuotatura + local sName = 'PockOppo_' .. ( 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 -1, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nPathInt, -1}}) + -- imposto direzione utensile opposta + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- imposto posizione braccio porta testa + if vtOrtho:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- inverto il percorso di lavorazione per lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- imposo affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return -1, sErr + end + end + end + return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace + end + end + end + + return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces +end + +--------------------------------------------------------------------- +local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, bSinglePart) + local sWarn + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + local bClosedOrthoFaces + local nFacInd, dFacElev, nFacInd2, dFacElev2 + local nBottomFace + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeMoreFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + -- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche + if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then + -- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura + for i = 1, Proc.Fct do + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + -- elimino una faccia + nBottomFace = i-1 + if EgtSurfTmRemoveFacet( nNewProc, nBottomFace) then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( nNewProc, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + EgtErase( nNewProc) + break + else + EgtErase( nNewProc) + local sErr = 'Error : MakeMoreFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + -- altrimenti esco + else + EgtErase( nNewProc) + break + end + end + -- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo + if bClosedOrthoFaces then + nFacInd = nBottomFace + -- rendo nulla la faccia opzionale perchè si tratta di una fessura + nFacInd2 = nil + dFacElev = BL.GetFaceElevation( Proc.Id, nFacInd) + bClosedOrthoFaces = false -- non setto come tunnel + end + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sErrCham, bForceUseBlade = EvaluateQParam( Proc, false, sDepthChamferMill, sPreemptiveChamfer, sForceUseBlade) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sErrCham + end + -- se è un tunnel provo a vedere se è possibile lavorarlo con la svuotatura o con la sega catena + if bClosedOrthoFaces then + local bTryWithBlades = true + -- lavoro fessura con svuotature (singola o doppia contrapposta) + local nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, 'Pocket', false, b3Solid, bClosedOrthoFaces) + if nOk < 0 then + return false, sErr + elseif nOk > 0 then + bTryWithBlades = false + end + -- Se la svuotatura precedente non è stata fatta e chamfer non è mutuamente esclusivo provo con la sega-catena + if bTryWithBlades and nChamfer < 2 then + -- verifico se posso farlo con la sega-catena + local bMakeChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick = VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho) + if bMakeChainSaw then + -- Verifico se necessarie più passate + local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dDimMin - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- inserisco la lavorazione di sawing + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLundIdFace}}) + -- imposto uso del lato faccia + -- al momento, dato che la fessura è passante da parte a parte, gestisco solo la lavorazione + -- dall'alto e di fronte (da dietro è disabilitata perchè ho exracorsa con la FAST). + -- Questa feature non è applicata su facce di testa e quindi non controllo l'entrata in X + if abs(vtOrtho:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se possibile aumento l'affondamento pari al raggio corner + 1 + if dMaxMat > (dDepth + dSawCornerRad + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad + 1)) + -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning + elseif dMaxMat < dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + elseif EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + end + end + -- altrimenti non è una fessura + else + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se U + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) + -- verifico se due facce o L con una o due facce di terminazione + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2) + -- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia + local bMakeBySideMill, bHead, sMilling, dMaxMat = VerifyIfByBHSideMill( Proc) + if bMakeBySideMill and ( dMaxMat <= dV) then + -- se smusso non è esclusivo + if nChamfer < 2 then + -- inserisco la lavorazione di fresatura + local sName = 'BHMill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso del lato faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) + -- calcolo step effettivo ed elevazione + local dVcalc = dV - dMaxMat + local dStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMaxMat + local nStep = ceil( dVcalc / dStep) + dStep = dVcalc / nStep + EgtSetMachiningParam( MCH_MP.STEP, dStep) + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dVcalc + dStep, 2) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- altrimenti lavoro con svuotatura + else + local bSpecial3faces = false + -- verifico se lavorando la faccia principale rimane esclusa molta sezione trasversale complessiva della feature (da box) + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local bBoxF = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfFac) + if dH * dV < 0.9 * ( bBoxF:getDimX() * bBoxF:getDimY()) then + bSpecial3faces = true + end + -- se riconosciuta gestione 3 facce + -- e limitata per ora alla feature 20 + if bSpecial3faces and Proc.Prc == 20 then + -- se smusso non è esclusivo + if nChamfer < 2 then + -- entrambe le facce non devono essere orientate verso il basso + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + -- se orientata verso il basso, verifico l'alternativa + if vtN:getZ() < BD.NZ_MINA and vtN2:getZ() < BD.NZ_MINA then + local sErr = 'Error : special LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd2, GDB_ID.ROOT) + -- eventuali tagli preliminari + do + local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw, nChamfer) + if not bOk then return false, sErr end + end + -- Recupero la lavorazione di fresa + local sMilling = ML.FindMilling( 'LongSmallCut') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero la lavorazione di svuotatura + local sMchFind = 'Pocket' + -- se forzato uso truciolatore + if EgtGetInfo( Proc.Id, sUseRoughTool, 'i') == 1 then + sMchFind = 'OpenPocket' + end + local dDiam = min( dH, dV) + local dDiam2 = min( dH2, dV2) + local dCollSic = 2 * BD.COLL_SIC + local dCollSic2 = 2 * BD.COLL_SIC + if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end + if abs( vtN2:getX()) > 0.7 or abs( vtN2:getY()) > 0.7 or abs( vtN2:getZ()) > 0.7 then dCollSic2 = 0 end + local sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2) + -- se non trova una svuotatura adatta provo ad assegnarla all'altra faccia + if not sPocketing then + dDiam, dDiam2 = dDiam2, dDiam + dCollSic, dCollSic2 = dCollSic2, dCollSic + nFacInd, nFacInd2 = nFacInd2, nFacInd + dH, dH2 = dH2, dH + dV, dV2 = dV2, dV + dFacElev, dFacElev2 = dFacElev2, dFacElev + rfFac, rfFac2 = rfFac2, rfFac + vtN, vtN2 = vtN2, vtN + sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2) + if not sPocketing then + local sErr = 'Error : pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- provo con contornatura + local dDiamTool = 20 + if bIsL then + local bOk, sErr + bOk, sWarn, dDiamTool = MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, true, sMilling, nFacInd2, dFacElev2) + if not bOk then return bOk, sWarn end + else + local sErr = 'Error : Impossible mill special LapJoint' + EgtOutLog( sErr) + return false, sErr + 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( {{ Proc.Id, nFacInd2}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev2, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- se abilitato dal parametro Q inserisco foro sullo spigolo + if EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 1 then + local bOk + bOk, sWarn = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, 0, nAddGrpId, dDiamTool, true) + if not bOk then return false, sWarn end + end + end + -- altrimenti lavorazione di svuotatura o contornatura + else + -- se orientata verso il basso, verifico l'alternativa + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + dFacElev, dFacElev2 = dFacElev2, dFacElev + end + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico non sia orientata verso il basso + local bFaceOk = ( vtN:getZ() >= BD.NZ_MINA) + if not bFaceOk then + local sErr = 'Error : LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- eventuali tagli preliminari + do + local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw, nChamfer) + if not bOk then return false, sErr end + end + -- imposto altezza aggiuntiva di elevazione + local dCollSic = 8 * BD.COLL_SIC + if abs( vtN:getX()) > 0.996 or abs( vtN:getY()) > 0.996 or abs( vtN:getZ()) > 0.996 then + dCollSic = 0 + elseif abs( vtN:getX()) > 0.866 or abs( vtN:getY()) > 0.866 or abs( vtN:getZ()) > 0.866 then + dCollSic = 2 * BD.COLL_SIC + elseif abs( vtN:getX()) > 0.707 or abs( vtN:getY()) > 0.707 or abs( vtN:getZ()) > 0.707 then + dCollSic = 5 * BD.COLL_SIC + end + local sMchFind = EgtIf( bSinglePart, 'Pocket', 'OpenPocket') + local nUseRoughTool = EgtIf( bSinglePart, 0, 1) + local dDiam = min( dH, dV) + local dDiamMax + local nUseRT + -- 04/08/2020 su richiesta di Fabio Squaratti, se settato parametro uso truciolatore (parametro Q), non si devono prendere altre frese, + -- piuttosto si da errore con il truciolatore. + -- Sicuramente questa opzione si scontra facilmente con altre interpretazioni dello stasso parametro Q + -- per tornare comportamento precedente settare bNewCheck = false + local bNewCheck = true + -- se processo 20 e non sto usando il truciolatore + if bNewCheck and Proc.Prc == 20 and nUseRoughTool == 0 then + -- verifico se forzato uso truciolatore + nUseRT = EgtGetInfo( Proc.Id, sUseRoughTool, 'i') + if nUseRT and nUseRT ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + end + end + -- verifico dalla forma se non posso prendere utensile grande + if ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 2 and bIsL) or Proc.Fct == 1 then + --ottengo un diametro utensile opportuno + dDiam, sMchFind, nUseRoughTool, dDiamMax = CheckDiamToolByFaces( Proc, nFacInd, dH, dV, bIsU, bIsL, ( dFacElev + dCollSic), nUseRoughTool) + if not dDiam and nUseRoughTool == 0 then + sMchFind = 'Pocket' + dDiam = min( dH, dV) + end + end + -- se processo 20 e non sto usando il truciolatore + if Proc.Prc == 20 and nUseRoughTool == 0 then + if nUseRT and nUseRT ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + if dDiamMax and Proc.Fct == 2 and bIsL then + dDiam = dDiamMax + end + end + end + --EgtOutLog( 'Mortise Find Diam =' .. EgtNumToString( dDiam)) + local sPocketing + if nUseRoughTool == 1 then + sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam) + if sMyPocketing and dMyTMaxDepth > 0.8 * dFacElev + dCollSic then + sPocketing = sMyPocketing + end + else + sPocketing = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic) + end + -- se non trovata verifico affondamento + if not sPocketing and nUseRoughTool == 0 then + local sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam) + if sMyPocketing and dMyTMaxDepth > 0.8 * dFacElev + dCollSic then + sPocketing = sMyPocketing + end + end + -- se non trova una svuotatura adatta + if not sPocketing then + -- se forma a L provo con contornatura + if bIsL then + -- se smusso non è esclusivo + if nChamfer < 2 then + return MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev) + end + -- altrimenti, in base alla forma, provo con svuotature di fianco o con la sega a catena o lama + else + local bTryWithBlades = true + local nOk, bOk, sStat, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces + -- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e + -- se non è possibile allora provo in seguito con lama o segacatena + -- o passare subito dalla lavorazione con lama/sega catena + if bTrySidePocketAtFirst and Proc.Fct == 3 and bIsU then + -- lavoro con svuotature (singola o doppia contrapposta) + nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFind, true, b3Solid) + if nOk < 0 then + return false, sErr + elseif nOk > 0 then + bTryWithBlades = false + end + bOk = true + end + -- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame + if bTryWithBlades and nChamfer < 2 then + bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, bForceUseBlade, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces, nBottomFace) + if not bOk and sStat == 'MNF' then + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr = 'Error : pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + else + return bOk, sWarn + end + -- altrimenti ho già svuotato dal fianco, esco + else + return bOk, sWarn + end + end + else + -- se devo inserire il chamfer + if ( ( Proc.Fct == 3 and bIsU) or (Proc.Fct == 2 and bIsL)) and nChamfer > 0 then + -- ottengo le dimensioni dello pseudotunnel + local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId) + local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return -1, sErr end + end + end + -- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo + -- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa + local bMadeASbyBld = false + if nChamfer < 2 and EgtGetInfo( Proc.Id, sAntisplintMode, 'i') == 1 and ( bIsU or bIsL) and + ( Proc.Box:getDimY() > b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > b3Raw:getDimZ() - 1) then + local nNumFac = EgtIf( bIsU, 2, 1) + local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra + -- se a U cerco di ottimizzare il lato di lavoro della lama + if bIsU then + if abs( vtN:getY()) > 0.996 then + nPrefSide = 0 + elseif abs( vtN:getZ()) > 0.7 or abs( vtN:getY()) > 0.7 then + -- se X è negativa allora devo tenere il motore a destra + if vtN:getX() < -(10 * GEO.EPS_SMALL) then + nPrefSide = 2 + end + end + end + -- va eseguito sulle facce diverse dalla principale + for nFacet = 0, nNumFac do + if nFacet ~= nFacInd then + local bInvertMach = false + if bIsU then + if abs(vtN:getZ()) > 0.7 or abs(vtN:getY()) > 0.7 then + -- prendo il vettore normale alla faccia + local _, vtNFc = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + -- valuto l'angolo tra le due facce + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT) + -- se superficie principale parallela al piano XZ + if nPrefSide == 0 then + -- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto) + if vtNFc:getX() * vtNFc:getZ() > 0 then + nPrefSide = 2 + -- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto) + else + nPrefSide = 1 + end + end + -- se faccia verso X+ e mandrino verso sinistra + if vtNFc:getX() > 0 and nPrefSide == 1 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + -- se faccia verso X- e mandrino verso destra + elseif vtNFc:getX() < 0 and nPrefSide == 2 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + end + end + end + local dSawThick = 0 + bMadeASbyBld, sWarn, nIdMach, dSawThick = MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw) + if not bMadeASbyBld then return false, sWarn end + if bInvertMach then + local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) + local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT) + local nSCC = EgtGetMachiningParam( MCH_MP.SCC) + local nInvSCC + if nSCC == MCH_SCC.ADIR_XP then + nInvSCC = MCH_SCC.ADIR_XM + elseif nSCC == MCH_SCC.ADIR_XM then + nInvSCC = MCH_SCC.ADIR_XP + elseif nSCC == MCH_SCC.ADIR_YP then + nInvSCC = MCH_SCC.ADIR_YM + elseif nSCC == MCH_SCC.ADIR_YM then + nInvSCC = MCH_SCC.ADIR_YP + else + nInvSCC = nSCC + end + local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE) + local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT) + if not bOrtUp then + -- inverto i parametri + EgtSetMachiningParam( MCH_MP.INVERT, not bInvert) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert) + EgtSetMachiningParam( MCH_MP.SCC, nInvSCC) + -- setto l'offset pari allo spessore lama + EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nIdMach, false) + return false, sErr + end + end + end + end + end + + -- se smusso non esclusivo + if nChamfer < 2 then + -- eseguo la svuotatura della faccia principale, mi restituisce id utensile, il diametro utensile per il foro opzionale + local tvtNx = {} + tvtNx[2] = vtN + local bOk + bOk, sWarn, sTuuidPk, dDiamTool = MakePocket( Proc, nPartId, ptC, tvtNx, nFacInd, sMchFind, nUseRoughTool, sPocketing, dFacElev + dCollSic) + if not bOk then return false, sWarn end + -- se ho più di 3 facce e non di forma ad u oppure ho 3 facce e di forma ad u + -- e non sono stati inseriti antischeggia di lama + -- controllo se c'è una faccia non ortogonale alla principale e la lavoro con una contornatura o svuotatura + if ( ( Proc.Fct > 3 and not bIsU) or ( Proc.Fct == 3 and bIsU)) and not bMadeASbyBld then + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + -- Cerco una faccia adiacente alla principale con angolo > 90 + local nFacAdj + local tDimAndRef = {} + tvtNx = {} + tvtNx[1] = vtN + tDimAndRef[1] = {dH, dV, rfFac} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + if bAdj and dAng < 0 and 180 + dAng > 90.1 then + local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vAdj[i], GDB_ID.ROOT) + _, tvtNx[2] = EgtSurfTmFacetCenter( Proc.Id, vAdj[i], GDB_ID.ROOT) + tDimAndRef[2] = {dH2, dV2, rfFac2} + local ptPs = ( ptP1 + ptP2) / 2 + local bOk + bOk, sWarn = MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtNx, nFacInd, vAdj[i], ptPs, tDimAndRef, + b3Raw, EgtIf( ( Proc.Fct == 3 and bIsU), 0, 2), nUseRoughTool, dAng, sPocketing, sTuuidPk, dFacElev) + if not bOk then return bOk, sWarn end + end + end + end + end + -- se abilitato dal parametro Q inserisco foro sullo spigolo + if EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 1 then + local bOk + bOk, sWarn = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool) + if not bOk then return false, sWarn end + -- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura + elseif EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 2 then + local bOk + bOk, sWarn = MakeCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool) + if not bOk then return false, sWarn end + -- altrimenti se abilitato dal parametro Q inserisco contorno con fresa più piccola + elseif EgtGetInfo( Proc.Id, sMakeContourWithSmallTool, 'i') == 1 then + local bOk + bOk, sWarn = MakeContourCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool) + if not bOk then return false, sWarn end + end + end + end + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- la divido in parti lungo X + local vAddId = {} + local nPart = max( ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN), 2) + local dPartLen = Proc.Box:getDimX() / nPart + local Xmin = Proc.Box:getMin():getX() + for i = 1, nPart do + -- eseguo divisione + local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i)) + if i > 1 then + local ptOn = Point3d( Xmin + ( i - 1) * dPartLen, 0, 0) + EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) + end + if i < nPart then + local ptOn = Point3d( Xmin + i * dPartLen, 0, 0) + EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) + end + table.insert( vAddId, AddId) + end + -- applico le lavorazioni sulle diverse parti + local sWarn + for i = 1, #vAddId do + local b3Box = EgtGetBBoxGlob( vAddId[i], GDB_BB.STANDARD) + local nFct = EgtSurfTmFacetCount( vAddId[i]) + local AddProc = { Id = vAddId[i], Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Box, Fct = nFct, Flg = Proc.Flg} + local bOk, sMyWarn = MakeMoreFaces( AddProc, nPhase, nRawId, nPartId, false) + if not sWarn then sWarn = sMyWarn end + if not bOk then return bOk, sWarn end + end + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +--------------------------------------------------------------------- +function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- limiti di fresatura semplice + local MAX_MILL_LIN = 80 + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- verifico forzatura lama + local bForcedBlade = EgtGetInfo( Proc.Id, sUseRoughTool, 'i') ~= 1 and EgtGetInfo( Proc.Id, sUseMill, 'i') ~= 1 + -- se lunghezza richiede spezzatura + if Proc.Box:getDimX() > BD.LONGCUT_MAXLEN then + -- una faccia + if Proc.Fct == 1 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + -- due facce + elseif Proc.Fct == 2 then + -- determino se due facce lunghe oppure una lunga e l'altra terminale + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) + local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD) + if abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 then + return Long2Cut.Make( Proc, nPhase, nRawId, nPartId) + elseif b3Fac1:getDimX() < 1 then + -- la faccia 0 deve essere quella lunga + EgtSurfTmSwapFacets( Proc.Id, 0, 1) + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + elseif b3Fac2:getDimX() < 1 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + else + if bForcedBlade then + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + else + return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId) + end + end + -- tre o più facce + else + return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId) + end + + -- altrimenti lavorazione unica + else + -- una faccia + if Proc.Fct == 1 then + -- se piccola, con fresa + if not bForcedBlade and ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then + return MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) + -- altrimenti, con lama + else + return Cut.Make( Proc, nPhase, nRawId, nPartId, 0) + end + -- due facce + elseif Proc.Fct == 2 then + -- determino l'angolo tra le facce + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + -- se ortogonali e non forzata lama, con fresa + if not bForcedBlade and bAdj and abs( dAng + 90) < 1 then + -- se piccole + if ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then + return MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) + else + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, true) + end + -- altrimenti, con lama + else + -- verifico se devo fare prima gli amussi + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se due facce o L con una o due facce di terminazione + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2) + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sErrCham = EvaluateQParam( Proc, false, sDepthChamferMill, sPreemptiveChamfer, sForceUseBlade) + if (Proc.Fct == 2 and bIsL) and nChamfer > 0 then + local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId) + local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return false, sErr end + end + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + end + -- tre o più facce + else + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, true) + end + end +end + +--------------------------------------------------------------------- +return ProcessLapJoint diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessLongCut.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessLongCut.lua new file mode 100644 index 0000000..e0a410b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessLongCut.lua @@ -0,0 +1,565 @@ +-- ProcessLongCut.lua by Egaltech s.r.l. 2020/06/11 +-- Gestione calcolo taglio longitudinale per Travi + +-- Tabella per definizione modulo +local ProcessLongCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessLongCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLongCut.Identify( Proc) + return (( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 10) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLongCut.Classify( Proc) + -- se una sola faccia non ci sono limiti + if Proc.Fct == 1 then + return true, false + end + -- verifico la normale della faccia principale + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 then + return true, true + end + return true, false +end + +--------------------------------------------------------------------- +local function MakeSideFace( nId, nFac, nSide, sMilling, dToolDiam) + -- inserisco la lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( nId) or tostring( nId)) .. '_' .. tostring( nFac) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nId, nFac}}) + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- uso della faccia + local nFaceUse = MCH_MILL_FU.PARAL_DOWN + if nSide == -2 then + nFaceUse = MCH_MILL_FU.PARAL_BACK + elseif nSide == 2 then + nFaceUse = MCH_MILL_FU.PARAL_FRONT + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- annullo offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +local function MakeByPocketing( Proc, nPhase, nRawId, nPartId) + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + -- cerco la svuotatura opportuna + local sPocketing = ML.FindPocketing( 'OpenPocket', Proc.Box:getDimX()) + 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 dMaxDepth = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + end + end + -- inserisco la lavorazione + 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( {{ Proc.Id, 0}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto attacco per tasca aperta + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev) + dFacElev = dMaxDepth + sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local _, dLen, dWidth = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + -- limitazioni su inizio e fine derivanti da altre facce + local bLimXmin = false + local bLimXmax = false + if Proc.Fct >= 3 then + bLimXmin = true + bLimXmax = true + elseif Proc.Fct >= 2 then + local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if vtN1:getX() > 0 then + bLimXmin = true + else + bLimXmax = true + end + end + -- Verifico lato di lavorazione + local nSide = 1 + if vtN:getZ() < - 0.5 then + nSide = -1 + elseif vtN:getY() < -0.7071 then + nSide = -2 + elseif vtN:getY() > 0.7071 then + nSide = 2 + end + + local sWarn + -- Se non limitato e da sopra e richiesto con doppio taglio di lama + if not bLimXmin and not bLimXmax and nSide == 1 and EgtGetInfo( Proc.Id, 'Q05', 'i') == 1 then + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN:getY() < 0) + -- determino numero di parti + local dStartAccDist = BD.LONGCUT_ENDLEN + local dEndAccDist = BD.LONGCUT_ENDLEN + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- determino l'utilizzo della faccia + local nFaceUse = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + local nFaceUse2 = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + -- si percorrono i lati alto e basso della faccia + local nM = 0 + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- ciclo sulle passate + local dOffset = ( dWidth + BD.DIM_STRIP_SMALL) / 2 ; + local dLioTang = 0 + local dLioPerp = ( dWidth - BD.DIM_STRIP_SMALL) / 2 + BD.CUT_SIC ; + for k = 1, 2 do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC) + local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC) + if ( not bFront and k == 1) or ( bFront and k == 2) then + dSal, dEal = dEal, dSal + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + + -- se altrimenti non è sotto : lavorazione Long2Cut + elseif nSide ~= - 1 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2Cut') + 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 dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se chiuso e corto, applico svuotatura con fresa opportuna + if bLimXmin and bLimXmax and Proc.Box:getDimX() < 2 * dToolDiam then + return MakeByPocketing( Proc, nPhase, nRawId, nPartId) + end + -- determino la massima elevazione + local dElev = 0 + local ptT1 = b3Raw:getMax() + local dDist1 = ( ptT1 - ptC) * vtN + dElev = max( dElev, dDist1) + local ptT2 = ptT1 - Y_AX() * b3Raw:getDimY() + local dDist2 = ( ptT2 - ptC) * vtN + dElev = max( dElev, dDist2) + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN:getY() < 0) + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + if ( bLimXmin and bFront) or ( bLimXmax and not bFront) then + dStartDist = dToolDiam / 2 + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + if ( bLimXmin and not bFront) or ( bLimXmax and bFront) then + dEndDist = dToolDiam / 2 + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- determino l'utilizzo della faccia + local nFaceUse = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + -- si percorre il lato basso della faccia + local nM = 0 + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC + if bFront then + nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + else + nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- ciclo sulle passate + local nO = 1 + local dStep = 0 + if dWidth + 2 * BD.CUT_EXTRA > 0.8 * dToolDiam then + nO = ceil(( dWidth + 2 * BD.CUT_EXTRA) / ( 0.6 * dToolDiam)) + if nO > 1 then + dStep = ( dWidth + 2 * BD.CUT_EXTRA) / nO + end + end + for k = nO, 1, -1 do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == 1, -dStartDist, - dStartAccDist - ( i - 2) * dC) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + local dEal = EgtIf( i == nC, -dEndDist, - dEndAccDist - ( nC - i - 1) * dC) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, ( k - 1) * dStep - BD.CUT_EXTRA) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- verifico massimo affondamento rispetto ad elevazione + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in LongCut : depth (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + end + local dDepth = min( 0, dMaxDepth - dElev ) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- eventuale lavorazione della faccia limitante l'inizio + if i == 1 and not bStartFixed then + local vtIni = EgtIf( bFront, X_AX(), -X_AX()) + for i = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT) + if vtIni * vtN > 0 then + MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam) + end + end + end + end + + -- eventuale lavorazione della faccia limitante la fine + if not bEndFixed then + local vtFin = EgtIf( bFront, -X_AX(), X_AX()) + for i = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT) + if vtFin * vtN > 0 then + MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam) + end + end + end + + -- altrimenti è sotto : lavorazione Long2CutDown + else + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2CutDown') + 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 dToolDiam = 0 + local dMaxDepth = 0 + local dThDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + end + end + -- larghezza faccia + local _, _, dWidth = BL.GetFaceHvRefDim( Proc.Id, 0) + -- aggiuntivo sull'affondamento + local dAgg = BD.CUT_EXTRA + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN:getY() < 0) + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + if ( bLimXmin and bFront) or ( bLimXmax and not bFront) then + dStartDist = dToolDiam / 2 + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + if ( bLimXmin and not bFront) or ( bLimXmax and bFront) then + dEndDist = dToolDiam / 2 + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino il numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + -- Limitazioni della lavorazione + local nPos = EgtIf( bFront, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, -dEndDist, -dEndAccDist - ( nPos - 2) * dC) + local dEal = EgtIf( nPos == nC, -dStartDist, -dStartAccDist - ( nC - nPos - 1) * dC) + -- Posizione braccio portatesta + local nSCC + if bFront then + nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + else + nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- verifico massimo affondamento (tengo conto dell'inclinazione utensile e della pinza con estremità conica) + local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * abs( vtN:getY() / vtN:getZ()) - 3) + if dWidth + dAgg > dMaxDepth - dCollSic then + sWarn = 'Warning in LongCut : depth (' .. EgtNumToString( dWidth + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth - dCollSic, 1) .. ')' + end + local dDepth = min( dMaxDepth - dCollSic, dWidth + dAgg) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessLongCut diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessLongDoubleCut.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessLongDoubleCut.lua new file mode 100644 index 0000000..693ffa0 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessLongDoubleCut.lua @@ -0,0 +1,695 @@ +-- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2020/08/03 +-- Gestione calcolo doppio taglio longitudinale per Travi + +-- Tabella per definizione modulo +local ProcessLong2Cut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessLongDoubleCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLong2Cut.Identify( Proc) + return ( Proc.Grp == 0 and Proc.Prc == 12) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLong2Cut.Classify( Proc) + return true, false +end + +--------------------------------------------------------------------- +function ProcessLong2Cut.GetLongFacesCount( Proc) + local nLongFaces = 0 + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if abs( vtN:getX()) < GEO.EPS_SMALL then + nLongFaces = nLongFaces + 1 + end + end + return nLongFaces +end + +--------------------------------------------------------------------- +-- Identificazione delle facce della feature. +-- Ritorna quattro valori : +-- flag delle facce limitanti (0= no, 1= a destra, 2= a sinistra, 3= entrambe) +-- vettore indici facce longitudinali +-- vettore dei centri delle facce longitudinali +-- vettore dei centri delle normali +function ProcessLong2Cut.IdentifyFaces( Proc) + + local nFaceLimit = 0 + local tFaceLong = {} + local tptC = {} + local tvtN = {} + + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se è una faccia limite a sinistra + if vtN:getX() > GEO.EPS_SMALL then + nFaceLimit = nFaceLimit + 2 + -- se è una faccia limite a destra + elseif vtN:getX() < -GEO.EPS_SMALL then + nFaceLimit = nFaceLimit + 1 + -- altrimenti è una faccia longitudinale + else + local nInd = #tFaceLong + 1 + tFaceLong[nInd] = i-1 + tptC[nInd], tvtN[nInd] = EgtSurfTmFacetCenter( Proc.Id, ( i-1), GDB_ID.ROOT) + end + end + return nFaceLimit, tFaceLong, tptC, tvtN +end + +--------------------------------------------------------------------- +local function MakeSideFace( nId, nFac, nSide, sMilling, dToolDiam) + -- inserisco la lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( nId) or tostring( nId)) .. '_' .. tostring( nFac) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nId, nFac}}) + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- uso della faccia + local nFaceUse = EgtIf( nSide == 1, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.ORTHO_LEFT) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- annullo offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +local function MakeByPocketing( Proc, nPhase, nRawId, nPartId, nFacInd, dFacElev) + -- cerco la svuotatura opportuna + local sPocketing = ML.FindPocketing( 'OpenPocket', Proc.Box:getDimX()) + 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 dMaxDepth = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + end + end + -- inserisco la lavorazione + 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( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto attacco per tasca aperta + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev) + dFacElev = dMaxDepth + sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) + + -- carico i dati delle face già inserite nelle opportune tabelle + local nFaceLimit, tFaceLong, ptC, vtN = ProcessLong2Cut.IdentifyFaces( Proc) + local dLen = Proc.Box:getDimX() + + -- verifico posizione (+1=sopra, -1=sotto, 0=sui lati) + local nSide = 0 + if vtN[1]:getZ() > -10 * GEO.EPS_SMALL and vtN[2]:getZ() > -10 * GEO.EPS_SMALL then + nSide = 1 + elseif vtN[1]:getZ() < -10 * GEO.EPS_SMALL and vtN[2]:getZ() < -10 * GEO.EPS_SMALL then + nSide = -1 + end + + -- angolo diedro per stabilire se taglio convesso + local bInt, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, tFaceLong[1], tFaceLong[2], GDB_ID.ROOT) + local bConvex + local bOrtho + local ptM + if bInt then + bConvex = ( dAng >= 0) + bOrtho = ( abs( dAng + 90) < 1) + ptM = ( ptP1 + ptP2) / 2 + else + bConvex = true + bOrtho = false + ptM = ( ptC[1] + ptC[2]) / 2 + end + local ptRef = ( ptC[1] + ptC[2]) / 2 + -- analisi del taglio + local vOrd = {} + local vFaceUse = {} + if nSide == 1 then + vOrd = EgtIf( ptC[1]:getY() < ptRef:getY(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + elseif nSide == -1 then + vOrd = EgtIf( ptC[1]:getY() < ptM:getY(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestParalOpposite( ptC[1] - ptM), BL.GetNearestParalOpposite( ptC[2] - ptM)} + else + local bFront = ( vtN[1]:getY() < 0) + if bFront then + vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + else + vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 2, 1}, { 1, 2}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + end + end + local vWidth = {} + _, _, vWidth[1] = BL.GetFaceHvRefDim( Proc.Id, tFaceLong[1]) + _, _, vWidth[2] = BL.GetFaceHvRefDim( Proc.Id, tFaceLong[2]) + + local sWarn + -- Se senza facce limitanti, da sopra e richiesto con doppio taglio di lama + if nFaceLimit == 0 and nSide == 1 and EgtGetInfo( Proc.Id, 'Q01', 'i') == 1 then + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + + -- determino numero di parti + local dStartAccDist = BD.LONGCUT_ENDLEN + local dEndAccDist = BD.LONGCUT_ENDLEN + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + + local nM = 0 + -- se convesso lavoro ogni faccia in due metà lasciando attaccata la parte centrale + if bConvex then + -- si percorrono i lati alto e basso della faccia + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- ciclo sulle due facce + for j = 1, #vOrd do + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN[vOrd[j]]:getY() < 0) + -- determino l'utilizzo della faccia + local nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + local nFaceUse2 = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + -- ciclo sulle passate + local dOffset = ( vWidth[vOrd[j]] + BD.DIM_STRIP_SMALL) / 2 ; + local dLioTang = 0 + local dLioPerp = ( vWidth[vOrd[j]] - BD.DIM_STRIP_SMALL) / 2 + BD.CUT_SIC ; + for k = 1, 2 do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) .. '_' .. tostring(j) + local nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vOrd[j]-1}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC) + local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC) + if ( not bFront and k == 1) or ( bFront and k == 2) then + dSal, dEal = dEal, dSal + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + end + -- altrimenti concavo + else + -- si percorrono i lati alto e basso della faccia + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- ciclo sulle due facce + for j = 1, #vOrd do + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN[vOrd[j]]:getY() < 0) + -- determino l'utilizzo della faccia + local nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + local nFaceUse2 = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + -- ciclo sulle passate + local dOffset + local dLioPerp + if j == 1 then -- il primo taglio lo faccio completo + dOffset = 0 + dLioPerp = vWidth[vOrd[j]] + BD.CUT_SIC + else -- il secondo ridotto della distanza minima e della componente spessore della lama + dOffset = BD.DIM_STRIP_SMALL + ((dToolThick* vtN[vOrd[1]]) - (dToolThick* vtN[vOrd[1]]) * vtN[vOrd[2]] * vtN[vOrd[2]]):len() + dLioPerp = vWidth[vOrd[j]] - dOffset + BD.CUT_SIC + end + local dLioTang = 0 + + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) + local nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vOrd[j]-1}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC) + local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC) + if ( bFront) then + dSal, dEal = dEal, dSal + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse2) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + end + + -- Se non è sotto : lavorazione Long2Cut + elseif nSide ~= - 1 then + + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2Cut') + 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 dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se chiuso e corto, applico svuotatura con fresa opportuna + if nFaceLimit == 3 and Proc.Box:getDimX() < 2 * dToolDiam then + -- svuotatura della prima faccia longitudinale + local dFacElev = BL.GetFaceElevation( Proc.Id, tFaceLong[1], nPartId) + local bOk, sErr = MakeByPocketing( Proc, nPhase, nRawId, nPartId, tFaceLong[1], dFacElev) + -- svuotatura della seconda faccia longitudinale + if not bOk then return bOk, sErr end + local dFacElev2 = BL.GetFaceElevation( Proc.Id, tFaceLong[2], nPartId) + return MakeByPocketing( Proc, nPhase, nRawId, nPartId, tFaceLong[2], dFacElev2) + end + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + -- se ho faccia limite a destra + if nFaceLimit == 1 or nFaceLimit == 3 then + dStartDist = dToolDiam / 2 + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + -- se ho faccia limite a sinistra + if nFaceLimit == 2 or nFaceLimit == 3 then + dEndDist = dToolDiam / 2 + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino il numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- se facce ortogonali (concave), lavoro solo quella con versore maggiormente verso l'alto + local nIni, nFin = 1, 2 + if bOrtho then + if vtN[vOrd[1]]:getZ() >= vtN[vOrd[2]]:getZ() then + nFin = 1 + else + nIni = 2 + end + end + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + -- su entrambe le facce + for i = nIni, nFin do + -- Limitazioni della lavorazione + local nPos = EgtIf( i == 1, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC) + local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC) + -- Posizione braccio portatesta + local nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- Verifico se da fare di fianco perchè normale troppo verso il basso (minore di -30deg) + local bSide = ( vtN[vOrd[i]]:getZ() < -0.5) + -- ciclo sulle passate + local nO = 1 + local dStep = 0 + local dAgg = EgtIf( bConvex, 2 * BD.CUT_EXTRA, BD.CUT_EXTRA) + local dLargh = vWidth[vOrd[i]] + if not bSide and dLargh > 0.8 * dToolDiam then + nO = ceil( dLargh / ( 0.6 * dToolDiam)) + if nO > 1 then + dStep = dLargh / nO + end + end + for k = 1, nO do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, tFaceLong[vOrd[i]]}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bSide, MCH_MILL_FU.PARAL_DOWN, vFaceUse[vOrd[i]])) + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bSide, true, false)) + -- imposto offset radiale (nullo se concavo o di lato) + local dOffsR = EgtIf( k < nO, ( nO - k) * dStep, EgtIf( bConvex, - BD.CUT_EXTRA, 0)) + if bSide then dOffsR = 0 end + EgtSetMachiningParam( MCH_MP.OFFSR, dOffsR) + -- se di lato, imposto offset longitudinale + if bSide then + EgtSetMachiningParam( MCH_MP.OFFSL, - BD.CUT_EXTRA) + end + -- attacco e uscita + local dLioPerp = EgtIf( bSide, dToolDiam, dLargh - dOffsR + BD.CUT_SIC) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante l'inizio (a destra) + if bConvex and j == 1 and not bStartFixed then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], 1, sMilling, dToolDiam) + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante la fine (a sinistra) + if bConvex and j == nC and not bEndFixed then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], -1, sMilling, dToolDiam) + end + end + end + -- altrimenti è sotto : lavorazione Long2CutDown + else + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2CutDown') + 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 dToolDiam = 0 + local dMaxDepth = 0 + local dThDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + end + end + -- aggiuntivo sull'affondamento + local dAgg = EgtIf( bConvex, BD.CUT_EXTRA, 0) + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + -- se ho facce limite a destra + if nFaceLimit == 1 or nFaceLimit == 3 then + dStartDist = dToolDiam / 2 + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + -- se ho facce limite a sinistra + if nFaceLimit == 2 or nFaceLimit == 3 then + dEndDist = dToolDiam / 2 + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino il numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + -- su entrambe le facce + for i = 1, 2 do + -- Limitazioni della lavorazione + local nPos = EgtIf( i == 1, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, - EgtIf( i == 1, dStartDist, dEndDist), - EgtIf( i == 1, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC) + local dEal = EgtIf( nPos == nC, - EgtIf( i == 1, dEndDist, dStartDist), - EgtIf( i == 1, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC) + -- Posizione braccio portatesta + local nSCC = MCH_SCC.ADIR_XP + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, tFaceLong[vOrd[i]]}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]]) + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- nel caso concavo, devo impostare la lunghezza di attacco ortogonale + if not bConvex then + local dNz = vtN[vOrd[i]]:getZ() + local dLioPerp = vWidth[vOrd[i]] * sqrt( 1 - dNz * dNz) / abs( dNz) + BD.COLL_SIC + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + end + -- verifico massimo affondamento (tengo conto dell'inclinazione utensile e della pinza con estremità conica) + local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * abs( vtN[vOrd[i]]:getY() / vtN[vOrd[i]]:getZ()) - 3) + if vWidth[vOrd[i]] + dAgg > dMaxDepth - dCollSic then + sWarn = 'Warning in LongDoubleCut : depth (' .. EgtNumToString( vWidth[vOrd[i]] + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth - dCollSic, 1) .. ')' + end + local dDepth = min( dMaxDepth - dCollSic, vWidth[vOrd[i]] + dAgg) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessLong2Cut diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessMark.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessMark.lua new file mode 100644 index 0000000..13d7843 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessMark.lua @@ -0,0 +1,131 @@ +-- ProcessMark.lua by Egaltech s.r.l. 2020/05/28 +-- Gestione calcolo marcatura per Travi +-- 2020/05/28 Tipo di lavorazione passato da Mark a Text + +-- Tabella per definizione modulo +local ProcessMark = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessMark started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessMark.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 60) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessMark.Classify( Proc) + -- recupero il versore estrusione o normale se testo + local vtN + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtN = EgtCurveExtrusion( Proc.Id, GDB_ID.ROOT) + else + vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtN then + return false + end + -- verifico se la marcatura è lavorabile solo da sotto + local bDown = (( vtN:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessMark.Make( Proc, nPhase, nRawId, nPartId) + -- recupero eventuale geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero i dati della marcatura + local vtExtr + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + else + vtExtr = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtExtr then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che la marcatura non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Text') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale lavorazione su seconda geometria + if AuxId then + -- inserisco la lavorazione di fresatura + local sName2 = 'Decor2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchF2Id = EgtAddMachining( sName, sMilling) + if not nMchF2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + 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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchF2Id, false) + return false, sErr + end + -- se geometria a X maggiore, la sposto prima + local ptS1 = EgtSP( Proc.Id, GDB_ID.ROOT) + local ptS2 = EgtSP( AuxId, GDB_ID.ROOT) + if ptS2:getX() > ptS1:getX() then + EgtRelocateGlob( nMchF2Id, nMchFId, GDB_IN.BEFORE) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessMark diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessMortise.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessMortise.lua new file mode 100644 index 0000000..21e0fd2 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessMortise.lua @@ -0,0 +1,297 @@ +-- ProcessMortise.lua by Egaltech s.r.l. 2020/05/27 +-- Gestione calcolo mortase per Travi + +-- Tabella per definizione modulo +local ProcessMortise = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessMortise started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessMortise.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 50) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 51) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 53)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature: decide se la feature è in una posizione che per lavorala +-- deve essere ribaltata o no +function ProcessMortise.Classify( Proc) + -- recupero e verifico il percorso supplementare + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero versore estrusione della curva supplementare e non più della superficie + -- perché quest'ultima potrebbe non avere il fondo e dare quindi un risultato non corretto + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtExtr then + return false + end + if not vtN then + return false + end + local bDown + -- Confronto le direzioni Z dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante + if abs( vtExtr:getZ() - vtN:getZ()) > GEO.EPS_SMALL then + bDown = false + -- altrimenti è chiusa + else + -- verifico se la mortasa è lavorabile solo da sotto + bDown = ( vtN:getZ() < - 0.1) + end + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessMortise.Make( Proc, nPhase, nRawId, nPartId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + local bForceOneSide + local bRevertSide + 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 versore estrusione della curva supplementare + local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT) + -- Se curva di contorno aperta + if not EgtCurveIsClosed( AuxId) then + local NewId, nCount = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id)) + if NewId then + -- elimino eventuali loop interni (non dovrebbero comunque esserci) + for i = 1, nCount - 1 do + EgtErase( NewId + i) + end + -- sostituisco il loop esterno alla curva originale + EgtModifyCurveExtrusion( NewId, vtExtr, GDB_ID.ROOT) + EgtRelocate( NewId, AuxId, GDB_IN.AFTER) + EgtErase( AuxId) + EgtChangeId( NewId, AuxId) + -- sistemo i lati aperti + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, 0)[1] + if vFacAdj then + local sOpen = '' + for i = 1, #vFacAdj do + if vFacAdj[i] < 0 then + sOpen = sOpen .. EgtIf( #sOpen > 0, ',', '') .. tostring( i - 1) + end + end + if #sOpen > 0 then + EgtSetInfo( AuxId, 'OPEN', sOpen) + end + end + end + end + -- recupero i dati della faccia di fondo + local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + local ptC = frMor:getOrigin() + local vtN = frMor:getVersZ() + -- Confronto le direzioni Z dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante + local bOpenBtm = ( abs( vtExtr:getZ() - vtN:getZ()) > GEO.EPS_SMALL) + if bOpenBtm then + -- creo superficie chiusa + local nFlat = EgtSurfTmByFlatContour( EgtGetParent( AuxId), AuxId, 0.02) + if nFlat then + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + -- verifico se copiare la geometria lungo l'asse Z + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frMor) + local bxMax = b3Aux:getMax() + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local bxMin = b3Mor:getMin() + local dMove = bxMin:getZ()-bxMax:getZ() + -- se il percorso ausiliario è esterno al grezzo, lo riavvicino + if abs( dMove) > GEO.EPS_SMALL then + AuxId = EgtCopyGlob( AuxId, BL.GetAddGroup(nPartId)) + EgtMove( AuxId, Vector3d(0,0,-dMove)) + EgtMove( nFlat, Vector3d(0,0,-dMove)) + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + end + -- cancello le prove del misfatto (superficie piana) + EgtErase( nFlat) + end + end + -- scrivo info nel log + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + if not bOpenBtm then + -- verifico che la mortasa non sia orientata verso il basso (limite -5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mortise from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- se mortasa passante + else + -- determino se la mortasa da lavorare sul lato opposto sia di angolo inferiore a quello consentito + if abs(vtN:getZ()) > 0.1 then + bForceOneSide = true + end + -- determino se è meglio lavorare la mortasa nel lato opposto + if vtN:getZ() < -GEO.EPS_SMALL then + bRevertSide = true + end + end + + -- determino altezza della mortasa + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local dMorH = b3Mor:getDimZ() + -- elevazione del punto centro + local _, dCenElev = BL.GetPointDirDepth( nPartId, ptC, vtN) + dMorH = max( dMorH, dCenElev or 0) + -- determino larghezza della mortasa + if dL < dW then dL, dW = dW, dL end + -- recupero la lavorazione + local sPocketing + if Proc.Prc ~= 53 then + sPocketing = ML.FindPocketing( 'Mortise', dW) + end + if not sPocketing then + sPocketing = ML.FindPocketing( 'Pocket', dW) + end + 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 + local bCW = true + 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) + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'Mort_' .. ( 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 + -- verifico se invertire versore estrusione geometria + if bRevertSide then + EgtModifyCurveExtrusion( AuxId, -vtExtr, GDB_ID.ROOT) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo la direzione di lavoro + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + if bRevertSide then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + else + if bRevertSide then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + end + local sWarn + local nDepthMin + -- se la mortasa è passante e non è forzata a un solo lato, riduco l'affondamento a metà profondità + if bOpenBtm and not bForceOneSide then + dMorH = dMorH * 0.5 + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + if dMorH > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in mortise : elevation (' .. EgtNumToString( dMorH,1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth,1) .. ')' + -- se non ho invertito la direzione di estrusione + if not bRevertSide then + nDepthMin = dMaxDepth - EgtIf( bOpenBtm and not bForceOneSide, dMorH * 2, dMorH) + else + nDepthMin = dMaxDepth + end + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + dMorH = dMaxDepth + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + else + if bOpenBtm and not bForceOneSide then -- se mortasa passante setto metà profondità + nDepthMin = -dMorH + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + end + end + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMorH, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- Se non c'è il fondo e la lavorazione non ha lavorato tutta la superficie per limite altezza utensile + -- inserisco una ulteriore lavorazione contraria + if bOpenBtm and not bForceOneSide and nDepthMin and abs(nDepthMin) > 0 then + -- inserisco la lavorazione di svuotatura opposta + sName = 'Mort_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_Oppo' + nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + EgtOutLog( sErr) + return false, sErr + end + -- faccio la copia e la metto nel layer dedicato alle geometrie aggiunte + local AuxId_oppo = EgtCopyGlob( AuxId, BL.GetAddGroup(nPartId)) + -- inverto la direzione estrusione di questa + EgtModifyCurveExtrusion( AuxId_oppo, - vtExtr, GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId_oppo, -1}}) + -- sistemo la direzione di lavoro + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + -- se altezza mortasa differente da altezza massima lavorabile + if abs( dMorH - dMaxDepth) > GEO.EPS_SMALL then + nDepthMin = -dMorH + else -- se sono uguali setto + nDepthMin = -( dMorH - BD.CUT_EXTRA) + end + -- setto profondità + EgtSetMachiningParam( MCH_MP.DEPTH, -nDepthMin+BD.CUT_EXTRA) + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (-nDepthMin+BD.CUT_EXTRA), 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessMortise diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfCamb.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfCamb.lua new file mode 100644 index 0000000..e297b5f --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfCamb.lua @@ -0,0 +1,587 @@ +-- ProcessProfCamb.lua by Egaltech s.r.l. 2020/05/22 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfCamb = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfCamb started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q01' -- i +local sEnableExtraBladeUpperFace = 'Q02' -- i +local sDepthChamferMill = 'Q03' -- d +local sOverMaterialForFinish = 'Q04' -- d +local sPreemptiveChamfer = 'Q05' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfCamb.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 103) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfCamb.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtNF) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtNF) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtSP( AuxId, GDB_ID.ROOT) + vtNP * 5.0 + -- determino asse di rotazione + local vtRot = - Y_AX() + if vtNF:getX() < 0 then vtRot = - vtRot end + if vtNF:getZ() < -0.1 then + vtRot = - vtRot + elseif vtNF:getY() < -0.1 then + vtRot:rotate( X_AX(), 90) + elseif vtNF:getY() > 0.1 then + vtRot:rotate( X_AX(), -90) + end + -- miglioro l'inclinazione (ripartendo da faccia perpendicolare asse trave) + vtNP[2] = 0 vtNP[3] = 0 + local dRot = 45 + for i = 1, 4 do + local vtNP2 = Vector3d( vtNP) + vtNP2:rotate( vtRot, dRot) + local frRef = Frame3d( ptStart, vtNP2) + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frRef) + if b3Box:getMax():getZ() < -3 then + vtNP = Vector3d( vtNP2) + end + dRot = dRot / 2 + end + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideAndInvert( Proc, bHead, dToolDiam) + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- ultima faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nLastFacet, GDB_ID.ROOT) + local nRefFacet = nLastFacet - 1 -- penultima faccia + local vtNF = EgtSurfTmFacetNormVersor( Proc.Id, nLastFacet, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nRefFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtNF:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, false, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + --variabili utilizzate in varie parti + local dToolMaxDepth = 0 + local dMillDiam = 0 + local sMilling + -- se smusso non è esclusivo + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtNF) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- leggo anticipatamente i parametri utensile fresa per dare un valore opportuno all'elevazione della lama + -- recupero la lavorazione di fresatura + sMilling = ML.FindMilling( 'Prof') + 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 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- se non da sotto e abilitato dal parametro Q aggiungo taglio di lama + if nSide ~= -1 and nLastFacet and EgtGetInfo( Proc.Id, sEnableExtraBladeUpperFace, 'i') == 1 then + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + local vtOrthoO = Vector3d(vtN) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, nLastFacet, sCutting, dToolDiam, vtOrthoO, nil, -((dMillDiam/2)+1), BD.CUT_SIC, 0, 0, nil, b3Raw) + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead, dMillDiam) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead, dMillDiam) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead, dMillDiam) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead, dMillDiam) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se non da sotto e parametro Q abilitato, inserisco lavorazione finitura angolo + if nSide ~= -1 and EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') == 1 then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, -0.5) + -- imposto tipo uso faccia + local nFaceUse = MCH_MILL_FU.ORTHO_DOWN + if nSide ~= 1 then + nFaceUse = EgtIf( vtN:getY() > 0.1, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then -- se feature di fianco o da sotto + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + -- altrimenti feature da sopra + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfCamb diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfConcave.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfConcave.lua new file mode 100644 index 0000000..534bdc2 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfConcave.lua @@ -0,0 +1,598 @@ +-- ProcessProfConcave.lua by Egaltech s.r.l. 2020/05/22 +-- Gestione calcolo profilo concavo per Travi + +-- Tabella per definizione modulo +local ProcessProfConcave = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfConcave started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q03' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q01' -- d +local sOverMaterialForFinish = 'Q02' -- d +local sPreemptiveChamfer = 'Q04' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfConcave.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 101) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfConcave.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, bNotModifLeadPar) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + -- modifico attacco e uscita + if not bNotModifLeadPar then + EgtSetMachiningParam( MCH_MP.LIPERP, -(dToolDiam/2)) + EgtSetMachiningParam( MCH_MP.LITANG, (dToolDiam/2)+0.5) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, (dToolDiam/3*2)) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + else + -- modifico attacco e uscita + if not bNotModifLeadPar then + EgtSetMachiningParam( MCH_MP.LIPERP, -(dToolDiam/2)) + EgtSetMachiningParam( MCH_MP.LITANG, (dToolDiam/2)+0.5) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, (dToolDiam/3*2)) + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end + end + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) // 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, false, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvertAndLead( Proc, bHead, dMillDiam, true) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvertAndLead( Proc, bHead, dMillDiam, true) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, true) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, true) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bLastTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + elseif vtN:getY() < -0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTUP_TOP) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (dToolMaxDepth/2), 1)) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bFirstTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then -- se feature di fianco o da sotto + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + -- altrimenti feature da sopra + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfConcave diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfConvex.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfConvex.lua new file mode 100644 index 0000000..8325c45 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfConvex.lua @@ -0,0 +1,597 @@ +-- ProcessProfConvex.lua by Egaltech s.r.l. 2020/05/22 +-- Gestione calcolo profilo convesso per Travi + +-- Tabella per definizione modulo +local ProcessProfConvex = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfConvex started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q05' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q02' -- d +local sOverMaterialForFinish = 'Q04' -- d +local sPreemptiveChamfer = 'Q01' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfConvex.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 102) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfConvex.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, bNotModifLeadPar) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + -- modifico attacco e uscita + if not bNotModifLeadPar then + EgtSetMachiningParam( MCH_MP.LIPERP, -(dToolDiam/2)) + EgtSetMachiningParam( MCH_MP.LITANG, (dToolDiam/2)+0.5) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, (dToolDiam/3*2)) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + else + -- modifico attacco e uscita + if not bNotModifLeadPar then + EgtSetMachiningParam( MCH_MP.LIPERP, -(dToolDiam/2)) + EgtSetMachiningParam( MCH_MP.LITANG, (dToolDiam/2)+0.5) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, (dToolDiam/3*2)) + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end + end + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) // 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, false, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvertAndLead( Proc, bHead, dMillDiam, true) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvertAndLead( Proc, bHead, dMillDiam, true) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, true) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, true) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bLastTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + elseif vtN:getY() < -0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTUP_TOP) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (dToolMaxDepth/2), 1)) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bFirstTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfConvex diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfFront.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfFront.lua new file mode 100644 index 0000000..51ae5f0 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfFront.lua @@ -0,0 +1,574 @@ +-- ProcessProfFront.lua by Egaltech s.r.l. 2020/05/22 +-- Gestione calcolo profilo frontale per Travi + +-- Tabella per definizione modulo +local ProcessProfFront = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfFront started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = '' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q01' -- d +local sOverMaterialForFinish = 'Q02' -- d +local sPreemptiveChamfer = 'Q03' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfFront.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 100) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfFront.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + local vtNP = Vector3d( vtN) + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, bNotModifLeadPar) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + -- modifico attacco e uscita + if not bNotModifLeadPar then + EgtSetMachiningParam( MCH_MP.LIPERP, -(dToolDiam/2)) + EgtSetMachiningParam( MCH_MP.LITANG, (dToolDiam/2)+0.5) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, (dToolDiam/3*2)) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + else + -- modifico attacco e uscita + if not bNotModifLeadPar then + EgtSetMachiningParam( MCH_MP.LIPERP, -(dToolDiam/2)) + EgtSetMachiningParam( MCH_MP.LITANG, (dToolDiam/2)+0.5) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, (dToolDiam/3*2)) + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end + end + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- ultima faccia + local nRefFacet = nLastFacet - 1 -- penultima faccia + -- determino la normale media + local CvxHullId = EgtSurfTmConvexHullInBBox( EgtGetParent( Proc.Id), Proc.Id, b3Raw, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( CvxHullId, 0, GDB_ID.ROOT) + EgtErase( CvxHullId) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + --EgtOutLog( 'vtN=' .. tostring( vtN)) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, false, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvertAndLead( Proc, bHead, dMillDiam, true) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvertAndLead( Proc, bHead, dMillDiam, true) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, true) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, true) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bFirstTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + -- se non da sotto, inserisco lavorazione finitura angolo + --if nSide ~= -1 then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- setto inversione e lato lavoro per lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- imposto tipo uso faccia + local nFaceUse = MCH_MILL_FU.PARAL_DOWN + if nSide ~= 1 then + nFaceUse = EgtIf( vtN:getY() > 0.1, MCH_MILL_FU.PARAL_FRONT, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + -- aggiorno ingombro testa o coda per presa + --if nSide == 0 then + -- if bHead then + -- BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + -- else + -- BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + -- end + --end + return true +end + +--------------------------------------------------------------------- +return ProcessProfFront diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfHead.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfHead.lua new file mode 100644 index 0000000..0c797d3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessProfHead.lua @@ -0,0 +1,611 @@ +-- ProcessProfHead.lua by Egaltech s.r.l. 2020/05/22 +-- Gestione calcolo profilo di testa per Travi + +-- Tabella per definizione modulo +local ProcessProfHead = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfHead started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q03' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q01' -- d +local sOverMaterialForFinish = 'Q04' -- d +local sPreemptiveChamfer = 'Q02' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfHead.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 106) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfHead.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- assegno la normale + local vtNP = Vector3d( vtN) + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, bNotModifLeadPar) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + -- modifico attacco e uscita + if not bNotModifLeadPar then + EgtSetMachiningParam( MCH_MP.LIPERP, -(dToolDiam/2)) + EgtSetMachiningParam( MCH_MP.LITANG, (dToolDiam/2)+0.5) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, (dToolDiam/3*2)) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + else + -- modifico attacco e uscita + if not bNotModifLeadPar then + EgtSetMachiningParam( MCH_MP.LIPERP, -(dToolDiam/2)) + EgtSetMachiningParam( MCH_MP.LITANG, (dToolDiam/2)+0.5) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, (dToolDiam/3*2)) + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end + end + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + -- determino la normale media + local CvxHullId = EgtSurfTmConvexHullInBBox( EgtGetParent( Proc.Id), Proc.Id, b3Raw, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( CvxHullId, 0, GDB_ID.ROOT) + EgtErase( CvxHullId) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi negli angoli + local vAngs = {} + for i = 1, Proc.Fct do + local _, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, i-1, i, GDB_ID.ROOT) + if ( dAng and dAng < -30) then + table.insert( vAngs, i - 1) + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, false, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvertAndLead( Proc, bHead, dMillDiam, true) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvertAndLead( Proc, bHead, dMillDiam, true) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, true) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideAndInvertAndLead( Proc, bHead, dToolDiam, true) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and #vAngs > 0 then + -- dimensioni feature + local dLen = Proc.Box:getDimX() + local dDep = EgtIf( nSide == 1, Proc.Box:getDimZ(), Proc.Box:getDimY()) + -- se più alta che lunga o da sotto con il parametro Q abilitato + if (dDep > dLen) or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1) then + for i = 1, #vAngs do + sName = 'ProfV'.. tostring( i)..'_'..( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dElev = EgtSurfTmFacetOppositeSide( Proc.Id, vAngs[i], EgtIf( bHead, X_AX(), -X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vAngs[i]}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dElev, 1)) + -- imposto posizione braccio + local nSCC = MCH_SCC.ADIR_YM + if nSide == 0 then + nSCC = EgtIf( vtN:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + -- altrimenti + else + for i = 1, #vAngs do + sName = 'ProfV'.. tostring( i)..'_'..( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dElev = EgtSurfTmFacetOppositeSide( Proc.Id, vAngs[i]+1, vtN, GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vAngs[i]+1}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dElev, 1)) + -- imposto posizione braccio + local nSCC = MCH_SCC.ADIR_YM + if nSide == 0 then + nSCC = EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfHead diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessRidgeLap.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessRidgeLap.lua new file mode 100644 index 0000000..eb0b408 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessRidgeLap.lua @@ -0,0 +1,205 @@ +-- ProcessRidgeLap.lua by Egaltech s.r.l. 2020/04/23 +-- Gestione calcolo mezzolegno di testa per Travi + +-- Tabella per definizione modulo +local ProcessRidgeLap = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessRidgeLap started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessRidgeLap.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 30) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessRidgeLap.Classify( Proc, b3Raw) + -- Se più corta del limite si può fare anche da sotto + if Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then + return true, false + end + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.707 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + return true + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getX()) < 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i-1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[3]]) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo riferimenti per facce inclinate + local vtRef = Vector3d( vtN[vFaceOrd[3]]) + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local nOrthoOpposite + if i % 2 == 1 then + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + else + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[3]]) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( EgtIf( bHead, X_AX(), -X_AX())) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtN[vFaceOrd[3]]:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtN[vFaceOrd[3]]:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessRidgeLap diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessRoundArch.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessRoundArch.lua new file mode 100644 index 0000000..e487a8a --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessRoundArch.lua @@ -0,0 +1,235 @@ +-- ProcessRoundArch.lua by Egaltech s.r.l. 2019/12/07 +-- Gestione calcolo archi per Travi + +-- Tabella per definizione modulo +local ProcessRoundArch = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessRoundArch started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessRoundArch.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 104) +end +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessRoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessRoundArch.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di coda + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessRoundArch.Classify( Proc) + -- se di testa o coda, è indifferente alla posizione + if Proc.Head or Proc.Tail then + return true, false + end + -- è intermedia, devo verificare la normale del centro + local nMidFacet = Proc.Fct // 2 + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se la feature è lavorabile solo da sotto + --local bDown = ( vtN:getZ() < - 0.1) + local bDown = false + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessRoundArch.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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) + local bDown = ( b3Aux:getMin():getZ() < b3Raw:getMin():getZ() + 5) + -- 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 + -- ne verifico la lunghezza per eventuale spezzatura e lavorazione in doppio + local nStep = 1 + local dStep = 0 + local dLenMax = BD.LONGCUT_ENDLEN + if b3Aux:getDimX() > dLenMax then + local dCrvLen = EgtCurveLength( AuxId) + nStep = ceil( dCrvLen / dLenMax) + dStep = dCrvLen / nStep + EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) + end + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local bCross = false + if abs( vtExtr:getY()) > 0.707 then + if b3Aux:getDimY() > b3Raw:getDimY() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimY()) + end + elseif abs( vtExtr:getZ()) > 0.707 then + if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimZ()) + end + end + local nDouble = 1 + local bCanDouble = abs( vtExtr:getY()) > 0.707 and bCross + local bStripOnSide = false + if bCross then + if nStep > 1 or ( bDown and b3Aux:getDimX() > 0.5 * b3Raw:getDimX()) then + -- devo lasciare un codolo + dDepth = dDepth - BD.DIM_STRIP + bStripOnSide = true + else + -- devo affondare un poco oltre + dDepth = dDepth + BD.CUT_EXTRA + end + end + if dDepth > dMaxDepth then + if bCanDouble then + nDouble = 2 + dDepth = min( 0.5 * dDepth, dMaxDepth) + else + dDepth = dMaxDepth + end + end + -- se utensile orizzontale verso Y+, non in doppio e codolo da lasciare, devo invertire per lavorare sempre da Y- + if vtExtr:getY() > 0.707 and nDouble == 1 and bStripOnSide then + bToolInv = true + end + -- eseguo + for i = 1, nStep do + for j = 1, nDouble do + -- 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}}) + -- eventuale accorciamento di testa + if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then + local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + end + -- eventuale accorciamento di coda + if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then + local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- se estrusione da sotto, inverto direzione fresa + if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- se seconda passata, inverto direzione di lavoro + if j == 2 then + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + if bToolInv then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + -- posizione braccio porta testa + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessRoundArch diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessSawCut.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessSawCut.lua new file mode 100644 index 0000000..080b527 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessSawCut.lua @@ -0,0 +1,189 @@ +-- ProcessSawCut.lua by Egaltech s.r.l. 2020/06/04 +-- Gestione calcolo taglio di lama per Travi + +-- Tabella per definizione modulo +local ProcessSawCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessSawCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSawCut.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 13) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessSawCut.Classify( Proc, b3Raw) + -- recupero i dati del versore direzione di accesso della lavorazione + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtDir = EgtSV( AuxId, GDB_ID.ROOT) + return true, ( vtDir:getZ() <= - 0.088) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSawCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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à vettore + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.GEO_VECTOR then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing access direction' + EgtOutLog( sErr) + return false, sErr + end + local vtDir = EgtSV( AuxId, GDB_ID.ROOT) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local frFace = Frame3d( ptC, vtDir ^ vtN, vtDir, vtN) + local b3Face = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFace) + local dLen = b3Face:getDimX() + local dWidth = b3Face:getDimY() + -- se taglio di testa + if Proc.Head then + -- se coincide con il taglio di separazione precedente, non va fatto + if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- altrimenti taglio di coda + else + -- se coincide con taglio di separazione, non va fatto + if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + end + -- recupero flag per inizio e fine interni + local bInside = (( EgtGetInfo( Proc.Id, 'Q01', 'i') or 0) ~= 0) + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 2 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- determino se lavorazione da davanti o da dietro e se da sotto + local bFront = ( vtDir ^ vtN):getX() > 0 + local bDownUp = ( vtN:getZ() < -0.259) + -- determino affondamento e distanza interna da inizio e fine + local dDepth = min( dWidth, dMaxDepth - BD.COLL_SIC) + local dInsDist = 0 + if bInside then + dInsDist = sqrt( dSawDiam * dDepth - dDepth * dDepth) + if 2 * dInsDist > dLen - 2 then + dInsDist = ( dLen - 2) / 2 + dDepth = dSawDiam / 2 - sqrt( dSawDiam * dSawDiam / 4 - dInsDist * dInsDist) + end + end + -- determino numero di parti + local dStartAccDist = BD.LONGCUT_ENDLEN + local dEndAccDist = BD.LONGCUT_ENDLEN + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + dC = dLen / ( nC + 2) + dStartAccDist = min( dC, dStartAccDist) + dEndAccDist = min( dC, dEndAccDist) + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + dStartAccDist = dLen / 2 + dEndAccDist = dStartAccDist + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- determino l'utilizzo della faccia + local nFaceUse = BL.GetNearestOrthoOpposite( vtDir) + if bDownUp then + nFaceUse = BL.GetOrtupOpposite( nFaceUse) + end + -- si percorrono i lati alto e basso della faccia + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- ciclo sulle passate + local dOffset = dWidth - dDepth ; + local dLioTang = 0 + local dLioPerp = dDepth + BD.CUT_SIC ; + -- inserisco le parti di lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nC) + local nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == 1, -dInsDist, -dStartAccDist - ( i - 2) * dC) + local dEal = EgtIf( i == nC, -dInsDist, -dEndAccDist - ( nC - i - 1) * dC) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- imposto offset longitudinale + if Proc.Grp == 0 then + EgtSetMachiningParam( MCH_MP.OFFSL, EgtIf( bDownUp, dSawThick / 2, -dSawThick / 2)) + end + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bFront ~= bDownUp, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + EgtSetMachiningParam( MCH_MP.INVERT, bFront) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessSawCut diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessScarfJoint.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessScarfJoint.lua new file mode 100644 index 0000000..18a9448 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessScarfJoint.lua @@ -0,0 +1,498 @@ +-- ProcessScarfJoint.lua by Egaltech s.r.l. 2020/07/21 +-- Gestione calcolo giunto Gerber per Travi + +-- Tabella per definizione modulo +local ProcessScarfJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessScarfJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessScarfJoint.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 71) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessScarfJoint.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q02', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function ApplyDiceCut( vFaceOrd, nGoodFace1, nGoodFace4, nAddGrpId, b3Solid, ptC, vtN, Proc, vtRef, bHead, sCutting, dSawDiam, b3Raw, dNewDiceDim) + + local vCuts = {} + local bOk = true + local sErr = '' + + if nGoodFace1 and nGoodFace4 and nGoodFace1 > 0 and nGoodFace4 > 0 then + -- lavoro solo la faccia inclinata perché la faccia tappo completa la lavoro successivamente + -- questo evita di lavorare due volte la faccia tappo + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[4]], vtN[vFaceOrd[4]], false, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], nil, dNewDiceDim) + elseif nGoodFace4 and nGoodFace4 > 0 then + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[4]], vtN[vFaceOrd[4]], true, nil, nil, nil, dNewDiceDim) + end + + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- lavoro la faccia interna in ogni caso + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- lavoro la faccia opposta (definita dal parametro P11) + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + return bOk, sErr, vCuts +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessScarfJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + + -- verifico che ci siano almeno quattro facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 3 then + local sErr = 'Error : number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + + -- ordino le facce in base al loro numero e al parallelismo delle due facce principali + -- faccia 1: superficie tappo + -- faccia 2: superficie principale di fondo + -- faccia 3: superficie opposta alla faccia 1 + -- faccia 4: superficie principale superiore + -- faccia 5: superficie di testa + local vtRef + local vFaceOrd = { 0, 0, 0, 0, 0} + if nFacetCnt == 5 then -- se ho 5 facce controllo il parallelismo della faccia 2 e 4 + if not AreSameVectorApprox( vtN[2], vtN[4]) then + local sErr = 'Error : main faces are not parallel (btl import problems)' + EgtOutLog( sErr) + return false, sErr + end + -- carico gli id delle facce + for i = 1, nFacetCnt do + vFaceOrd[i] = i + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[4]]:getY(), vtN[vFaceOrd[4]]:getZ()) + elseif nFacetCnt == 4 then -- se ho 4 facce + if AreSameVectorApprox( vtN[1], vtN[3]) then -- sono nel caso in cui manca la faccia 1 + for i = 1, nFacetCnt do + vFaceOrd[i+1] = i + end + elseif AreSameVectorApprox( vtN[2], vtN[4]) then -- sono nel caso in cui manca la faccia 5 + for i = 1, nFacetCnt do + vFaceOrd[i] = i + end + else -- altrimenti ho una condizione di facce non previsto e do errore + local sErr = 'Error : crazy faces(4)' + EgtOutLog( sErr) + return false, sErr + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[4]]:getY(), vtN[vFaceOrd[4]]:getZ()) + elseif nFacetCnt == 3 then -- se ho 3 facce + if AreSameVectorApprox( vtN[1], vtN[3]) then -- sono nel caso in cui manca la faccia 1 + for i = 1, nFacetCnt do + vFaceOrd[i+1] = i + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[4]]:getY(), vtN[vFaceOrd[4]]:getZ()) + else + for i = 1, nFacetCnt do + vFaceOrd[i] = i + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[2]]:getY(), vtN[vFaceOrd[2]]:getZ()) + end + end + + -- determino se di testa o di coda + local bHead = ( vtN[1]:getX() > 0) + + -- normalizzo vettore di riferimento per le facce ortogonali all'asse trave + vtRef:normalize() + + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + + -- creo superfici partendo da punto e versore delle facce 4 (inclinata) e 1 (tappo) + local nFace1 + local nFace4 + local nGoodFace1 + local nGoodFace4 + if vtN[vFaceOrd[4]] then + nFace4 = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vFaceOrd[4]], vtN[vFaceOrd[4]], b3Solid, GDB_ID.ROOT) + end + if vtN[vFaceOrd[1]] then + nFace1 = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], b3Solid, GDB_ID.ROOT) + end + if nFace4 and nFace1 then + -- taglio la superficie di tappo e quella inclinata per capire se per il taglio a cubetti si devono considerare una o due superfici + local bOk = EgtCutSurfTmPlane( nFace1, ptC[vFaceOrd[4]], -vtN[vFaceOrd[4]], false, GDB_ID.ROOT) + bOk = bOk and EgtCutSurfTmPlane( nFace4, ptC[vFaceOrd[1]], -vtN[vFaceOrd[1]], false, GDB_ID.ROOT) + + if not bOk then + local sErr = 'Error : wrong cut surfaces' + EgtOutLog( sErr) + return false, sErr + end + + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + nGoodFace1 = EgtSurfTmFacetCount( nFace1) + nGoodFace4 = EgtSurfTmFacetCount( nFace4) + elseif nFace4 then + nGoodFace4 = EgtSurfTmFacetCount( nFace4) + elseif nFace1 then + nGoodFace1 = EgtSurfTmFacetCount( nFace1) + end + + local bOkd, sErrD, vCuts = ApplyDiceCut( vFaceOrd, nGoodFace1, nGoodFace4, nAddGrpId, b3Solid, ptC, vtN, Proc, vtRef, bHead, sCutting, dSawDiam, b3Raw) + if not bOkd then return bOkd, sErrD end + + if #vCuts == 0 then + -- se ho la faccia intermedia, per prima cosa verifico se ho intersezione con la faccia tappo + if nGoodFace4 ~= 0 then + -- taglio sulla faccia interna + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + -- se non ho intersezione con la faccia tappo posso fare il taglio sul fianco + if not nGoodFace1 or nGoodFace1 == 0 then + -- lavoro la faccia opposta (definita dal parametro P11) + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + -- inserisco la lavorazione + local vtRef2 = EgtIf( abs(vtRef:getZ()) < GEO.EPS_SMALL, Z_AX(), EgtIf( bHead, Y_AX(), -Y_AX())) + bOkd, sErrD = BL.MakeOneFaceBySaw( nFace4, nGoodFace4 - 1, sCutting, dSawDiam, vtRef2, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + else -- altrimenti se ho intersezione forzo il DiceCut ad essere eseguito con distanze più piccole + -- definisco la nuova dimensione massima del dice cut + local dNewDiceDim = EgtIf( abs(vtRef:getZ()) < GEO.EPS_SMALL, b3Raw:getDimZ(), b3Raw:getDimY()) + bOkd, sErrD = ApplyDiceCut( vFaceOrd, nGoodFace1, nGoodFace4, nAddGrpId, b3Solid, ptC, vtN, Proc, vtRef, bHead, sCutting, dSawDiam, b3Raw, dNewDiceDim) + if not bOkd then return bOkd, sErrD end + end + else + -- taglio sulla faccia interna + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + -- lavoro la faccia opposta (definita dal parametro P11) + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + end + end + + -- taglio sulla faccia esterna + if vFaceOrd[5] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[5]], X_AX()) and abs( ptC[vFaceOrd[5]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[5]], - X_AX()) and abs( ptC[vFaceOrd[5]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[5] - 1) + if DimV > DimH then + vtOrthoO = Vector3d( frHV:getVersX()) + else + vtOrthoO = Vector3d( vtRef) + end + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[5] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + + -- lavoro superficie principale di fondo con una svuotatura + if vFaceOrd[2] ~= 0 then + + local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vFaceOrd[2]-1, GDB_ID.ROOT) + -- calcolo la dimensione da passare + local dDiamMax = EgtIf( abs( frMor:getVersX():getY()) < abs( frMor:getVersY():getY()), dL, dW) + -- determino la distanza tra le due facce inclinate + local dDistFaces + if vFaceOrd[4] ~= 0 then + dDistFaces = abs((ptC[vFaceOrd[2]]-ptC[vFaceOrd[4]])*vtN[vFaceOrd[2]]) + end + -- recupero la lavorazione. considerando l dimensione del lato e l'affondamento + local sPocketing + if dDistFaces then + sPocketing = ML.FindPocketing( 'OpenPocket', dDiamMax, dDistFaces) + else + sPocketing = ML.FindPocketing( 'OpenPocket', dDiamMax) + end + + 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( {{ Proc.Id, vFaceOrd[2]-1}}) + -- imposto elevazione + if dDistFaces then + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dDistFaces, 1) .. ';') + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + + return true, sErrC +end + +--------------------------------------------------------------------- +return ProcessScarfJoint diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessSimpleScarf.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessSimpleScarf.lua new file mode 100644 index 0000000..fe8a3c3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessSimpleScarf.lua @@ -0,0 +1,324 @@ +-- ProcessSimpleScarf.lua by Egaltech s.r.l. 2020/06/04 +-- Gestione calcolo giunto Gerber per Travi + +-- Tabella per definizione modulo +local ProcessSimpleScarf = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessSimpleScarf started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSimpleScarf.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 70) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessSimpleScarf.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSimpleScarf.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Error : number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getY()) > 0.1 or abs( vtN[i]:getZ()) > 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error : missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + bHead = ( vtN[vFaceOrd[1]]:getX() > 0) + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO = Vector3d( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true, sErrC +end + +--------------------------------------------------------------------- +return ProcessSimpleScarf diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessSplit.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessSplit.lua new file mode 100644 index 0000000..8a029c2 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessSplit.lua @@ -0,0 +1,233 @@ +-- ProcessSplit.lua by Egaltech s.r.l. 2020/06/16 +-- Gestione calcolo tagli di separazione per Travi + +-- Tabella per definizione modulo +local ProcessSplit = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessSplit started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSplit.Identify( Proc) + return ( Proc.Grp == 2 and Proc.Prc == 350) +end + +--------------------------------------------------------------------- +-- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) +local function VerifyCurveForChamfer( AuxId) + if not AuxId then + return -2 + end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + return -1 + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- va bene solo se direzione estrusione orizzontale + if abs( vtExtr:getZ()) > 0.1 then + return 0 + end + return 1 +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( nOriId, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico le entità curva associate (max 2) + local sVal = EgtGetInfo( nOriId, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local AuxId, Aux2Id + if vsAuxId and #vsAuxId >=1 then + AuxId = tonumber( vsAuxId[1]) + end + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if AuxId then AuxId = AuxId + nOriId end + if Aux2Id then Aux2Id = Aux2Id + nOriId end + local nRes = VerifyCurveForChamfer( AuxId) + if nRes == 0 and Aux2Id then + AuxId = Aux2Id + nRes = VerifyCurveForChamfer( AuxId) + end + if nRes == -2 then + return true + end + if nRes == -1 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + if nRes == 0 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true, nil +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSplit.Make( Proc, nPhase, nRawId, nPartId) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- inserimento smussi + local nOriId = EgtGetInfo( Proc.Id, 'ORI', 'i') + if nOriId then + local bOkc, sErrC = MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bSplit, 'SplitSide', 'TailSide')) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, true, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 50 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- caratteristiche taglio + local bHorizCut = ( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL and b3Raw:getDimZ() < dMaxDepth - BD.CUT_EXTRA) + local dDimYRef = EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, dMaxDepth - BD.CUT_EXTRA, BD.MAX_DIM_HTCUT_HBEAM) + local bDoubleCut = ( not bHorizCut and b3Raw:getDimY() > dDimYRef + 10 * GEO.EPS_SMALL) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- flag di lavorazione faccia + local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_FRONT) + -- separazione solo se esiste grezzo successivo con pezzi o scaricabile + local nNextRawId = EgtGetNextRawPart( nRawId) + local bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() > BD.MinRaw)) + -- determino se più tagli con offset + local nCuts = 1 + local dOffsL = 0 + if not bSplit then + -- cerco grezzo successivo che sia nella fase + if nNextRawId and EgtVerifyRawPartPhase( nNextRawId, nPhase) then + local b3NextRaw = EgtGetRawPartBBox( nNextRawId) + local dLenEndRaw = ptC:getX() - b3NextRaw:getMin():getX() + nCuts = ceil( dLenEndRaw / BD.MAX_LEN_SCRAP) + dOffsL = dLenEndRaw / nCuts + -- aggiorno ingombro del grezzo corrente con quello del successivo + b3Raw:Add( b3NextRaw) + end + end + -- calcolo extra taglio ed accorciamento + local dCutExtra = 0 + local dAccStart = 0 + if b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL or b3Raw:getDimY() < 2 * BD.MAX_DIM_HTCUT_HBEAM + 10 * GEO.EPS_SMALL then + dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN, BD.CUT_EXTRA) + dAccStart = 0 + else + dCutExtra = - ( b3Raw:getDimY() - dMaxDepth - BD.CUT_EXTRA) + local dSawRad = dSawDiam / 2 + local dKL = dSawRad - dMaxDepth + b3Raw:getDimY() / 2 + BD.CUT_EXTRA_MIN + dAccStart = sqrt( dSawRad * dSawRad - dKL * dKL) + end + -- se necessari tagli in doppio, eseguo gli opposti + if bDoubleCut then + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes = EgtIf( bSplit, 'Presplit;', 'Precut;') + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_BACK, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, sNotes, b3Raw) + if not bOk then return false, true, sErr end + end + end + -- eseguo i tagli necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes + if bSplit then + sNotes = EgtIf( i == 1, 'Split;', 'Presplit;') + else + sNotes = EgtIf( i == 1, 'Cut;', 'Precut;') + end + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, sNotes, b3Raw) + if not bOk then return false, true, sErr end + end + -- ritorno anche flag di passaggio a fase successiva + return true, true +end + +--------------------------------------------------------------------- +return ProcessSplit diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessStepJoint.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessStepJoint.lua new file mode 100644 index 0000000..6392272 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessStepJoint.lua @@ -0,0 +1,480 @@ +-- ProcessStepJoint.lua by Egaltech s.r.l. 2020/06/04 +-- Gestione calcolo giunto a gradino per Travi + +-- Tabella per definizione modulo +local ProcessStepJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessStepJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessStepJoint.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 80) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessStepJoint.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- gestisco solo 2 o 3 facce + if nFacetCnt ~= 2 and nFacetCnt ~= 3 then + return false, false + end + -- se due facce, verifico se convesso + local bConvex = false + if nFacetCnt == 2 then + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + bConvex = not bAdj or ( dAng > 0) + end + -- verifico le normali delle facce + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if not bConvex and vtN:getZ() < - 0.72 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione al caso due facce +local function MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se convesso, lo tratto come due tagli singoli + if bConvex then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- lavoro per prima la faccia più diretta in alto + local vOrd = { 1, 2} + if vtN[2]:getZ() > vtN[1]:getZ() then + vOrd = { 2, 1} + end + -- creo piano di taglio coincidente con la prima faccia e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[1]], vtN[vOrd[1]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- creo piano di taglio coincidente con la seconda faccia e lo lavoro + AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[2]], vtN[vOrd[2]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- altrimenti + else + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local k, l = nBigInd, nSmaInd + if ( i % 2) == 1 then + k, l = l, k + end + local nOrthoOpposite + if bOnY then + local bFront = ( ptC[k]:getY() < ptPs:getY()) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + local bOver = ( ptC[k]:getZ() > ptC[l]:getZ()) + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, EgtIf( bHead, 'HeadSide', 'TailSide')) + if not bOk then + return bOk, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione al caso tre facce +local function MakeThreeFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- riduco a forma canonica ( concavo tra 0 e 1, faccia 2 oltre convesso) + local bAdj12, _, _, dAng12 = EgtSurfTmFacetsContact( Proc.Id, 1, 2, GDB_ID.ROOT) + local bAdj20, _, _, dAng20 = EgtSurfTmFacetsContact( Proc.Id, 2, 0, GDB_ID.ROOT) + if bAdj12 then + if dAng12 < 0 then + EgtSurfTmSwapFacets( Proc.Id, 0, 2) + end + elseif bAdj20 then + if dAng20 < 0 then + EgtSurfTmSwapFacets( Proc.Id, 1, 2) + end + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + ptC[3], vtN[3] = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- Taglio la faccia 2 + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio coincidente con la faccia 2 e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[3], vtN[3], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- Taglio le facce 0 e 1 concave + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local k, l = nBigInd, nSmaInd + if ( i % 2) == 1 then + k, l = l, k + end + local nOrthoOpposite + if bOnY then + local bFront = ( ptC[k]:getY() < ptPs:getY()) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + local bOver = ( ptC[k]:getZ() > ptC[l]:getZ()) + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, EgtIf( bHead, 'HeadSide', 'TailSide')) + if not bOk then + return bOk, sErr + end + end + -- Eventuale segnalazione ingombro di testa o coda + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessStepJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- se due facce + if Proc.Fct == 2 then + local bOk, sErr = MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + return bOk, sErr or sErrC + -- se altrimenti tre facce + elseif Proc.Fct == 3 then + local bOk, sErr = MakeThreeFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + return bOk, sErr or sErrC + -- altrimenti errore + else + local sErr = 'Error : face number not allowed' + EgtOutLog( sErr) + return false, sErr + end +end + +--------------------------------------------------------------------- +return ProcessStepJoint diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessStepJointNotch.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessStepJointNotch.lua new file mode 100644 index 0000000..c2812cd --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessStepJointNotch.lua @@ -0,0 +1,594 @@ +-- ProcessStepJointNotch.lua by Egaltech s.r.l. 2020/06/04 +-- Gestione calcolo tacca a gradino per Travi + +-- Tabella per definizione modulo +local ProcessStepJointNotch = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessStepJointNotch started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessStepJointNotch.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 80) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessStepJointNotch.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- gestisco solo 2 o 4 facce + if nFacetCnt ~= 2 and nFacetCnt ~= 4 and nFacetCnt ~= 6 and nFacetCnt ~= 8 then + return false, false + end + -- verifico le normali delle facce + local bDown = false + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se faccia limite la salto + if AreSameOrOppositeVectorApprox( vtN, Y_AX()) or AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + -- attualmente non gestita +-- return false, false + -- altrimenti faccia principale + elseif vtN:getZ() < -0.1 then + bDown = true + end + end + return true, bDown +end + +--------------------------------------------------------------------- +local function MachineByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Solid, ptC, vtN, nBigInd, nSmaInd, bOnY, ptPs, b3Raw) + + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local k, l = nBigInd, nSmaInd + if ( i % 2) == 1 then + k, l = l, k + end + local nOrthoOpposite + if bOnY then + local bFront = ( ptC[k]:getY() < ptPs:getY()) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + local bOver = true + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + if not bOk then + return bOk, sErr + end + end + return true +end + +--------------------------------------------------------------------- +local function MakePocket( Proc, nPartId, ptPs, vtN, nFaceRef, nDiffWidth, sMchFind, nUseRoughTool, tBHx) + + -- calcolo il elevazione dal punto medio + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[nFaceRef]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + local dCollSic = 2 * BD.COLL_SIC + local sTuuidMstr + -- calcolo il diametro utensile + local dDiamTool + if nUseRoughTool == 1 then + dDiamTool = max( 80, min( tBHx[nFaceRef][1], tBHx[nFaceRef][2])) + else + -- se non uso truciolatore prendo il valore dalle dimensioni minime delle facce + dDiamTool = min( tBHx[nFaceRef][1], tBHx[nFaceRef][2]) + end + local sPocketing = ML.FindPocketing( sMchFind, dDiamTool, dElev + dCollSic) + if not sPocketing then + local sErr = 'Error : pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile + if EgtMdbSetCurrMachining( sPocketing) then + sTuuidMstr = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidMstr) or '') then + dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dDiamTool + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef - 1) + 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( {{ Proc.Id, (nFaceRef-1)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if vtN[nFaceRef]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- La tasca ha sempre almeno un lato aperto, imposto opportuno attacco + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, '', sTuuidMstr +end + +--------------------------------------------------------------------- +local function MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, ptC, vtN, nBigInd, nSmaInd, ptPs, tBHx, b3Raw, nDiffWidth, nUseRoughTool, dAng) + + local sMchFind = 'Pocket' + -- se feature é larga come trave imposto openpocket + if nDiffWidth == 0 then + sMchFind = 'OpenPocket' + -- altrimenti se non è passante disabilito il truciolatore + else + nUseRoughTool = 0 + end + -- applico la svuotatura + local bOk, sErr, sTuuidMstr = MakePocket( Proc, nPartId, ptPs, vtN, nBigInd, nDiffWidth, sMchFind, nUseRoughTool, tBHx) + if not bOk then + return bOk, sErr + end + -- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto + if dAng > -90.1 then + -- se la normale della faccia corta si discosta dalla trave di più di 40° utilizzo la svuotatura altrimenti la contornatura + if abs( vtN[nSmaInd]:getX()) < 0.766 then + -- applico la svuotatura + local bOk, sErr = MakePocket( Proc, nPartId, ptPs, vtN, nSmaInd, nDiffWidth, sMchFind, nUseRoughTool, tBHx) + if not bOk then + return bOk, sErr + end + -- altrimenti contornatura + else + local bOpenStart = false + local bOpenEnd = false + if nDiffWidth == 0 then + bOpenStart = true + bOpenEnd = true + else + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBigInd-1))[1] + for j = 1, #vAdj2 do + if vAdj2[j] == (nSmaInd-1) then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == (nSmaInd-1) do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == (nSmaInd-1) do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + end + end + local sMilling + if nUseRoughTool > 0 then + sMilling = ML.FindMilling( 'Long2Cut', nil, sTuuidMstr) + else + sMilling = ML.FindMilling( 'LongSmallCut', nil, sTuuidMstr) + end + + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 50 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + end + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( tBHx[nBigInd][3]:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, (nSmaInd-1)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- setto inversione del percorso + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- setto a 0 eventuali offset + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + return true +end + +--------------------------------------------------------------------- +-- Lavorazione di due facce +local function MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local tBHx = {} + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- angolo diedro + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + local bConvex + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local rfFac1, dH1, dV1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1, GDB_ID.ROOT) + local nBigInd = EgtIf( dV1 * dH1 >= dV2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + tBHx[1] = {dH1, dV1, rfFac1} + tBHx[2] = {dH2, dV2, rfFac2} + -- verifico parametro Q per stabilire se deve essere lavorato con truciolatore + -- o se larghezza inferiore del trave, utilizzare una svuotatura + local nUseRoughTool = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 + -- se feature non è larga come trave o è selezionato l'utilizzo del truciolatore utilizzo svuotatura + if nDiffWidth > 0 or nUseRoughTool == 1 then + -- se angolo compreso è >= di 90° applico svuotatura con fresa + if not bConvex and dAng >= -90.1 then + local bOk, sErr = MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, ptC, vtN, nBigInd, nSmaInd, ptPs, tBHx, b3Raw, nDiffWidth, nUseRoughTool, dAng) + if not bOk then + return bOk, sErr + end + else + local sErr = 'Error : internal angle less than square angle' + EgtOutLog( sErr) + return false, sErr + end + -- altrimenti provo a lavorare con la lama + else + local bOk, sErr = MachineByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Solid, ptC, vtN, nBigInd, nSmaInd, bOnY, ptPs, b3Raw) + if not bOk then + return bOk, sErr + end + end + return true +end + +--------------------------------------------------------------------- +-- Lavorazione di due facce +local function MakeFourFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + -- Prime due facce + local bOk, sErr = MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + -- Seconde due facce + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- copio la superficie e scambio le facce + local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) + if AddId then + EgtSurfTmSwapFacets( AddId, 0, 2) + EgtSurfTmSwapFacets( AddId, 1, 3) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local NewProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = MakeTwoFaces( NewProc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + end + return true +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- prendo il boundig box della feature + local bBoxExtr = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD ) + local nTypePos = 0 + -- determino se sborda da un lato + if abs( vtExtr:getZ()) < 0.1 then -- se orizzontale + -- se altezza percorso inferiore della larghezza trave + if dWidth < b3Raw:getDimY() - 1 then + nTypePos = 1 + -- verifico se sborda verso y+ + if abs( bBoxExtr:getMax():getY() - b3Raw:getMax():getY()) < 0.1 then + nTypePos = 2 + -- se sborda verso y- + elseif abs( bBoxExtr:getMin():getY() - b3Raw:getMin():getY()) < 0.1 then + nTypePos = 3 + end + end + elseif abs( vtExtr:getZ()) > 0.9 then -- se verticale + -- se altezza percorso inferiore della larghezza trave + if dWidth < b3Raw:getDimZ() - 1 then + nTypePos = 1 + -- verifico se sborda verso z+ + if abs( bBoxExtr:getMax():getZ() - b3Raw:getMax():getZ()) < 0.1 then + nTypePos = 4 + -- se sborda verso z- + elseif abs( bBoxExtr:getMin():getZ() - b3Raw:getMin():getZ()) < 0.1 then + nTypePos = 5 + end + end + else -- altrimenti se altra direzione setto per non fare smussi + nTypePos = 6 + end + + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0 + if dDepth < 0.1 then return true, '', nTypePos end + + -- disabilito smusso se feature non sborda dalla trave almeno da un lato + if nTypePos == 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn , nTypePos + end + -- salto lo smusso se sborda dal lato in Z- o una direzione diversa da Y e Z + if nTypePos >= 5 then + local sWarn = 'Warning : skipped chamfer (wrong side to apply)' + EgtOutLog( sWarn) + return true, sWarn, nTypePos + end + local bExeNormal = true + local bExeOpposite = true + -- controllo le lavorazioni quando la feature è orizzontale + if abs( vtExtr:getY()) > 0.99 then + -- se diretta verso Y+ + if vtExtr:getY() > 0 then + -- se sborda verso Y+ abilito solo la lavorazione della parte normale + if nTypePos == 2 then + bExeOpposite = false + -- se sborda verso Y- abilito solo la lavorazione della parte opposta + elseif nTypePos == 3 then + bExeNormal = false + end + -- altrimenti diretta verso Y- + else + -- se sborda verso Y+ abilito solo la lavorazione della parte opposta + if nTypePos == 2 then + bExeNormal = false + -- se sborda verso Y- abilito solo la lavorazione della parte normale + elseif nTypePos == 3 then + bExeOpposite = false + end + end + -- se diretta verso Z + elseif abs( vtExtr:getZ()) > 0.99 then + -- se diretta verso Z+ + if vtExtr:getZ() > 0 then + -- se sborda verso Z+ abilito solo la lavorazione della parte normale + if nTypePos == 4 or nTypePos == 0 then + bExeOpposite = false + else -- altrimenti disabilito entrambe + bExeNormal = false + bExeOpposite = false + end + -- altrimenti diretta verso Z- + else + -- se sborda verso Z+ abilito solo la lavorazione della parte opposta + if nTypePos == 4 or nTypePos == 0 then + bExeNormal = false + else -- altrimenti disabilito entrambe + bExeNormal = false + bExeOpposite = false + end + end + end + + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + if bExeNormal then + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + if bExeOpposite then + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + return true, '', nTypePos +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessStepJointNotch.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- esecuzione eventuale smusso + -- ottengo anche il flag che indica che la feature è larga come la trave + local bOkc, sErrC, nDiffWidth = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- come fatto nella classify, conto solo le facce che non sono dirette in Y o Z + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + local nUsableFaces = 0 + + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se faccia limite la salto + if AreSameOrOppositeVectorApprox( vtN, Y_AX()) or AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + -- altrimenti faccia principale + else + nUsableFaces = nUsableFaces + 1 + end + end + + -- se due facce + if nUsableFaces == 2 then + local bOk, sErr = MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + -- se quattro facce + elseif nUsableFaces == 4 then + local bOk, sErr = MakeFourFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + -- altrimenti errore + else + local sErr = 'Error : face number not allowed' + EgtOutLog( sErr) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessStepJointNotch diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessTenon.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessTenon.lua new file mode 100644 index 0000000..dc77031 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessTenon.lua @@ -0,0 +1,264 @@ +-- ProcessTenon.lua by Egaltech s.r.l. 2020/07/25 +-- Gestione calcolo tenone per Travi + +-- Tabella per definizione modulo +local ProcessTenon = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTenon started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + + +--------------------------------------------------------------------- +local function VerifyOrientation( Proc, vtN, b3Raw) + -- se trave molto bassa + if b3Raw:getDimZ() <= 120 then + -- se tenone praticamente in asse, accetto fino a -45 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.7072) + -- altrimenti accetto fino a -30deg + else + return ( vtN:getZ() >= -0.51) + end + -- se trave bassa + elseif b3Raw:getDimZ() <= 200 then + -- se tenone praticamente in asse, accetto fino a -30 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.51) + -- altrimenti accetto fino a -20deg + else + return ( vtN:getZ() >= -0.343) + end + -- se trave media + elseif b3Raw:getDimZ() <= 300 then + -- se tenone praticamente in asse, accetto fino a -20 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.343) + -- altrimenti, accetto fino a -10 deg + else + return ( vtN:getZ() >= -0.174) + end + -- altrimenti + else + -- accetto fino a -5deg + return ( vtN:getZ() >= -0.088) + end +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessTenon.Identify( Proc) + return ( (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 50) or + (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 52)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessTenon.Classify( Proc, b3Raw) + -- recupero i dati della curva di contorno della faccia top + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se il tenone è lavorabile solo da sotto + local bDown = not VerifyOrientation( Proc, vtExtr, b3Raw) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessTenon.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') 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') + 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 di contorno della faccia top + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + local bClosed = EgtCurveIsClosed( AuxId) + -- verifico che il tenone non sia orientato troppo verso il basso + if not VerifyOrientation( Proc, vtExtr, b3Raw) then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Tenon from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza del tenone + local frTen = Frame3d( ptBC, vtExtr) + local b3Ten = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frTen) + local dTenH = b3Ten:getDimZ() + -- assegno centro e normale della faccia top + local vtN = vtExtr + local ptC = ptBC + vtN * dTenH + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- determino larghezza massima di svuotatura + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frTen) + local dPockX = max( b3Ten:getMax():getX() - b3Aux:getMax():getX(), b3Aux:getMin():getX() - b3Ten:getMin():getX()) + local dPockY = max( b3Ten:getMax():getY() - b3Aux:getMax():getY(), b3Aux:getMin():getY() - b3Ten:getMin():getY()) + local dPockL = max( dPockX, dPockY) + -- porto inizio curva il più possibile sul bordo + BL.PutStartNearestToEdge( AuxId, b3Solid) + -- se vero tenone inclinato o non esattamente alle estremità, necessario taglio di lama sulla testa + if Proc.Prc ~= 52 and + ( not AreSameOrOppositeVectorApprox( vtN, X_AX()) or + ( Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dOvmHead - 100 * GEO.EPS_SMALL and + Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 100 * GEO.EPS_SMALL)) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla testa del tenone e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC, vtN, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- se pezzo piccolo, in coda e piano inclinato attorno a Z applico svuotatura + if b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getX() < 0 and abs( vtExtr:getY()) > 0.173 then + local sPocketing = ML.FindPocketing( 'OpenPocket') + -- 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( {{ AddId, -1}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + local nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- altrimenti applico taglio di lama + else + local b3Cut = EgtGetBBoxGlob( AddId or GDB_ID.NULL, GDB_BB.STANDARD) + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Cut, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getZ() > 0.25) + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0, bFromBottom) + if not bOk then return bOk, sErr end + end + end + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Tenon', dTenH) or ML.FindMilling( 'Tenon') + 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 dMillDiam = 20 + local dMaxDepth = 0 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + local dDepth = 0 + if dTenH > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in tenon : elevation (' .. EgtNumToString( dTenH, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth - dTenH + dTenH = dMaxDepth + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + -- determino il numero di passate concentriche (max 5) + local MAX_PASS = 5 + local nPass = min( ceil( dPockL / ( 0.7 * dMillDiam)), MAX_PASS) + local dStep = min( dPockL, 0.7 * dMillDiam * MAX_PASS) / nPass + for i = nPass, 1, -1 do + -- inserisco la passata finale della lavorazione + local sNameF = 'TenF_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo i parametri + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dTenH - 100 * GEO.EPS_SMALL, 1) .. ';') + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + local dOffset = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- se contorno aperto, cambio parametri di attacco/uscita + if not bClosed then + EgtSetMachiningParam( MCH_MP.LITANG, 0.7 * dMillDiam) + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, 0.7 * dMillDiam) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if abs( vtExtr:getY()) > 0.088 then + nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if abs( vtN:getY()) > 0.1 or ( b3Raw:getDimZ() - Proc.Box:getDimZ()) < BD.MIN_HEIGHT then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessTenon diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessText.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessText.lua new file mode 100644 index 0000000..eac4f34 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessText.lua @@ -0,0 +1,86 @@ +-- ProcessText.lua by Egaltech s.r.l. 2018/04/17 +-- Gestione calcolo testi per Travi + +-- Tabella per definizione modulo +local ProcessText = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessText started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessText.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 61) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessText.Classify( Proc) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + return false + end + -- verifico se il testo è lavorabile solo da sotto + local bDown = (( vtN:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessText.Make( Proc, nPhase, nRawId, nPartId) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Text with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che il testo non sia orientato verso il basso (-5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Text from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Text') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Text_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -1}}) + -- imposto posizione braccio porta testa + if vtN:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessText diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessTyroleanDovetail.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessTyroleanDovetail.lua new file mode 100644 index 0000000..a5cead2 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/LuaLibs/ProcessTyroleanDovetail.lua @@ -0,0 +1,711 @@ +-- ProcessTyroleanDovetail.lua by Egaltech s.r.l. 2020/08/03 +-- Gestione calcolo giunzione tirolese + +-- Tabella per definizione modulo +local ProcessTyroleanDovetail = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTyroleanDovetail started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sDepthChamferMill = '' -- d + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessTyroleanDovetail.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 136) +end + +--------------------------------------------------------------------- +local function AssignQValues( Proc) + + -- reset delle variabili assegnazione parametri Q + sDepthChamferMill = '' + + if Proc.Prc == 136 then + sDepthChamferMill = 'Q01' -- d + end +end + +--------------------------------------------------------------------- +local function TestElleShape3( Proc) + -- valida solo nel caso di tre facce + if Proc.Fct ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessTyroleanDovetail.Classify( Proc, b3Raw) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + local nFlatFaceNeg + local bDown = false + -- individuo se c'è faccia rastremata verso Z- + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < -1 + GEO.EPS_SMALL then + nFlatFaceNeg = i-1 + break + end + end + -- se trovata faccia rastremata rivolta verso Z- + -- verifico se lunghezza faccia piatta è compatibile con il taglio di lama + if nFlatFaceNeg then + -- se ho 3 facce sicuramente è gruppo 3 o 4, setto il ribaltamento senza ulteriori controlli + if nFacetCnt == 3 then + bDown = true + -- altrimenti faccio controllo di lavorabilità da sotto e setto eventuale ribaltamento + -- ( può essere gruppi 1 o 2, oppure gruppo 3 o 4 ma spostati verso le teste) + else + -- prendo le dimensioni della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFlatFaceNeg, GDB_ID.ROOT) + local nOtherFace = EgtIf( nFlatFaceNeg == 0, nFlatFaceNeg + 1, nFlatFaceNeg - 1) + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT) + local dDist = dist( ptP1, ptP2) + local dLargeface + local dDelta = 100000 + local dDeltadH = abs( dDist - dH) + local dDeltadV = abs( dDist - dV) + -- prendo la dimensione diversa dalla lunghezza di adiacenza + if dDeltadH < dDeltadV then + dLargeface = dV + else + dLargeface = dH + end + -- se lunghezza faccia maggiore di taglio lama da sotto setto il ribaltamento + if dLargeface > BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then + bDown = true + end + -- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama setto il ribaltamento + if dAng < 0 and dAng > -90 + 5 * GEO.EPS_SMALL then + bDown = true + end + end + -- altrimenti controllo la componente in Z delle facce + else + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- altrimenti se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + -- considerazioni: al momento non è possibile sapere se ci sono due rastremature o una quindi se è rivolta verso il basso + -- viene dato errore, altrimenti si potrebbe imporre la rotazione di 180 (ovviamente con una sola rastrematura rivolta verso il basso) + if abs(vtN:getZ()) > abs(vtN:getX()) and abs(vtN:getZ()) > abs(vtN:getY()) and vtN:getZ() < -0.5 then + return false + end + end + end + return true, bDown +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc, sDephtCham) + local nChamfer = 0 + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + + return nChamfer, dDepth +end + +--------------------------------------------------------------------- +local function MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- recupero la geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- ordino le facce (1=faccia ausiliaria, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + local dMinZedFace = 1 + for i = 1, nFacetCnt do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinZedFace then + dMinZedFace = dXVal + vFaceOrd[3] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + if AuxId then + local vtNx = EgtSurfTmFacetNormVersor( AuxId, 0, GDB_ID.ROOT) + bHead = ( vtNx:getX() > 0) + end + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato + local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), 'b') + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + else + dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + end + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < (#vCuts-1) or (i == #vCuts) then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head and AuxId then + local dHCI = 00 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + -- altrimenti di fianco + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail and AuxId then + local dTCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + -- altrimenti di fianco + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +local function MakeMillCut( Proc, i, j, k, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep) + local sWarn = '' + -- inserisco la lavorazione di fresatura + -- per evitare nomi lavorazioni coincidenti, concateno anche il Proc.Id se il nome (del Proc.Id) è presente + local s2ndName = EgtGetName( Proc.Id) or '' + local sName = 'MillTCone_' .. ( EgtIf( #s2ndName > 0, s2ndName, tostring( Proc.Id))) .. ( EgtIf( #s2ndName > 0, '_' .. tostring( Proc.Id), '')) .. '_' .. tostring(i) .. '_' .. tostring(j) + local kStep = k or 0 + if kStep > 0 then + sName = sName .. '_' .. tostring(k) + end + 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( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( TabNAD[j][1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + if kStep % 2 == 1 then + -- imposto lato destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, 2) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + -- imposto lato sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + -- tolgo inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + -- imposto affondamento in base al passo del ciclo + EgtSetMachiningParam( MCH_MP.DEPTH, dOffs) + --imposto passo 0 + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto offset radiale in base all'angolo tra le due facce e alla posizione in Z + il passo laterale + dOffrRad = dOffrRad + dAddOffsRad + -- per le passate intermedie aggiungo un delta sull'offset radiale perchè c'è già il taglio di lama precedente + EgtSetMachiningParam( MCH_MP.OFFSR, dOffrRad + EgtIf( ( i < nStep) and ( kStep < 1), 0.5, 0)) + -- imposto offset longotudinale a 0 + EgtSetMachiningParam( MCH_MP.OFFSL, 0) + -- imposto gli attacchi + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( dToolDiam * 0.75)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( dToolDiam * 0.75)) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill solo in ultima passata in Z locale + local sUserNotes + if i < nStep then + sUserNotes = 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + else + sUserNotes = 'VMRS=0;' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + _, sWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + + local sWarn = '' + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- recupero l'angolo di spoglia dell'utensile a tronco di cono + -- recupero la lavorazione + local sMchFind = 'ProfTCone' + local sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on TyroleanDovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 100 + local dMaxMat = 50 + local dSideAngle = 0 + local dStepmach = 0 + local bUCutMax + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + -- ottengo il passo della lavorazione + dStepmach = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) + end + end + if dStepmach <= 0.1 then + dStepmach = dMaxMat * 0.5 + end + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, sin(dSideAngle)) + if not nFacInd or nFacInd < 0 then + -- provo eliminando i sottosquadra + nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, -2) + if not nFacInd or nFacInd < 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MakeMachByMill could not find reference face' + EgtOutLog( sErr) + return false, sErr + else + bUCutMax = true + end + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham = EvaluateQParam( Proc, sDepthChamferMill) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se U + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) + -- verifico se due facce o L con una o due facce di terminazione + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc)) + -- faccio tagli di lama come antischeggia sulle altre 2 facce + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN:getY(), vtN:getZ()) + vtRef:normalize() + local TabNAD = {} + -- ciclo inserimento tagli antischeggia sulle facce + for i = 1, nFacetCnt do + if (i-1) ~= nFacInd then + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, (i-1), GDB_ID.ROOT) + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) + if dAng then + TabNAD[i] = { vtN2, dAng, dist( ptP1, ptP2)} + end + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + else + dTrim = ((dToolThick* vtN) * vtN2 * vtN2):len() + end + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, (i-1), sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + 1), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- creo percorsi di lavorazione +-- local nCountSkipStep = 0 +-- local nMaxSkippedStep = 0 + local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dStepmach) + local dStep = dFacElev / nStep + local dLargeVal + local nLenSideMax + for i = 1, nStep do + local dOffs = ( i * dStep) - dFacElev + if i == nStep then dOffs = 0 end + local dOffsSide = 0 + local dDelta = 100000 + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + local dParzElev = dOffs + -- calcolo la larghezza (solo 1 volta) + if i == 1 then + -- se ho un sottosquadra maggiore dell'angolo di spoglia utensile + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dParzElev = dFacElev + end + local dDeltadH = abs( TabNAD[j][3] - dH) + local dDeltadV = abs( TabNAD[j][3] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta + 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + nLenSideMax = j + end + else + if dDeltadV < dDelta + 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + nLenSideMax = j + end + end + end + -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) + dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) + end + end + -- se la larghezza è più grande dell'utensile allora posso lavorare il passo + if ( dLargeVal - dOffsSide) >= dToolDiam then + -- resetto il contatore skip +-- nCountSkipStep = 0 + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + -- calcolo l'offset radiale in base all'affondamento + local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dOffrRad = -( tan( 90 + TabNAD[j][2]) * dFacElev) + end + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, 0, nStep, dToolDiam, dStep) + if not bOk then + return false, sErr + else + sWarn = sErr + end + -- se lato lavorato è il più lungo e la larghezza cava consente passi interni + if j == nLenSideMax and ( dLargeVal - dOffsSide) > 2*dToolDiam then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) + local dStepSide = ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) / nStepSide + for k = 1, nStepSide do + local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep) + if not bOk then + return false, sErr + else + sWarn = sErr + end + end + end + end + end + -- altrimenti passo saltato esco con errore + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' + EgtOutLog( sErr) + return false, sErr + end + end + + -- se ho saltato più di un passo invalido le lavorazioni +-- if nMaxSkippedStep >= 2 or ( nStep >= nMaxSkippedStep and nMaxSkippedStep >= 1) then +-- local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' +-- EgtOutLog( sErr) +-- return false, sErr +-- end + + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessTyroleanDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- se ho due facce allora è di testa + if nFacetCnt == 2 then + local bOk, sErr = MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + if not bOk then return bOk, sErr end + else + local bOk, sErr = MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + if not bOk then return bOk, sErr end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dTCI) + end + + return true +end + +--------------------------------------------------------------------- +return ProcessTyroleanDovetail diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/Process.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/Process.lua new file mode 100644 index 0000000..7c804c7 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/Process.lua @@ -0,0 +1,258 @@ +-- Process.lua by Egaltech s.r.l. 2020/01/08 +-- Gestione calcolo disposizione e lavorazioni per Travi +-- Si opera sulla macchina corrente +-- 2020/01/08 Aggiunta seconda sezione limite (BD.MAX_WIDTH2 x BD.MAX_HEIGHT2). + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not sMachDir then + EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Travi', 'ERROR') + return +end +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + EgtOutBox( 'La macchina corrente non è configurata per lavorare travi', 'Lavora Travi', 'ERROR') + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Segnalazione avvio +EgtOutLog( '*** Beam Process Start ***', 1) + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Variabili di modulo +local vBeam = {} +local dRawW +local dRawH + +------------------------------------------------------------------------------------------------------------- +-- *** Recupero le travi selezionate *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessInputData() + + -- Recupero le travi selezionate + local nId = EgtGetFirstSelectedObj() + while nId do + local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) + if nPartId then + local bFound = false + for i = 1, #vBeam do + if vBeam[i].Id == nPartId then + bFound = true + break + end + end + if not bFound then + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + end + nId = EgtGetNextSelectedObj() + end + if #vBeam == 0 then + EgtOutBox( 'Non sono state selezionate travi', 'Lavora Travi', 'ERROR') + return false + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi selezionate : ' .. sOut, 1) + end + + -- Ne recupero e verifico le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + EgtOutBox( 'Box non definito per la trave ' .. vBeam[i].Name, 'Lavora Travi', 'ERROR') + return false + else + vBeam[i].Box = b3Solid + end + end + dRawW = vBeam[1].Box:getDimY() + dRawH = vBeam[1].Box:getDimZ() + local vBeamErr = {} + for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end + end + if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + EgtDeselectPartObjs( vBeam[vBeamErr[i]].Id) + table.remove( vBeam, vBeamErr[i]) + end + EgtOutLog( sOut, 1) + EgtOutBox( sOut, 'Lavora Travi', 'INFO') + EgtDraw() + return false + end + EgtDeselectAll() + + -- Le ordino in senso di lunghezza crescente + table.sort( vBeam, function( B1, B2) return B1.Box:getDimX() < B2.Box:getDimX() end) + do + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi ordinate : ' .. sOut, 1) + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle travi nel grezzo *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessBeams() + + -- Determinazione minimo grezzo scaricabile + BE.CalcMinUnloadableRaw( dRawW, dRawH) + + -- Lunghezza totale delle travi + local dTotLen = 0 + for i = 1, #vBeam - 1 do + dTotLen = dTotLen + vBeam[i].Box:getDimX() + end + dTotLen = dTotLen + max( vBeam[#vBeam].Box:getDimX(), BD.MinRaw) + local dAddLen = BD.OVM_HEAD + ( #vBeam - 1) * BD.OVM_MID + EgtOutLog( 'Ltot : ' .. EgtNumToString( dTotLen, 1) .. ' Lagg : '.. EgtNumToString( dAddLen, 1), 1) + + -- Richiedo lunghezza del grezzo e sovramateriale di testa + local vsVal = EgtDialogBox( 'Lavora Travi' .. ' (Ltot='.. EgtNumToString( dTotLen + dAddLen + 0.5, 0) .. ', Lmax=' .. EgtNumToString( BD.MAX_RAW, 0) .. ')', + {'Lunghezza grezzo', EgtNumToString( BD.STD_RAW, 0)}, + {'Sovramateriale di testa', EgtNumToString( BD.OVM_HEAD, 0)}, + {'Forza sezione verticale', ' CB:true,*false'}) + if not vsVal then + EgtDraw() + return + end + local dRawL = EgtEvalNumExpr( vsVal[1]) + if not dRawL then + local sOut = 'Lunghezza grezzo errata : ' .. vsVal[1] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + dRawL = min( dRawL, BD.MAX_RAW) + local dOvmHead = EgtEvalNumExpr( vsVal[2]) + if not dOvmHead then + local sOut = 'Sovramateriale di testa errato : ' .. vsVal[2] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo sezione barra con travi + local bVert = ( vsVal[3] == 'true') + if bVert then + if dRawW > dRawH then dRawW, dRawH = dRawH, dRawW end + end + EgtOutLog( 'Lraw : ' .. EgtNumToString( dRawL, 1) .. ' Lovm : '.. EgtNumToString( dOvmHead, 1), 1) + + -- Verifico sezione barra non troppo grande + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) and + ( dRawW > BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' .. + 'e (' .. EgtNumToString( BD.MAX_WIDTH2, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT2, 2) .. ')' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Verifico sezione barra non troppo piccola + if dRawW < BD.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < BD.MIN_HEIGHT - 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'sotto i limiti della macchina (' .. EgtNumToString( BD.MIN_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MIN_HEIGHT, 2) .. ')' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo le travi nel grezzo + local bOk, sErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) + if not bOk then + EgtOutLog( sErr) + EgtOutBox( sErr, 'Lavora Travi', 'ERROR') + EgtDraw() + return false + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessFeatures() + + local bOk, Stats = BE.ProcessFeatures() + local nErrCnt = 0 + local nWarnCnt = 0 + local sOutput = '' + for i = 1, #Stats do + if Stats[i].Err > 0 then + nErrCnt = nErrCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + elseif Stats[i].Err < 0 then + nWarnCnt = nWarnCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + end + end + if #sOutput > 0 then EgtOutLog( sOutput) end + if nErrCnt > 0 then + EgtOutBox( sOutput, 'Lavora Travi', 'ERRORS') + EgtDraw() + return false + elseif nWarnCnt > 0 then + EgtOutBox( sOutput, 'Lavora Travi', 'WARNINGS') + EgtDraw() + return true + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Esecuzione *** +------------------------------------------------------------------------------------------------------------- +if not MyProcessInputData() then return end + +if not MyProcessBeams() then return end + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +if not MyProcessFeatures() then return end diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/Rotate.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/Rotate.lua new file mode 100644 index 0000000..c7a6c9b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/Rotate.lua @@ -0,0 +1,32 @@ +-- Rotate.lua by Egaltech s.r.l. 2017/11/04 +-- Gestione rotazione di una Trave + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Rotate Trave', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la trave ' .. sName, 'Rotate Trave', 'ERROR') + return +end + +-- eseguo rotazione di 90 gradi attorno asse X +local ptRot = b3Solid:getMin() + Vector3d( 0, b3Solid:getDimZ() / 2, b3Solid:getDimZ() / 2) +EgtRotate( nPartId, ptRot, X_AX(), 90, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/Stato_lavori.xlsx b/ProgramData/EgtCAM5/Beam 2020.08.14/Stato_lavori.xlsx new file mode 100644 index 0000000..4f8e29e Binary files /dev/null and b/ProgramData/EgtCAM5/Beam 2020.08.14/Stato_lavori.xlsx differ diff --git a/ProgramData/EgtCAM5/Beam 2020.08.14/Swap.lua b/ProgramData/EgtCAM5/Beam 2020.08.14/Swap.lua new file mode 100644 index 0000000..c5d74a3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam 2020.08.14/Swap.lua @@ -0,0 +1,31 @@ +-- Swap.lua by Egaltech s.r.l. 2017/11/02 +-- Gestione scambio testa coda di una Trave + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Swap Trave', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la trave ' .. sName, 'Swap Trave', 'ERROR') + return +end + +-- eseguo rotazione di 180 gradi attorno asse Z +EgtRotate( nPartId, b3Solid:getCenter(), Z_AX(), 180, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/BatchProcess cbxT5.lua b/ProgramData/EgtCAM5/Beam con BpxT5/BatchProcess cbxT5.lua new file mode 100644 index 0000000..fb55753 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/BatchProcess cbxT5.lua @@ -0,0 +1,387 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2019/08/29 +-- Gestione calcolo batch disposizione e lavorazioni per Travi +-- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. +-- 2019/07/16 Aggiunta gestione modalità oltre 10 per impostazione macchina e uscita. +-- 2019/07/19 Aggiunta gestione collisioni. +-- 2019/07/24 Aggiunta gestione extra-corse. +-- 2019/08/29 Aggiunta possibilità di processare file NGE. + +-- CB +-- 2019/09 aggiunto passaggio lunghezze (solo per prove) e modifica a messaggi di errore + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--BEAM = {} +--BEAM.FILE = 'c:\\EgtData\\Varie\\TestEssetreFast\\TestFabio\\Accettazione.btl' +--BEAM.MACHINE = 'FAST' +--BEAM.FLAG = 3 +-- inizializzo errore in esecuzione features +BEAM.ERRFeature = '' +-- Flag abilitazione controllo collisione +local bVerifyCollision = true + +-- Log dati di generazione +local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. BEAM.MACHINE .. ', ' .. tostring( BEAM.FLAG) +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( BEAM.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 ( BEAM.FLAG == 1 or BEAM.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 errore +local function PostWarnView( nWarn, sMsg) + if nWarn ~= 0 and ( BEAM.FLAG == 1 or BEAM.FLAG == 2) then + EgtSetView( SCE_VD.ISO_SW, false) + EgtZoom( SCE_ZM.ALL) + EgtOutBox( sMsg, 'BatchProcess (wrn=' .. tostring( nWarn) .. ')', 'WARNINGS') + end +end + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Impostazione della macchina corrente +EgtResetCurrMachGroup() +local sMachine = 'Essetre-' .. BEAM.MACHINE +if not EgtSetCurrMachine( sMachine) then + BEAM.ERR = 11 + BEAM.MSG = 'Error selecting machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + BEAM.ERR = 12 + BEAM.MSG = 'Error not configured for beams machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Se modalità visualizzazione finestre per DB esco +if BEAM.FLAG > 10 then + BEAM.ERR = 0 + return +end + +-- Segnalazione avvio +EgtOutLog( '*** Beam BatchProcess Start ***', 1) + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Verifico il tipo di file +local _, _, sExt = EgtSplitPath( BEAM.FILE) +local bBtl = ( string.upper( sExt or '') ~= '.NGE') + +-- Se Btl, lo importo +if bBtl then +EgtNewFile() + + EgtSetDefaultMaterial( BLACK()) -- +++++++++++++++++++++++++++++ + +if not EgtImportBtl( BEAM.FILE, EIB_FL.TS3_POS) then + BEAM.ERR = 13 + BEAM.MSG = 'Error importing BTL file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end +-- altrimenti apro Nge +else + if not EgtOpenFile( BEAM.FILE) then + BEAM.ERR = 13 + BEAM.MSG = 'Error opening NGE file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + -- faccio copia del file originale + local sDir, sTitle, sExt = EgtSplitPath( BEAM.FILE) + EgtCopyFile( BEAM.FILE, sDir..sTitle..'.ori'..sExt) +end + +-- Recupero l'elenco ordinato delle travi +local vBeam = {} +local nPartId = EgtGetFirstPart() +while nPartId do + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + nPartId = EgtGetNextPart( nPartId) +end +if #vBeam == 0 then + BEAM.ERR = 14 + BEAM.MSG = 'Error no beams in the file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) +end + +-- Ne recupero le dimensioni +for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + BEAM.ERR = 15 + BEAM.MSG = 'Box undefined for beam ' .. vBeam[i].Name + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + vBeam[i].Box = b3Solid + end +end + +-- Ne recupero la posizione +for i = 1, #vBeam do + local PosX = EgtGetInfo( vBeam[i].Id, 'POSX', 'd') + vBeam[i].PosX = PosX +end + +-- Eseguo eventuali rotazioni e inversioni testa-coda +for i = 1, #vBeam do + local b3Solid = vBeam[i].Box + -- rotazione + local dRotAng = EgtGetInfo( vBeam[i].Id, 'ROTATED', 'd') + if dRotAng and abs( dRotAng) > GEO.EPS_ANG_SMALL then + local ptRotCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptRotCen, X_AX(), dRotAng, GDB_RT.GLOB) + b3Solid:rotate( ptRotCen, X_AX(), dRotAng) + end + -- inversione + local dInvAng = 180 - ( EgtGetInfo( vBeam[i].Id, 'INVERTED', 'd') or 0) + if abs( dInvAng) > GEO.EPS_ANG_SMALL then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptInvCen, Z_AX(), dInvAng, GDB_RT.GLOB) + end +end + +-- Ne verifico le dimensioni +local dRawW = vBeam[1].Box:getDimY() +local dRawH = vBeam[1].Box:getDimZ() +local vBeamErr = {} +for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end +end +if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + table.remove( vBeam, vBeamErr[i]) + end + BEAM.ERR = 16 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Verifico sezione barra +if dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Lunghezza della barra +local dRawL = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'BARLEN', 'd') + or BEAM.TESTLEN or 12000 +-- Sovramateriale di testa +local dOvmHead = vBeam[1].PosX or 10 + +-- Sistemo le travi nel grezzo +local bPbOk, sPbErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) +if not bPbOk then + BEAM.ERR = 18 + BEAM.MSG = sPbErr + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Imposto Nome file CN +local _, sName, _ = EgtSplitPath( BEAM.FILE) +EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +-- Lavoro le features +local bPfOk, Stats = BE.ProcessFeatures() +local nErrCnt = 0 +local nWarnCnt = 0 +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 + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = 19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + BEAM.ERRFeature = BEAM.ERRFeature..sMsg + elseif Stats[i].Err < 0 then + nWarnCnt = nWarnCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, sMsg) + BEAM.ERR = -19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + end +end + +-- Salvo il progetto +local sNgeFile = EgtChangePathExtension( BEAM.FILE, '.nge') +EgtSaveFile( sNgeFile) + +-- Visualizzazione avvisi o errori +if #sOutput > 0 then EgtOutLog( sOutput) end +if nErrCnt > 0 then + PostErrView( 19, sOutput) + return +elseif nWarnCnt > 0 then + PostWarnView( 19, sOutput) +end + +-- Genero programma CN, se richiesto +if BEAM.FLAG == 0 then + if not EgtGenerate( '', 'EgtCAM5 - ' .. sNgeFile) then + BEAM.ERR = 20 + BEAM.MSG = 'Error generating NC part program : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end +end + +-- Eseguo stima tempi +if not EgtEstimate( '', 'EgtCAM5 - ' .. sNgeFile) then + BEAM.ERR = 21 + BEAM.MSG = 'Error estimating production time : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end +local Ttot = EgtGetInfo( EgtGetCurrMachGroup(), 'Ttot') +local sTime = 'Total Time = ' .. EgtNumToString( Ttot, 1) +EgtOutLog( sTime) + +-- Se verifica, eseguo simulazione in cieco +if BEAM.FLAG == 3 and bVerifyCollision then + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.COLLISION then + BEAM.ERR = 22 + BEAM.MSG = 'Head-part collision' + elseif nErr == MCH_SHE.OUTSTROKE then + BEAM.ERR = 23 + BEAM.MSG = 'Axis outstroke ' .. sErr + elseif nErr == MCH_SHE.SPECIAL then + BEAM.ERR = 24 + BEAM.MSG = 'Charriot error ' .. sErr + else + BEAM.ERR = 25 + BEAM.MSG = 'General failure (contact supplier)' + end + BEAM.ROT = 0 + BEAM.CUTID = 0 + BEAM.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 + BEAM.CUTID = EgtGetVal( vItem[i], 'CUTID', 'i') or 0 + elseif string.find( vItem[i], 'TASKID', 1, true) then + BEAM.TASKID = EgtGetVal( vItem[i], 'TASKID', 'i') or 0 + end + end + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + return + end +end + +-- Imposto la vista ISO 3d, se richiesto +if BEAM.FLAG == 1 or BEAM.FLAG == 2 then + EgtSetView( SCE_VD.ISO_SW, false) +end + +-- Completamento senza errori e avvisi +if nWarnCnt == 0 then + BEAM.ERR = 0 + BEAM.MSG = '---' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) +end + +-- Scrittura tempo totale stimato di lavorazione +WriteTimeToLogFile( Ttot) diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/BatchProcess.lua b/ProgramData/EgtCAM5/Beam con BpxT5/BatchProcess.lua new file mode 100644 index 0000000..692a294 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/BatchProcess.lua @@ -0,0 +1,381 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2019/08/29 +-- Gestione calcolo batch disposizione e lavorazioni per Travi +-- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. +-- 2019/07/16 Aggiunta gestione modalità oltre 10 per impostazione macchina e uscita. +-- 2019/07/19 Aggiunta gestione collisioni. +-- 2019/07/24 Aggiunta gestione extra-corse. +-- 2019/08/29 Aggiunta possibilità di processare file NGE. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--BEAM = {} +--BEAM.FILE = 'c:\\EgtData\\Varie\\TestEssetreFast\\Xxx\\2-Banchina smussata.nge' +--BEAM.MACHINE = 'FAST' +--BEAM.FLAG = 3 + +-- Flag abilitazione controllo collisione +local bVerifyCollision = true + +-- Log dati di generazione +local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. BEAM.MACHINE .. ', ' .. tostring( BEAM.FLAG) +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( BEAM.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 ( BEAM.FLAG == 1 or BEAM.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 errore +local function PostWarnView( nWarn, sMsg) + if nWarn ~= 0 and ( BEAM.FLAG == 1 or BEAM.FLAG == 2) then + EgtSetView( SCE_VD.ISO_SW, false) + EgtZoom( SCE_ZM.ALL) + EgtOutBox( sMsg, 'BatchProcess (wrn=' .. tostring( nWarn) .. ')', 'WARNINGS') + end +end + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Impostazione della macchina corrente +EgtResetCurrMachGroup() +local sMachine = 'Essetre-' .. BEAM.MACHINE +if not EgtSetCurrMachine( sMachine) then + BEAM.ERR = 11 + BEAM.MSG = 'Error selecting machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + BEAM.ERR = 12 + BEAM.MSG = 'Error not configured for beams machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Se modalità visualizzazione finestre per DB esco +if BEAM.FLAG > 10 then + BEAM.ERR = 0 + return +end + +-- Segnalazione avvio +EgtOutLog( '*** Beam BatchProcess Start ***', 1) + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Verifico il tipo di file +local _, _, sExt = EgtSplitPath( BEAM.FILE) +local bBtl = ( string.upper( sExt or '') ~= '.NGE') + +-- Se Btl, lo importo +if bBtl then + EgtNewFile() + + EgtSetDefaultMaterial( BLACK()) -- +++++++++++++++++++++++++++++ + + if not EgtImportBtl( BEAM.FILE, EIB_FL.TS3_POS) then + BEAM.ERR = 13 + BEAM.MSG = 'Error importing BTL file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end +-- altrimenti apro Nge +else + if not EgtOpenFile( BEAM.FILE) then + BEAM.ERR = 13 + BEAM.MSG = 'Error opening NGE file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + -- faccio copia del file originale + local sDir, sTitle, sExt = EgtSplitPath( BEAM.FILE) + EgtCopyFile( BEAM.FILE, sDir..sTitle..'.ori'..sExt) +end + +-- Recupero l'elenco ordinato delle travi +local vBeam = {} +local nPartId = EgtGetFirstPart() +while nPartId do + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + nPartId = EgtGetNextPart( nPartId) +end +if #vBeam == 0 then + BEAM.ERR = 14 + BEAM.MSG = 'Error no beams in the file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) +end + +-- Ne recupero le dimensioni +for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + BEAM.ERR = 15 + BEAM.MSG = 'Box undefined for beam ' .. vBeam[i].Name + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + vBeam[i].Box = b3Solid + end +end + +-- Ne recupero la posizione +for i = 1, #vBeam do + local PosX = EgtGetInfo( vBeam[i].Id, 'POSX', 'd') + vBeam[i].PosX = PosX +end + +-- Eseguo eventuali rotazioni e inversioni testa-coda +for i = 1, #vBeam do + local b3Solid = vBeam[i].Box + -- rotazione + local dRotAng = EgtGetInfo( vBeam[i].Id, 'ROTATED', 'd') + if dRotAng and abs( dRotAng) > GEO.EPS_ANG_SMALL then + local ptRotCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptRotCen, X_AX(), dRotAng, GDB_RT.GLOB) + b3Solid:rotate( ptRotCen, X_AX(), dRotAng) + end + -- inversione + local dInvAng = 180 - ( EgtGetInfo( vBeam[i].Id, 'INVERTED', 'd') or 0) + if abs( dInvAng) > GEO.EPS_ANG_SMALL then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptInvCen, Z_AX(), dInvAng, GDB_RT.GLOB) + end +end + +-- Ne verifico le dimensioni +local dRawW = vBeam[1].Box:getDimY() +local dRawH = vBeam[1].Box:getDimZ() +local vBeamErr = {} +for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end +end +if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + table.remove( vBeam, vBeamErr[i]) + end + BEAM.ERR = 16 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Verifico sezione barra +if dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Lunghezza della barra +local dRawL = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'BARLEN', 'd') or 12000 +-- Sovramateriale di testa +local dOvmHead = vBeam[1].PosX or 10 + +-- Sistemo le travi nel grezzo +local bPbOk, sPbErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) +if not bPbOk then + BEAM.ERR = 18 + BEAM.MSG = sPbErr + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Imposto Nome file CN +local _, sName, _ = EgtSplitPath( BEAM.FILE) +EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +-- Lavoro le features +local bPfOk, Stats = BE.ProcessFeatures() +local nErrCnt = 0 +local nWarnCnt = 0 +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 + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = 19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = -19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + end +end + +-- Salvo il progetto +local sNgeFile = EgtChangePathExtension( BEAM.FILE, '.nge') +EgtSaveFile( sNgeFile) + +-- Visualizzazione avvisi o errori +if #sOutput > 0 then EgtOutLog( sOutput) end +if nErrCnt > 0 then + PostErrView( 19, sOutput) + return +elseif nWarnCnt > 0 then + PostWarnView( 19, sOutput) +end + +-- Genero programma CN, se richiesto +if BEAM.FLAG == 0 then + if not EgtGenerate( '', 'EgtCAM5 - ' .. sNgeFile) then + BEAM.ERR = 20 + BEAM.MSG = 'Error generating NC part program : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end +end + +-- Eseguo stima tempi +if not EgtEstimate( '', 'EgtCAM5 - ' .. sNgeFile) then + BEAM.ERR = 21 + BEAM.MSG = 'Error estimating production time : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end +local Ttot = EgtGetInfo( EgtGetCurrMachGroup(), 'Ttot') +local sTime = 'Total Time = ' .. EgtNumToString( Ttot, 1) +EgtOutLog( sTime) + +-- Se verifica, eseguo simulazione in cieco +if BEAM.FLAG == 3 and bVerifyCollision then + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.COLLISION then + BEAM.ERR = 22 + BEAM.MSG = 'Head-part collision' + elseif nErr == MCH_SHE.OUTSTROKE then + BEAM.ERR = 23 + BEAM.MSG = 'Axis outstroke ' .. sErr + elseif nErr == MCH_SHE.SPECIAL then + BEAM.ERR = 24 + BEAM.MSG = 'Charriot error ' .. sErr + else + BEAM.ERR = 25 + BEAM.MSG = 'General failure (contact supplier)' + end + BEAM.ROT = 0 + BEAM.CUTID = 0 + BEAM.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 + BEAM.CUTID = EgtGetVal( vItem[i], 'CUTID', 'i') or 0 + elseif string.find( vItem[i], 'TASKID', 1, true) then + BEAM.TASKID = EgtGetVal( vItem[i], 'TASKID', 'i') or 0 + end + end + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + return + end +end + +-- Imposto la vista ISO 3d, se richiesto +if BEAM.FLAG == 1 or BEAM.FLAG == 2 then + EgtSetView( SCE_VD.ISO_SW, false) +end + +-- Completamento senza errori e avvisi +if nWarnCnt == 0 then + BEAM.ERR = 0 + BEAM.MSG = '---' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) +end + +-- Scrittura tempo totale stimato di lavorazione +WriteTimeToLogFile( Ttot) diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Beam.ini b/ProgramData/EgtCAM5/Beam con BpxT5/Beam.ini new file mode 100644 index 0000000..7340e64 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/Beam.ini @@ -0,0 +1,14 @@ +[Beam] +BtlEnable=1 +BaseDir=C:\EgtData\Beam +BtlExec=BatchProcess.lua +Button1=Process.lua,Images\Process.png,Lavora Travi +Button2=ClearProcess.lua,Images\ClearProcess.png,Cancella Lavorazione Trave +Button3=Swap.lua,Images\Swap.png,Scambia estremi trave +Button4=Rotate.lua,Images\Rotate.png,Ruota trave +Button5=DisableFeatures.lua,Images\DisableFeatures.png,Disabilita lavorazioni +Button6=EnableFeatures.lua,Images\EnableFeatures.png,Abilita lavorazioni +Button7=BeamMachinings,Images\BeamMachinings.png,Lista lavorazioni +Button8=HideAll.lua,Images\HideAll.png,Nascondi tutte le travi non selezionate +Button9=ShowAll.lua,Images\ShowAll.png,Visualizza tutte le travi +Button10=ShowBuilding.lua,Images\ShowBuilding.png,Visualizza struttura/Visualizza pezzi diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/ClearProcess.lua b/ProgramData/EgtCAM5/Beam con BpxT5/ClearProcess.lua new file mode 100644 index 0000000..f0dc6eb --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/ClearProcess.lua @@ -0,0 +1,57 @@ +-- ClearProcess.lua by Egaltech s.r.l. 2019/01/10 +-- Se la trave non è parte di un gruppo di lavoro, cancello geometrie aggiunte + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Recupero la prima trave selezionata +local ObjId = EgtGetFirstSelectedObj() +local PartId = EgtGetParent( EgtGetParent( ObjId or GDB_ID.NULL) or GDB_ID.NULL) +if not PartId then return end + +-- Recupero appartenenza a gruppi di lavoro +local vMGrps = {} +local sLst = EgtGetInfo( PartId, GDB_SI.LIST) +if sLst then + vLst = EgtSplitString( sLst) + if vLst then + for i = 1, #vLst do + local MGrpId = EgtGetParent( EgtGetParent( EgtGetParent( vLst[i]) or GDB_ID.NULL) or GDB_ID.NULL) + if MGrpId then + table.insert( vMGrps, EgtGetName( MGrpId)) + end + end + end +end + +-- Chiedo conferma della cancellazione +if #vMGrps > 0 then + local sOut = 'I seguenti gruppi di lavoro verranno cancellati :\n ' .. table.concat( vMGrps, ',') .. '.\nConfermi ?' + if not EgtOutBox( sOut, 'Cancella Lavorazioni', 'QUESTION') then + return + end +end + +-- Cancello i gruppi di lavoro e le geometrie aggiuntive relative +for i = 1, #vMGrps do + EgtRemoveMachGroup( EgtGetMachGroupId( vMGrps[i]) or GDB_ID.NULL) + EgtErase( EgtGetFirstNameInGroup( PartId, vMGrps[i]) or GDB_ID.NULL) +end + +-- Cancello eventuali altre geometrie aggiuntive per gruppi di lavoro +local LayId = EgtGetFirstLayer( PartId) +while LayId do + local NextLayId = EgtGetNextLayer( LayId) + if EgtGetInfo( LayId, '!MGO') then + EgtErase( LayId) + end + LayId = NextLayId +end + +-- Aggiorno interfaccia grafica +EgtDeselectPartObjs( PartId) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/DisableFeatures.lua b/ProgramData/EgtCAM5/Beam con BpxT5/DisableFeatures.lua new file mode 100644 index 0000000..0d1c3b1 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/DisableFeatures.lua @@ -0,0 +1,32 @@ +-- DisableFeatures.lua by Egaltech s.r.l. 2018/04/25 +-- Gestione disabilitazione delle feature selezionate + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +if EgtGetSelectedObjCount() == 0 then + EgtOutBox( 'Nessuna lavorazione selezionata', 'Disabilita lavorazioni', 'ERROR') +end + +local nId = EgtGetFirstSelectedObj() +while nId do + -- verifico sia una feature + local nParentId = EgtGetParent( nId) + if EgtIsLayer( nParentId) and EgtGetName( nParentId) == 'Processings' and + EgtGetInfo( nId, 'GRP', 'i') and EgtGetInfo( nId, 'PRC', 'i') then + EgtSetInfo( nId, 'DO', 0) + EgtSetColor( nId, Color3d( 160, 160, 160)) + local nAuxId = EgtGetInfo( nId, 'AUXID', 'i') + if nAuxId then + EgtSetColor( nId + nAuxId, Color3d( 160, 160, 160)) + end + end + nId = EgtGetNextSelectedObj() +end + +EgtDeselectAll() +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/EnableFeatures.lua b/ProgramData/EgtCAM5/Beam con BpxT5/EnableFeatures.lua new file mode 100644 index 0000000..756b77e --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/EnableFeatures.lua @@ -0,0 +1,32 @@ +-- DisableFeatures.lua by Egaltech s.r.l. 2018/04/25 +-- Gestione abilitazione delle feature selezionate + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +if EgtGetSelectedObjCount() == 0 then + EgtOutBox( 'Nessuna lavorazione selezionata', 'Abilita lavorazioni', 'ERROR') +end + +local nId = EgtGetFirstSelectedObj() +while nId do + -- verifico sia una feature + local nParentId = EgtGetParent( nId) + if EgtIsLayer( nParentId) and EgtGetName( nParentId) == 'Processings' and + EgtGetInfo( nId, 'GRP', 'i') and EgtGetInfo( nId, 'PRC', 'i') then + EgtRemoveInfo( nId, 'DO') + EgtResetColor( nId) + local nAuxId = EgtGetInfo( nId, 'AUXID', 'i') + if nAuxId then + EgtResetColor( nId + nAuxId) + end + end + nId = EgtGetNextSelectedObj() +end + +EgtDeselectAll() +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/HideAll.lua b/ProgramData/EgtCAM5/Beam con BpxT5/HideAll.lua new file mode 100644 index 0000000..abbc8fa --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/HideAll.lua @@ -0,0 +1,40 @@ +-- HideAll.lua by Egaltech s.r.l. 2019/03/16 +-- Gestione nascondimento di tutte le Travi non selezionate + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- se non ci sono pezzi selezionati, esco +if not EgtGetFirstSelectedObj() then return end + +-- nascondo tutti i pezzi non selezionati +local bCurrPL = false +local nPartId = EgtGetFirstPart() +while nPartId do + local nStat = GDB_ST.ON + local nLayId = EgtGetFirstLayer( nPartId) + while nLayId do + local nEntId = EgtGetFirstInGroup( nLayId) + if nEntId then + nStat = EgtGetCalcStatus( nEntId) + break + else + nLayId = EgtGetNextLayer( nLayId) + end + end + if nStat ~= GDB_ST.SEL then + EgtSetMode( nPartId, GDB_MD.HIDDEN) + else + EgtDeselectPartObjs( nPartId) + if not bCurrPL then + bCurrPL = EgtSetCurrPartLayer( nPartId, EgtGetFirstLayer( nPartId)) + end + end + nPartId = EgtGetNextPart( nPartId) +end + +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Images/BeamMachinings.png b/ProgramData/EgtCAM5/Beam con BpxT5/Images/BeamMachinings.png new file mode 100644 index 0000000..5ab6b0c Binary files /dev/null and b/ProgramData/EgtCAM5/Beam con BpxT5/Images/BeamMachinings.png differ diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Images/ClearProcess.png b/ProgramData/EgtCAM5/Beam con BpxT5/Images/ClearProcess.png new file mode 100644 index 0000000..d627bcc Binary files /dev/null and b/ProgramData/EgtCAM5/Beam con BpxT5/Images/ClearProcess.png differ diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Images/DisableFeatures.png b/ProgramData/EgtCAM5/Beam con BpxT5/Images/DisableFeatures.png new file mode 100644 index 0000000..10249b4 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam con BpxT5/Images/DisableFeatures.png differ diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Images/EnableFeatures.png b/ProgramData/EgtCAM5/Beam con BpxT5/Images/EnableFeatures.png new file mode 100644 index 0000000..1753231 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam con BpxT5/Images/EnableFeatures.png differ diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Images/HideAll.png b/ProgramData/EgtCAM5/Beam con BpxT5/Images/HideAll.png new file mode 100644 index 0000000..3ed46af Binary files /dev/null and b/ProgramData/EgtCAM5/Beam con BpxT5/Images/HideAll.png differ diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Images/Process.png b/ProgramData/EgtCAM5/Beam con BpxT5/Images/Process.png new file mode 100644 index 0000000..c040a0d Binary files /dev/null and b/ProgramData/EgtCAM5/Beam con BpxT5/Images/Process.png differ diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Images/Rotate.png b/ProgramData/EgtCAM5/Beam con BpxT5/Images/Rotate.png new file mode 100644 index 0000000..bd1532e Binary files /dev/null and b/ProgramData/EgtCAM5/Beam con BpxT5/Images/Rotate.png differ diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Images/ShowAll.png b/ProgramData/EgtCAM5/Beam con BpxT5/Images/ShowAll.png new file mode 100644 index 0000000..37a0de8 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam con BpxT5/Images/ShowAll.png differ diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Images/ShowBuilding.png b/ProgramData/EgtCAM5/Beam con BpxT5/Images/ShowBuilding.png new file mode 100644 index 0000000..419a955 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam con BpxT5/Images/ShowBuilding.png differ diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Images/Swap.png b/ProgramData/EgtCAM5/Beam con BpxT5/Images/Swap.png new file mode 100644 index 0000000..04fa8f8 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam con BpxT5/Images/Swap.png differ diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/BeamExec.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/BeamExec.lua new file mode 100644 index 0000000..ddad10b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/BeamExec.lua @@ -0,0 +1,846 @@ +-- BeamExec.lua by Egaltech s.r.l. 2019/09/25 +-- Libreria esecuzione lavorazioni per Travi +-- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. +-- 2019/09/04 Corretto controllo feature di testa e coda con sovramateriale di testa elevato. +-- 2019/09/25 Aggiunta gestione StepJoint e StepJointNotch + +-- Tabella per definizione modulo +local BeamExec = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali e libero tutti gli altri +_G.package.loaded.BeamData = nil +_G.package.loaded.CutData = nil +_G.package.loaded.MillingData = nil +_G.package.loaded.PocketingData = nil +_G.package.loaded.DrillData = nil +_G.package.loaded.SawingData = nil +local BD = require( 'BeamData') + +-- Carico le librerie +_G.package.loaded.MachiningLib = nil +local BM = require( 'MachiningLib') +_G.package.loaded.BeamLib = nil +local BL = require( 'BeamLib') +_G.package.loaded.DiceCut = nil +local DC = require( 'DiceCut') +_G.package.loaded.FacesBySaw = nil +local Fbs = require( 'FacesBySaw') +_G.package.loaded.ProcessHeadCut = nil +local Hcut= require( 'ProcessHeadCut') +_G.package.loaded.ProcessSplit = nil +local Split = require( 'ProcessSplit') +_G.package.loaded.ProcessCut = nil +local Cut = require( 'ProcessCut') +_G.package.loaded.ProcessDoubleCut = nil +local DoubleCut = require( 'ProcessDoubleCut') +_G.package.loaded.ProcessLongCut = nil +local LongCut = require( 'ProcessLongCut') +_G.package.loaded.ProcessLongDoubleCut = nil +local Long2Cut = require( 'ProcessLongDoubleCut') +_G.package.loaded.ProcessRidgeLap = nil +local RidgeLap = require( 'ProcessRidgeLap') +_G.package.loaded.ProcessLapJoint = nil +local LapJoint = require( 'ProcessLapJoint') +_G.package.loaded.ProcessChamfer = nil +local Chamfer = require( 'ProcessChamfer') +_G.package.loaded.ProcessDrill = nil +local Drill = require( 'ProcessDrill') +_G.package.loaded.ProcessTenon = nil +local Tenon = require( 'ProcessTenon') +_G.package.loaded.ProcessMortise = nil +local Mortise = require( 'ProcessMortise') +_G.package.loaded.ProcessDtTenon = nil +local DtTenon = require( 'ProcessDtTenon') +_G.package.loaded.ProcessDtMortise = nil +local DtMortise = require( 'ProcessDtMortise') +_G.package.loaded.ProcessMark = nil +local Mark = require( 'ProcessMark') +_G.package.loaded.ProcessText = nil +local Text = require( 'ProcessText') +_G.package.loaded.ProcessSimpleScarf = nil +local Scarf = require( 'ProcessSimpleScarf') +_G.package.loaded.ProcessStepJoint = nil +local StepJoint = require( 'ProcessStepJoint') +_G.package.loaded.ProcessStepJointNotch = nil +local StJoNotch = require( 'ProcessStepJointNotch') +_G.package.loaded.ProcessProfFront = nil +local ProfFront = require( 'ProcessProfFront') +_G.package.loaded.ProcessProfConcave = nil +local ProfConcave = require( 'ProcessProfConcave') +_G.package.loaded.ProcessProfConvex = nil +local ProfConvex = require( 'ProcessProfConvex') +_G.package.loaded.ProcessProfCamb = nil +local ProfCamb = require( 'ProcessProfCamb') +_G.package.loaded.ProcessProfHead = nil +local ProfHead = require( 'ProcessProfHead') +_G.package.loaded.ProcessRoundArch = nil +local RoundArch = require( 'ProcessRoundArch') +_G.package.loaded.ProcessFreeContour = nil +local FreeContour = require( 'ProcessFreeContour') +_G.package.loaded.ProcessDecor = nil +local Decor = require( 'ProcessDecor') + +EgtOutLog( ' BeamExec started', 1) + + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle travi nel grezzo *** +------------------------------------------------------------------------------------------------------------- +function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) + + -- Determinazione minimo grezzo scaricabile + BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) + + -- Creazione nuovo gruppo di lavoro + local sMgName = EgtGetMachGroupNewName( 'Mach_1') + 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 + BD.OriTR = Point3d( b3Tab:getDimX(), b3Tab:getDimY(), 0) + + -- Impostazione dell'attrezzaggio di default + EgtImportSetup() + + -- Inserimento dei pezzi con il loro grezzo + local Cnt = 0 + local Len = dRawL + local DeltaS = dOvmHead + local DeltaE = BD.OVM_MID + for i = 1, #vBeam do + -- assegno identificativo pezzo + local Pz = vBeam[i].Id + -- dati del pezzo + local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT) + local b3Solid = vBeam[i].Box + if b3Part:isEmpty() or b3Solid:isEmpty() then break end + EgtOutLog( 'PartSez=' .. EgtNumToString( b3Part:getDimY(), 1) .. 'x' .. EgtNumToString( b3Part:getDimZ(), 1), 3) + -- se sezione compatibile e lunghezza disponibile sufficiente + local PartLen = b3Solid:getDimX() + local PartWidth = b3Solid:getDimY() + local PartHeight = b3Solid:getDimZ() + local NextLen = Len - DeltaS - PartLen - DeltaE + if (( abs( PartWidth - dRawW) < 10 * GEO.EPS_SMALL and abs( PartHeight - dRawH) < 10 * GEO.EPS_SMALL) or + ( abs( PartHeight - dRawW) < 10 * GEO.EPS_SMALL and abs( PartWidth - dRawH) < 10 * GEO.EPS_SMALL)) and + NextLen + DeltaE >= 0 then + -- eventuale sovramateriale di testa + if vBeam[i].PosX then + DeltaS = max( vBeam[i].PosX - ( dRawL - Len), 0) + end + -- dimensioni del grezzo + local CrawLen = min( PartLen + DeltaS + DeltaE, Len) + local Delta = CrawLen - PartLen - DeltaS + -- creo e posiziono il grezzo + local nRaw = EgtAddRawPart( Point3d(0,0,0), CrawLen, dRawW, dRawH, BD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, BD.OriTR, MCH_CR.TR) + EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) + -- assegno ordine in lavorazione + Cnt = Cnt + 1 + EgtSetInfo( nRaw, 'ORD', Cnt) + -- creo o pulisco gruppo geometrie aggiuntive + if not BL.CreateOrEmptyAddGroup( Pz) then + local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz) + return false, sOut + end + -- se sovramateriale di testa, aggiungo faccia per taglio iniziale al pezzo + if DeltaS > 1. then + BL.AddPartStartFace( Pz, b3Solid) + EgtSetInfo( nRaw, 'HOVM', DeltaS) + end + -- aggiungo faccia per taglio finale al pezzo + BL.AddPartEndFace( Pz, b3Solid) + -- inserisco il pezzo nel grezzo + EgtDeselectPartObjs( Pz) + local ptPos = b3Part:getMin() - b3Solid:getMin() + Vector3d( Delta, ( dRawW - PartWidth) / 2, ( dRawH - PartHeight) / 2) + EgtAddPartToRawPart( Pz, ptPos, nRaw) + if abs( PartWidth - dRawW) > 10 * GEO.EPS_SMALL then + -- rotazione attorno a centro geometria complessiva del pezzo + EgtRotatePartInRawPart( Pz, X_AX(), 90) + -- correggo per eccentricità solido rispetto a geometria complessiva del pezzo + local vtEccOri = b3Solid:getCenter() - b3Part:getCenter() + local vtEccRot = Vector3d( vtEccOri) + vtEccRot:rotate( X_AX(), 90) + EgtMovePartInRawPart( Pz, ( vtEccOri - vtEccRot)) + end + -- aggiorno la lunghezza residua della barra + Len = Len - CrawLen + end + -- se rimasto troppo poco grezzo, esco + --if Len < BD.MinRaw then break end + DeltaS = 0 + end + + -- Se rimasto materiale aggiungo grezzo dell'avanzo + if Len > 10 then + local nRaw = EgtAddRawPart( Point3d(0,0,0), Len, dRawW, dRawH, BD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, BD.OriTR, MCH_CR.TR) + EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) + -- assegno ordine in lavorazione + Cnt = Cnt + 1 + EgtSetInfo( nRaw, 'ORD', Cnt) + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) + + -- Determinazione minimo grezzo scaricabile + if dRawW * dRawH > 40000 then + BD.MinRaw = BD.MINRAW_L + elseif dRawW * dRawH > 14500 then + BD.MinRaw = BD.MINRAW_M + else + BD.MinRaw = BD.MINRAW_S + end +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- feature sempre di testa o coda per il gruppo + if Proc.Grp == 1 or Proc.Grp == 2 then + return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- feature sempre di testa o coda nonostante il gruppo + if ( Proc.Grp == 3 or Proc.Grp == 4) and + ( Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then + return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- gestioni speciali + if LapJoint.Identify( Proc) then + return LapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if Drill.Identify( Proc) then + return Drill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if RoundArch.Identify( Proc) then + return RoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if FreeContour.Identify( Proc) then + return FreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + -- non è di testa + return false +end + +------------------------------------------------------------------------------------------------------------- +local function IsTailFeature( Proc, b3Raw, dCurrOvmH) + -- feature sempre di testa o coda per il gruppo + if Proc.Grp == 1 or Proc.Grp == 2 then + return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- feature sempre di testa o coda nonostante il gruppo + if ( Proc.Grp == 3 or Proc.Grp == 4) and + ( Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then + return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- gestioni speciali + if LapJoint.Identify( Proc) then + return LapJoint.IsTailFeature( Proc, b3Raw) + end + if RoundArch.Identify( Proc) then + return RoundArch.IsTailFeature( Proc, b3Raw) + end + if Drill.Identify( Proc) then + return Drill.IsTailFeature( Proc, b3Raw) + end + if FreeContour.Identify( Proc) then + return FreeContour.IsTailFeature( Proc, b3Raw) + end + -- non è di coda + return false +end + +------------------------------------------------------------------------------------------------------------- +local function CollectFeatures( PartId, b3Raw, dCurrOvmH) + -- recupero le feature + local vProc = {} + local LayerId = {} + LayerId[1] = BL.GetAddGroup( PartId) + LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings') + for nInd = 1, 2 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.Id = ProcId + Proc.Grp = nGrp + Proc.Prc = nPrc + Proc.Flg = 1 + Proc.Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD) + Proc.Fct = EgtSurfTmFacetCount( ProcId) or 0 + Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH) + Proc.Tail = IsTailFeature( Proc, b3Raw, dCurrOvmH) + Proc.Diam = 0 + Proc.Fcs = 0 + Proc.Fce = 0 + Proc.CutId = nCutId + Proc.TaskId = nTaskId + table.insert( vProc, Proc) + -- se foro + if Drill.Identify( Proc) then + -- assegno diametro + Proc.Diam = EgtGetInfo( Proc.Id, 'P12', 'd') or 0 + -- assegno faccia di entrata e uscita (dati tabelle sempre per riferimento) + Proc.Fcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + Proc.Fce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + -- verifico se necessaria seconda lavorazione da parte opposta per foro più lungo della punta + if Drill.Split( Proc, b3Raw) then + -- aggiorno flag prima parte foro (dati tabelle sempre per riferimento) + Proc.Flg = 2 + -- definisco dati seconda parte + local Proc2 = {} + Proc2.Id = ProcId + Proc2.Grp = nGrp + Proc2.Prc = nPrc + Proc2.Flg = -2 + Proc2.Box = BBox3d( Proc.Box) + Proc2.Fct = Proc.Fct + Proc2.Diam = Proc.Diam + Proc2.Head = Proc.Head + Proc2.Tail = Drill.IsTailFeature( Proc2, b3Raw, dCurrOvmH) + Proc2.Fcs = Proc.Fce + Proc2.Fce = Proc.Fcs + Proc2.CutId = Proc.CutId + Proc2.TaskId = Proc.TaskId + table.insert( vProc, Proc2) + end + end + end + end + ProcId = EgtGetNext( ProcId) + end + end + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function OrderFeatures( vProc, b3Raw) + + -- funzione di confronto + -- secondo centro box in X (taglio di intestazione prima di altri tagli di testa e taglio di separazione però prima di altri tagli di coda) + local function CompareFeatures( B1, B2) + -- se primo è intestazione va sempre prima + if Hcut.Identify( B1) then + return true + end + -- se l'altro è intestazione va sempre prima + if Hcut.Identify( B2) then + return false + end + -- se primo è feature di coda e l'altro è separazione o non è feature di coda + if B1.Tail and ( Split.Identify( B2) or not B2.Tail) then + return false + end + -- se secondo è feature di coda e l'altro è separazione o non è feature di coda + if B2.Tail and ( Split.Identify( B1) or not B1.Tail) then + return true + end + -- se primo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda + if abs( B1.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + return B1.Box:getMin():getX() + 50 > B2.Box:getCenter():getX() + end + -- se secondo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda + if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + return B1.Box:getCenter():getX() > B2.Box:getMin():getX() + 50 + end + -- se primo è foro e l'altro no, lo penalizzo + if B1.Prc == 40 and B2.Prc ~= 40 then + return B1.Box:getCenter():getX() > B2.Box:getMax():getX() + 100 + end + -- se secondo è foro e l'altro no, lo penalizzo + if B2.Prc == 40 and B1.Prc ~= 40 then + return B1.Box:getMax():getX() + 100 > B2.Box:getCenter():getX() + end + -- se sono fori e hanno posizione praticamente uguale ordino secondo diametro e faccia di inizio (Fcs) + if B1.Prc == 40 and B2.Prc == 40 and abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) < 600 then + if abs( B1.Diam - B2.Diam) < 1.0 then + if B1.Fcs == B2.Fcs then + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + else + return B1.Fcs > B2.Fcs + end + else + return ( B1.Diam > B2.Diam) + end + end + -- se entrambi tenoni e si intersecano, metto prima tenone vero e poi base tenone + if Tenon.Identify( B1) and Tenon.Identify( B2) and + B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then + return ( B1.Prc == 50 and B2.Prc == 52) + end + -- se uno di testa e non l'altro, privilegio questo + if B1.Head ~= B2.Head then + return B1.Head + end + -- confronto standard + if abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) > 0.4 * ( B1.Box:getDimX() + B2.Box:getDimX()) then + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + elseif abs( B1.Box:getCenter():getY() - B2.Box:getCenter():getY()) > 0.4 * ( B1.Box:getDimY() + B2.Box:getDimY()) then + return B1.Box:getCenter():getY() > B2.Box:getCenter():getY() + else + return B1.Box:getCenter():getZ() > B2.Box:getCenter():getZ() + end + end + + -- eseguo ordinamento + table.sort( vProc, CompareFeatures) + + -- riunisco fori con lo stesso diametro e non troppo lontani + for i = 1, #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 40 then + for j = i + 1, #vProc do + local ProcJ = vProc[j] + if ProcJ.Prc == 40 and ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and + abs( ProcJ.Diam - ProcI.Diam) < 1.0 and abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < 600.0 then + if j > i + 1 then + local ProcK = vProc[i+1] + if ProcK.Prc ~= 40 or abs( ProcK.Diam - ProcJ.Diam) > 1.0 or ProcJ.Box:getCenter():getX() < ProcK.Box:getCenter():getX() then + table.insert( vProc, i + 1, table.remove( vProc, j)) + end + end + break + end + end + end + end + -- riunisco marcature, testi e decori non troppo lontani + for i = 1, #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 60 or ProcI.Prc == 61 or ProcI.Prc == 959 then + for j = i + 1, #vProc do + local ProcJ = vProc[j] + if ( ProcJ.Prc == 60 or ProcJ.Prc == 61 or ProcJ.Prc == 959) and + ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and + abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < 300.0 then + if j > i + 1 then + table.insert( vProc, i + 1, table.remove( vProc, j)) + end + break + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +local function ClassifyFeatures( vProc, b3Raw, Stats) + local bAllOk = true + local bSomeDown = false + local bSplitRot = false + local nHeading + local nSplitting + for i = 1, #vProc do + local Proc = vProc[i] + local bOk = true + local bDown = false + -- se intestatura + if Hcut.Identify( Proc) then + nHeading = i + -- se separazione + elseif Split.Identify( Proc) then + nSplitting = i + -- se taglio + elseif Cut.Identify( Proc) then + bOk, bDown = Cut.Classify( Proc) + -- se doppio taglio + elseif DoubleCut.Identify( Proc) then + bOk, bDown = DoubleCut.Classify( Proc) + -- se taglio longitudinale + elseif LongCut.Identify( Proc) then + bOk, bDown = LongCut.Classify( Proc) + -- se doppio taglio longitudinale + elseif Long2Cut.Identify( Proc) then + bOk, bDown = Long2Cut.Classify( Proc) + -- se mezzo-legno di testa + elseif RidgeLap.Identify( Proc) then + bOk, bDown = RidgeLap.Classify( Proc) + -- se mezzo-legno, fessura, fessura frontale, notch, tasca, tacca + elseif LapJoint.Identify( Proc) then + bOk, bDown = LapJoint.Classify( Proc) + -- se foratura + elseif Drill.Identify( Proc) then + bOk, bDown = Drill.Classify( Proc, b3Raw) + -- se tenone + elseif Tenon.Identify( Proc) then + bOk, bDown = Tenon.Classify( Proc) + -- se mortasa (anche frontale) + elseif Mortise.Identify( Proc) then + bOk, bDown = Mortise.Classify( Proc) + -- se tenone a coda di rondine + elseif DtTenon.Identify( Proc) then + bOk, bDown = DtTenon.Classify( Proc) + -- se mortasa a coda di rondine (anche frontale) + elseif DtMortise.Identify( Proc) then + bOk, bDown = DtMortise.Classify( Proc) + -- se marcatura + elseif Mark.Identify( Proc) then + bOk, bDown = Mark.Classify( Proc) + -- se testo + elseif Text.Identify( Proc) then + bOk, bDown = Text.Classify( Proc) + -- se giunto Gerber + elseif Scarf.Identify( Proc) then + bOk, bDown = Scarf.Classify( Proc) + -- se giunto a gradino + elseif StepJoint.Identify( Proc) then + bOk, bDown = StepJoint.Classify( Proc) + -- se tacca a gradino + elseif StJoNotch.Identify( Proc) then + bOk, bDown = StJoNotch.Classify( Proc) + -- se arco + elseif RoundArch.Identify( Proc) then + bOk, bDown = RoundArch.Classify( Proc) + -- se contorno libero + elseif FreeContour.Identify( Proc) then + bOk, bDown = FreeContour.Classify( Proc) + -- se decorazione + elseif Decor.Identify( Proc) then + bOk, bDown = Decor.Classify( Proc) + end + -- assegno risultato + if bOk then + -- non ammessa feature di testa da lavorare ribaltata + if Proc.Head and bDown then + Proc.Flg = 0 + Proc.Down = true + bAllOk = false + table.insert( Stats, {Err = 1, Msg='Error : impossible to machine by orientation', CutId=Proc.CutId, TaskId=Proc.TaskId}) + -- gestione feature di coda da lavorare ribaltata + elseif Proc.Tail and bDown then + Proc.Down = true + bSomeDown = true + bSplitRot = true + -- caso normale + else + Proc.Down = bDown + if bDown then bSomeDown = true end + end + else + Proc.Flg = 0 + bAllOk = false + table.insert( Stats, {Err = 1, Msg='Error : impossible to machine', CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + end + -- se necessario ribaltamento, assegno intestatura alla fase ribaltata + if bSomeDown and nHeading then + vProc[nHeading].Down = true + end + -- se necessaria rotazione del ribaltato, assegno separazione alla fase ribaltata + if bSplitRot then + vProc[nSplitting].Down = true + end + return bAllOk, bSomeDown, bSplitRot +end + +------------------------------------------------------------------------------------------------------------- +local function PrintFeatures( vProc, b3Raw) + EgtOutLog( ' RawBox=' .. tostring( b3Raw)) + for i = 1, #vProc do + local Proc = vProc[i] + local sOut = string.format( ' Proc=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s', + Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId, + Proc.Flg, EgtIf( Proc.Down, 'T', 'F'), EgtIf( Proc.Head, 'T', 'F'), EgtIf( Proc.Tail, 'T', 'F'), + Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, tostring( Proc.Box)) + EgtOutLog( sOut) + end +end + +------------------------------------------------------------------------------------------------------------- +local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3Raw) + local bOk = true + local sErr = '' + local bNewPhase = false + -- se intestatura ( 1-340-X ) + if Hcut.Identify( Proc) then + -- esecuzione taglio di testa + bOk, sErr = Hcut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se separazione ( 2-350-X ) + elseif Split.Identify( Proc) then + -- esecuzione separazione o eliminazione grezzo residuo + bOk, _, sErr = Split.Make( Proc, nPhase, nRawId, nPartId) + -- richiedo il passaggio alla seconda fase di lavorazione di questa trave + bNewPhase = true + -- se taglio ( 1/2-010-X) + elseif Cut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se doppio taglio ( 1/2-011-X) + elseif DoubleCut.Identify( Proc) then + -- se due facce, eseguo doppio taglio + if Proc.Fct == 2 then + bOk, sErr = DoubleCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- altrimenti eseguo singolo taglio + else + bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + end + -- se taglio longitudinale ( 0/3/4-010-X) + elseif LongCut.Identify( Proc) then + -- esecuzione taglio longitudinale + bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) + -- se doppio taglio longitudinale ( 0-012-X) + elseif Long2Cut.Identify( Proc) then + -- se due facce, eseguo doppio taglio longitudinale + if Proc.Fct == 2 then + bOk, sErr = Long2Cut.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti eseguo singolo taglio longitudinale + else + bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) + end + -- se mezzo-legno di testa ( 1/2-030-X) + elseif RidgeLap.Identify( Proc) then + -- esecuzione mezzo-legno di testa + bOk, sErr = RidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mezzo-legno ( 3/4-030-X) o scanalatura ( 3/4-016-X) o tacca ( 3/4-020-X) + elseif LapJoint.Identify( Proc) then + -- esecuzione mezzo-legno o scanalatura + bOk, sErr = LapJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se smusso ( 3/4-036-X) + elseif Chamfer.Identify( Proc) then + -- esecuzione smusso + bOk, sErr = Chamfer.Make( Proc, nPhase, nRawId, nPartId) + -- se foratura ( 3/4-040-X) + elseif Drill.Identify( Proc) then + -- esecuzione foratura + bOk, sErr = Drill.Make( Proc, nPhase, nRawId, nPartId) + -- se tenone ( 1/2-050-X) + elseif Tenon.Identify( Proc) then + -- esecuzione tenone + bOk, sErr = Tenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mortasa ( 3/4-050-X) anche frontale ( 3/4-051-X) + elseif Mortise.Identify( Proc) then + -- esecuzione mortasa + bOk, sErr = Mortise.Make( Proc, nPhase, nRawId, nPartId) + -- se tenone a coda di rondine ( 1/2-055-X) + elseif DtTenon.Identify( Proc) then + -- esecuzione tenone + bOk, sErr = DtTenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mortasa a coda di rondine ( 3/4-055-X) anche frontale ( 3/4-056-X) + elseif DtMortise.Identify( Proc) then + -- esecuzione mortasa + bOk, sErr = DtMortise.Make( Proc, nPhase, nRawId, nPartId) + -- se marcatura ( 3/4-060-X) + elseif Mark.Identify( Proc) then + -- esecuzione marcatura + bOk, sErr = Mark.Make( Proc, nPhase, nRawId, nPartId) + -- se testo ( 4-061-X) + elseif Text.Identify( Proc) then + -- esecuzione testo + bOk, sErr = Text.Make( Proc, nPhase, nRawId, nPartId) + -- se giunto Gerber ( 1/2-070-X) + elseif Scarf.Identify( Proc) then + -- esecuzione giunto Gerber + bOk, sErr = Scarf.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se giunto a gradino + elseif StepJoint.Identify( Proc) then + -- esecuzione giunto a gradino + bOk, sErr = StepJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se tacca a gradino + elseif StJoNotch.Identify( Proc) then + -- esecuzione tacca a gradino + bOk, sErr = StJoNotch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo Front ( 3/4-100-X) + elseif ProfFront.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo concavo ( 3/4-101-X) + elseif ProfConcave.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo convesso ( 3/4-102-X) + elseif ProfConvex.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo caudato ( 3/4-103-X) + elseif ProfCamb.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se arco ( 4-104-X) + elseif RoundArch.Identify( Proc) then + -- esecuzione arco + bOk, sErr = RoundArch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo Head ( 3/4-106-X) + elseif ProfHead.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se contorno libero ( 0/3/4-250-X) + elseif FreeContour.Identify( Proc) then + -- esecuzione contorno + bOk, sErr = FreeContour.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se decorazione ( 0/3/4-959-X) + elseif Decor.Identify( Proc) then + -- esecuzione decorazione + bOk, sErr = Decor.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti feature sconosciuta + else + sErr = 'Error on process ' .. tostring( Proc.Id) .. ' unknown type (' .. tonumber( Proc.Grp) .. '-' .. tonumber( Proc.Prc) .. ')' + EgtOutLog( sErr) + bOk = false + end + return bOk, sErr, bNewPhase +end + +------------------------------------------------------------------------------------------------------------- +function BeamExec.ProcessFeatures() + local nTotErr = 0 + local Stats = {} + local nOrd = 1 + local nRawId = EgtGetFirstRawPart() + while nRawId do + -- verifico che il grezzo contenga pezzi oppure sia abbastanza lungo da essere scaricato coi carrelli + local nPartId = EgtGetFirstPartInRawPart( nRawId) + if not nPartId and EgtGetRawPartBBox( nRawId):getDimX() < BD.MinRaw then break end + -- aggiungo la fase, se non è la prima + if nOrd == 1 then + EgtSetCurrPhase( 1) + else + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) + end + local nPhase = EgtGetCurrPhase() + local nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', EgtIf( nPartId, 'START', 'REST')) + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtOutLog( 'Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( nRawId) .. ' Part=' .. tostring( nPartId), 1) + -- ingombro del grezzo e sovramateriale di testa + local b3Raw = EgtGetRawPartBBox( nRawId) + local dCurrOvmH = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 + -- recupero le feature di lavorazione della trave + vProc = CollectFeatures( nPartId, b3Raw, dCurrOvmH) + -- le ordino lungo X + OrderFeatures( vProc, b3Raw) + -- le classifico + local bAllOk, bSomeDown, bSplitRot = ClassifyFeatures( vProc, b3Raw, Stats) + if not bAllOk then + nTotErr = nTotErr + 1 + end + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc, b3Raw) + end + -- se richiesto ribaltamento + if bSomeDown then + -- ribalto le travi della fase corrente + local nRId = nRawId + while nRId do + EgtRotateRawPart( nRId, X_AX(), 180) + nRId = EgtGetNextRawPart( nRId) + end + EgtSetInfo( nDispId, 'ROT', -2) + -- inserisco le lavorazioni da lavorare ribaltate + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and Proc.Down then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3Raw) + if not bOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + elseif sMsg and #sMsg > 0 then + table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + else + table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + EgtRotateRawPart( nRawId, X_AX(), 180) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'MID2') + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtSetInfo( nDispId, 'ROT', -2) + end + end + end + -- se separazione non ancora effettuata, aggiungo nuova fase con le travi in posizione standard + if not bSplitRot then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) + -- altrimenti + else + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', EgtIf( not bSplitRot, 'MID', 'END2')) + EgtSetInfo( nDispId, 'ORD', nOrd) + end + -- inserisco le lavorazioni non ribaltate della trave + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and not Proc.Down then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, 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 + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'END') + EgtSetInfo( nDispId, 'ORD', nOrd) + end + end + end + -- passo al grezzo successivo + nOrd = nOrd + 1 + nRawId = EgtGetNextRawPart( nRawId) + end + + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + local bApplOk, sApplErrors = EgtApplyAllMachinings() + if not bApplOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err = 1, Msg=sApplErrors, Rot=0, CutId=0, TaskId=0}) + end + + return ( nTotErr == 0), Stats +end + +------------------------------------------------------------------------------------------------------------- +return BeamExec diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/BeamLib.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/BeamLib.lua new file mode 100644 index 0000000..317d18b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/BeamLib.lua @@ -0,0 +1,769 @@ +-- BeamLib.lua by Egaltech s.r.l. 2019/09/04 +-- Libreria globale per Travi + +-- Tabella per definizione modulo +local BeamLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' BeamLib started', 1) + +------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetAddGroup( PartId) + -- recupero il nome del gruppo di lavoro corrente + local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL) + if not sMchGrp then return nil, nil end + -- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco + local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp) + -- restituisco Id e Nome + return AddGrpId, sMchGrp +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.CreateOrEmptyAddGroup( PartId) + -- recupero i dati del gruppo aggiuntivo + local AddGrpId, sMchGrp = BeamLib.GetAddGroup( PartId) + if not sMchGrp then return false end + -- se esiste lo svuoto + if AddGrpId then + return EgtEmptyGroup( AddGrpId) + end + -- altrimenti lo creo + AddGrpId = EgtGroup( PartId or GDB_ID.NULL) + if not AddGrpId then return false end + -- assegno nome, flag di layer per gruppo di lavoro e colore + EgtSetName( AddGrpId, sMchGrp) + EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup()) + EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 50)) + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPartStartFace( PartId, b3Solid) + -- recupero gruppo per geometria aggiuntiva + local AddGrpId = BeamLib.GetAddGroup( PartId) + if not AddGrpId then + local sErr = 'Error on process StartFace impossible to find AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo nuovo taglio iniziale + local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMax(), X_AX(), b3Solid, GDB_RT.GLOB) + if not nStmId then + local sErr = 'Error on process StartFace impossible to create Face' + EgtOutLog( sErr) + return false, sErr + end + -- applico gli opportuni attributi di feature + EgtSetName( nStmId, 'StartCut') + EgtSetInfo( nStmId, 'GRP', 1) + EgtSetInfo( nStmId, 'PRC', 340) + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPartEndFace( PartId, b3Solid) + -- recupero gruppo per geometria aggiuntiva + local AddGrpId = BeamLib.GetAddGroup( PartId) + if not AddGrpId then + local sErr = 'Error on process EndFace impossible to find AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo nuovo taglio finale + local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMin(), -X_AX(), b3Solid, GDB_RT.GLOB) + if not nStmId then + local sErr = 'Error on process EndFace impossible to create Face' + EgtOutLog( sErr) + return false, sErr + end + -- applico gli opportuni attributi di feature + EgtSetName( nStmId, 'EndCut') + EgtSetInfo( nStmId, 'GRP', 2) + EgtSetInfo( nStmId, 'PRC', 350) + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPhaseWithRawParts( nFirstRawId, OriTR, dDeltaSucc) + EgtAddPhase() + local nRawId = nFirstRawId + local dRawMove = 0 + while nRawId do + EgtKeepRawPart( nRawId) + EgtMoveToCornerRawPart( nRawId, OriTR, MCH_CR.TR) + EgtMoveRawPart( nRawId, Vector3d( - dRawMove, 0, 0)) + if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end + dRawMove = dRawMove + EgtGetRawPartBBox( nRawId):getDimX() + nRawId = EgtGetNextRawPart( nRawId) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartOnTop( nCrvId) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- cerco l'estremo più alto e lo imposto come inizio + local dUmax = 0 + local dZmax = - GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf, 0.5 do + local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) + if ptP and ptP:getZ() > dZmax + GEO.EPS_SMALL then + dZmax = ptP:getZ() + dUmax = dU + end + end + if abs( dUmax - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUmax) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- recupero il versore normale al piano di lavoro o estrusione + local vtN = EgtCurveExtrusion( nCrvId, GDB_ID.ROOT) + -- coefficienti per riportare la distanza nel piano di lavoro + local dCoeffX = 1 / ( sqrt( 1 - vtN:getX() * vtN:getX())) + local dCoeffY = 1 / ( sqrt( 1 - vtN:getY() * vtN:getY())) + local dCoeffZ = 1 / ( sqrt( 1 - vtN:getZ() * vtN:getZ())) + -- cerco l'estremo più vicino al box e lo imposto come inizio (escluso Zmin) + local dUopt = 0 + local dDopt = GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf, 0.5 do + local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) + if ptP then + local vtMin = ptP - b3Raw:getMin() + local vtMax = ptP - b3Raw:getMax() + local dD = abs( vtMin:getX()) * dCoeffX + dD = min( abs( vtMax:getX()) * dCoeffX, dD) + dD = min( abs( vtMin:getY()) * dCoeffY, dD) + dD = min( abs( vtMax:getY()) * dCoeffY, dD) + dD = min( abs( vtMax:getZ()) * dCoeffZ, dD) + if dD < dDopt + GEO.EPS_SMALL then + dDopt = dD + dUopt = dU + end + end + end + if abs( dUopt - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUopt) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetPointDirDepth( nRawId, ptP, vtDir) + -- recupero il solido del grezzo + local nSolId = EgtGetFirstNameInGroup( nRawId, 'RawSolid') + if not nSolId then return end + -- interseco con la retta + local bOk, vType, vPar = EgtLineSurfTmInters( ptP, vtDir, nSolId, GDB_RT.GLOB) + if not bOk then return end + if not vPar or #vPar == 0 then return -2 end + local dLenIn, dLenOut + for i = 1, #vPar do + if vPar[i] < 0 then + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = -1 + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN then + dLenIn = -2 + end + else + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = vPar[i] + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN or vType[i] == GDB_SLT.TOUCH then + dLenOut = vPar[i] + end + end + end + return dLenIn, dLenOut +end + +--------------------------------------------------------------------- +function BeamLib.GetNearestParalOpposite( vtRef) + -- devo confrontare la componente orizzontale con quella verticale + local dHorSq = vtRef:getX() * vtRef:getX() + vtRef:getY() * vtRef:getY() + local dVertSq =vtRef:getZ() * vtRef:getZ() + -- se prevalente la componente orizzontale + if dHorSq >= dVertSq then + if abs( vtRef:getX()) > abs( vtRef:getY()) then + if vtRef:getX() > 0 then + return MCH_MILL_FU.PARAL_LEFT + else + return MCH_MILL_FU.PARAL_RIGHT + end + elseif abs( vtRef:getY()) > abs( vtRef:getZ()) then + if vtRef:getY() > 0 then + return MCH_MILL_FU.PARAL_FRONT + else + return MCH_MILL_FU.PARAL_BACK + end + end + -- altrimenti prevale la verticale + else + if vtRef:getZ() > 0 then + return MCH_MILL_FU.PARAL_DOWN + else + return MCH_MILL_FU.PARAL_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetNearestOrthoOpposite( vtRef) + -- devo confrontare la componente orizzontale con quella verticale + local dHorSq = vtRef:getX() * vtRef:getX() + vtRef:getY() * vtRef:getY() + local dVertSq =vtRef:getZ() * vtRef:getZ() + -- se prevalente la componente orizzontale + if dHorSq >= dVertSq then + if abs( vtRef:getX()) >= abs( vtRef:getY()) then + if vtRef:getX() > 0 then + return MCH_MILL_FU.ORTHO_LEFT + else + return MCH_MILL_FU.ORTHO_RIGHT + end + else + if vtRef:getY() > 0 then + return MCH_MILL_FU.ORTHO_FRONT + else + return MCH_MILL_FU.ORTHO_BACK + end + end + -- altrimenti prevale la verticale + else + if vtRef:getZ() > 0 then + return MCH_MILL_FU.ORTHO_DOWN + else + return MCH_MILL_FU.ORTHO_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetOrtupOpposite( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return MCH_MILL_FU.ORTUP_LEFT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return MCH_MILL_FU.ORTUP_RIGHT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return MCH_MILL_FU.ORTUP_FRONT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return MCH_MILL_FU.ORTUP_BACK + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return MCH_MILL_FU.ORTUP_DOWN + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return MCH_MILL_FU.ORTUP_TOP + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetVersRef( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return X_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return -X_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return Y_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return -Y_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return Z_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return -Z_AX() + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetBoxFaceNorm( b3Box, ptP, vtV) + local vtNx = V_NULL() + if abs( ptP:getX() - b3Box:getMin():getX()) < 10 * GEO.EPS_SMALL then + vtNx = -X_AX() + elseif abs( ptP:getX() - b3Box:getMax():getX()) < 10 * GEO.EPS_SMALL then + vtNx = X_AX() + end + local vtNy = V_NULL() + if abs( ptP:getY() - b3Box:getMin():getY()) < 10 * GEO.EPS_SMALL then + vtNy = -Y_AX() + elseif abs( ptP:getY() - b3Box:getMax():getY()) < 10 * GEO.EPS_SMALL then + vtNy = Y_AX() + end + local vtNz = V_NULL() + if abs( ptP:getZ() - b3Box:getMin():getZ()) < 10 * GEO.EPS_SMALL then + vtNz = -Z_AX() + elseif abs( ptP:getZ() - b3Box:getMax():getZ()) < 10 * GEO.EPS_SMALL then + vtNz = Z_AX() + end + local dNxDotV = vtNx * vtV + local dNyDotV = vtNy * vtV + local dNzDotV = vtNz * vtV + if dNxDotV > dNyDotV and dNxDotV > dNzDotV then + return vtNx + elseif dNyDotV > dNzDotV and dNyDotV > dNxDotV then + return vtNy + else + return vtNz + end +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceWithMostAdj( nSurfId) + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nSurfId) + -- recupero le normali delle facce + local vvtN = {} + for i = 1, nFacCnt do + local _, vtN = EgtSurfTmFacetCenter( nSurfId, i - 1, GDB_ID.ROOT) + vvtN[i] = vtN ; + end + -- adiacenze e sottosquadra delle facce + local vAdj = {} + local vUcut = {} + for i = 1, nFacCnt do + -- recupero le adiacenze del loop esterno + local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + vAdj[i] = nCount + -- ne determino eventuale sottosquadra (- 3deg) + local bUcut = false + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + local vtN = vvtN[i] + local vtN2 = vvtN[vFacAdj[j]+1] + if vtN * vtN2 < -0.05 then + bUcut = true + end + end + end + vUcut[i] = bUcut + end + -- se 4 facce tutte con adiacenza 2, allora è un tunnel + if nFacCnt == 4 then + if vAdj[1] == 2 and vAdj[2] == 2 and vAdj[3] == 2 and vAdj[4] == 2 then + return -1, GEO.INFINITO + end + end + -- recupero le facce non in sottosquadra e con il maggior numero di adiacenze + local nFacInd = {} + local nMaxAdj = 0 + local nSupAdj = 0 + for i = 1, nFacCnt do + if not vUcut[i] then + if vAdj[i] > nMaxAdj then + nFacInd = {} + nFacInd[1] = i - 1 + nMaxAdj = vAdj[i] + elseif vAdj[i] == nMaxAdj and nMaxAdj > 0 then + table.insert( nFacInd, i - 1) + end + end + if vAdj[i] > nSupAdj then + nSupAdj = vAdj[i] + end + end + -- verifico non ci sia una faccia in sottosquadra con adiacenza superiore + if nSupAdj > nMaxAdj then + return -2, GEO.INFINITO + end + -- premio la faccia con minore elevazione + local nFacOpt, nFacOpt2 + local dMinElev, dMinElev2 = GEO.INFINITO, GEO.INFINITO + for i = 1, #nFacInd do + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacInd[i], GDB_ID.ROOT) + local frOCS = Frame3d( ptC, vtN) ; + local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS) + if b3Box:getDimZ() < dMinElev then + if dMinElev < dMinElev2 then + nFacOpt2 = nFacOpt + dMinElev2 = dMinElev + end + nFacOpt = nFacInd[i] + dMinElev = b3Box:getDimZ() + elseif b3Box:getDimZ() < dMinElev2 then + nFacOpt2 = nFacInd[i] + dMinElev2 = b3Box:getDimZ() + end + end + return nFacOpt, dMinElev, nFacOpt2, dMinElev2 +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceBox( nSurfId, nFacet) + -- estraggo la faccia temporaneamente + local FacId = EgtCopySurfTmFacet( nSurfId, nFacet, EgtGetParent( nSurfId)) + if not FacId then return end + -- determino l'ingombro in globale + local b3Glob = EgtGetBBoxGlob( FacId, GDB_BB.STANDARD) + -- cancello la faccia temporanea + EgtErase( FacId) + -- restituisco il bounding box + return b3Glob +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceHvRefDim( nSurfId, nFacet) + -- recupero centro e normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + if not ptC or not vtN then return end + -- riferimento tipo OCS della faccia (X orizz, Y max pendenza, Z normale) + local frHV = Frame3d( ptC, vtN) + if frHV:getVersY():getZ() < 0 then + frHV:rotate( ptC, vtN, 180) + end + -- estraggo la faccia temporaneamente + local FacId = EgtCopySurfTmFacet( nSurfId, nFacet, EgtGetParent( nSurfId)) + -- determino l'ingombro in questo riferimento + local b3HV = EgtGetBBoxRef( FacId, GDB_BB.STANDARD, frHV) + -- cancello la faccia temporanea + EgtErase( FacId) + -- restituisco i valori calcolati + return frHV, b3HV:getDimX(), b3HV:getDimY() +end + +--------------------------------------------------------------------- +function BeamLib.CalcLeadInOutGeom( ptP1, ptP2, vtV1, vtV2, vtN, dRad, vtRef, dCutExtra, b3Box) + -- Mi assicuro che i vettori ingresso/uscita giacciano nel piano + vtV1 = vtV1 - vtV1 * vtN * vtN ; vtV1:normalize() + vtV2 = vtV2 - vtV2 * vtN * vtN ; vtV2:normalize() + -- Versore tangente al taglio + local vtTg = ptP2 - ptP1 ; + vtTg = vtTg - vtTg * vtN * vtN ; vtTg:normalize() + -- Sistema di riferimento intrinseco al taglio + local vtX = vtTg ^ vtN + local frFace = Frame3d( ptP1, vtX, vtTg, vtN) + EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Versori di attacco e uscita + local dCos1 = vtV1 * vtRef + local dCos2 = vtV2 * vtRef + local vtLi, vtLo + if dCos1 > dCos2 then + vtLi = vtV1 + vtLo = vtV1 + else + vtLi = vtV2 + vtLo = vtV2 + end + local bRight = ( vtX * vtLi > 0) + -- Versori di attacco e uscita nel riferimento intrinseco al taglio + local vtLiL = Vector3d( vtLi) ; vtLiL:toLoc( frFace) + local vtLoL = Vector3d( vtLo) ; vtLoL:toLoc( frFace) + -- Spostamento punti per effetto dell'extra di taglio + if dCutExtra > GEO.EPS_SMALL then + ptP1 = ptP1 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) + ptP2 = ptP2 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) + end + -- Attacco + local dLiTang = 10000 + local dLiPerp = 10000 + local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtLi, b3Box) + if bLiOk and #vLiPar > 0 then + -- con la prima faccia di uscita + local dLen = vLiPar[#vLiPar] + local ptInt = ptP1 + vtLi * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3Box, ptInt, vtLi) + EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLi * vtFN) + local dLiLen = dLen + dAddLen + EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) + dLiTang = - dLiLen * vtLiL:getY() + dLiPerp = EgtIf( bRight, dLiLen, - dLiLen) * vtLiL:getX() + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtLi, b3Mod) + if bLiOk2 and #vLiPar2 > 0 then + local dLen2 = vLiPar2[#vLiPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP1 + vtLi * dLen2, vtLi) + EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLi * vtFN2) + local dLiLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) + local dLiTang2 = - dLiLen2 * vtLiL:getY() + local dLiPerp2 = EgtIf( bRight, dLiLen2, - dLiLen2) * vtLiL:getX() + if dLiLen2 < dLiLen then + dLiTang = dLiTang2 + dLiPerp = dLiPerp2 + end + end + end + -- Lunghezza di uscita + local dLoTang = 10000 + local dLoPerp = 10000 + local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtLo, b3Box) + if bLoOk and #vLoPar > 0 then + -- con la prima faccia di uscita + local dLen = vLoPar[#vLoPar] + local ptInt = ptP2 + vtLo * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3Box, ptInt, vtLo) + EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLo * vtFN) + local dLoLen = dLen + dAddLen + EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) + dLoTang = dLoLen * vtLoL:getY() + dLoPerp = EgtIf( bRight, dLoLen, - dLoLen) * vtLoL:getX() + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtLo, b3Mod) + if bLoOk2 and #vLoPar2 > 0 then + local dLen2 = vLoPar2[#vLoPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP2 + vtLo * dLen2, vtLo) + EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLo * vtFN2) + local dLoLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) + local dLoTang2 = dLoLen2 * vtLoL:getY() + local dLoPerp2 = EgtIf( bRight, dLoLen2, - dLoLen2) * vtLoL:getX() + if dLoLen2 < dLoLen then + dLoTang = dLoTang2 + dLoPerp = dLoPerp2 + end + end + end + return dLiTang, dLiPerp, dLoTang, dLoPerp +end + +--------------------------------------------------------------------- +function BeamLib.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dRad, vtRef, dCutExtra, b3Box) + -- Versore tangente al taglio + local vtTg = ptP2 - ptP1 ; + vtTg = vtTg - vtTg * vtN * vtN ; vtTg:normalize() + -- Sistema di riferimento intrinseco al taglio + local vtX = vtTg ^ vtN + local frFace = Frame3d( ptP1, vtX, vtTg, vtN) + if ( vtX * vtRef < 0) then + vtX = - vtX + end + EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Spostamento punti per effetto dell'extra di taglio + if dCutExtra > GEO.EPS_SMALL then + ptP1 = ptP1 - vtX * dCutExtra + ptP2 = ptP2 - vtX * dCutExtra + end + -- Attacco + local dLiTang = 10000 + local dLiPerp = 0 + local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtTg, b3Box) + if bLiOk and #vLiPar > 0 then + local dLen = vLiPar[1] + local ptInt = ptP1 + vtTg * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3Box, ptInt, -vtTg) + EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) + local dLiLen = dLen + dAddLen + EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) + dLiTang = - dLiLen + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtTg, b3Mod) + if bLiOk2 and #vLiPar2 > 0 then + local dLen2 = vLiPar2[1] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP1 + vtTg * dLen2, -vtTg) + EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) + local dLiLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) + if -dLiLen2 < -dLiLen then + dLiTang = - dLiLen2 + end + end + end + -- Lunghezza di uscita + local dLoTang = 10000 + local dLoPerp = 0 + local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtTg, b3Box) + if bLoOk and #vLoPar > 0 then + local dLen = vLoPar[#vLoPar] + local ptInt = ptP2 + vtTg * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3Box, ptInt, vtTg) + EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) + local dLoLen = dLen + dAddLen + EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) + dLoTang = dLoLen + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtTg, b3Mod) + if bLoOk2 and #vLoPar2 > 0 then + local dLen2 = vLoPar2[#vLoPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP2 + vtTg * dLen2, vtTg) + EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) + local dLoLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) + if dLoLen2 < dLoLen then + dLoTang = dLoLen2 + end + end + end + return dLiTang, dLiPerp, dLoTang, dLoPerp +end + +--------------------------------------------------------------------- +function BeamLib.MakeOneFaceBySaw( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDwnUp, dCutExtra, dCutSic, dCutOffset, dAccStart, sNotes, b3Raw) + -- risolvo paramentro ambiguo + local nOrthoOpposite + local vtOrthO + if isVector3d( Par5) then + nOrthoOpposite = BeamLib.GetNearestOrthoOpposite( Par5) + vtOrthO = Vector3d( Par5) + else + nOrthoOpposite = Par5 + vtOrthO = BeamLib.GetVersRef( Par5) + end + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + -- linea o bilinea di lavorazione (qui uso nOrthoOpposite per ripetere esattamente il calcolo del Mach) + local ptP1, ptPm, ptP2, vtV1, vtV2, dLen, dWidth = EgtSurfTmFacetOppositeSide( nSurfId, nFacet, BeamLib.GetVersRef( nOrthoOpposite), GDB_ID.ROOT) + if dLen < 1.1 or dWidth < 1.1 then + local sWarn = 'Face ' .. string.format( '%d,%d', nSurfId, nFacet) .. ' skipped : too small' + EgtOutLog( sWarn, 1) + return true, '' + end + vtV1 = - vtV1 + local bInvert = ( ptP2:getZ() < ptP1:getZ() - 100 * GEO.EPS_SMALL) + if bInvert then + ptP1, ptP2 = ptP2, ptP1 + vtV1, vtV2 = vtV2, vtV1 + end + local vtTg = ptP2 - ptP1 ; vtTg:normalize() + local dAllStart = 0 + local dAllEnd = 0 + -- se bilinea, scarto la parte più allineata con la direzione ortogonale + if ( ( ptPm - ptP1) - ( ptPm - ptP1) * vtTg * vtTg):len() > 100 * GEO.EPS_SMALL then + local vtTg1 = ptPm - ptP1 ; vtTg1:normalize() + local vtTg2 = ptP2 - ptPm ; vtTg2:normalize() + local dDist1 = dist( ptP1, ptPm) + local dDist2 = dist( ptP2, ptPm) + --if dDist1 >= dDist2 then + if abs( vtTg1 * vtOrthO) < abs( vtTg2 * vtOrthO) then + ptP2 = Point3d( ptPm) + dAllEnd = - dDist2 - 10 * GEO.EPS_SMALL + else + ptP1 = Point3d( ptPm) + dAllStart = - dDist1 - 10 * GEO.EPS_SMALL + end + vtTg = ptP2 - ptP1 ; vtTg:normalize() + end + -- verifico se lavorazione con lama sotto e testa sopra + if not dVzLimDwnUp then dVzLimDwnUp = -0.5 end + local bDownUp = ( vtN:getZ() < dVzLimDwnUp) + local nFaceUse = nOrthoOpposite + if bDownUp then nFaceUse = BeamLib.GetOrtupOpposite( nOrthoOpposite) end + local bWsRight = ( bInvert ~= bDownUp) + local nWorkSide = EgtIf( bWsRight, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) + -- Versore di riferimento + local vtRef = Vector3d( vtTg) + vtRef:rotate( vtN, EgtIf( bInvert, -90, 90)) + -- Versore esterno + local vtOut = vtRef - vtRef * vtTg * vtTg ; vtOut:normalize() + -- Versore ausiliario (direzione braccio) + local vtAux = Vector3d( vtN:getX(), vtN:getY(), 0) ; vtAux:normalize() + vtAux:rotate( Z_AX(), EgtIf( bWsRight, 90, -90)) + if vtAux:isSmall() then + vtAux = Vector3d( vtOut:getX(), vtOut:getY(), 0) ; vtAux:normalize() + else + if abs( vtAux * vtOut) < GEO.EPS_SMALL then + if abs( vtTg:getZ()) > 0.5 then + if vtAux * vtRef < 0 then + vtAux = - vtAux + end + elseif vtAux * vtTg > 0 then + vtAux = - vtAux + end + elseif vtAux * vtOut < 0 then + vtAux = - vtAux + end + end + -- parametri di attacco/uscita + local b3Box = BBox3d( b3Raw) + b3Box:expand( dCutSic) + local dLiTang, dLiPerp, dLoTang, dLoPerp + if ( vtV1:getZ() > -0.1 or vtV2:getZ() > -0.1) and ( abs( vtV1:getY()) > 0.707 or abs( vtV2:getY()) > 0.707 or vtN:getZ() < 0.95) then + dLiTang, dLiPerp, dLoTang, dLoPerp = BeamLib.CalcLeadInOutGeom( ptP1, ptP2, vtV1, vtV2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + else + dLiTang, dLiPerp, dLoTang, dLoPerp = BeamLib.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + end + -- posizione braccio + EgtOutLog( 'vtN=' .. tostring( vtN) .. ' vtRef=' .. tostring( vtRef) .. ' vtOut=' .. tostring( vtOut) .. ' vtAux=' .. tostring( vtAux), 3) + local nSCC = MCH_SCC.NONE + if abs( vtAux:getX()) > abs( vtAux:getY()) then + nSCC = EgtIf( ( vtAux:getX() > 0), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + else + nSCC = EgtIf( ( vtAux:getY() > 0), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + -- inserisco la lavorazione di taglio + local sName = 'Cut_' .. ( EgtGetName( nSurfId) or tostring( nSurfId)) .. '_' .. tostring( nFacet + 1) + local nMchFId = EgtAddMachining( sName, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + sName = EgtGetOperationName( nMchFId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nSurfId, nFacet}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, bInvert) + EgtSetMachiningParam( MCH_MP.WORKSIDE, nWorkSide) + -- affondamento aggiuntivo + EgtSetMachiningParam( MCH_MP.OFFSR, -dCutExtra) + -- offset longitudinale + EgtSetMachiningParam( MCH_MP.OFFSL, EgtIf( bDownUp, -dCutOffset, dCutOffset)) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLiTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLiPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLoTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLoPerp) + -- imposto allungamenti iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAllStart - dAccStart) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAllEnd) + -- eventuali note + if sNotes and #sNotes > 0 then EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, sName +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.UpdateHCING( nRawId, dHCI) + local dOldHCI = EgtGetInfo( nRawId, 'HCING', 'd') + if not dOldHCI or dHCI > dOldHCI then + EgtSetInfo( nRawId, 'HCING', dHCI) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.UpdateTCING( nRawId, dTCI) + local dOldTCI = EgtGetInfo( nRawId, 'TCING', 'd') + if not dOldTCI or dTCI > dOldTCI then + EgtSetInfo( nRawId, 'TCING', dTCI) + end +end + +------------------------------------------------------------------------------------------------------------- +return BeamLib diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut b02.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut b02.lua new file mode 100644 index 0000000..2f219e4 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut b02.lua @@ -0,0 +1,622 @@ +-- DiceCut.lua by Egaltech s.r.l. 2019/10/02 +-- Gestione dei piano paralleli nei tagli lunghi: equidistanziamento dei piani paralleli + +-- Tabella per definizione modulo +local DiceCut = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' DiceCut started', 1) + +-- Dati +local BD = require( 'BeamData') + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- creo i piani paralleli +-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptC: il punto centrale del piano della feature +-- vtN: il versore normale del piano della feature +-- nCopyPlane: 0 => genera una copia del piano passato, 1=> non genera una copia del piano passato +-- dOffset: offset dei piani paralleli +-- nStep: numero massimo di step +-- Color: colre del fascio di piani +-- dTolerance*: distanza tra i piani paralleli e i piani di taglio (se non esistono altre superfici può essere omesso) +-- bNoTolOnFirstCut*: elimina la tolleranza per il primo piano del fascio (se non esistono altre superfici può essere omesso) +-- ptCCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +local function GetParallelPlanes( nParent, BBoxRawPart, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) + local ptMyCCut + if ptCCut and vtNCut then + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + local ptMyCCut1 + if ptCCut1 and vtNCut1 then + ptMyCCut1 = Point3d( ptCCut1 + 0 * vtNCut1) + end + local TabellaTmSurfParallel = {} + local i = nCopyPlane + while i < nStep do + local SurfId = EgtSurfTmPlaneInBBox( nParent, ptC + ( i * dOffset) * vtN, vtN, BBoxRawPart, GDB_RT.GLOB) + local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL) + if nFacet > 0 and vtNCut and ptMyCCut then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut, -vtNCut, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut, -vtNCut, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and vtNCut1 and ptMyCCut1 then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut1, -vtNCut1, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut1, -vtNCut1, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 then + table.insert( TabellaTmSurfParallel, SurfId) + EgtSetColor( SurfId, Color) + else + EgtErase( SurfId) + break + end + i = i + 1 + end + return TabellaTmSurfParallel +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrderedCutTable: +-- nParent: il layer +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function GetOrderedCutTable( nParent, TabParallelPlanes, TabOrtoPlanes) + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + local TabellaOrderParallelCut1 = {} + + for IndexTmP=1, StepParallel do + TabellaOrderParallelCut1[IndexTmP] = {} + for IndexOrto=1, StepOrto do + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT) + local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + if Copy1Id and ptOrtoN then + EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB) + EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + local nFacet1 = EgtSurfTmFacetCount( Copy1Id) + local nFacet2 = EgtSurfTmFacetCount( Copy2Id) + if nFacet1 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + elseif nFacet2 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + break + else + table.insert( TabellaOrderParallelCut1[IndexTmP], Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + end + end + end + table.insert(TabellaOrderParallelCut1[IndexTmP], TabParallelPlanes[IndexTmP]) + end + return TabellaOrderParallelCut1 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrtoCutCenter: +-- idFacet: l'id della faccia +-- ptC: il punto centrale della faccia +-- vtN: il versore normale della faccia +-- vtO: il versore dei piani ortogonali +-- dOffsetEff: offset della distanza dal punto centrale +-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset +local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff) + -- riferimento intrinseco + local asseX = vtO + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + -- ingombro della faccia secondo questo riferimento + local Box = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, Frame) + local dLen = Box:getDimX() + local dWidth = Box:getDimY() + + -- se faccia con un lato piccolo e non diretta troppo verso il basso, non servono dice + if ( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > -0.5 then + return nil, nil, nil + end + + local N = ceil( dLen / dOffsetEff) + local dOffsetRel = dLen / N + local dCopyPlane + local dCenOffs = ( Box:getMax():getX() + Box:getMin():getX()) / 2 + + if dLen <= dOffsetRel then + dOffsetRel = 0 + dCopyPlane = 1 + elseif dLen <= 2 * dOffsetRel then + dOffsetRel = 0 + dCopyPlane = 0 + else + if N % 2 == 0 then + dCopyPlane = 0 + elseif N % 2 == 1 then + dCopyPlane = 0.5 + end + end + + return dOffsetRel, dCopyPlane, dCenOffs +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- TableMesh: +-- TableOrto: tabella delle superfici dei piani ortogonali +-- TableParallel: tabella delle superfici dei piani paralleli +-- Forma una tabella unica delle superfici di taglio inserendo strati di tagli ortogonali alternati da strati di taglio parallelo +local function TableMesh( TableOrto, TableParallel) + local TableUnited = {} + for i=1, #TableOrto do + table.insert( TableUnited, TableOrto[i]) + table.insert( TableUnited, TableParallel[i]) + end + return TableUnited +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- FindValue: +-- tab: tabella da scansionare +-- val: valore da cercare +-- Verifica se tab contiene val, a supporto della funzione SortOrtoCutsByNormalMethod +local function FindValue( tab, val) + for index, value in ipairs( tab) do + if value == val then + return true + end + end + return false +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- SortOrtoCutsByNormalMethod: +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio sfruttando il prodotto dei versori normali (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function SortOrtoCutsByNormalMethod( TabParallelPlanes, TabOrtoPlanes) + -- tabella dei tagli ordinati + local TabOrderOrtoCut = {} + -- tabella ausiliaria dei dati inseriti nell'ordine + local TabAux = {} + -- ciclo di ordinamento + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + for IndexTmP=1, StepParallel do + TabOrderOrtoCut[IndexTmP] = {} + local ptParalN, vtNParalN = EgtSurfTmFacetCenter( TabParallelPlanes[IndexTmP][1], 0, GDB_ID.ROOT) + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- controlla che l'elemento da valutare non sia gia' stato inserito nella tabella + if not FindValue( TabAux, OrtoPlaneId) then + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( OrtoPlaneId, 0, GDB_ID.ROOT) + local scalarProduct = ( ptOrtoN - ptParalN) * vtNParalN + if scalarProduct > 0 then + table.insert( TabOrderOrtoCut[IndexTmP], OrtoPlaneId) + table.insert( TabAux, OrtoPlaneId) + end + end + end + end + end + -- cancello dal DB geometrico i tagli non inseriti + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- ricerco il taglio tra gli inseriti + if not FindValue( TabAux, OrtoPlaneId) then + EgtErase( OrtoPlaneId) + end + end + end + return TabOrderOrtoCut +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- VerifyFirstOrthoCut : +-- CutTable: tabella dei tagli +-- OffsetP: offset della distanza dal punto centrale +-- BBoxRawPart: il grezzo della barra +-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua +local function VerifyFirstOrthoCut( CutTable, OffsetP, BBoxRawPart) + + if not CutTable[1] or not CutTable[2] then return end + + local CutOId = CutTable[1][1] + local Cut1Id = CutTable[2][1] + local Cut2Id = CutTable[2][2] + + if CutOId and Cut1Id and Cut2Id then + -- centri e normali delle due semifacce + local ptC1, vtN1 = EgtSurfTmFacetCenter( Cut1Id, 0, GDB_ID.ROOT) + local ptC2, vtN2 = EgtSurfTmFacetCenter( Cut2Id, 0, GDB_ID.ROOT) + -- normale alla faccia ortogonale + local _, vtO = EgtSurfTmFacetCenter( CutOId, 0, GDB_ID.ROOT) + vtO = vtO - vtO * vtN1 * vtN1 ; vtO:normalize() + -- calcolo lunghezza prima semi-faccia + local asseX1 = vtO + local asseY1 = vtN1 ^ asseX1 + local Frame1 = Frame3d( ptC1, ptC1+asseX1, ptC1+asseY1) + local Box1 = EgtGetBBoxRef( Cut1Id, GDB_BB.STANDARD, Frame1) + local x1 = Box1:getDimX() + -- calcolo lunghezza seconda semi-faccia + local asseX2 = vtO + local asseY2 = vtN2 ^ asseX2 + local Frame2 = Frame3d( ptC2, ptC2+asseX2, ptC2+asseY2) + local Box2 = EgtGetBBoxRef( Cut2Id, GDB_BB.STANDARD, Frame2) + local x2 = Box2:getDimX() + -- lunghezza totale faccia + local dLongSize = x1 + x2 + -- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti + if dLongSize <= OffsetP + 1.0 and vtN1:getZ() > -0.5 then + local nParent = EgtGetParent( Cut1Id) + local SurfId = EgtSurfTmBySewing( nParent, { Cut1Id, Cut2Id}) + EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) + EgtErase( CutOId) + table.remove( CutTable[1], 1) + table.remove( CutTable[2], 1) + table.remove( CutTable[2], 1) + table.insert( CutTable[2], 1, SurfId) + end + end +end + +-- ricavo i vertici del box +local function CalcolaPuntiEstremiBox( BBoxRawPart) + local minPoint = BBoxRawPart:getMin() + local dimx = BBoxRawPart:getDimX() + local dimy = BBoxRawPart:getDimY() + local dimz = BBoxRawPart:getDimZ() + local TBoxPoint = {} + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY() , minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY() + dimy, minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY() + dimy, minPoint:getZ() + dimz)}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY(), minPoint:getZ() + dimz)}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY(), minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY() + dimy, minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY() + dimy, minPoint:getZ() + dimz)}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY(), minPoint:getZ() + dimz)}) + return TBoxPoint +end +-- + +local function CalcolaVettoriDaPuntoAEstremi(Ptc, Vtn, TBoxPoint) + for i = 1, #TBoxPoint, 1 do + local v = TBoxPoint[i].Point - Ptc + local p = Vtn*v + table.insert(TBoxPoint[i], {Vector = v, Project = p} ) + end +end +-- + +-- restituisce i punti che devono essere presi in considerazione per la costruzione del BoundingBox +local function VerificaEstremiGrezzo(TPoint) + local bEstremoCompreso + local TableGrezzo = {} + for i = 1, #TPoint, 1 do + bEstremoCompreso = true + for j = 1, #TPoint[i], 1 do + if TPoint[i][j].Project < GEO.EPS_SMALL then + bEstremoCompreso = false + end + end + table.insert(TableGrezzo, {Point = TPoint[i].Point, Compreso = bEstremoCompreso}) + end + return TableGrezzo +end +-- + +-- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature +-- le funzioni commentate permettono di vedere la creazione di BoundingBox +local function DistanzaMassima( Ptc1, Vtn1, BBoxRawPart, TPoint, Ptc2, Vtn2) + -- ottengo il riferimento al piano + local Frame1 = Frame3d( Ptc1, Vtn1) + --EgtSetGridFrame( Frame1) + local IdAux = EgtGroup( EgtGetCurrPart(), Frame1) + EgtSetName( IdAux, "Aux") + + local IdSurf1 = EgtSurfTmPlaneInBBox( IdAux, Ptc1, Vtn1, BBoxRawPart, GDB_RT.GLOB) + local IdSurf2 + + if Ptc2 and Vtn2 then + EgtCutSurfTmPlane( IdSurf1, Ptc2, -Vtn2, false, GDB_RT.GLOB) + IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, Ptc2, Vtn2, BBoxRawPart, GDB_RT.GLOB) + EgtCutSurfTmPlane( IdSurf2, Ptc1, -Vtn1, false, GDB_RT.GLOB) + end + + local BB1 = EgtGetBBoxRef( IdSurf1, GDB_BB.STANDARD, Frame1) + + if IdSurf2 then + local BB2 = EgtGetBBoxRef( IdSurf2, GDB_BB.STANDARD, Frame1) + BB1:Add( BB2) + end + + for j = 1, #TPoint, 1 do + if TPoint[j].Compreso then + TPoint[j].Point:toLoc( Frame1) + BB1:Add( TPoint[j].Point) + end + end + --EgtSetGridFrame( Frame1) + --EgtSurfTmBBox( IdAux, BB1, GDB_RT.GRID) + EgtErase( IdAux) + return BB1:getDimZ() +end +-- + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- DiceCut.GetDice : +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptCPlanes: il punto centrale del piano della feature +-- vtNPlanes: il versore normale del piano della feature +-- bGetOrtoPlanes*: se voglio calcolare i piani ortogonali al piano passato (se non esistono altre superfici può essere omesso) +-- ptCBond*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNBond*: il versore normale della superfice limitante (se non esistono altre superfici può essere omesso) +---------------------------------------------------------------------------------------------------------------------------------------------------- +function DiceCut.GetDice( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, bGetOrtoPlanes, ptCBond, vtNBond) + -- |NUOVO|: ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo + local TBoxPoint = CalcolaPuntiEstremiBox( BBoxRawPart) + local distPlanesP + local distPlanseO + CalcolaVettoriDaPuntoAEstremi( ptCPlanes, vtNPlanes, TBoxPoint) + if ptCBond and vtNBond then + CalcolaVettoriDaPuntoAEstremi( ptCBond, vtNBond, TBoxPoint) + end + local TabPointResult = VerificaEstremiGrezzo(TBoxPoint) + distPlanesP = DistanzaMassima( ptCPlanes, vtNPlanes, BBoxRawPart, TabPointResult, ptCBond, vtNBond) + if ptCBond and vtNBond then + distPlanesO = DistanzaMassima( ptCBond, vtNBond, BBoxRawPart, TabPointResult, ptCPlanes, vtNPlanes) + end + + local dTolerance = 0 -- distanza di sicurezza per i tagli ortogonali + local OffsetP = BD.MAX_DIM_DICE -- distanza tra i piani paralleli + local StepP = 20 -- numero massimo di piani paralleli da generare + local OffsetO = BD.MAX_DIM_DICE -- distanza tra i piani ortogonali + local StepO = 20 -- numero massimo di piani ortogonali da generare + + -- se normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda + if abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then + --OffsetP = BD.MAX_DIM_HTCUT + OffsetO = BD.MAX_DIM_HTCUT + end + + -- aggiungo piccolo extra agli offset + OffsetP = OffsetP + 10 * GEO.EPS_SMALL + OffsetO = OffsetO + 10 * GEO.EPS_SMALL + + -- se seconda faccia non definita, forzo calcolo piani ortogonali + if not ptCBond or not vtNBond then + bGetOrtoPlanes = true + end + + -- se piani non ortogonali, diminuisco la distanza di offset opportunamente + local originalOffsetP = OffsetP + if not bGetOrtoPlanes then + local dCoeff = ( vtNPlanes ^ vtNBond):len() + OffsetP = OffsetP * dCoeff + OffsetO = OffsetO * dCoeff + end + + --|NUOVO| + local n = ceil( distPlanesP/ OffsetP) + OffsetP = distPlanesP/ n + if distPlanesO then + n = ceil( distPlanesO/ OffsetO) + OffsetO = distPlanesO/ n + end + + -- elenco di tutte le superfici generate dai tagli + local TabFUCHSIA = {} + local TabGREEN = {} + + -- PIANI PARALLELI alla faccia di taglio + local TabellaTmSurfP = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, 0, OffsetP, StepP, Color3d( FUCHSIA(), 60), dTolerance, true, ptCBond, vtNBond) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfP, TabFromIn[i]) + end + + -- PIANI ORTOGONALI alla faccia di taglio + -- orientamento definito da seconda faccia + if not bGetOrtoPlanes then + local TabellaTmSurfOrto = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCBond, vtNBond, 0, OffsetO, StepO, Color3d( GREEN(), 60), dTolerance, false, ptCPlanes, vtNPlanes) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfOrto, TabFromIn[i]) + end + local TabellaOrderParallelCut = GetOrderedCutTable( nParent, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati + local TabellaOrderOrtoCut = GetOrderedCutTable( nParent, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato + + TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato + TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati + + -- orientamento da definire + else + for PlnInd = 1, #TabellaTmSurfP do + -- piano interno + local ptCInner, vtNInner = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd], 0, GDB_ID.ROOT) + -- eventuale piano esterno + local ptCOuter, vtNOuter = nil, nil + if PlnInd > 1 then + ptCOuter, vtNOuter = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd-1], 0, GDB_ID.ROOT) + vtNOuter = -vtNOuter + end + -- calcolo la direzione dei piani ortogonali + local vtO = VectorFromUprightOrtho( vtNInner) + if vtNInner:getZ() > 0.05 or vtNInner:getZ() < -0.5 then + vtO:rotate( vtNInner, 90) + -- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente + if abs( vtO:getY()) > abs( vtO:getX()) and vtNInner:getZ() > -0.5 then + vtO:rotate( vtNInner, 90) + else + if ptCInner:getX() > BBoxRawPart:getCenter():getX() then + if vtO:getX() < 0 then vtO = - vtO end + else + if vtO:getX() > 0 then vtO = - vtO end + end + end + end + -- calcolo le dimensioni dell'offset e se dove posizionare la prima faccia: + -- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato + -- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato + -- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero + local OffsetRel, CopyPlane, dCenOffs = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, OffsetO) + + if OffsetRel and CopyPlane and dCenOffs then + ptCInner = ptCInner + dCenOffs * vtO + local TabRight = GetParallelPlanes( nParent, BBoxRawPart, ptCInner, vtO, CopyPlane, -OffsetO, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + if CopyPlane == 0 then + CopyPlane = 1 + end + local TabLeft = GetParallelPlanes( nParent, BBoxRawPart, ptCInner, vtO, CopyPlane, OffsetO, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + -- carico la tabella con gli indici riordinati + local TempOrtoTab = {} + for i = #TabLeft, 1, -1 do + table.insert( TempOrtoTab, TabLeft[i]) + end + for i = 1, #TabRight do + table.insert( TempOrtoTab, TabRight[i]) + end + -- creo una tabella per ogni piano per generare i tagli sulla Inner + local TempParTab = GetOrderedCutTable( nParent, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) + for i = 1, #TempParTab do + table.insert( TabFUCHSIA, TempParTab[i]) + end + table.insert( TabGREEN, TempOrtoTab) + else + table.insert( TabFUCHSIA, {TabellaTmSurfP[PlnInd]}) + table.insert( TabGREEN, {}) + end + end + end + + -- Se sono state costruite non più di una faccia parallela e una faccia perpendicolare, allora non servono e tengo le originali + if #TabGREEN == 1 and #TabGREEN[1] <= 1 and #TabFUCHSIA == 1 and #TabFUCHSIA[1] <= 1 then + if #TabGREEN[1] == 1 then + EgtErase( TabGREEN[1][1]) + end + TabGREEN = {} + if #TabFUCHSIA[1] == 1 then + EgtErase( TabFUCHSIA[1][1]) + end + TabFUCHSIA = {} + end + + -- Si uniscono le tabelle dei tagli ortogonali e paralleli in una sola tabella + local UltimateTable = TableMesh( TabGREEN, TabFUCHSIA) + + -- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato + if not bGetOrtoPlanes then + VerifyFirstOrthoCut( UltimateTable, originalOffsetP, BBoxRawPart) + end + + return UltimateTable +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- PrintOrderCut: +-- TabellaOrderCut: tabella delle superfici di taglio +-- stampo l'ordine dei piani di taglio ricevendo una tabella con gli strati parallelo/ortogonali già ordinati +function DiceCut.PrintOrderCut( TabellaOrderCut) + local Step = #TabellaOrderCut + if Step > 0 then + EgtOutLog( " L'ordine delle superfici da tagliare è il seguente:") + else + EgtOutLog( ' Non sono necessarie superfici aggiuntive di taglio.') + end + for i = 1, Step do + if i % 2 == 1 then + EgtOutLog( ' *** Strato di taglio ' .. EgtNumToString( ( i + 1) / 2, 0)) + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli ortogonali: ') + else + EgtOutLog( ' Tagli ortogonali assenti') + end + else + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli paralleli: ') + else + EgtOutLog( ' Tagli paralleli assenti') + end + end + for j=1, #TabellaOrderCut[i] do + EgtOutLog( ' Indice faccia ' .. (TabellaOrderCut[i][j] or 0)) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +local function DiceCutTest() + + -- salvo l'indice del layer Trimesh selezionato + local SelectedIndex = EgtGetFirstSelectedObj() + -- verifico che sia selezionato un elemento + if not SelectedIndex then return end + + -- salvo l'indice del layer Processing + local nParent = EgtGetParent( SelectedIndex) + -- salvo l'indice del layer Part + local nRawPart = EgtGetParent( nParent) + local nBox = EgtGetFirstNameInGroup( nRawPart, 'Box') + -- carico il bounding box della trave + -- local BBoxRawPart = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD ) + local BBoxRawPart = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD ) + -- seleziono il Part e il Layer di destinazione + EgtSetCurrPartLayer( nRawPart, nParent) + + -- conto il numero di facce da processare + local nFacet = EgtSurfTmFacetCount( SelectedIndex) + EgtOutLog( ' Numero facce ' .. nFacet, 1) + + -- salvo + local TabPlanesFeatures = {} + for i = 1, nFacet do + local ptC, vtN = EgtSurfTmFacetCenter( SelectedIndex, i - 1, GDB_ID.ROOT) + table.insert( TabPlanesFeatures, { ptC = ptC, vtN = vtN}) + end + local ptC1 = Point3d( TabPlanesFeatures[1].ptC) + local vtN1 = Vector3d( TabPlanesFeatures[1].vtN) + + local CutTable = {} + if nFacet == 1 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, true) + elseif nFacet == 2 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN) + end + + if EgtGetDebugLevel() > 1 then + DiceCut.PrintOrderCut( CutTable) + end + + EgtDeselectAll() + + EgtDraw() +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +--DiceCutTest() + +return DiceCut diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut b04.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut b04.lua new file mode 100644 index 0000000..2c4fdd4 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut b04.lua @@ -0,0 +1,641 @@ +-- DiceCut.lua by Egaltech s.r.l. 2019/10/02 +-- Gestione dei piano paralleli nei tagli lunghi: equidistanziamento dei piani paralleli +-- ver b04 2019/10/03 +-- Tabella per definizione modulo +local DiceCut = {} + +-- Include +require( 'EgtBase') +EgtEnableDebug( true) +EgtOutLog( ' DiceCut started', 1) + +-- Dati +local BD = require( 'BeamData') + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- creo i piani paralleli +-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptC: il punto centrale del piano della feature +-- vtN: il versore normale del piano della feature +-- nCopyPlane: 0 => genera una copia del piano passato, 1=> non genera una copia del piano passato +-- dOffset: offset dei piani paralleli +-- nStep: numero massimo di step +-- Color: colre del fascio di piani +-- dTolerance*: distanza tra i piani paralleli e i piani di taglio (se non esistono altre superfici può essere omesso) +-- bNoTolOnFirstCut*: elimina la tolleranza per il primo piano del fascio (se non esistono altre superfici può essere omesso) +-- ptCCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +local function GetParallelPlanes( nParent, BBoxRawPart, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) + local ptMyCCut + if ptCCut and vtNCut then + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + local ptMyCCut1 + if ptCCut1 and vtNCut1 then + ptMyCCut1 = Point3d( ptCCut1 + 0 * vtNCut1) + end + local TabellaTmSurfParallel = {} + local i = nCopyPlane + while i < nStep do + local SurfId = EgtSurfTmPlaneInBBox( nParent, ptC + ( i * dOffset) * vtN, vtN, BBoxRawPart, GDB_RT.GLOB) + local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL) + if nFacet > 0 and vtNCut and ptMyCCut then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut, -vtNCut, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut, -vtNCut, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and vtNCut1 and ptMyCCut1 then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut1, -vtNCut1, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut1, -vtNCut1, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 then + table.insert( TabellaTmSurfParallel, SurfId) + EgtSetColor( SurfId, Color) + else + EgtErase( SurfId) + break + end + i = i + 1 + end + return TabellaTmSurfParallel +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrderedCutTable: +-- nParent: il layer +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function GetOrderedCutTable( nParent, TabParallelPlanes, TabOrtoPlanes) + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + local TabellaOrderParallelCut1 = {} + + for IndexTmP=1, StepParallel do + TabellaOrderParallelCut1[IndexTmP] = {} + for IndexOrto=1, StepOrto do + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT) + local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + if Copy1Id and ptOrtoN then + EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB) + EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + local nFacet1 = EgtSurfTmFacetCount( Copy1Id) + local nFacet2 = EgtSurfTmFacetCount( Copy2Id) + if nFacet1 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + elseif nFacet2 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + break + else + table.insert( TabellaOrderParallelCut1[IndexTmP], Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + end + end + end + table.insert(TabellaOrderParallelCut1[IndexTmP], TabParallelPlanes[IndexTmP]) + end + return TabellaOrderParallelCut1 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrtoCutCenter: +-- idFacet: l'id della faccia +-- ptC: il punto centrale della faccia +-- vtN: il versore normale della faccia +-- vtO: il versore dei piani ortogonali +-- dOffsetEff: offset della distanza dal punto centrale +-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset +local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff) + -- riferimento intrinseco + local asseX = vtO + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + -- ingombro della faccia secondo questo riferimento + local Box = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, Frame) + local dLen = Box:getDimX() + local dWidth = Box:getDimY() + + -- se faccia con un lato piccolo e non diretta troppo verso il basso, non servono dice + if ( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > -0.5 then + return nil, nil, nil + end + + local N = ceil( dLen / dOffsetEff) + local dOffsetRel = dLen / N + local dCopyPlane + local dCenOffs = ( Box:getMax():getX() + Box:getMin():getX()) / 2 + + if dLen <= dOffsetRel then + dOffsetRel = 0 + dCopyPlane = 1 + elseif dLen <= 2 * dOffsetRel then + dOffsetRel = 0 + dCopyPlane = 0 + else + if N % 2 == 0 then + dCopyPlane = 0 + elseif N % 2 == 1 then + dCopyPlane = 0.5 + end + end + + -- |NUOVO| : restituisco il punto centrale del Box come centro delle facce + local IdAux = EgtGroup( EgtGetParent( FacetId), Frame) + EgtSetName( IdAux, "Aux") + ptC = EgtSurfTmFacetCenter( EgtSurfTmBBox( IdAux, Box, GDB_RT.LOC), 0, GDB_ID.ROOT) + EgtErase( IdAux) + + return dOffsetRel, dCopyPlane, dCenOffs +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- TableMesh: +-- TableOrto: tabella delle superfici dei piani ortogonali +-- TableParallel: tabella delle superfici dei piani paralleli +-- Forma una tabella unica delle superfici di taglio inserendo strati di tagli ortogonali alternati da strati di taglio parallelo +local function TableMesh( TableOrto, TableParallel) + local TableUnited = {} + for i=1, #TableOrto do + table.insert( TableUnited, TableOrto[i]) + table.insert( TableUnited, TableParallel[i]) + end + return TableUnited +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- FindValue: +-- tab: tabella da scansionare +-- val: valore da cercare +-- Verifica se tab contiene val, a supporto della funzione SortOrtoCutsByNormalMethod +local function FindValue( tab, val) + for index, value in ipairs( tab) do + if value == val then + return true + end + end + return false +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- SortOrtoCutsByNormalMethod: +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio sfruttando il prodotto dei versori normali (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function SortOrtoCutsByNormalMethod( TabParallelPlanes, TabOrtoPlanes) + -- tabella dei tagli ordinati + local TabOrderOrtoCut = {} + -- tabella ausiliaria dei dati inseriti nell'ordine + local TabAux = {} + -- ciclo di ordinamento + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + for IndexTmP=1, StepParallel do + TabOrderOrtoCut[IndexTmP] = {} + local ptParalN, vtNParalN = EgtSurfTmFacetCenter( TabParallelPlanes[IndexTmP][1], 0, GDB_ID.ROOT) + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- controlla che l'elemento da valutare non sia gia' stato inserito nella tabella + if not FindValue( TabAux, OrtoPlaneId) then + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( OrtoPlaneId, 0, GDB_ID.ROOT) + local scalarProduct = ( ptOrtoN - ptParalN) * vtNParalN + if scalarProduct > 0 then + table.insert( TabOrderOrtoCut[IndexTmP], OrtoPlaneId) + table.insert( TabAux, OrtoPlaneId) + end + end + end + end + end + -- cancello dal DB geometrico i tagli non inseriti + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- ricerco il taglio tra gli inseriti + if not FindValue( TabAux, OrtoPlaneId) then + EgtErase( OrtoPlaneId) + end + end + end + return TabOrderOrtoCut +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- VerifyFirstOrthoCut : +-- CutTable: tabella dei tagli +-- OffsetP: offset della distanza dal punto centrale +-- BBoxRawPart: il grezzo della barra +-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua +local function VerifyFirstOrthoCut( CutTable, OffsetP, BBoxRawPart) + + if not CutTable[1] or not CutTable[2] then return end + + local CutOId = CutTable[1][1] + local Cut1Id = CutTable[2][1] + local Cut2Id = CutTable[2][2] + + if CutOId and Cut1Id and Cut2Id then + -- centri e normali delle due semifacce + local ptC1, vtN1 = EgtSurfTmFacetCenter( Cut1Id, 0, GDB_ID.ROOT) + local ptC2, vtN2 = EgtSurfTmFacetCenter( Cut2Id, 0, GDB_ID.ROOT) + -- normale alla faccia ortogonale + local _, vtO = EgtSurfTmFacetCenter( CutOId, 0, GDB_ID.ROOT) + vtO = vtO - vtO * vtN1 * vtN1 ; vtO:normalize() + -- calcolo lunghezza prima semi-faccia + local asseX1 = vtO + local asseY1 = vtN1 ^ asseX1 + local Frame1 = Frame3d( ptC1, ptC1+asseX1, ptC1+asseY1) + local Box1 = EgtGetBBoxRef( Cut1Id, GDB_BB.STANDARD, Frame1) + local x1 = Box1:getDimX() + -- calcolo lunghezza seconda semi-faccia + local asseX2 = vtO + local asseY2 = vtN2 ^ asseX2 + local Frame2 = Frame3d( ptC2, ptC2+asseX2, ptC2+asseY2) + local Box2 = EgtGetBBoxRef( Cut2Id, GDB_BB.STANDARD, Frame2) + local x2 = Box2:getDimX() + -- lunghezza totale faccia + local dLongSize = x1 + x2 + -- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti + if dLongSize <= OffsetP + 1.0 and vtN1:getZ() > -0.5 then + local nParent = EgtGetParent( Cut1Id) + local SurfId = EgtSurfTmBySewing( nParent, { Cut1Id, Cut2Id}) + EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) + EgtErase( CutOId) + table.remove( CutTable[1], 1) + table.remove( CutTable[2], 1) + table.remove( CutTable[2], 1) + table.insert( CutTable[2], 1, SurfId) + end + end +end + +-- ricavo i vertici del box +local function CalcolaPuntiEstremiBox( BBoxRawPart) + local minPoint = BBoxRawPart:getMin() + local dimx = BBoxRawPart:getDimX() + local dimy = BBoxRawPart:getDimY() + local dimz = BBoxRawPart:getDimZ() + local TBoxPoint = {} + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY() , minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY() + dimy, minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY() + dimy, minPoint:getZ() + dimz)}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY(), minPoint:getZ() + dimz)}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY(), minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY() + dimy, minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY() + dimy, minPoint:getZ() + dimz)}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY(), minPoint:getZ() + dimz)}) + return TBoxPoint +end +-- + +local function CalcolaVettoriDaPuntoAEstremi(Ptc, Vtn, TBoxPoint) + for i = 1, #TBoxPoint, 1 do + local v = TBoxPoint[i].Point - Ptc + local p = Vtn*v + table.insert(TBoxPoint[i], {Vector = v, Project = p} ) + end +end +-- + +-- restituisce i punti che devono essere presi in considerazione per la costruzione del BoundingBox +local function VerificaEstremiGrezzo(TPoint) + local bEstremoCompreso + local TableGrezzo = {} + for i = 1, #TPoint, 1 do + bEstremoCompreso = true + for j = 1, #TPoint[i], 1 do + if TPoint[i][j].Project < GEO.EPS_SMALL then + bEstremoCompreso = false + end + end + table.insert(TableGrezzo, {Point = TPoint[i].Point, Compreso = bEstremoCompreso}) + end + return TableGrezzo +end +-- + +-- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature +-- le funzioni commentate permettono di vedere la creazione di BoundingBox +local function DistanzaMassima( nParent, Ptc1, Vtn1, BBoxRawPart, TPoint, Ptc2, Vtn2) + -- ottengo il riferimento al piano + local Frame1 = Frame3d( Ptc1, Vtn1) + --EgtSetGridFrame( Frame1) + local IdAux = EgtGroup( nParent, Frame1) + EgtSetName( IdAux, "Aux") + + local IdSurf1 = EgtSurfTmPlaneInBBox( IdAux, Ptc1, Vtn1, BBoxRawPart, GDB_RT.GLOB) + local IdSurf2 + + if Ptc2 and Vtn2 then + EgtCutSurfTmPlane( IdSurf1, Ptc2, -Vtn2, false, GDB_RT.GLOB) + IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, Ptc2, Vtn2, BBoxRawPart, GDB_RT.GLOB) + EgtCutSurfTmPlane( IdSurf2, Ptc1, -Vtn1, false, GDB_RT.GLOB) + end + + local BB1 = EgtGetBBoxRef( IdSurf1, GDB_BB.STANDARD, Frame1) + + if IdSurf2 then + local BB2 = EgtGetBBoxRef( IdSurf2, GDB_BB.STANDARD, Frame1) + BB1:Add( BB2) + end + + for j = 1, #TPoint, 1 do + if TPoint[j].Compreso then + TPoint[j].Point:toLoc( Frame1) + BB1:Add( TPoint[j].Point) + end + end + --EgtSetGridFrame( Frame1) + --EgtSurfTmBBox( IdAux, BB1, GDB_RT.GRID) + EgtErase( IdAux) + return BB1:getDimZ() +end +-- + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- DiceCut.GetDice : +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptCPlanes: il punto centrale del piano della feature +-- vtNPlanes: il versore normale del piano della feature +-- bGetOrtoPlanes*: se voglio calcolare i piani ortogonali al piano passato (se non esistono altre superfici può essere omesso) +-- ptCBond*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNBond*: il versore normale della superfice limitante (se non esistono altre superfici può essere omesso) +---------------------------------------------------------------------------------------------------------------------------------------------------- +function DiceCut.GetDice( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, bGetOrtoPlanes, ptCBond, vtNBond) + + --[[ ]] + + -- |NUOVO|: ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo + local TBoxPoint = CalcolaPuntiEstremiBox( BBoxRawPart) + local distPlanesP + local distPlanseO + CalcolaVettoriDaPuntoAEstremi( ptCPlanes, vtNPlanes, TBoxPoint) + if ptCBond and vtNBond then + CalcolaVettoriDaPuntoAEstremi( ptCBond, vtNBond, TBoxPoint) + end + local TabPointResult = VerificaEstremiGrezzo(TBoxPoint) + distPlanesP = DistanzaMassima( nParent, ptCPlanes, vtNPlanes, BBoxRawPart, TabPointResult, ptCBond, vtNBond) + if ptCBond and vtNBond then + distPlanesO = DistanzaMassima( nParent, ptCBond, vtNBond, BBoxRawPart, TabPointResult, ptCPlanes, vtNPlanes) + end + + + -- ]] + + local dTolerance = 0 -- distanza di sicurezza per i tagli ortogonali + local OffsetP = BD.MAX_DIM_DICE -- distanza tra i piani paralleli + local StepP = 20 -- numero massimo di piani paralleli da generare + local OffsetO = BD.MAX_DIM_DICE -- distanza tra i piani ortogonali + local StepO = 20 -- numero massimo di piani ortogonali da generare + + -- se normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda + if abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then + --OffsetP = BD.MAX_DIM_HTCUT + OffsetO = BD.MAX_DIM_HTCUT + end + + -- aggiungo piccolo extra agli offset + OffsetP = OffsetP + 10 * GEO.EPS_SMALL + OffsetO = OffsetO + 10 * GEO.EPS_SMALL + + -- se seconda faccia non definita, forzo calcolo piani ortogonali + if not ptCBond or not vtNBond then + bGetOrtoPlanes = true + end + + -- se piani non ortogonali, diminuisco la distanza di offset opportunamente + local originalOffsetP = OffsetP + if not bGetOrtoPlanes then + local dCoeff = ( vtNPlanes ^ vtNBond):len() + OffsetP = OffsetP * dCoeff + OffsetO = OffsetO * dCoeff + end + + + + + --|NUOVO| + local n = ceil( distPlanesP/ OffsetP) + OffsetP = distPlanesP/ n + if distPlanesO then + n = ceil( distPlanesO/ OffsetO) + OffsetO = distPlanesO/ n + end + + + + + + -- elenco di tutte le superfici generate dai tagli + local TabFUCHSIA = {} + local TabGREEN = {} + + -- PIANI PARALLELI alla faccia di taglio + local TabellaTmSurfP = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, 0, OffsetP, StepP, Color3d( FUCHSIA(), 60), dTolerance, true, ptCBond, vtNBond) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfP, TabFromIn[i]) + end + + -- PIANI ORTOGONALI alla faccia di taglio + -- orientamento definito da seconda faccia + if not bGetOrtoPlanes then + local TabellaTmSurfOrto = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCBond, vtNBond, 0, OffsetO, StepO, Color3d( GREEN(), 60), dTolerance, false, ptCPlanes, vtNPlanes) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfOrto, TabFromIn[i]) + end + local TabellaOrderParallelCut = GetOrderedCutTable( nParent, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati + local TabellaOrderOrtoCut = GetOrderedCutTable( nParent, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato + + TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato + TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati + + -- orientamento da definire + else + for PlnInd = 1, #TabellaTmSurfP do + -- piano interno + local ptCInner, vtNInner = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd], 0, GDB_ID.ROOT) + -- eventuale piano esterno + local ptCOuter, vtNOuter = nil, nil + if PlnInd > 1 then + ptCOuter, vtNOuter = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd-1], 0, GDB_ID.ROOT) + vtNOuter = -vtNOuter + end + -- calcolo la direzione dei piani ortogonali + local vtO = VectorFromUprightOrtho( vtNInner) + if vtNInner:getZ() > 0.05 or vtNInner:getZ() < -0.5 or abs( vtNInner:getY()) > 0.866 then + vtO:rotate( vtNInner, 90) + -- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente + if abs( vtO:getY()) > abs( vtO:getX()) and vtNInner:getZ() > -0.5 then + vtO:rotate( vtNInner, 90) + else + if ptCInner:getX() > BBoxRawPart:getCenter():getX() then + if vtO:getX() < 0 then vtO = - vtO end + else + if vtO:getX() > 0 then vtO = - vtO end + end + end + end + -- calcolo le dimensioni dell'offset e se dove posizionare la prima faccia: + -- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato + -- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato + -- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero + local OffsetRel, CopyPlane, dCenOffs = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, OffsetO) + + if OffsetRel and CopyPlane and dCenOffs then + ptCInner = ptCInner + dCenOffs * vtO + local TabRight = GetParallelPlanes( nParent, BBoxRawPart, ptCInner, vtO, CopyPlane, -OffsetO, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + if CopyPlane == 0 then + CopyPlane = 1 + end + local TabLeft = GetParallelPlanes( nParent, BBoxRawPart, ptCInner, vtO, CopyPlane, OffsetO, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + -- carico la tabella con gli indici riordinati + local TempOrtoTab = {} + for i = #TabLeft, 1, -1 do + table.insert( TempOrtoTab, TabLeft[i]) + end + for i = 1, #TabRight do + table.insert( TempOrtoTab, TabRight[i]) + end + -- creo una tabella per ogni piano per generare i tagli sulla Inner + local TempParTab = GetOrderedCutTable( nParent, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) + for i = 1, #TempParTab do + table.insert( TabFUCHSIA, TempParTab[i]) + end + table.insert( TabGREEN, TempOrtoTab) + else + table.insert( TabFUCHSIA, {TabellaTmSurfP[PlnInd]}) + table.insert( TabGREEN, {}) + end + end + end + + -- Se sono state costruite non più di una faccia parallela e una faccia perpendicolare, allora non servono e tengo le originali + if #TabGREEN == 1 and #TabGREEN[1] <= 1 and #TabFUCHSIA == 1 and #TabFUCHSIA[1] <= 1 then + if #TabGREEN[1] == 1 then + EgtErase( TabGREEN[1][1]) + end + TabGREEN = {} + if #TabFUCHSIA[1] == 1 then + EgtErase( TabFUCHSIA[1][1]) + end + TabFUCHSIA = {} + end + + -- Si uniscono le tabelle dei tagli ortogonali e paralleli in una sola tabella + local UltimateTable = TableMesh( TabGREEN, TabFUCHSIA) + + -- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato + if not bGetOrtoPlanes then + VerifyFirstOrthoCut( UltimateTable, originalOffsetP, BBoxRawPart) + end + + return UltimateTable +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- PrintOrderCut: +-- TabellaOrderCut: tabella delle superfici di taglio +-- stampo l'ordine dei piani di taglio ricevendo una tabella con gli strati parallelo/ortogonali già ordinati +function DiceCut.PrintOrderCut( TabellaOrderCut) + local Step = #TabellaOrderCut + if Step > 0 then + EgtOutLog( " L'ordine delle superfici da tagliare è il seguente:") + else + EgtOutLog( ' Non sono necessarie superfici aggiuntive di taglio.') + end + for i = 1, Step do + if i % 2 == 1 then + EgtOutLog( ' *** Strato di taglio ' .. EgtNumToString( ( i + 1) / 2, 0)) + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli ortogonali: ') + else + EgtOutLog( ' Tagli ortogonali assenti') + end + else + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli paralleli: ') + else + EgtOutLog( ' Tagli paralleli assenti') + end + end + for j=1, #TabellaOrderCut[i] do + EgtOutLog( ' Indice faccia ' .. (TabellaOrderCut[i][j] or 0)) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +local function DiceCutTest() + + -- salvo l'indice del layer Trimesh selezionato + local SelectedIndex = EgtGetFirstSelectedObj() + -- verifico che sia selezionato un elemento + if not SelectedIndex then return end + + -- salvo l'indice del layer Processing + local nParent = EgtGetParent( SelectedIndex) + -- salvo l'indice del layer Part + local nRawPart = EgtGetParent( nParent) + local nBox = EgtGetFirstNameInGroup( nRawPart, 'Box') + -- carico il bounding box della trave + -- local BBoxRawPart = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD ) + local BBoxRawPart = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD ) + -- seleziono il Part e il Layer di destinazione + EgtSetCurrPartLayer( nRawPart, nParent) + + -- conto il numero di facce da processare + local nFacet = EgtSurfTmFacetCount( SelectedIndex) + EgtOutLog( ' Numero facce ' .. nFacet, 1) + + -- salvo + local TabPlanesFeatures = {} + for i = 1, nFacet do + local ptC, vtN = EgtSurfTmFacetCenter( SelectedIndex, i - 1, GDB_ID.ROOT) + table.insert( TabPlanesFeatures, { ptC = ptC, vtN = vtN}) + end + local ptC1 = Point3d( TabPlanesFeatures[1].ptC) + local vtN1 = Vector3d( TabPlanesFeatures[1].vtN) + + local CutTable = {} + if nFacet == 1 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, true) + elseif nFacet == 2 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN) + end + + if EgtGetDebugLevel() > 1 then + DiceCut.PrintOrderCut( CutTable) + end + + EgtDeselectAll() + + EgtDraw() +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +--DiceCutTest() + +return DiceCut diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut original.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut original.lua new file mode 100644 index 0000000..da23780 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut original.lua @@ -0,0 +1,517 @@ +-- DiceCut.lua by Egaltech s.r.l. 2019/08/07 +-- Gestione dei piano paralleli nei tagli lunghi + +-- Tabella per definizione modulo +local DiceCut = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' DiceCut started', 1) + +-- Dati +local BD = require( 'BeamData') + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- creo i piani paralleli +-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptC: il punto centrale del piano della feature +-- vtN: il versore normale del piano della feature +-- nCopyPlane: 0 => genera una copia del piano passato, 1=> non genera una copia del piano passato +-- dOffset: offset dei piani paralleli +-- nStep: numero massimo di step +-- Color: colre del fascio di piani +-- dTolerance*: distanza tra i piani paralleli e i piani di taglio (se non esistono altre superfici può essere omesso) +-- bNoTolOnFirstCut*: elimina la tolleranza per il primo piano del fascio (se non esistono altre superfici può essere omesso) +-- ptCCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +local function GetParallelPlanes( nParent, BBoxRawPart, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) + local ptMyCCut + if ptCCut and vtNCut then + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + local ptMyCCut1 + if ptCCut1 and vtNCut1 then + ptMyCCut1 = Point3d( ptCCut1 + 0 * vtNCut1) + end + local TabellaTmSurfParallel = {} + local i = nCopyPlane + while i < nStep do + local SurfId = EgtSurfTmPlaneInBBox( nParent, ptC + ( i * dOffset) * vtN, vtN, BBoxRawPart, GDB_RT.GLOB) + local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL) + if nFacet > 0 and vtNCut and ptMyCCut then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut, -vtNCut, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut, -vtNCut, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and vtNCut1 and ptMyCCut1 then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut1, -vtNCut1, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut1, -vtNCut1, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 then + table.insert( TabellaTmSurfParallel, SurfId) + EgtSetColor( SurfId, Color) + else + EgtErase( SurfId) + break + end + i = i + 1 + end + return TabellaTmSurfParallel +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrderedCutTable: +-- nParent: il layer +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function GetOrderedCutTable( nParent, TabParallelPlanes, TabOrtoPlanes) + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + local TabellaOrderParallelCut1 = {} + + for IndexTmP=1, StepParallel do + TabellaOrderParallelCut1[IndexTmP] = {} + for IndexOrto=1, StepOrto do + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT) + local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + if Copy1Id and ptOrtoN then + EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB) + EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + local nFacet1 = EgtSurfTmFacetCount( Copy1Id) + local nFacet2 = EgtSurfTmFacetCount( Copy2Id) + if nFacet1 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + elseif nFacet2 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + break + else + table.insert( TabellaOrderParallelCut1[IndexTmP], Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + end + end + end + table.insert(TabellaOrderParallelCut1[IndexTmP], TabParallelPlanes[IndexTmP]) + end + return TabellaOrderParallelCut1 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrtoCutCenter: +-- idFacet: l'id della faccia +-- ptC: il punto centrale della faccia +-- vtN: il versore normale della faccia +-- vtO: il versore dei piani ortogonali +-- dOffsetEff: offset della distanza dal punto centrale +-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset +local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff) + -- riferimento intrinseco + local asseX = vtO + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + -- ingombro della faccia secondo questo riferimento + local Box = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, Frame) + local dLen = Box:getDimX() + local dWidth = Box:getDimY() + + -- se faccia con un lato piccolo e non diretta troppo verso il basso, non servono dice + if ( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > -0.5 then + return nil, nil, nil + end + + local N = ceil( dLen / dOffsetEff) + local dOffsetRel = dLen / N + local dCopyPlane + local dCenOffs = ( Box:getMax():getX() + Box:getMin():getX()) / 2 + + if dLen <= dOffsetRel then + dOffsetRel = 0 + dCopyPlane = 1 + elseif dLen <= 2 * dOffsetRel then + dOffsetRel = 0 + dCopyPlane = 0 + else + if N % 2 == 0 then + dCopyPlane = 0 + elseif N % 2 == 1 then + dCopyPlane = 0.5 + end + end + return dOffsetRel, dCopyPlane, dCenOffs +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- TableMesh: +-- TableOrto: tabella delle superfici dei piani ortogonali +-- TableParallel: tabella delle superfici dei piani paralleli +-- Forma una tabella unica delle superfici di taglio inserendo strati di tagli ortogonali alternati da strati di taglio parallelo +local function TableMesh( TableOrto, TableParallel) + local TableUnited = {} + for i=1, #TableOrto do + table.insert( TableUnited, TableOrto[i]) + table.insert( TableUnited, TableParallel[i]) + end + return TableUnited +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- FindValue: +-- tab: tabella da scansionare +-- val: valore da cercare +-- Verifica se tab contiene val, a supporto della funzione SortOrtoCutsByNormalMethod +local function FindValue( tab, val) + for index, value in ipairs( tab) do + if value == val then + return true + end + end + return false +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- SortOrtoCutsByNormalMethod: +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio sfruttando il prodotto dei versori normali (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function SortOrtoCutsByNormalMethod( TabParallelPlanes, TabOrtoPlanes) + -- tabella dei tagli ordinati + local TabOrderOrtoCut = {} + -- tabella ausiliaria dei dati inseriti nell'ordine + local TabAux = {} + -- ciclo di ordinamento + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + for IndexTmP=1, StepParallel do + TabOrderOrtoCut[IndexTmP] = {} + local ptParalN, vtNParalN = EgtSurfTmFacetCenter( TabParallelPlanes[IndexTmP][1], 0, GDB_ID.ROOT) + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- controlla che l'elemento da valutare non sia gia' stato inserito nella tabella + if not FindValue( TabAux, OrtoPlaneId) then + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( OrtoPlaneId, 0, GDB_ID.ROOT) + local scalarProduct = ( ptOrtoN - ptParalN) * vtNParalN + if scalarProduct > 0 then + table.insert( TabOrderOrtoCut[IndexTmP], OrtoPlaneId) + table.insert( TabAux, OrtoPlaneId) + end + end + end + end + end + -- cancello dal DB geometrico i tagli non inseriti + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- ricerco il taglio tra gli inseriti + if not FindValue( TabAux, OrtoPlaneId) then + EgtErase( OrtoPlaneId) + end + end + end + return TabOrderOrtoCut +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- VerifyFirstOrthoCut : +-- CutTable: tabella dei tagli +-- OffsetP: offset della distanza dal punto centrale +-- BBoxRawPart: il grezzo della barra +-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua +local function VerifyFirstOrthoCut( CutTable, OffsetP, BBoxRawPart) + + if not CutTable[1] or not CutTable[2] then return end + + local CutOId = CutTable[1][1] + local Cut1Id = CutTable[2][1] + local Cut2Id = CutTable[2][2] + + if CutOId and Cut1Id and Cut2Id then + -- centri e normali delle due semifacce + local ptC1, vtN1 = EgtSurfTmFacetCenter( Cut1Id, 0, GDB_ID.ROOT) + local ptC2, vtN2 = EgtSurfTmFacetCenter( Cut2Id, 0, GDB_ID.ROOT) + -- normale alla faccia ortogonale + local _, vtO = EgtSurfTmFacetCenter( CutOId, 0, GDB_ID.ROOT) + vtO = vtO - vtO * vtN1 * vtN1 ; vtO:normalize() + -- calcolo lunghezza prima semi-faccia + local asseX1 = vtO + local asseY1 = vtN1 ^ asseX1 + local Frame1 = Frame3d( ptC1, ptC1+asseX1, ptC1+asseY1) + local Box1 = EgtGetBBoxRef( Cut1Id, GDB_BB.STANDARD, Frame1) + local x1 = Box1:getDimX() + -- calcolo lunghezza seconda semi-faccia + local asseX2 = vtO + local asseY2 = vtN2 ^ asseX2 + local Frame2 = Frame3d( ptC2, ptC2+asseX2, ptC2+asseY2) + local Box2 = EgtGetBBoxRef( Cut2Id, GDB_BB.STANDARD, Frame2) + local x2 = Box2:getDimX() + -- lunghezza totale faccia + local dLongSize = x1 + x2 + -- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti + if dLongSize <= OffsetP + 1.0 and vtN1:getZ() > -0.5 then + local nParent = EgtGetParent( Cut1Id) + local SurfId = EgtSurfTmBySewing( nParent, { Cut1Id, Cut2Id}) + EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) + EgtErase( CutOId) + table.remove( CutTable[1], 1) + table.remove( CutTable[2], 1) + table.remove( CutTable[2], 1) + table.insert( CutTable[2], 1, SurfId) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- DiceCut.GetDice : +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptCPlanes: il punto centrale del piano della feature +-- vtNPlanes: il versore normale del piano della feature +-- bGetOrtoPlanes*: se voglio calcolare i piani ortogonali al piano passato (se non esistono altre superfici può essere omesso) +-- ptCBond*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNBond*: il versore normale della superfice limitante (se non esistono altre superfici può essere omesso) +---------------------------------------------------------------------------------------------------------------------------------------------------- +function DiceCut.GetDice( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, bGetOrtoPlanes, ptCBond, vtNBond) + + local dTolerance = 0 -- distanza di sicurezza per i tagli ortogonali + local OffsetP = BD.MAX_DIM_DICE -- distanza tra i piani paralleli + local StepP = 20 -- numero massimo di piani paralleli da generare + local OffsetO = BD.MAX_DIM_DICE -- distanza tra i piani ortogonali + local StepO = 20 -- numero massimo di piani ortogonali da generare + + -- se normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda + if abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then + --OffsetP = BD.MAX_DIM_HTCUT + OffsetO = BD.MAX_DIM_HTCUT + end + + -- aggiungo piccolo extra agli offset + OffsetP = OffsetP + 10 * GEO.EPS_SMALL + OffsetO = OffsetO + 10 * GEO.EPS_SMALL + + -- se seconda faccia non definita, forzo calcolo piani ortogonali + if not ptCBond or not vtNBond then + bGetOrtoPlanes = true + end + + -- se piani non ortogonali, diminuisco la distanza di offset opportunamente + local originalOffsetP = OffsetP + if not bGetOrtoPlanes then + local dCoeff = ( vtNPlanes ^ vtNBond):len() + OffsetP = OffsetP * dCoeff + OffsetO = OffsetO * dCoeff + end + + -- elenco di tutte le superfici generate dai tagli + local TabFUCHSIA = {} + local TabGREEN = {} + + -- PIANI PARALLELI alla faccia di taglio + local TabellaTmSurfP = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, 0, OffsetP, StepP, Color3d( FUCHSIA(), 60), dTolerance, true, ptCBond, vtNBond) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfP, TabFromIn[i]) + end + + -- PIANI ORTOGONALI alla faccia di taglio + -- orientamento definito da seconda faccia + if not bGetOrtoPlanes then + local TabellaTmSurfOrto = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCBond, vtNBond, 0, OffsetO, StepO, Color3d( GREEN(), 60), dTolerance, false, ptCPlanes, vtNPlanes) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfOrto, TabFromIn[i]) + end + local TabellaOrderParallelCut = GetOrderedCutTable( nParent, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati + local TabellaOrderOrtoCut = GetOrderedCutTable( nParent, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato + + TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato + TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati + + -- orientamento da definire + else + for PlnInd = 1, #TabellaTmSurfP do + -- piano interno + local ptCInner, vtNInner = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd], 0, GDB_ID.ROOT) + -- eventuale piano esterno + local ptCOuter, vtNOuter = nil, nil + if PlnInd > 1 then + ptCOuter, vtNOuter = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd-1], 0, GDB_ID.ROOT) + vtNOuter = -vtNOuter + end + -- calcolo la direzione dei piani ortogonali + local vtO = VectorFromUprightOrtho( vtNInner) + if vtNInner:getZ() > 0.05 or vtNInner:getZ() < -0.5 or abs( vtNInner:getY()) > 0.866 then + vtO:rotate( vtNInner, 90) + -- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente + if abs( vtO:getY()) > abs( vtO:getX()) and vtNInner:getZ() > -0.5 then + vtO:rotate( vtNInner, 90) + else + if ptCInner:getX() > BBoxRawPart:getCenter():getX() then + if vtO:getX() < 0 then vtO = - vtO end + else + if vtO:getX() > 0 then vtO = - vtO end + end + end + end + -- calcolo le dimensioni dell'offset e se dove posizionare la prima faccia: + -- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato + -- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato + -- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero + local OffsetRel, CopyPlane, dCenOffs = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, OffsetO) + + if OffsetRel and CopyPlane and dCenOffs then + ptCInner = ptCInner + dCenOffs * vtO + local TabRight = GetParallelPlanes( nParent, BBoxRawPart, ptCInner, vtO, CopyPlane, -OffsetO, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + if CopyPlane == 0 then + CopyPlane = 1 + end + local TabLeft = GetParallelPlanes( nParent, BBoxRawPart, ptCInner, vtO, CopyPlane, OffsetO, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + -- carico la tabella con gli indici riordinati + local TempOrtoTab = {} + for i = #TabLeft, 1, -1 do + table.insert( TempOrtoTab, TabLeft[i]) + end + for i = 1, #TabRight do + table.insert( TempOrtoTab, TabRight[i]) + end + -- creo una tabella per ogni piano per generare i tagli sulla Inner + local TempParTab = GetOrderedCutTable( nParent, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) + for i = 1, #TempParTab do + table.insert( TabFUCHSIA, TempParTab[i]) + end + table.insert( TabGREEN, TempOrtoTab) + else + table.insert( TabFUCHSIA, {TabellaTmSurfP[PlnInd]}) + table.insert( TabGREEN, {}) + end + end + end + + -- Se sono state costruite non più di una faccia parallela e una faccia perpendicolare, allora non servono e tengo le originali + if #TabGREEN == 1 and #TabGREEN[1] <= 1 and #TabFUCHSIA == 1 and #TabFUCHSIA[1] <= 1 then + if #TabGREEN[1] == 1 then + EgtErase( TabGREEN[1][1]) + end + TabGREEN = {} + if #TabFUCHSIA[1] == 1 then + EgtErase( TabFUCHSIA[1][1]) + end + TabFUCHSIA = {} + end + + -- Si uniscono le tabelle dei tagli ortogonali e paralleli in una sola tabella + local UltimateTable = TableMesh( TabGREEN, TabFUCHSIA) + + -- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato + if not bGetOrtoPlanes then + VerifyFirstOrthoCut( UltimateTable, originalOffsetP, BBoxRawPart) + end + + return UltimateTable +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- PrintOrderCut: +-- TabellaOrderCut: tabella delle superfici di taglio +-- stampo l'ordine dei piani di taglio ricevendo una tabella con gli strati parallelo/ortogonali già ordinati +function DiceCut.PrintOrderCut( TabellaOrderCut) + local Step = #TabellaOrderCut + if Step > 0 then + EgtOutLog( " L'ordine delle superfici da tagliare è il seguente:") + else + EgtOutLog( ' Non sono necessarie superfici aggiuntive di taglio.') + end + for i = 1, Step do + if i % 2 == 1 then + EgtOutLog( ' *** Strato di taglio ' .. EgtNumToString( ( i + 1) / 2, 0)) + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli ortogonali: ') + else + EgtOutLog( ' Tagli ortogonali assenti') + end + else + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli paralleli: ') + else + EgtOutLog( ' Tagli paralleli assenti') + end + end + for j=1, #TabellaOrderCut[i] do + EgtOutLog( ' Indice faccia ' .. (TabellaOrderCut[i][j] or 0)) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +local function DiceCutTest() + + -- salvo l'indice del layer Trimesh selezionato + local SelectedIndex = EgtGetFirstSelectedObj() + -- verifico che sia selezionato un elemento + if not SelectedIndex then return end + + -- salvo l'indice del layer Processing + local nParent = EgtGetParent( SelectedIndex) + -- salvo l'indice del layer Part + local nRawPart = EgtGetParent( nParent) + local nBox = EgtGetFirstNameInGroup( nRawPart, 'Box') + -- carico il bounding box della trave + -- local BBoxRawPart = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD ) + local BBoxRawPart = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD ) + -- seleziono il Part e il Layer di destinazione + EgtSetCurrPartLayer( nRawPart, nParent) + + -- conto il numero di facce da processare + local nFacet = EgtSurfTmFacetCount( SelectedIndex) + EgtOutLog( ' Numero facce ' .. nFacet, 1) + + -- salvo + local TabPlanesFeatures = {} + for i = 1, nFacet do + local ptC, vtN = EgtSurfTmFacetCenter( SelectedIndex, i - 1, GDB_ID.ROOT) + table.insert( TabPlanesFeatures, { ptC = ptC, vtN = vtN}) + end + local ptC1 = Point3d( TabPlanesFeatures[1].ptC) + local vtN1 = Vector3d( TabPlanesFeatures[1].vtN) + + local CutTable = {} + if nFacet == 1 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, true) + elseif nFacet == 2 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN) + end + + if EgtGetDebugLevel() > 1 then + DiceCut.PrintOrderCut( CutTable) + end + + EgtDeselectAll() + + EgtDraw() +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +--DiceCutTest() + +return DiceCut diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut.lua new file mode 100644 index 0000000..1689931 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/DiceCut.lua @@ -0,0 +1,641 @@ +-- DiceCut.lua by Egaltech s.r.l. 2019/10/02 +-- Gestione dei piano paralleli nei tagli lunghi: equidistanziamento dei piani paralleli +-- ver b04 2019/10/03 +-- Tabella per definizione modulo +local DiceCut = {} + +-- Include +require( 'EgtBase') +--EgtEnableDebug( true) +EgtOutLog( ' DiceCut started', 1) + +-- Dati +local BD = require( 'BeamData') + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- creo i piani paralleli +-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptC: il punto centrale del piano della feature +-- vtN: il versore normale del piano della feature +-- nCopyPlane: 0 => genera una copia del piano passato, 1=> non genera una copia del piano passato +-- dOffset: offset dei piani paralleli +-- nStep: numero massimo di step +-- Color: colre del fascio di piani +-- dTolerance*: distanza tra i piani paralleli e i piani di taglio (se non esistono altre superfici può essere omesso) +-- bNoTolOnFirstCut*: elimina la tolleranza per il primo piano del fascio (se non esistono altre superfici può essere omesso) +-- ptCCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +local function GetParallelPlanes( nParent, BBoxRawPart, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) + local ptMyCCut + if ptCCut and vtNCut then + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + local ptMyCCut1 + if ptCCut1 and vtNCut1 then + ptMyCCut1 = Point3d( ptCCut1 + 0 * vtNCut1) + end + local TabellaTmSurfParallel = {} + local i = nCopyPlane + while i < nStep do + local SurfId = EgtSurfTmPlaneInBBox( nParent, ptC + ( i * dOffset) * vtN, vtN, BBoxRawPart, GDB_RT.GLOB) + local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL) + if nFacet > 0 and vtNCut and ptMyCCut then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut, -vtNCut, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut, -vtNCut, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and vtNCut1 and ptMyCCut1 then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut1, -vtNCut1, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut1, -vtNCut1, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 then + table.insert( TabellaTmSurfParallel, SurfId) + EgtSetColor( SurfId, Color) + else + EgtErase( SurfId) + break + end + i = i + 1 + end + return TabellaTmSurfParallel +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrderedCutTable: +-- nParent: il layer +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function GetOrderedCutTable( nParent, TabParallelPlanes, TabOrtoPlanes) + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + local TabellaOrderParallelCut1 = {} + + for IndexTmP=1, StepParallel do + TabellaOrderParallelCut1[IndexTmP] = {} + for IndexOrto=1, StepOrto do + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT) + local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + if Copy1Id and ptOrtoN then + EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB) + EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + local nFacet1 = EgtSurfTmFacetCount( Copy1Id) + local nFacet2 = EgtSurfTmFacetCount( Copy2Id) + if nFacet1 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + elseif nFacet2 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + break + else + table.insert( TabellaOrderParallelCut1[IndexTmP], Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + end + end + end + table.insert(TabellaOrderParallelCut1[IndexTmP], TabParallelPlanes[IndexTmP]) + end + return TabellaOrderParallelCut1 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrtoCutCenter: +-- idFacet: l'id della faccia +-- ptC: il punto centrale della faccia +-- vtN: il versore normale della faccia +-- vtO: il versore dei piani ortogonali +-- dOffsetEff: offset della distanza dal punto centrale +-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset +local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff) + -- riferimento intrinseco + local asseX = vtO + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + -- ingombro della faccia secondo questo riferimento + local Box = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, Frame) + local dLen = Box:getDimX() + local dWidth = Box:getDimY() + + -- se faccia con un lato piccolo e non diretta troppo verso il basso, non servono dice + if ( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > -0.5 then + return nil, nil, nil + end + + local N = ceil( dLen / dOffsetEff) + local dOffsetRel = dLen / N + local dCopyPlane + local dCenOffs = ( Box:getMax():getX() + Box:getMin():getX()) / 2 + + if dLen <= dOffsetRel then + dOffsetRel = 0 + dCopyPlane = 1 + elseif dLen <= 2 * dOffsetRel then + dOffsetRel = 0 + dCopyPlane = 0 + else + if N % 2 == 0 then + dCopyPlane = 0 + elseif N % 2 == 1 then + dCopyPlane = 0.5 + end + end + + -- |NUOVO| : restituisco il punto centrale del Box come centro delle facce + local IdAux = EgtGroup( EgtGetParent( FacetId), Frame) + EgtSetName( IdAux, "Aux") + ptC = EgtSurfTmFacetCenter( EgtSurfTmBBox( IdAux, Box, GDB_RT.LOC), 0, GDB_ID.ROOT) + EgtErase( IdAux) + + return dOffsetRel, dCopyPlane, dCenOffs +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- TableMesh: +-- TableOrto: tabella delle superfici dei piani ortogonali +-- TableParallel: tabella delle superfici dei piani paralleli +-- Forma una tabella unica delle superfici di taglio inserendo strati di tagli ortogonali alternati da strati di taglio parallelo +local function TableMesh( TableOrto, TableParallel) + local TableUnited = {} + for i=1, #TableOrto do + table.insert( TableUnited, TableOrto[i]) + table.insert( TableUnited, TableParallel[i]) + end + return TableUnited +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- FindValue: +-- tab: tabella da scansionare +-- val: valore da cercare +-- Verifica se tab contiene val, a supporto della funzione SortOrtoCutsByNormalMethod +local function FindValue( tab, val) + for index, value in ipairs( tab) do + if value == val then + return true + end + end + return false +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- SortOrtoCutsByNormalMethod: +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio sfruttando il prodotto dei versori normali (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function SortOrtoCutsByNormalMethod( TabParallelPlanes, TabOrtoPlanes) + -- tabella dei tagli ordinati + local TabOrderOrtoCut = {} + -- tabella ausiliaria dei dati inseriti nell'ordine + local TabAux = {} + -- ciclo di ordinamento + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + for IndexTmP=1, StepParallel do + TabOrderOrtoCut[IndexTmP] = {} + local ptParalN, vtNParalN = EgtSurfTmFacetCenter( TabParallelPlanes[IndexTmP][1], 0, GDB_ID.ROOT) + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- controlla che l'elemento da valutare non sia gia' stato inserito nella tabella + if not FindValue( TabAux, OrtoPlaneId) then + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( OrtoPlaneId, 0, GDB_ID.ROOT) + local scalarProduct = ( ptOrtoN - ptParalN) * vtNParalN + if scalarProduct > 0 then + table.insert( TabOrderOrtoCut[IndexTmP], OrtoPlaneId) + table.insert( TabAux, OrtoPlaneId) + end + end + end + end + end + -- cancello dal DB geometrico i tagli non inseriti + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- ricerco il taglio tra gli inseriti + if not FindValue( TabAux, OrtoPlaneId) then + EgtErase( OrtoPlaneId) + end + end + end + return TabOrderOrtoCut +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- VerifyFirstOrthoCut : +-- CutTable: tabella dei tagli +-- OffsetP: offset della distanza dal punto centrale +-- BBoxRawPart: il grezzo della barra +-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua +local function VerifyFirstOrthoCut( CutTable, OffsetP, BBoxRawPart) + + if not CutTable[1] or not CutTable[2] then return end + + local CutOId = CutTable[1][1] + local Cut1Id = CutTable[2][1] + local Cut2Id = CutTable[2][2] + + if CutOId and Cut1Id and Cut2Id then + -- centri e normali delle due semifacce + local ptC1, vtN1 = EgtSurfTmFacetCenter( Cut1Id, 0, GDB_ID.ROOT) + local ptC2, vtN2 = EgtSurfTmFacetCenter( Cut2Id, 0, GDB_ID.ROOT) + -- normale alla faccia ortogonale + local _, vtO = EgtSurfTmFacetCenter( CutOId, 0, GDB_ID.ROOT) + vtO = vtO - vtO * vtN1 * vtN1 ; vtO:normalize() + -- calcolo lunghezza prima semi-faccia + local asseX1 = vtO + local asseY1 = vtN1 ^ asseX1 + local Frame1 = Frame3d( ptC1, ptC1+asseX1, ptC1+asseY1) + local Box1 = EgtGetBBoxRef( Cut1Id, GDB_BB.STANDARD, Frame1) + local x1 = Box1:getDimX() + -- calcolo lunghezza seconda semi-faccia + local asseX2 = vtO + local asseY2 = vtN2 ^ asseX2 + local Frame2 = Frame3d( ptC2, ptC2+asseX2, ptC2+asseY2) + local Box2 = EgtGetBBoxRef( Cut2Id, GDB_BB.STANDARD, Frame2) + local x2 = Box2:getDimX() + -- lunghezza totale faccia + local dLongSize = x1 + x2 + -- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti + if dLongSize <= OffsetP + 1.0 and vtN1:getZ() > -0.5 then + local nParent = EgtGetParent( Cut1Id) + local SurfId = EgtSurfTmBySewing( nParent, { Cut1Id, Cut2Id}) + EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) + EgtErase( CutOId) + table.remove( CutTable[1], 1) + table.remove( CutTable[2], 1) + table.remove( CutTable[2], 1) + table.insert( CutTable[2], 1, SurfId) + end + end +end + +-- ricavo i vertici del box +local function CalcolaPuntiEstremiBox( BBoxRawPart) + local minPoint = BBoxRawPart:getMin() + local dimx = BBoxRawPart:getDimX() + local dimy = BBoxRawPart:getDimY() + local dimz = BBoxRawPart:getDimZ() + local TBoxPoint = {} + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY() , minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY() + dimy, minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY() + dimy, minPoint:getZ() + dimz)}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX(), minPoint:getY(), minPoint:getZ() + dimz)}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY(), minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY() + dimy, minPoint:getZ())}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY() + dimy, minPoint:getZ() + dimz)}) + table.insert(TBoxPoint, {Point = Point3d( minPoint:getX() + dimx, minPoint:getY(), minPoint:getZ() + dimz)}) + return TBoxPoint +end +-- + +local function CalcolaVettoriDaPuntoAEstremi(Ptc, Vtn, TBoxPoint) + for i = 1, #TBoxPoint, 1 do + local v = TBoxPoint[i].Point - Ptc + local p = Vtn*v + table.insert(TBoxPoint[i], {Vector = v, Project = p} ) + end +end +-- + +-- restituisce i punti che devono essere presi in considerazione per la costruzione del BoundingBox +local function VerificaEstremiGrezzo(TPoint) + local bEstremoCompreso + local TableGrezzo = {} + for i = 1, #TPoint, 1 do + bEstremoCompreso = true + for j = 1, #TPoint[i], 1 do + if TPoint[i][j].Project < GEO.EPS_SMALL then + bEstremoCompreso = false + end + end + table.insert(TableGrezzo, {Point = TPoint[i].Point, Compreso = bEstremoCompreso}) + end + return TableGrezzo +end +-- + +-- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature +-- le funzioni commentate permettono di vedere la creazione di BoundingBox +local function DistanzaMassima( nParent, Ptc1, Vtn1, BBoxRawPart, TPoint, Ptc2, Vtn2) + -- ottengo il riferimento al piano + local Frame1 = Frame3d( Ptc1, Vtn1) + --EgtSetGridFrame( Frame1) + local IdAux = EgtGroup( nParent, Frame1) + EgtSetName( IdAux, "Aux") + + local IdSurf1 = EgtSurfTmPlaneInBBox( IdAux, Ptc1, Vtn1, BBoxRawPart, GDB_RT.GLOB) + local IdSurf2 + + if Ptc2 and Vtn2 then + EgtCutSurfTmPlane( IdSurf1, Ptc2, -Vtn2, false, GDB_RT.GLOB) + IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, Ptc2, Vtn2, BBoxRawPart, GDB_RT.GLOB) + EgtCutSurfTmPlane( IdSurf2, Ptc1, -Vtn1, false, GDB_RT.GLOB) + end + + local BB1 = EgtGetBBoxRef( IdSurf1, GDB_BB.STANDARD, Frame1) + + if IdSurf2 then + local BB2 = EgtGetBBoxRef( IdSurf2, GDB_BB.STANDARD, Frame1) + BB1:Add( BB2) + end + + for j = 1, #TPoint, 1 do + if TPoint[j].Compreso then + TPoint[j].Point:toLoc( Frame1) + BB1:Add( TPoint[j].Point) + end + end + --EgtSetGridFrame( Frame1) + --EgtSurfTmBBox( IdAux, BB1, GDB_RT.GRID) + EgtErase( IdAux) + return BB1:getDimZ() +end +-- + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- DiceCut.GetDice : +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptCPlanes: il punto centrale del piano della feature +-- vtNPlanes: il versore normale del piano della feature +-- bGetOrtoPlanes*: se voglio calcolare i piani ortogonali al piano passato (se non esistono altre superfici può essere omesso) +-- ptCBond*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNBond*: il versore normale della superfice limitante (se non esistono altre superfici può essere omesso) +---------------------------------------------------------------------------------------------------------------------------------------------------- +function DiceCut.GetDice( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, bGetOrtoPlanes, ptCBond, vtNBond) + + --[[ ]] + + -- |NUOVO|: ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo + local TBoxPoint = CalcolaPuntiEstremiBox( BBoxRawPart) + local distPlanesP + local distPlanseO + CalcolaVettoriDaPuntoAEstremi( ptCPlanes, vtNPlanes, TBoxPoint) + if ptCBond and vtNBond then + CalcolaVettoriDaPuntoAEstremi( ptCBond, vtNBond, TBoxPoint) + end + local TabPointResult = VerificaEstremiGrezzo(TBoxPoint) + distPlanesP = DistanzaMassima( nParent, ptCPlanes, vtNPlanes, BBoxRawPart, TabPointResult, ptCBond, vtNBond) + if ptCBond and vtNBond then + distPlanesO = DistanzaMassima( nParent, ptCBond, vtNBond, BBoxRawPart, TabPointResult, ptCPlanes, vtNPlanes) + end + + + -- ]] + + local dTolerance = 0 -- distanza di sicurezza per i tagli ortogonali + local OffsetP = BD.MAX_DIM_DICE -- distanza tra i piani paralleli + local StepP = 20 -- numero massimo di piani paralleli da generare + local OffsetO = BD.MAX_DIM_DICE -- distanza tra i piani ortogonali + local StepO = 20 -- numero massimo di piani ortogonali da generare + + -- se normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda + if abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then + --OffsetP = BD.MAX_DIM_HTCUT + OffsetO = BD.MAX_DIM_HTCUT + end + + -- aggiungo piccolo extra agli offset + OffsetP = OffsetP + 10 * GEO.EPS_SMALL + OffsetO = OffsetO + 10 * GEO.EPS_SMALL + + -- se seconda faccia non definita, forzo calcolo piani ortogonali + if not ptCBond or not vtNBond then + bGetOrtoPlanes = true + end + + -- se piani non ortogonali, diminuisco la distanza di offset opportunamente + local originalOffsetP = OffsetP + if not bGetOrtoPlanes then + local dCoeff = ( vtNPlanes ^ vtNBond):len() + OffsetP = OffsetP * dCoeff + OffsetO = OffsetO * dCoeff + end + + + + + --|NUOVO| + local n = ceil( distPlanesP/ OffsetP) + OffsetP = distPlanesP/ n + if distPlanesO then + n = ceil( distPlanesO/ OffsetO) + OffsetO = distPlanesO/ n + end + + + + + + -- elenco di tutte le superfici generate dai tagli + local TabFUCHSIA = {} + local TabGREEN = {} + + -- PIANI PARALLELI alla faccia di taglio + local TabellaTmSurfP = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, 0, OffsetP, StepP, Color3d( FUCHSIA(), 60), dTolerance, true, ptCBond, vtNBond) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfP, TabFromIn[i]) + end + + -- PIANI ORTOGONALI alla faccia di taglio + -- orientamento definito da seconda faccia + if not bGetOrtoPlanes then + local TabellaTmSurfOrto = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCBond, vtNBond, 0, OffsetO, StepO, Color3d( GREEN(), 60), dTolerance, false, ptCPlanes, vtNPlanes) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfOrto, TabFromIn[i]) + end + local TabellaOrderParallelCut = GetOrderedCutTable( nParent, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati + local TabellaOrderOrtoCut = GetOrderedCutTable( nParent, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato + + TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato + TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati + + -- orientamento da definire + else + for PlnInd = 1, #TabellaTmSurfP do + -- piano interno + local ptCInner, vtNInner = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd], 0, GDB_ID.ROOT) + -- eventuale piano esterno + local ptCOuter, vtNOuter = nil, nil + if PlnInd > 1 then + ptCOuter, vtNOuter = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd-1], 0, GDB_ID.ROOT) + vtNOuter = -vtNOuter + end + -- calcolo la direzione dei piani ortogonali + local vtO = VectorFromUprightOrtho( vtNInner) + if vtNInner:getZ() > 0.05 or vtNInner:getZ() < -0.5 or abs( vtNInner:getY()) > 0.866 then + vtO:rotate( vtNInner, 90) + -- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente + if abs( vtO:getY()) > abs( vtO:getX()) and vtNInner:getZ() > -0.5 then + vtO:rotate( vtNInner, 90) + else + if ptCInner:getX() > BBoxRawPart:getCenter():getX() then + if vtO:getX() < 0 then vtO = - vtO end + else + if vtO:getX() > 0 then vtO = - vtO end + end + end + end + -- calcolo le dimensioni dell'offset e se dove posizionare la prima faccia: + -- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato + -- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato + -- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero + local OffsetRel, CopyPlane, dCenOffs = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, OffsetO) + + if OffsetRel and CopyPlane and dCenOffs then + ptCInner = ptCInner + dCenOffs * vtO + local TabRight = GetParallelPlanes( nParent, BBoxRawPart, ptCInner, vtO, CopyPlane, -OffsetO, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + if CopyPlane == 0 then + CopyPlane = 1 + end + local TabLeft = GetParallelPlanes( nParent, BBoxRawPart, ptCInner, vtO, CopyPlane, OffsetO, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + -- carico la tabella con gli indici riordinati + local TempOrtoTab = {} + for i = #TabLeft, 1, -1 do + table.insert( TempOrtoTab, TabLeft[i]) + end + for i = 1, #TabRight do + table.insert( TempOrtoTab, TabRight[i]) + end + -- creo una tabella per ogni piano per generare i tagli sulla Inner + local TempParTab = GetOrderedCutTable( nParent, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) + for i = 1, #TempParTab do + table.insert( TabFUCHSIA, TempParTab[i]) + end + table.insert( TabGREEN, TempOrtoTab) + else + table.insert( TabFUCHSIA, {TabellaTmSurfP[PlnInd]}) + table.insert( TabGREEN, {}) + end + end + end + + -- Se sono state costruite non più di una faccia parallela e una faccia perpendicolare, allora non servono e tengo le originali + if #TabGREEN == 1 and #TabGREEN[1] <= 1 and #TabFUCHSIA == 1 and #TabFUCHSIA[1] <= 1 then + if #TabGREEN[1] == 1 then + EgtErase( TabGREEN[1][1]) + end + TabGREEN = {} + if #TabFUCHSIA[1] == 1 then + EgtErase( TabFUCHSIA[1][1]) + end + TabFUCHSIA = {} + end + + -- Si uniscono le tabelle dei tagli ortogonali e paralleli in una sola tabella + local UltimateTable = TableMesh( TabGREEN, TabFUCHSIA) + + -- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato + if not bGetOrtoPlanes then + VerifyFirstOrthoCut( UltimateTable, originalOffsetP, BBoxRawPart) + end + + return UltimateTable +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- PrintOrderCut: +-- TabellaOrderCut: tabella delle superfici di taglio +-- stampo l'ordine dei piani di taglio ricevendo una tabella con gli strati parallelo/ortogonali già ordinati +function DiceCut.PrintOrderCut( TabellaOrderCut) + local Step = #TabellaOrderCut + if Step > 0 then + EgtOutLog( " L'ordine delle superfici da tagliare è il seguente:") + else + EgtOutLog( ' Non sono necessarie superfici aggiuntive di taglio.') + end + for i = 1, Step do + if i % 2 == 1 then + EgtOutLog( ' *** Strato di taglio ' .. EgtNumToString( ( i + 1) / 2, 0)) + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli ortogonali: ') + else + EgtOutLog( ' Tagli ortogonali assenti') + end + else + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli paralleli: ') + else + EgtOutLog( ' Tagli paralleli assenti') + end + end + for j=1, #TabellaOrderCut[i] do + EgtOutLog( ' Indice faccia ' .. (TabellaOrderCut[i][j] or 0)) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +local function DiceCutTest() + + -- salvo l'indice del layer Trimesh selezionato + local SelectedIndex = EgtGetFirstSelectedObj() + -- verifico che sia selezionato un elemento + if not SelectedIndex then return end + + -- salvo l'indice del layer Processing + local nParent = EgtGetParent( SelectedIndex) + -- salvo l'indice del layer Part + local nRawPart = EgtGetParent( nParent) + local nBox = EgtGetFirstNameInGroup( nRawPart, 'Box') + -- carico il bounding box della trave + -- local BBoxRawPart = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD ) + local BBoxRawPart = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD ) + -- seleziono il Part e il Layer di destinazione + EgtSetCurrPartLayer( nRawPart, nParent) + + -- conto il numero di facce da processare + local nFacet = EgtSurfTmFacetCount( SelectedIndex) + EgtOutLog( ' Numero facce ' .. nFacet, 1) + + -- salvo + local TabPlanesFeatures = {} + for i = 1, nFacet do + local ptC, vtN = EgtSurfTmFacetCenter( SelectedIndex, i - 1, GDB_ID.ROOT) + table.insert( TabPlanesFeatures, { ptC = ptC, vtN = vtN}) + end + local ptC1 = Point3d( TabPlanesFeatures[1].ptC) + local vtN1 = Vector3d( TabPlanesFeatures[1].vtN) + + local CutTable = {} + if nFacet == 1 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, true) + elseif nFacet == 2 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN) + end + + if EgtGetDebugLevel() > 1 then + DiceCut.PrintOrderCut( CutTable) + end + + EgtDeselectAll() + + EgtDraw() +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +--DiceCutTest() + +return DiceCut diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/FacesBySaw.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/FacesBySaw.lua new file mode 100644 index 0000000..5a1a05e --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/FacesBySaw.lua @@ -0,0 +1,152 @@ +-- FacesBySaw.lua by Egaltech s.r.l. 2019/09/20 +-- Gestione taglio con lama di feature con una, due o tre facce + +-- Tabella per definizione modulo +local FacesBySaw = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' FacesBySaw started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +function FacesBySaw.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, sCutName) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico il numero di facce della tacca + if Proc.Fct ~= 2 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw facet number not supported' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero dati su giunzione tra facce + local bTouch, ptT1, ptT2, dAngT = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if not bTouch then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw faces not touching' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo direzione di lavoro + local vtRef = {} + local vtTg = ptT2 - ptT1 ; + vtRef[1] = vtN[1] ^ vtTg + if vtRef[1] * vtN[2] < 0 then vtRef[1] = - vtRef[1] end + vtRef[2] = vtN[2] ^ vtTg + if vtRef[2] * vtN[1] < 0 then vtRef[2] = - vtRef[2] end + -- determino quale faccia è più grande + local ptPs = ( ptT1 + ptT2) / 2 + local dSqDim1 = ( ptC[1] - ptPs):sqlen() + local dSqDim2 = ( ptC[2] - ptPs):sqlen() + local nBigInd = EgtIf( dSqDim1 >= dSqDim2, 1, 2) + local nSmaInd = 3 - nBigInd + -- recupero la lavorazione + local sCutting = ML.FindCutting( sCutName) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 5 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- calcolo extra taglio + local dCutExtra = 0 + if dAngT < -92 then + dCutExtra = - dSawThick / tan( 180 + dAngT) + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- assegno il modo di tagliare + local vtOrthO = EgtIf( ( i % 2) == 1, vtRef[nSmaInd], vtRef[nBigInd]) + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthO, nil, dCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- lavoro la prima faccia + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, vtRef[1], nil, dCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + -- lavoro seconda faccia + bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 1, sCutting, dSawDiam, vtRef[2], nil, dCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +function FacesBySaw.MakeThree( Proc, nPhase, nRawId, nPartId, sCutName) + return false +end + +return FacesBySaw \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/MachiningLib.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/MachiningLib.lua new file mode 100644 index 0000000..ae139d1 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/MachiningLib.lua @@ -0,0 +1,105 @@ +-- MachiningLib.lua by Egaltech s.r.l. 2019/07/25 +-- Libreria ricerca lavorazioni per Travi + +-- Tabella per definizione modulo +local MachiningLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' MachiningLib started', 1) + +-- Dati +local BD = require( 'BeamData') +local Cuttings = require( 'CutData') +local Millings = require( 'MillingData') +local Pocketings = require( 'PocketingData') +local Sawings = require( 'SawingData') +local Drillings = require( 'DrillData') + +--------------------------------------------------------------------- +function MachiningLib.FindCutting( sType) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.On and Cutting.Type == sType then + return Cutting.Name + end + end +end + +--------------------------------------------------------------------- +function MachiningLib.FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.On and Milling.Type == sType then + return Milling.Name + 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 EgtMdbSetCurrMachining( Pocketing.Name) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + local sTool = EgtTdbGetToolFromUUID( sTuuid) + if sTool and EgtTdbSetCurrTool( sTool) then + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxDepth = EgtTdbGetCurrToolMaxDepth() + if ( not dMaxDiam or dTDiam < dMaxDiam) and + ( not dDepth or dTMaxDepth > dDepth) then + return Pocketing.Name + end + end + end + end +end + +--------------------------------------------------------------------- +function MachiningLib.FindSawing( sType) + for i = 1, #Sawings do + local Sawing = Sawings[i] + if Sawing.On and Sawing.Type == sType 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 EgtMdbSetCurrMachining( Drilling.Name) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + local sTool = EgtTdbGetToolFromUUID( sTuuid) + if sTool and EgtTdbSetCurrTool( sTool) then + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + if dTDiam < dDiam + 10 * GEO.EPS_SMALL and dTDiam > dDiam - BD.DRILL_TOL - 10 * GEO.EPS_SMALL then + return Drilling.Name, Drilling.Type, dTMaxMat + end + 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 EgtMdbSetCurrMachining( Drilling.Name) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + local sTool = EgtTdbGetToolFromUUID( sTuuid) + if sTool and EgtTdbSetCurrTool( sTool) 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 +end + +------------------------------------------------------------------------------------------------------------- +return MachiningLib diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessChamfer.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessChamfer.lua new file mode 100644 index 0000000..d2d0cff --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessChamfer.lua @@ -0,0 +1,53 @@ +-- ProcessChamfer.lua by Egaltech s.r.l. 2018/04/12 +-- Gestione calcolo profilo libero per Travi + +-- Tabella per definizione modulo +local ProcessChamfer = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessChamfer started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessChamfer.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 36) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessChamfer.Make( Proc, nPhase, nRawId, nPartId) + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Chamfer') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Chm_' .. ( 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( {{ Proc.Id, 0}}) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessChamfer diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessCut.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessCut.lua new file mode 100644 index 0000000..ebdebfc --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessCut.lua @@ -0,0 +1,194 @@ +-- ProcessCut.lua by Egaltech s.r.l. 2019/09/19 +-- Gestione calcolo singoli tagli di lama per Travi + +-- Tabella per definizione modulo +local ProcessCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessCut.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessCut.Classify( Proc, b3Raw) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN:getZ() <= - 0.5 and abs( vtN:getY()) > 0.1 then + local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0) + if DimH > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local bDownCut = (vtN:getZ() <= - 0.5) + -- se taglio di testa + if Proc.Head then + -- se coincide con il taglio di separazione precedente, non va fatto + if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- altrimenti taglio di coda + else + -- se coincide con taglio di separazione, non va fatto + if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( Proc.Head, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- determino la direzione di taglio preferenziale + local _, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0) + local bHorizCut = (( dCutV < dMaxDepth + 10 * GEO.EPS_SMALL and dCutH > dCutV + 10 * GEO.EPS_SMALL) and not bDownCut) + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, true) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtN) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + if bHorizCut then + vtOrthoO = Z_AX() + elseif vtN:getY() > -0.02 then + vtOrthoO = Y_AX() + else + vtOrthoO = -Y_AX() + end + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se taglio dal basso + if bDownCut then + -- se strato pari composto da 1 o 2 elementi + if i % 2 == 0 and #vCuts[i] <= 2 then + -- il primo elemento prende la direzione prevista, il secondo quella opposta + local vtNewOrthoO = Vector3d( vtOrthoO) + local dVzLimDwnUp = -0.5 + if j ~= 1 then + vtNewOrthoO = -vtOrthoO + dVzLimDwnUp = -0.72 + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtNewOrthoO, dVzLimDwnUp, 0.1, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- tutti gli altri casi vengono saltati + -- caso generale + else + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -0.5, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + end + -- altrimenti tagli diretti della faccia + else + -- lavoro la faccia + local vtOrthoO + if bHorizCut then + vtOrthoO = Z_AX() + elseif vtN:getY() > -0.02 then + vtOrthoO = Y_AX() + else + vtOrthoO = -Y_AX() + end + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if abs( vtN:getZ()) > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if abs( vtN:getZ()) > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessCut diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDecor.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDecor.lua new file mode 100644 index 0000000..4a7ecd8 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDecor.lua @@ -0,0 +1,81 @@ +-- ProcessDecor.lua by Egaltech s.r.l. 2018/04/18 +-- Gestione calcolo decoro per Travi + +-- Tabella per definizione modulo +local ProcessDecor = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDecor started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDecor.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 959) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDecor.Classify( Proc) + -- recupero i dati della decorazione + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico sia una decorazione + if not vtExtr then + return false + end + -- verifico se la decorazione è lavorabile solo da sotto + local bDown = (( vtExtr:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDecor.Make( Proc, nPhase, nRawId, nPartId) + -- recupero i dati della decorazione + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico che la decorazione non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Decor from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sToFind = EgtGetInfo( Proc.Id, 'P15') + local sMilling = ML.FindMilling( sToFind) + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessDecor diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDoubleCut.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDoubleCut.lua new file mode 100644 index 0000000..cd0a410 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDoubleCut.lua @@ -0,0 +1,209 @@ +-- ProcessDoubleCut.lua by Egaltech s.r.l. 2019/09/25 +-- Gestione calcolo doppi tagli di lama per Travi + +-- Tabella per definizione modulo +local ProcessDoubleCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessDoubleCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDoubleCut.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 11) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDoubleCut.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- se due facce, verifico se convesso + local bConvex = true + if nFacetCnt == 2 then + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + bConvex = not bAdj or ( dAng > 0) + end + -- verifico le normali delle facce + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if not bConvex and vtN:getZ() < - 0.72 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDoubleCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se convesso, lo tratto come due tagli singoli + if bConvex then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- lavoro per prima la faccia più diretta in alto + local vOrd = { 1, 2} + if vtN[2]:getZ() > vtN[1]:getZ() then + vOrd = { 2, 1} + end + -- creo piano di taglio coincidente con la prima faccia e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptC[vOrd[1]], vtN[vOrd[1]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- creo piano di taglio coincidente con la seconda faccia e lo lavoro + AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptC[vOrd[2]], vtN[vOrd[2]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- altrimenti + else + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local k, l = nBigInd, nSmaInd + if ( i % 2) == 1 then + k, l = l, k + end + local nOrthoOpposite + if bOnY then + local bFront = ( ptC[k]:getY() < ptPs:getY()) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + local bOver = ( ptC[k]:getZ() > ptC[l]:getZ()) + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, EgtIf( bHead, 'HeadSide', 'TailSide')) + if not bOk then + return bOk, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + return true +end + +--------------------------------------------------------------------- +return ProcessDoubleCut diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDrill.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDrill.lua new file mode 100644 index 0000000..48cff7b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDrill.lua @@ -0,0 +1,225 @@ +-- ProcessDrill.lua by Egaltech s.r.l. 2019/08/29 +-- Gestione calcolo forature per Travi + +-- Tabella per definizione modulo +local ProcessDrill = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDrill started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- Costanti +local TH_RAD = 35 -- raggio portautensile +local COS_SLANT_LIM = 0.866 -- 30deg da piano + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDrill.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 40) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDrill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDrill.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- 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 + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- se entrata principale + if Proc.Flg > 0 then + local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + return ( ( nFcs == 5 or nFcs == 6) and vtExtr:getX() < -0.5) + -- altrimenti entrata opposta + else + local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + return ( ( nFce == 5 or nFce == 6) and vtExtr:getX() > 0.5) + end +end + +--------------------------------------------------------------------- +-- Verifica se da lavorare in due metà +function ProcessDrill.Split( 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 bOpen = ( Proc.Fce ~= 0) + -- recupero la lavorazione + local sDrilling, _, dMaxMat = ML.FindDrilling( dDiam) + if not sDrilling then + return bOpen + end + -- restituisco se va fatto in doppio (solo fori orizzontali) + return ( bOpen and dLen > dMaxMat + 10 * GEO.EPS_SMALL and ( abs( vtExtr:getY()) * b3Raw:getDimZ() > abs( vtExtr:getZ()) * b3Raw:getDimY() or Proc.Fce == 5 or Proc.Fce == 6)) +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) + if Proc.Flg == -2 then + vtExtr = - vtExtr + ptCen = ptCen + vtExtr * dLen + end + -- verifico se troppo inclinato e quindi non lavorabile + if not ( Proc.Fcs == 5 or Proc.Fcs == 6) and abs( vtExtr:getX()) > COS_SLANT_LIM then + return false, false + end + local bOpen = ( Proc.Fce ~= 0) + local bFaceDown = ( ptCen:getZ() < b3Raw:getMin():getZ() + dDiam) and vtExtr:getZ() < -0.5 + -- verifico se il foro è fattibile solo da sotto + local bDown = (( vtExtr:getZ() < BD.DRILL_VZ_MIN or bFaceDown) and ( not bOpen or Proc.Flg ~= 1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) + -- 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) + if Proc.Flg == -2 then vtExtr = - vtExtr end + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- verifico che il foro non sia fattibile solo da sotto + local bToInvert = ( vtExtr:getZ() < BD.DRILL_VZ_MIN) + 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 bToInvert then vtExtr = - vtExtr end + if Proc.Flg == -2 then bToInvert = true 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 + 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 + end + end + -- se foro intermedio e inclinato, limito il massimo affondamento + if not ( Proc.Fcs == 5 or Proc.Fcs == 6) then + local CosB = abs( vtExtr:getX()) + if CosB < COS_SLANT_LIM then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dMaxDepth = dMaxDepth - TH_RAD * 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 Proc.Flg == 2 or Proc.Flg == -2 then + dDepth = dLen / 2 + BD.DRILL_OVERLAP + end + 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, aggiungo alle note massima elevazione (coincide con affondamento) + if nType == 'Drill' then + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ',' + 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( nMchFId, false) + return false, sWarn + else + return true, ( sMyWarn or sWarn) + end + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +return ProcessDrill diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDtMortise.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDtMortise.lua new file mode 100644 index 0000000..4d9834f --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDtMortise.lua @@ -0,0 +1,112 @@ +-- ProcessMortise.lua by Egaltech s.r.l. 2019/08/07 +-- Gestione calcolo mortase a coda di rondice per Travi + +-- Tabella per definizione modulo +local ProcessDtMortise = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDtMortise started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDtMortise.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 55) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 56)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDtMortise.Classify( Proc) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se la mortasa è lavorabile solo da sotto + local bDown = ( vtN:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDtMortise.Make( Proc, nPhase, nRawId, nPartId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 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 top + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- verifico che la mortasa non sia orientata verso il basso (-5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' DtMortise from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'DtMortise') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile + local dToolDiam = 50 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + end + end + -- verifico se necessarie più passate (distanza all'imbocco ortogonale all'asse) + local vtDiff = EgtEP( AuxId, GDB_RT.GLOB) - EgtSP( AuxId, GDB_RT.GLOB) + local vtAx = EgtEV( AuxId, GDB_RT.GLOB) - EgtSV( AuxId, GDB_RT.GLOB) + vtAx:normalize() + local vtOrtDiff = vtDiff - vtDiff * vtAx * vtAx + local dDist = vtOrtDiff:len() + if dDist < dToolDiam + 0.5 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Dt mortise too narrow' + EgtOutLog( sErr) + return false, sErr + end + local nPass = ceil( dDist / ( 1.9 * dToolDiam)) + local dStep = ( dDist - 0.95 * dToolDiam) / ( 2 * nPass) + for i = nPass, 1, -1 do + -- inserisco la lavorazione di contornatura + local sNameF = 'DtMt_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nPass) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- imposto offset + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessDtMortise diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDtTenon.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDtTenon.lua new file mode 100644 index 0000000..e2f479d --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessDtTenon.lua @@ -0,0 +1,173 @@ +-- ProcessTenon.lua by Egaltech s.r.l. 2019/07/16 +-- Gestione calcolo tenone a coda di rondine per Travi + +-- Tabella per definizione modulo +local ProcessDtTenon = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTenon started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDtTenon.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 55) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDtTenon.Classify( Proc) + -- recupero i dati della curva di contorno della faccia top + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se il tenone è lavorabile solo da sotto + local bDown = ( vtExtr:getZ() < - 0.26) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDtTenon.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + -- verifico che il tenone non sia orientato verso il basso (-15 deg) + if vtExtr:getZ() < - 0.26 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' DtTenon from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza del tenone + local frDtTen = Frame3d( ptBC, vtExtr) + local b3DtTen = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frDtTen) + local dDtTenH = b3DtTen:getDimZ() + -- assegno centro e normale della faccia top + local vtN = vtExtr + local ptC = ptBC + vtN * dDtTenH + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- porto inizio curva a Zmax + BL.PutStartOnTop( AuxId) + -- se tenone inclinato o non esattamente alle estremità, necessario taglio di lama sulla testa + if not AreSameOrOppositeVectorApprox( vtN, X_AX()) or + ( Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dOvmHead - 100 * GEO.EPS_SMALL and + Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 100 * GEO.EPS_SMALL) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla testa del tenone e lo lavoro + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptC, vtN, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'DtTenon') + 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 dTDiam = 50 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + end + end + -- calcolo distanza massima della curva dal punto più lontano della base tenone Dt (facet 0) + local dMaxDist = 0 + local nLoopId, nLoopCnt = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id)) + if nLoopId then + local dUmin, dUmax = EgtCurveDomain( nLoopId) + for dU = dUmin, dUmax do + local ptP = EgtUP( nLoopId, dU, GDB_ID.ROOT) + local ptNear = EgtNP( AuxId, ptP, GDB_ID.ROOT) + local dDist = dist( ptP, ptNear) + if dDist > dMaxDist then + dMaxDist = dDist + end + end + for i = 1, nLoopCnt do + EgtErase( nLoopId + i - 1) + end + else + local b3DtAux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frDtTen) + dMaxDist = 2 * ( b3DtTen:getRadius() - b3DtAux:getRadius()) + end + EgtOutLog( 'MaxDist=' .. EgtNumToString( dMaxDist, 3), 3) + -- Cicli di lavorazione (max 4) + local MAX_PASS = 4 + local nStep = min( ceil( dMaxDist / ( 0.7 * dTDiam)), MAX_PASS) + local dStep = min( dMaxDist, 0.7 * dTDiam * MAX_PASS) / nStep + for i = nStep, 1, -1 do + -- inserisco la passata di sgrossatura della lavorazione + local sNameR = 'DtTn_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchRId = EgtAddMachining( sNameR, sMilling) + if not nMchRId then + local sErr = 'Error adding machining ' .. sNameR .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo i parametri + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dDtTenH, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchRId, false) + return false, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessDtTenon diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessFreeContour.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessFreeContour.lua new file mode 100644 index 0000000..a954599 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessFreeContour.lua @@ -0,0 +1,339 @@ +-- ProcessFreeContour.lua by Egaltech s.r.l. 2019/07/19 +-- Gestione calcolo profilo libero per Travi + +-- Tabella per definizione modulo +local ProcessFreeContour = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessFreeContour started', 1) + +-- Dati +local BD = require( 'BeamData') +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) +end +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessFreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- se pocket, ne verifico la direzione di lavorazione + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + if bPocket then + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if not AuxId then + return false + end + AuxId = AuxId + Proc.Id + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if vtN:getX() < 0.5 then + return false + else + return true + end + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessFreeContour.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- se pocket, ne verifico la direzione di lavorazione + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + if bPocket then + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if not AuxId then + return false + end + AuxId = AuxId + Proc.Id + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if vtN:getX() > - 0.5 then + return false + else + return true + end + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di coda + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessFreeContour.Classify( Proc) + -- verifico se di tipo pocket + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- se non è pocket, è indifferente alla posizione + if not bPocket then + return true, false + end + -- è pocket, devo verificare la normale del piano di svuotatura (versore estrusione del contorno) + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if not AuxId then + return false + end + AuxId = AuxId + Proc.Id + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se la feature è lavorabile solo da sotto (tasca con normale verso il basso) + local bDown = ( vtN:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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) & 256) == 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 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 + -- ne verifico la lunghezza per eventuale spezzatura e lavorazione in doppio + local nStep = 1 + local dStep = 0 + local dLenMax = min( BD.LONGCUT_MAXLEN, 0.5 * b3Raw:getDimX()) + local b3Aux = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Aux:getDimX() > dLenMax then + local dCrvLen = EgtCurveLength( AuxId) + nStep = ceil( dCrvLen / dLenMax) + dStep = dCrvLen / nStep + EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) + end + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local bCross = false + if abs( vtExtr:getY()) > 0.707 then + if b3Aux:getDimY() > b3Raw:getDimY() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimY()) + end + elseif abs( vtExtr:getZ()) > 0.707 then + if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimZ()) + end + end + local nDouble = 1 + local bCanDouble = abs( vtExtr:getY()) > 0.707 and bCross + if bCross then + if nStep > 1 then + -- devo lasciare un codolo + dDepth = dDepth - BD.DIM_STRIP + else + -- devo affondare un poco oltre + dDepth = dDepth + BD.CUT_EXTRA + end + end + if dDepth > dMaxDepth then + if bCanDouble then + nDouble = 2 + dDepth = min( 0.5 * dDepth, dMaxDepth) + else + dDepth = dMaxDepth + end + end + -- eseguo + for i = 1, nStep do + for j = 1, nDouble do + -- 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}}) + -- eventuale accorciamento di testa + if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then + local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + end + -- eventuale accorciamento di coda + if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then + local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- se estrusione da sotto, inverto direzione fresa + if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- se seconda passata, inverto direzione di lavoro + if j == 2 then + EgtSetMachiningParam( MCH_MP.INVERT, 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 + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +local function MakeByPocket( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- 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) & 256) == 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, nPhase, nRawId, nPartId, dOvmHead) + -- recupero la tipologia + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- se svuotatura + if bPocket then + return MakeByPocket( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- altrimenti contornatura + else + return MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead) + end +end + +--------------------------------------------------------------------- +return ProcessFreeContour diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessHeadCut.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessHeadCut.lua new file mode 100644 index 0000000..f65259a --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessHeadCut.lua @@ -0,0 +1,87 @@ +-- ProcessSplit.lua by Egaltech s.r.l. 2019/06/29 +-- Gestione calcolo tagli di testa per Travi + +-- Tabella per definizione modulo +local ProcessHeadCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessSplit started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessHeadCut.Identify( Proc) + return ( Proc.Grp == 1 and Proc.Prc == 340) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessHeadCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + local bHorizCut = ( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL and b3Raw:getDimZ() < BD.MAX_DIM_HTCUT) + local dDimYRef = EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, BD.MAX_DIM_HTCUT, BD.MAX_DIM_HTCUT_HBEAM) + local bDoubleCut = ( not bHorizCut and b3Raw:getDimY() > dDimYRef + 10 * GEO.EPS_SMALL) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- se coincide con inizio grezzo, non va fatto + if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX()) < 10 * GEO.EPS_SMALL then + return true + end + -- flag di lavorazione faccia + local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_FRONT) + -- determino se più tagli con offset + local nCuts = ceil( dOvmHead / BD.MAX_LEN_SCRAP) + local dOffsL = dOvmHead / nCuts + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- calcolo extra taglio ed accorciamento + local dCutExtra = 0 + local dAccStart = 0 + if b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL or b3Raw:getDimY() < 2 * BD.MAX_DIM_HTCUT_HBEAM + 10 * GEO.EPS_SMALL then + dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY(), 0) + BD.CUT_EXTRA + dAccStart = 0 + else + dCutExtra = - ( b3Raw:getDimY() - BD.MAX_DIM_HTCUT - BD.CUT_EXTRA) + local dSawRad = dSawDiam / 2 + local dKL = dSawRad - ( BD.MAX_DIM_HTCUT + BD.CUT_EXTRA) + b3Raw:getDimY() / 2 + BD.CUT_EXTRA_MIN + dAccStart = sqrt( dSawRad * dSawRad - dKL * dKL) + end + -- se necessari tagli in doppio, eseguo gli opposti + if bDoubleCut then + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_BACK, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, '', b3Raw) + if not bOk then return false, sErr end + end + end + -- eseguo i tagli necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, '', b3Raw) + if not bOk then return false, sErr end + end + return true +end + +--------------------------------------------------------------------- +return ProcessHeadCut diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessLapJoint.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessLapJoint.lua new file mode 100644 index 0000000..d43132b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessLapJoint.lua @@ -0,0 +1,691 @@ +-- ProcessLapJoint.lua by Egaltech s.r.l. 2019/09/09 +-- Gestione calcolo mezzo-legno per Travi + +-- Tabella per definizione modulo +local ProcessLapJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') +local DoubleCut = require( 'ProcessDoubleCut') +local LongCut = require( 'ProcessLongCut') +local Long2Cut = require( 'ProcessLongDoubleCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessLapJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLapJoint.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or + ( Proc.Grp == 4 and Proc.Prc == 39)) +end + +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- se una o due facce ora è sicuramente di testa + if Proc.Fct <= 2 then + return true + end + -- deve avere la normale principale diretta verso la testa + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN:getX() < 0.5 then + return false + elseif Proc.Fct >= 5 then + return true + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessLapJoint.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- se una o due facce ora è sicuramente di coda + if Proc.Fct <= 2 then + return true + end + -- deve avere la normale principale diretta verso la coda + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN:getX() > -0.5 then + return false + else + return true + end +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLapJoint.Classify( Proc) + -- se 1 faccia + if Proc.Fct == 1 then + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + --local bDown = ( vtN:getZ() < BD.NZ_MINA) + --return true, bDown + return true, false + -- se 2 facce + elseif Proc.Fct == 2 then + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bSmall = ( ( Proc.Head or Proc.Tail) and Proc.Box:getDimX() < BD.MAX_LEN_RIDGELAP_FROM_BOTTOM) or + ( not ( Proc.Head or Proc.Tail) and Proc.Box:getDimY() < BD.MAX_LEN_RIDGELAP_FROM_BOTTOM) + local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or + ( vtN[1]:getZ() < BD.NZ_MINA and ( vtN[2]:getZ() < -0.1 or not bSmall)) or + ( vtN[2]:getZ() < BD.NZ_MINA and ( vtN[1]:getZ() < -0.1 or not bSmall)) + return true, bDown + -- se più di 2 facce + else + -- recupero la faccia con il maggior numero di adiacenze e minor elevazione + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id) + if nFacInd < 0 then + return false + end + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bDown = ( vtN:getZ() < BD.NZ_MINA) + -- se verso il basso, verifico se utilizzabile seconda faccia + if bDown then + if nFacInd2 and dElev2 < 2 * dElev then + local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINA) + end + end + return true, bDown + end +end + +--------------------------------------------------------------------- +-- Lavorazione con fresa +--------------------------------------------------------------------- +local function MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se orientata verso l'alto + local bUp = ( vtN:getZ() >= BD.NZ_MINA) + -- scelta faccia da lavorare + local nFacInd = 0 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'BirdsMouth') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + if vtN:getX() > 0 then + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_LEFT, MCH_MILL_FU.PARAL_LEFT)) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.PARAL_RIGHT)) + end + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + if not bUp then EgtSetMachiningParam( MCH_MP.INVERT, true) end + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- dati medi + local ptM = ( ptC[1] + ptC[2]) / 2 + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- scelta faccia da lavorare + local nFacInd + -- se entrambe possibili + if bFaceOk[1] and bFaceOk[2] then + -- se in testa o coda, scelgo quella con la normale più parallela all'asse trave + if Proc.Head or Proc.Tail then + if vtN[1]:getZ() < BD.NZ_MINA then + nFacInd = 1 + elseif vtN[2]:getZ() < BD.NZ_MINA then + nFacInd = 0 + else + nFacInd = EgtIf( abs( vtN[1]:getX()) > abs( vtN[2]:getX()), 0, 1) + end + -- altrimenti, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+) + else + if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then + if ptM:getX() > b3Raw:getCenter():getX() then + nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1) + else + nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1) + end + else + nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1) + end + end + elseif bFaceOk[1] then + nFacInd = 0 + else + nFacInd = 1 + end + local nOthInd = 1 - nFacInd + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'BirdsMouth') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + if vtN[nOthInd+1]:getX() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_LEFT) + elseif vtN[nOthInd+1]:getX() < -0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_RIGHT) + elseif vtN[nOthInd+1]:getZ() < -0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_TOP) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_DOWN) + end + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto posizione braccio porta testa + if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw) + -- se interessa l'intera sezione della trave, necessaria sgrossatura + if Proc.Box:getDimY() > 0.9 * b3Raw:getDimY() and Proc.Box:getDimZ() > 0.9 * b3Raw:getDimZ() then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo sgrossatura e la lavoro + local AddId = EgtSurfTmConvexHullInBBox( nAddGrpId, Proc.Id, b3Raw, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local nCutFacet = EgtSurfTmFacetCount( AddId) + if nCutFacet == 1 then + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + elseif nCutFacet == 2 then + local bOk, sErr = DoubleCut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev) + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Riordino le dimensioni per avere dH > dV + if dH < dV then + dH, dV = dV, dH + end + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > 0.5 * dH then + nFacAdj = vAdj[i] + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) + break + end + end + end + -- Determino se estremi aperti o chiusi + local bOpenStart = false + local bOpenEnd = false + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,')) + for j = 1, #vAdj2 do + if vAdj2[j] == nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + end + -- Se entrambi gli estremi sono aperti e fattibile con lama + if bOpenStart and bOpenEnd and dElev <= BD.MAX_DIM_DICE then + -- Recupero la lavorazione di lama + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 4 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ()) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- Eseguo i tagli + local nStep = ceil( ( dV - 0.5) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + local dOffs = ( i - 1) * dStep + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, nil, 0, BD.CUT_SIC, dOffs, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- altrimenti con sega a catena + else + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) + -- Calcolo angolo 3° asse rot (da direz. utensile) + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) + local ptP1, ptP2 = EgtSurfTmFacetOppositeSide( Proc.Id, nFacAdj, rfFac:getVersZ(), GDB_ID.ROOT) + local vtT = vtN ^ (ptP2 - ptP1) + local d3RotAng = EgtIf( abs( vtT:getZ()) < GEO.EPS_SMALL, 0, 90) + -- Recupero la lavorazione + local sSawing = ML.FindSawing( 'Sawing') + if not sSawing then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chainsawing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero i dati dell'utensile + local dSawWidth = 75 + local dSawThick = 8 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- Verifico se necessarie più passate + local nStep = ceil( ( dV - 0.5) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- Applico la lavorazione con sega a catena a questa faccia + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=' .. EgtNumToString( d3RotAng)) + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + elseif EgtIsMachiningEmpty() then + local _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id) + assert( ( nFacInd and nFacInd >= 0), 'Error : MakeMoreFaces could not find reference face') + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se orientata verso il basso, verifico l'alternativa + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + dFacElev, dFacElev2 = dFacElev2, dFacElev + end + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico non sia orientata verso il basso + local bFaceOk = ( vtN:getZ() >= BD.NZ_MINA) + if not bFaceOk then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- eventuali tagli preliminari + do + local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw) + if not bOk then + return false, sErr + end + end + -- recupero la lavorazione + local sPocketing = ML.FindPocketing( 'Mortise', min( dH, dV)) + -- se non trova una svuotatura adatta, provo con la sega a catena o lama + if not sPocketing then + return MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev) + end + -- recupero i dati dell'utensile + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + 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( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL 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 + local sWarn + if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev) + dFacElev = dMaxDepth + sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- la divido in parti lungo X + local vAddId = {} + local nPart = ceil( Proc.Box:getDimX() / min( BD.LONGCUT_MAXLEN, 0.5 * b3Raw:getDimX())) + local dPartLen = Proc.Box:getDimX() / nPart + local Xmin = Proc.Box:getMin():getX() + for i = 1, nPart do + -- eseguo divisione + local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i)) + if i > 1 then + local ptOn = Point3d( Xmin + ( i - 1) * dPartLen, 0, 0) + EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) + end + if i < nPart then + local ptOn = Point3d( Xmin + i * dPartLen, 0, 0) + EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) + end + table.insert( vAddId, AddId) + end + -- applico le lavorazioni sulle diverse parti + for i = 1, #vAddId do + local b3Box = EgtGetBBoxGlob( vAddId[i], GDB_BB.STANDARD) + local nFct = EgtSurfTmFacetCount( vAddId[i]) + local AddProc = { Id = vAddId[i], Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Box, Fct = nFct, Flg = Proc.Flg} + local bOk, sErr = MakeMoreFaces( AddProc, nPhase, nRawId, nPartId) + if not bOk then + return bOk, sErr + end + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +--------------------------------------------------------------------- +function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- limiti di fresatura semplice + local MAX_MILL_LIN = 80 + local MAX_MILL_VOL = ( 80 * 240 * 20) / 2 + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + + -- se lunghezza richiede spezzatura + if Proc.Box:getDimX() > min( BD.LONGCUT_MAXLEN, 0.5 * b3Raw:getDimX()) then + -- una faccia + if Proc.Fct == 1 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + -- due facce + elseif Proc.Fct == 2 then + -- determino se due facce lunghe oppure una lunga e l'altra terminale + + return Long2Cut.Make( Proc, nPhase, nRawId, nPartId) + -- tre facce + elseif Proc.Fct == 3 then + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + -- se una faccia terminale e due lunghe + if bIsL then + return Long2Cut.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti U lunga + else + return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId) + end + -- più facce + else + return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId) + end + + -- altrimenti lavorazione unica + else + -- una faccia + if Proc.Fct == 1 then + -- se piccola, con fresa + if ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) or + Proc.Box:getDimX() * Proc.Box:getDimY() * Proc.Box:getDimZ() < MAX_MILL_VOL then + return MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) + -- altrimenti, con lama + else + return Cut.Make( Proc, nPhase, nRawId, nPartId, 0) + end + -- due facce + elseif Proc.Fct == 2 then + -- determino l'angolo tra le facce + local _, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + -- se ortogonali e piccole, con fresa + if abs( dAng + 90) < 1 and + ( ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) or + Proc.Box:getDimX() * Proc.Box:getDimY() * Proc.Box:getDimZ() < MAX_MILL_VOL) then + return MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) + -- altrimenti, con lama + else + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + end + -- tre o più facce + else + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId) + end + end +end + +--------------------------------------------------------------------- +return ProcessLapJoint diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessLongCut.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessLongCut.lua new file mode 100644 index 0000000..9c475e9 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessLongCut.lua @@ -0,0 +1,253 @@ +-- ProcessLongCut.lua by Egaltech s.r.l. 2019/07/25 +-- Gestione calcolo taglio longitudinale per Travi + +-- Tabella per definizione modulo +local ProcessLongCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessLongCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLongCut.Identify( Proc) + return (( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 10) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLongCut.Classify( Proc) + -- se una sola faccia non ci sono limiti + if Proc.Fct == 1 then + return true, false + end + -- verifico la normale della faccia principale + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 then + return true, true + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local dLen = Proc.Box:getDimX() + local dWidth = sqrt( Proc.Box:getDimY() * Proc.Box:getDimY() + Proc.Box:getDimZ() * Proc.Box:getDimZ()) + -- limitazioni su inizio e fine derivanti da altre facce + local bLimXmin = false + local bLimXmax = false + if Proc.Fct >= 3 then + bLimXmin = true + bLimXmax = true + elseif Proc.Fct >= 2 then + local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if vtN1:getX() > 0 then + bLimXmin = true + else + bLimXmax = true + end + end + -- Verifico se lavorazione da sotto + local nSide = 1 + if vtN:getZ() < - 0.5 then nSide = -1 end + + -- Se non è sotto : lavorazione Long2Cut + if nSide ~= - 1 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2Cut') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + end + end + local dStartDist = 0 + if ( bLimXmin and vtN:getY() < 0) or ( bLimXmax and vtN:getY() > 0) then + dStartDist = dToolDiam / 2 + end + local dEndDist = 0 + if ( bLimXmin and vtN:getY() > 0) or ( bLimXmax and vtN:getY()< 0) then + dEndDist = dToolDiam / 2 + end + -- determino numero di parti + local nC = ceil( ( dLen - 2 * BD.LONGCUT_ENDLEN) / BD.LONGCUT_MAXLEN) + local dC = ( dLen - 2 * BD.LONGCUT_ENDLEN) / nC + local dAccDist = BD.LONGCUT_ENDLEN + if nC > 0 then + nC = nC + 2 + else + nC = EgtIf( dLen > BD.LONGCUT_ENDLEN, 2, 1) + dAccDist = EgtIf( nC == 2, dLen / 2, 0) + end + -- si percorre il lato basso della faccia + local nM = 0 + for i = 1, nC do + -- ciclo sulle passate + local nO = 1 + local dStep = 0 + if dWidth + 2 * BD.CUT_EXTRA > dToolDiam then + nO = ceil(( dWidth + 2 * BD.CUT_EXTRA) / dToolDiam) + if nO > 1 then + dStep = ( dWidth + 2 * BD.CUT_EXTRA - dToolDiam) / ( nO - 1) + end + end + for k = nO, 1, -1 do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == 1, -dStartDist, - dAccDist - ( i - 2) * dC) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + local dEal = EgtIf( i == nC, -dEndDist, - dAccDist - ( nC - i - 1) * dC) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale (nullo se concavo) + if k >1 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( k - 1) * dStep) + else + EgtSetMachiningParam( MCH_MP.OFFSR, - BD.CUT_EXTRA) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + -- se ci sono le facce limitanti + for i = 1, Proc.Fct - 1 do + -- inserisco la lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, i}}) + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + -- altrimenti è sotto : lavorazione Long2CutDown + else + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2CutDown') + 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 dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- larghezza faccia + local _, _, dWidth = BL.GetFaceHvRefDim( Proc.Id, 0) + -- aggiuntivo sull'affondamento + local dAgg = BD.CUT_EXTRA + -- determino il numero di parti in cui dividere la lavorazione + local dEndLen = BD.LONGCUT_ENDLEN + if dLen < 2 * dEndLen + BD.LONGCUT_MAXLEN then + dEndLen = dLen / 3 + end + local nC = ceil( ( dLen - 2 * dEndLen) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then dC = ( dLen - 2 * dEndLen) / nC end + nC = nC + 2 + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + -- Limitazioni della lavorazione + local nPos = EgtIf( vtN:getY() < 0, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, 0, - dEndLen - ( nPos - 2) * dC) + local dEal = EgtIf( nPos == nC, 0, - dEndLen - ( nC - nPos - 1) * dC) + -- Posizione braccio portatesta + local nSCC + if vtN:getY() < 0 then + nSCC = EgtIf( ( j == 1 or j == nC - 1), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + else + nSCC = EgtIf( ( j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + local dDepth = min( dMaxDepth, dWidth + dAgg) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + + return true +end + +--------------------------------------------------------------------- +return ProcessLongCut diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessLongDoubleCut.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessLongDoubleCut.lua new file mode 100644 index 0000000..a752533 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessLongDoubleCut.lua @@ -0,0 +1,284 @@ +-- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2019/09/04 +-- Gestione calcolo doppio taglio longitudinale per Travi + +-- Tabella per definizione modulo +local ProcessLong2Cut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessLongDoubleCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLong2Cut.Identify( Proc) + return ( Proc.Grp == 0 and Proc.Prc == 12) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLong2Cut.Classify( Proc) + -- verifico le normali delle facce + --local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + --for i = 1, nFacetCnt do + -- local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- if vtN:getZ() < - 0.707 then + -- return true, true + -- end + --end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) + -- dati delle facce + local nFc = {0,1} + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if Proc.Fct == 3 then + if abs( vtN[1]:getX()) > 0.5 then + nFc = {2,1} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT) + elseif abs( vtN[2]:getX()) > 0.5 then + nFc = {0,2} + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT) + end + end + local dLen = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD):getDimX() + -- verifico che il doppio taglio longitudinale non sia orientato verso il basso + --if vtN[1]:getZ() < - 0.707 or vtN[2]:getZ() < - 0.707 then + -- local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Longitudinal Double Cut from bottom impossible' + -- EgtOutLog( sErr) + -- return false, sErr + --end + -- verifico posizione (+1=sopra, -1=sotto, 0=sui lati) + local nSide = 0 + if vtN[1]:getZ() > -10 * GEO.EPS_SMALL and vtN[2]:getZ() > -10 * GEO.EPS_SMALL then + nSide = 1 + elseif vtN[1]:getZ() < -10 * GEO.EPS_SMALL and vtN[2]:getZ() < -10 * GEO.EPS_SMALL then + nSide = -1 + end + -- angolo diedro per stabilire se taglio convesso + local bInt, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFc[1], nFc[2], GDB_ID.ROOT) + local bConvex + local bOrtho + local ptM + if bInt then + bConvex = ( dAng >= 0) + bOrtho = ( abs( dAng + 90) < 1) + ptM = ( ptP1 + ptP2) / 2 + else + bConvex = true + bOrtho = false + ptM = ( ptC[1] + ptC[2]) / 2 + end + -- analisi del taglio + local vOrd = {} + local vFaceUse = {} + if nSide == 1 then + vOrd = EgtIf( ptC[1]:getY() < ptM:getY(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + elseif nSide == -1 then + vOrd = EgtIf( ptC[1]:getY() < ptM:getY(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestParalOpposite( ptC[1] - ptM), BL.GetNearestParalOpposite( ptC[2] - ptM)} + else + local bFront = ( vtN[1]:getY() < 0) + if bFront then + vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + else + vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 2, 1}, { 1, 2}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + end + end + local vWidth = {} + _, _, vWidth[1] = BL.GetFaceHvRefDim( Proc.Id, nFc[1]) + _, _, vWidth[2] = BL.GetFaceHvRefDim( Proc.Id, nFc[2]) + + -- Se non è sotto : lavorazione Long2Cut + if nSide ~= - 1 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2Cut') + 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 dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- determino il numero di parti in cui dividere la lavorazione + local dEndLen = BD.LONGCUT_ENDLEN + if dLen < 2 * dEndLen + BD.LONGCUT_MAXLEN then + dEndLen = dLen / 3 + end + local nC = ceil( ( dLen - 2 * dEndLen) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then dC = ( dLen - 2 * dEndLen) / nC end + nC = nC + 2 + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + -- se facce ortogonali (concave), lavoro solo quella con versore maggiormente verso l'alto + local nIni, nFin = 1, 2 + if bOrtho then + if vtN[vOrd[1]]:getZ() >= vtN[vOrd[2]]:getZ() then + nFin = 1 + else + nIni = 2 + end + end + -- su entrambe le facce + for i = nIni, nFin do + -- Limitazioni della lavorazione + local nPos = EgtIf( i == 1, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, 0, - dEndLen - ( nPos - 2) * dC) + local dEal = EgtIf( nPos == nC, 0, - dEndLen - ( nC - nPos - 1) * dC) + -- Posizione braccio portatesta + local nSCC = EgtIf( ( j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- ciclo sulle passate + local nO = 1 + local dStep = 0 + local dAgg = EgtIf( bConvex, 2 * BD.CUT_EXTRA, BD.CUT_EXTRA) + if vWidth[vOrd[i]] > 0.8 * dToolDiam then + nO = ceil( vWidth[vOrd[i]] / ( 0.6 * dToolDiam)) + if nO > 1 then + dStep = vWidth[vOrd[i]] / nO + end + end + for k = 1, nO do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFc[vOrd[i]]}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]]) + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- imposto offset radiale (nullo se concavo) + if k < nO then + EgtSetMachiningParam( MCH_MP.OFFSR, ( nO - k) * dStep) + else + EgtSetMachiningParam( MCH_MP.OFFSR, EgtIf( bConvex, - BD.CUT_EXTRA, 0)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + end + + -- altrimenti è sotto : lavorazione Long2CutDown + else + local sWarn + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2CutDown') + 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 dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- aggiuntivo sull'affondamento + local dAgg = EgtIf( bConvex, BD.CUT_EXTRA, 0) + -- determino il numero di parti in cui dividere la lavorazione + local dEndLen = BD.LONGCUT_ENDLEN + if dLen < 2 * dEndLen + BD.LONGCUT_MAXLEN then + dEndLen = dLen / 3 + end + local nC = ceil( ( dLen - 2 * dEndLen) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then dC = ( dLen - 2 * dEndLen) / nC end + nC = nC + 2 + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + -- su entrambe le facce + for i = 1, 2 do + -- Limitazioni della lavorazione + local nPos = EgtIf( i == 1, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, 0, - dEndLen - ( nPos - 2) * dC) + local dEal = EgtIf( nPos == nC, 0, - dEndLen - ( nC - nPos - 1) * dC) + -- Posizione braccio portatesta + local nSCC = EgtIf( ( j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFc[vOrd[i]]}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]]) + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + if vWidth[vOrd[i]] + dAgg > dMaxDepth - BD.COLL_SIC then + sWarn = 'Warning in double cut : depth (' .. EgtNumToString( vWidth[vOrd[i]] + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth - BD.COLL_SIC, 1) .. ')' + end + local dDepth = min( dMaxDepth - BD.COLL_SIC, vWidth[vOrd[i]] + dAgg) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessLong2Cut diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessMark.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessMark.lua new file mode 100644 index 0000000..71d8973 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessMark.lua @@ -0,0 +1,91 @@ +-- ProcessMark.lua by Egaltech s.r.l. 2018/04/18 +-- Gestione calcolo marcatura per Travi + +-- Tabella per definizione modulo +local ProcessMark = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessMark started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessMark.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 60) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessMark.Classify( Proc) + -- recupero il versore estrusione + local vtN = EgtCurveExtrusion( Proc.Id, GDB_ID.ROOT) + -- verifico sia una curva + if not vtN then + return false + end + -- verifico se la marcatura è lavorabile solo da sotto + local bDown = (( vtN:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessMark.Make( Proc, nPhase, nRawId, nPartId) + -- recupero eventuale geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero i dati della marcatura + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico sia una curva + if not vtExtr then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che la marcatura non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + local vGeom = {{ Proc.Id, -1}} + if AuxId then vGeom[2] = { AuxId, -1} end + EgtSetMachiningGeometry( vGeom) + -- 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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessMark diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessMortise.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessMortise.lua new file mode 100644 index 0000000..7108ff3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessMortise.lua @@ -0,0 +1,125 @@ +-- ProcessMortise.lua by Egaltech s.r.l. 2019/08/27 +-- Gestione calcolo mortase per Travi + +-- Tabella per definizione modulo +local ProcessMortise = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessMortise started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessMortise.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 50) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 51) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 53)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessMortise.Classify( Proc) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se la mortasa è lavorabile solo da sotto + local bDown = ( vtN:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessMortise.Make( Proc, nPhase, nRawId, nPartId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- se curva aperta la allungo e chiudo + if not EgtCurveIsClosed( AuxId) then + local _, nCount = EgtCurveDomain( AuxId) + EgtCloseCurveCompo( AuxId) + EgtSetInfo( AuxId, 'OPEN', nCount) + end + -- recupero i dati del bottom + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- verifico che la mortasa non sia orientata verso il basso (-5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mortise from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza della mortasa + local frMor = Frame3d( ptC, vtN) + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local dMorH = b3Mor:getDimZ() + -- elevazione del punto centro + local _, dCenElev = BL.GetPointDirDepth( nRawId, ptC, vtN) + dMorH = max( dMorH, dCenElev or 0) + -- recupero la lavorazione + local sPocketing = ML.FindPocketing( 'Mortise', 30) + 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 = 'Mort_' .. ( 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 vtN:getY() < GEO.EPS_SMALL 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 + local sWarn + if dMorH > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in mortise : elevation (' .. EgtNumToString( dMorH,1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth,1) .. ')' + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dMorH) + dMorH = dMaxDepth + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMorH, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessMortise diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfCamb.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfCamb.lua new file mode 100644 index 0000000..b957fb2 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfCamb.lua @@ -0,0 +1,260 @@ +-- ProcessProfCamb.lua by Egaltech s.r.l. 2019/04/10 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfCamb = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfCamb started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfCamb.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 103) +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtNF) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtNF) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtSP( AuxId, GDB_ID.ROOT) + vtNP * 5.0 + -- determino asse di rotazione + local vtRot = - Y_AX() + if vtNF:getX() < 0 then vtRot = - vtRot end + if vtNF:getZ() < -0.1 then + vtRot = - vtRot + elseif vtNF:getY() < -0.1 then + vtRot:rotate( X_AX(), 90) + elseif vtNF:getY() > 0.1 then + vtRot:rotate( X_AX(), -90) + end + -- miglioro l'inclinazione (ripartendo da faccia perpendicolare asse trave) + vtNP[2] = 0 vtNP[3] = 0 + local dRot = 45 + for i = 1, 4 do + local vtNP2 = Vector3d( vtNP) + vtNP2:rotate( vtRot, dRot) + local frRef = Frame3d( ptStart, vtNP2) + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frRef) + if b3Box:getMax():getZ() < -3 then + vtNP = Vector3d( vtNP2) + end + dRot = dRot / 2 + end + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- ultima faccia + local nRefFacet = nLastFacet - 1 -- penultima faccia + local vtNF = EgtSurfTmFacetNormVersor( Proc.Id, nLastFacet, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nRefFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtNF:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtNF) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + -- se non da sotto, inserisco lavorazione finitura angolo + if nSide ~= -1 then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, -0.5) + -- imposto tipo uso faccia + local nFaceUse = MCH_MILL_FU.ORTHO_DOWN + if nSide ~= 1 then + nFaceUse = EgtIf( vtN:getY() > 0.1, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- aggiorno ingombro testa o coda per presa + if nSide == 0 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfCamb diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfConcave.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfConcave.lua new file mode 100644 index 0000000..4229c8c --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfConcave.lua @@ -0,0 +1,282 @@ +-- ProcessProfConcave.lua by Egaltech s.r.l. 2019/04/08 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfConcave = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfConcave started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfConcave.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 101) +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) // 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- imposto parametri di attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 5) + EgtSetMachiningParam( MCH_MP.LOPERP, 5) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- imposto parametri di attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 5) + EgtSetMachiningParam( MCH_MP.LOPERP, 5) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + -- eventuale finitura faccia finale (ortogonale alla trave) + if nSide ~= -1 and bLastTrim then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- eventuale finitura faccia iniziale (parallela alla trave) + if nSide ~= -1 and bFirstTrim then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfConcave diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfConvex.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfConvex.lua new file mode 100644 index 0000000..a959d69 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfConvex.lua @@ -0,0 +1,282 @@ +-- ProcessProfConvex.lua by Egaltech s.r.l. 2019/04/08 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfConvex = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfConvex started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfConvex.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 102) +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) // 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- imposto parametri di attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 5) + EgtSetMachiningParam( MCH_MP.LOPERP, 5) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- imposto parametri di attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 5) + EgtSetMachiningParam( MCH_MP.LOPERP, 5) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + -- eventuale finitura faccia finale (ortogonale alla trave) + if nSide ~= -1 and bLastTrim then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- eventuale finitura faccia iniziale (parallela alla trave) + if nSide ~= -1 and bFirstTrim then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfConvex diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfFront.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfFront.lua new file mode 100644 index 0000000..8a85400 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfFront.lua @@ -0,0 +1,236 @@ +-- ProcessProfFront.lua by Egaltech s.r.l. 2019/04/10 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfFront = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfFront started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfFront.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 100) +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + local vtNP = Vector3d( vtN) + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- ultima faccia + local nRefFacet = nLastFacet - 1 -- penultima faccia + -- determino la normale media + local CvxHullId = EgtSurfTmConvexHullInBBox( EgtGetParent( Proc.Id), Proc.Id, b3Raw, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( CvxHullId, 0, GDB_ID.ROOT) + EgtErase( CvxHullId) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + --EgtOutLog( 'vtN=' .. tostring( vtN)) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + -- se non da sotto, inserisco lavorazione finitura angolo + if nSide ~= -1 then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- imposto tipo uso faccia + local nFaceUse = MCH_MILL_FU.PARAL_DOWN + if nSide ~= 1 then + nFaceUse = EgtIf( vtN:getY() > 0.1, MCH_MILL_FU.PARAL_FRONT, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- aggiorno ingombro testa o coda per presa + if nSide == 0 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfFront diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfHead.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfHead.lua new file mode 100644 index 0000000..27791ac --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessProfHead.lua @@ -0,0 +1,303 @@ +-- ProcessProfHead.lua by Egaltech s.r.l. 2019/04/11 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfHead = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfHead started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfHead.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 106) +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- assegno la normale + local vtNP = Vector3d( vtN) + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + -- determino la normale media + local CvxHullId = EgtSurfTmConvexHullInBBox( EgtGetParent( Proc.Id), Proc.Id, b3Raw, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( CvxHullId, 0, GDB_ID.ROOT) + EgtErase( CvxHullId) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi negli angoli + local vAngs = {} + for i = 1, Proc.Fct do + local _, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, i-1, i, GDB_ID.ROOT) + if ( dAng and dAng < -30) then + table.insert( vAngs, i - 1) + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- imposto parametri di attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 5) + EgtSetMachiningParam( MCH_MP.LOPERP, 5) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- imposto parametri di attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 5) + EgtSetMachiningParam( MCH_MP.LOPERP, 5) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + -- eventuali finiture + if nSide ~= -1 and #vAngs > 0 then + -- dimensioni feature + local dLen = Proc.Box:getDimX() + local dDep = EgtIf( nSide == 1, Proc.Box:getDimZ(), Proc.Box:getDimY()) + -- se più alta che lunga + if dDep > dLen then + for i = 1, #vAngs do + sName = 'ProfV'.. tostring( i)..'_'..( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dElev = EgtSurfTmFacetOppositeSide( Proc.Id, vAngs[i], EgtIf( bHead, X_AX(), -X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vAngs[i]}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dElev, 1)) + -- imposto posizione braccio + local nSCC = MCH_SCC.ADIR_YM + if nSide == 0 then + nSCC = EgtIf( vtN:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + -- altrimenti + else + for i = 1, #vAngs do + sName = 'ProfV'.. tostring( i)..'_'..( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dElev = EgtSurfTmFacetOppositeSide( Proc.Id, vAngs[i]+1, vtN, GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vAngs[i]+1}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dElev, 1)) + -- imposto posizione braccio + local nSCC = MCH_SCC.ADIR_YM + if nSide == 0 then + nSCC = EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfHead diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessRidgeLap.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessRidgeLap.lua new file mode 100644 index 0000000..9402b47 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessRidgeLap.lua @@ -0,0 +1,205 @@ +-- ProcessRidgeLap.lua by Egaltech s.r.l. 2019/04/01 +-- Gestione calcolo mezzolegno di testa per Travi + +-- Tabella per definizione modulo +local ProcessRidgeLap = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessRidgeLap started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessRidgeLap.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 30) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessRidgeLap.Classify( Proc) + -- Se più corta del limite si può fare anche da sotto + if Proc.Box:getDimX() < BD.MAX_LEN_RIDGELAP_FROM_BOTTOM then + return true, false + end + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.707 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + return true + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getX()) < 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i-1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[3]]) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo riferimenti per facce inclinate + local vtRef = Vector3d( vtN[vFaceOrd[3]]) + local vtRef2 = Vector3d( vtN[vFaceOrd[2]]) + -- eseguo + for i = 1, #vCuts do + local nOrthoOpposite + if i % 2 == 1 then + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + else + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[3]]) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[2]]) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtN[vFaceOrd[3]]:getZ()) > 0.1 then + local b3Fac1 = BL.GetFaceBox( Proc.Id, vFaceOrd[1] - 1) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtN[vFaceOrd[3]]:getZ()) > 0.1 then + local b3Fac1 = BL.GetFaceBox( Proc.Id, vFaceOrd[1] - 1) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessRidgeLap diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessRoundArch.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessRoundArch.lua new file mode 100644 index 0000000..1a41dd7 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessRoundArch.lua @@ -0,0 +1,214 @@ +-- ProcessRoundArch.lua by Egaltech s.r.l. 2019/06/13 +-- Gestione calcolo archi per Travi + +-- Tabella per definizione modulo +local ProcessRoundArch = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessRoundArch started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessRoundArch.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 104) +end +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessRoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessRoundArch.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di coda + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessRoundArch.Classify( Proc) + -- se di testa o coda, è indifferente alla posizione + if Proc.Head or Proc.Tail then + return true, false + end + -- è intermedia, devo verificare la normale del centro + local nMidFacet = Proc.Fct // 2 + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se la feature è lavorabile solo da sotto + --local bDown = ( vtN:getZ() < - 0.1) + local bDown = false + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessRoundArch.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 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 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 + -- se non di testa o coda ne verifico la lunghezza per eventuale spezzatura + local nStep = 1 + local dStep = 0 + local dLenMax = min( BD.LONGCUT_MAXLEN, 0.5 * b3Raw:getDimX()) + local b3Aux = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Aux:getDimX() > dLenMax then + local dCrvLen = EgtCurveLength( AuxId) + nStep = ceil( dCrvLen / dLenMax) + dStep = dCrvLen / nStep + EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) + end + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local nDouble = 1 + local bCanDouble = ( abs( vtExtr:getZ()) < 0.5 and abs( vtExtr:getX()) < 0.1 and b3Aux:getDimY() > b3Raw:getDimY() - 1.0) + if nStep > 1 then + -- devo lasciare un codolo + dDepth = dDepth - BD.DIM_STRIP + else + -- devo affondare un poco oltre + dDepth = dDepth + BD.CUT_EXTRA + end + if dDepth > dMaxDepth then + if bCanDouble then + nDouble = 2 + dDepth = min( 0.5 * dDepth, dMaxDepth) + else + dDepth = dMaxDepth + end + end + -- eseguo + for i = 1, nStep do + for j = 1, nDouble do + -- 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}}) + -- eventuale accorciamento di testa + if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then + local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + end + -- eventuale accorciamento di coda + if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then + local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- se estrusione da sotto, inverto direzione fresa + if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- se seconda passata, inverto direzione di lavoro + if j == 2 then + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + if bToolInv then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + -- posizione braccio porta testa + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessRoundArch diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessSimpleScarf.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessSimpleScarf.lua new file mode 100644 index 0000000..eaae7aa --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessSimpleScarf.lua @@ -0,0 +1,214 @@ +-- ProcessSimpleScarf.lua by Egaltech s.r.l. 2018/11/04 +-- Gestione calcolo giunto Gerber per Travi + +-- Tabella per definizione modulo +local ProcessSimpleScarf = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessSimpleScarf started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSimpleScarf.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 70) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessSimpleScarf.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSimpleScarf.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + return true + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getY()) > 0.1 or abs( vtN[i]:getZ()) > 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per facce inclinate + local vtRef2 = Vector3d( vtN[vFaceOrd[2]]) + -- eseguo + for i = 1, #vCuts do + local nOrthoOpposite + if i % 2 == 1 then + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + else + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtRef2 = vtN[vFaceOrd[2]] + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[2] - 1) + if DimV <= DimH then + vtRef2 = Vector3d( frHV:getVersY()) + else + vtRef2 = Vector3d( frHV:getVersX()) + end + end + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = BL.GetFaceBox( Proc.Id, vFaceOrd[1] - 1) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = BL.GetFaceBox( Proc.Id, vFaceOrd[1] - 1) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessSimpleScarf diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessSplit.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessSplit.lua new file mode 100644 index 0000000..b6ff06a --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessSplit.lua @@ -0,0 +1,104 @@ +-- ProcessSplit.lua by Egaltech s.r.l. 2019/06/29 +-- Gestione calcolo tagli di separazione per Travi + +-- Tabella per definizione modulo +local ProcessSplit = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessSplit started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSplit.Identify( Proc) + return ( Proc.Grp == 2 and Proc.Prc == 350) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSplit.Make( Proc, nPhase, nRawId, nPartId) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + local bHorizCut = ( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL and b3Raw:getDimZ() < BD.MAX_DIM_HTCUT) + local dDimYRef = EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, BD.MAX_DIM_HTCUT, BD.MAX_DIM_HTCUT_HBEAM) + local bDoubleCut = ( not bHorizCut and b3Raw:getDimY() > dDimYRef + 10 * GEO.EPS_SMALL) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- flag di lavorazione faccia + local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_FRONT) + -- separazione solo se esiste grezzo successivo con pezzi o scaricabile + local nNextRawId = EgtGetNextRawPart( nRawId) + local bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() > BD.MinRaw)) + -- determino se più tagli con offset + local nCuts = 1 + local dOffsL = 0 + if not bSplit then + -- cerco grezzo successivo che sia nella fase + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtVerifyRawPartPhase( nNextRawId, nPhase) then + local b3NextRaw = EgtGetRawPartBBox( nNextRawId) + local dLenEndRaw = ptC:getX() - b3NextRaw:getMin():getX() + nCuts = ceil( dLenEndRaw / BD.MAX_LEN_SCRAP) + dOffsL = dLenEndRaw / nCuts + end + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bSplit, 'SplitSide', 'TailSide')) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, true, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- calcolo extra taglio ed accorciamento + local dCutExtra = 0 + local dAccStart = 0 + if b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL or b3Raw:getDimY() < 2 * BD.MAX_DIM_HTCUT_HBEAM + 10 * GEO.EPS_SMALL then + dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY(), 0) + BD.CUT_EXTRA + dAccStart = 0 + else + dCutExtra = - ( b3Raw:getDimY() - BD.MAX_DIM_HTCUT - BD.CUT_EXTRA) + local dSawRad = dSawDiam / 2 + local dKL = dSawRad - ( BD.MAX_DIM_HTCUT + BD.CUT_EXTRA) + b3Raw:getDimY() / 2 + BD.CUT_EXTRA_MIN + dAccStart = sqrt( dSawRad * dSawRad - dKL * dKL) + end + -- se necessari tagli in doppio, eseguo gli opposti + if bDoubleCut then + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes = EgtIf( bSplit, 'Presplit;', 'Precut;') + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_BACK, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, sNotes, b3Raw) + if not bOk then return false, true, sErr end + end + end + -- eseguo i tagli necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes + if bSplit then + sNotes = EgtIf( i == 1, 'Split;', 'Presplit;') + else + sNotes = EgtIf( i == 1, 'Cut;', 'Precut;') + end + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, sNotes, b3Raw) + if not bOk then return false, true, sErr end + end + -- ritorno anche flag di passaggio a fase successiva + return true, true +end + +--------------------------------------------------------------------- +return ProcessSplit diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessStepJoint.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessStepJoint.lua new file mode 100644 index 0000000..c5525fd --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessStepJoint.lua @@ -0,0 +1,213 @@ +-- ProcessStepJoint.lua by Egaltech s.r.l. 2019/09/25 +-- Gestione calcolo giunto a gradino per Travi + +-- Tabella per definizione modulo +local ProcessStepJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessStepJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessStepJoint.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 80) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessStepJoint.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- gestisco solo 2 facce + if nFacetCnt ~= 2 then + return false, false + end + -- se due facce, verifico se convesso + local bConvex = true + if nFacetCnt == 2 then + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + bConvex = not bAdj or ( dAng > 0) + end + -- verifico le normali delle facce + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if not bConvex and vtN:getZ() < - 0.72 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessStepJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se convesso, lo tratto come due tagli singoli + if bConvex then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- lavoro per prima la faccia più diretta in alto + local vOrd = { 1, 2} + if vtN[2]:getZ() > vtN[1]:getZ() then + vOrd = { 2, 1} + end + -- creo piano di taglio coincidente con la prima faccia e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptC[vOrd[1]], vtN[vOrd[1]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- creo piano di taglio coincidente con la seconda faccia e lo lavoro + AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptC[vOrd[2]], vtN[vOrd[2]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- altrimenti + else + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local k, l = nBigInd, nSmaInd + if ( i % 2) == 1 then + k, l = l, k + end + local nOrthoOpposite + if bOnY then + local bFront = ( ptC[k]:getY() < ptPs:getY()) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + local bOver = ( ptC[k]:getZ() > ptC[l]:getZ()) + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, EgtIf( bHead, 'HeadSide', 'TailSide')) + if not bOk then + return bOk, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + return true +end + +--------------------------------------------------------------------- +return ProcessStepJoint diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessStepJointNotch.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessStepJointNotch.lua new file mode 100644 index 0000000..64521d0 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessStepJointNotch.lua @@ -0,0 +1,152 @@ +-- ProcessStepJointNotch.lua by Egaltech s.r.l. 2019/09/25 +-- Gestione calcolo tacca a gradino per Travi + +-- Tabella per definizione modulo +local ProcessStepJointNotch = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessStepJointNotch started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessStepJointNotch.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 80) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessStepJointNotch.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- gestisco solo 2 facce + if nFacetCnt ~= 2 then + return false, false + end + -- verifico le normali delle facce + local bDown = false + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < -0.1 then + bDown = true + end + end + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessStepJointNotch.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local k, l = nBigInd, nSmaInd + if ( i % 2) == 1 then + k, l = l, k + end + local nOrthoOpposite + if bOnY then + local bFront = ( ptC[k]:getY() < ptPs:getY()) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + local bOver = ( ptC[k]:getZ() > ptC[l]:getZ()) + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + if not bOk then + return bOk, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessStepJointNotch diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessTenon.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessTenon.lua new file mode 100644 index 0000000..a2b5938 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessTenon.lua @@ -0,0 +1,188 @@ +-- ProcessTenon.lua by Egaltech s.r.l. 2019/07/16 +-- Gestione calcolo tenone per Travi + +-- Tabella per definizione modulo +local ProcessTenon = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTenon started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessTenon.Identify( Proc) + return ( (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 50) or + (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 52)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessTenon.Classify( Proc) + -- recupero i dati della curva di contorno della faccia top + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se il tenone è lavorabile solo da sotto + local bDown = ( vtExtr:getZ() < - 0.26) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessTenon.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva di contorno della faccia top + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + local bClosed = EgtCurveIsClosed( AuxId) + -- verifico che il tenone non sia orientato verso il basso (-15 deg) + if vtExtr:getZ() < - 0.26 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Tenon from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza del tenone + local frTen = Frame3d( ptBC, vtExtr) + local b3Ten = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frTen) + local dTenH = b3Ten:getDimZ() + -- assegno centro e normale della faccia top + local vtN = vtExtr + local ptC = ptBC + vtN * dTenH + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- determino larghezza massima di svuotatura + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frTen) + local dPockX = max( b3Ten:getMax():getX() - b3Aux:getMax():getX(), b3Aux:getMin():getX() - b3Ten:getMin():getX()) + local dPockY = max( b3Ten:getMax():getY() - b3Aux:getMax():getY(), b3Aux:getMin():getY() - b3Ten:getMin():getY()) + local dPockL = max( dPockX, dPockY) + -- porto inizio curva il più possibile sul bordo + BL.PutStartNearestToEdge( AuxId, b3Solid) + -- se vero tenone inclinato o non esattamente alle estremità, necessario taglio di lama sulla testa + if Proc.Prc ~= 52 and + ( not AreSameOrOppositeVectorApprox( vtN, X_AX()) or + ( Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dOvmHead - 100 * GEO.EPS_SMALL and + Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 100 * GEO.EPS_SMALL)) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla testa del tenone e lo lavoro + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptC, vtN, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Tenon') + 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 dMillDiam = 20 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) 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 + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + local dDepth = 0 + if dTenH > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in tenon : elevation (' .. EgtNumToString( dTenH, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth - dTenH + dTenH = dMaxDepth + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + -- determino il numero di passate concentriche (max 4) + local MAX_PASS = 4 + local nPass = min( ceil( dPockL / ( 0.7 * dMillDiam)), MAX_PASS) + local dStep = min( dPockL, 0.7 * dMillDiam * MAX_PASS) / nPass + for i = nPass, 1, -1 do + -- inserisco la passata finale della lavorazione + local sNameF = 'TenF_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo i parametri + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dTenH, 1) .. ';') + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + local dOffset = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- se contorno aperto, cambio parametri di attacco/uscita + if not bClosed then + EgtSetMachiningParam( MCH_MP.LITANG, 0.7 * dMillDiam) + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, 0.7 * dMillDiam) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if abs( vtN:getY()) > 0.1 or ( b3Raw:getDimZ() - Proc.Box:getDimZ()) < BD.MIN_HEIGHT then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessTenon diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessText.lua b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessText.lua new file mode 100644 index 0000000..eac4f34 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/LuaLibs/ProcessText.lua @@ -0,0 +1,86 @@ +-- ProcessText.lua by Egaltech s.r.l. 2018/04/17 +-- Gestione calcolo testi per Travi + +-- Tabella per definizione modulo +local ProcessText = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessText started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessText.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 61) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessText.Classify( Proc) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + return false + end + -- verifico se il testo è lavorabile solo da sotto + local bDown = (( vtN:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessText.Make( Proc, nPhase, nRawId, nPartId) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Text with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che il testo non sia orientato verso il basso (-5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Text from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Text') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Text_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -1}}) + -- imposto posizione braccio porta testa + if vtN:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessText diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Process.lua b/ProgramData/EgtCAM5/Beam con BpxT5/Process.lua new file mode 100644 index 0000000..29c8bb4 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/Process.lua @@ -0,0 +1,241 @@ +-- Process.lua by Egaltech s.r.l. 2019/07/02 +-- Gestione calcolo disposizione e lavorazioni per Travi +-- Si opera sulla macchina corrente + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + EgtOutBox( 'La macchina corrente non è configurata per lavorare travi', 'Lavora Travi', 'ERROR') + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Segnalazione avvio +EgtOutLog( '*** Beam Process Start ***', 1) + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Variabili di modulo +local vBeam = {} +local dRawW +local dRawH + +------------------------------------------------------------------------------------------------------------- +-- *** Recupero le travi selezionate *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessInputData() + + -- Recupero le travi selezionate + local nId = EgtGetFirstSelectedObj() + while nId do + local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) + if nPartId then + local bFound = false + for i = 1, #vBeam do + if vBeam[i].Id == nPartId then + bFound = true + break + end + end + if not bFound then + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + end + nId = EgtGetNextSelectedObj() + end + if #vBeam == 0 then + EgtOutBox( 'Non sono state selezionate travi', 'Lavora Travi', 'ERROR') + return false + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi selezionate : ' .. sOut, 1) + end + + -- Ne recupero e verifico le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + EgtOutBox( 'Box non definito per la trave ' .. vBeam[i].Name, 'Lavora Travi', 'ERROR') + return false + else + vBeam[i].Box = b3Solid + end + end + dRawW = vBeam[1].Box:getDimY() + dRawH = vBeam[1].Box:getDimZ() + local vBeamErr = {} + for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end + end + if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + EgtDeselectPartObjs( vBeam[vBeamErr[i]].Id) + table.remove( vBeam, vBeamErr[i]) + end + EgtOutLog( sOut, 1) + EgtOutBox( sOut, 'Lavora Travi', 'INFO') + EgtDraw() + return false + end + EgtDeselectAll() + + -- Le ordino in senso di lunghezza crescente + table.sort( vBeam, function( B1, B2) return B1.Box:getDimX() < B2.Box:getDimX() end) + do + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi ordinate : ' .. sOut, 1) + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle travi nel grezzo *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessBeams() + + -- Determinazione minimo grezzo scaricabile + BE.CalcMinUnloadableRaw( dRawW, dRawH) + + -- Lunghezza totale delle travi + local dTotLen = 0 + for i = 1, #vBeam - 1 do + dTotLen = dTotLen + vBeam[i].Box:getDimX() + end + dTotLen = dTotLen + max( vBeam[#vBeam].Box:getDimX(), BD.MinRaw) + local dAddLen = BD.OVM_HEAD + ( #vBeam - 1) * BD.OVM_MID + EgtOutLog( 'Ltot : ' .. EgtNumToString( dTotLen, 1) .. ' Lagg : '.. EgtNumToString( dAddLen, 1), 1) + + -- Richiedo lunghezza del grezzo e sovramateriale di testa + local vsVal = EgtDialogBox( 'Lavora Travi' .. ' (Ltot='.. EgtNumToString( dTotLen + dAddLen + 0.5, 0) .. ', Lmax=' .. EgtNumToString( BD.MAX_RAW, 0) .. ')', + {'Lunghezza grezzo', EgtNumToString( BD.STD_RAW, 0)}, + {'Sovramateriale di testa', EgtNumToString( BD.OVM_HEAD, 0)}, + {'Forza sezione verticale', ' CB:true,*false'}) + if not vsVal then + EgtDraw() + return + end + local dRawL = EgtEvalNumExpr( vsVal[1]) + if not dRawL then + local sOut = 'Lunghezza grezzo errata : ' .. vsVal[1] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + dRawL = min( dRawL, BD.MAX_RAW) + local dOvmHead = EgtEvalNumExpr( vsVal[2]) + if not dOvmHead then + local sOut = 'Sovramateriale di testa errato : ' .. vsVal[2] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo sezione barra con travi + local bVert = ( vsVal[3] == 'true') + if bVert then + if dRawW > dRawH then dRawW, dRawH = dRawH, dRawW end + end + EgtOutLog( 'Lraw : ' .. EgtNumToString( dRawL, 1) .. ' Lovm : '.. EgtNumToString( dOvmHead, 1), 1) + + -- Verifico sezione barra + if dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ')' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo le travi nel grezzo + local bOk, sErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) + if not bOk then + EgtOutLog( sErr) + EgtOutBox( sErr, 'Lavora Travi', 'ERROR') + EgtDraw() + return false + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessFeatures() + + local bOk, Stats = BE.ProcessFeatures() + local nErrCnt = 0 + local nWarnCnt = 0 + local sOutput = '' + for i = 1, #Stats do + if Stats[i].Err > 0 then + nErrCnt = nErrCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + elseif Stats[i].Err < 0 then + nWarnCnt = nWarnCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + end + end + if #sOutput > 0 then EgtOutLog( sOutput) end + if nErrCnt > 0 then + EgtOutBox( sOutput, 'Lavora Travi', 'ERRORS') + EgtDraw() + return false + elseif nWarnCnt > 0 then + EgtOutBox( sOutput, 'Lavora Travi', 'WARNINGS') + EgtDraw() + return true + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Esecuzione *** +------------------------------------------------------------------------------------------------------------- +if not MyProcessInputData() then return end + +if not MyProcessBeams() then return end + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +if not MyProcessFeatures() then return end diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Rotate.lua b/ProgramData/EgtCAM5/Beam con BpxT5/Rotate.lua new file mode 100644 index 0000000..c7a6c9b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/Rotate.lua @@ -0,0 +1,32 @@ +-- Rotate.lua by Egaltech s.r.l. 2017/11/04 +-- Gestione rotazione di una Trave + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Rotate Trave', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la trave ' .. sName, 'Rotate Trave', 'ERROR') + return +end + +-- eseguo rotazione di 90 gradi attorno asse X +local ptRot = b3Solid:getMin() + Vector3d( 0, b3Solid:getDimZ() / 2, b3Solid:getDimZ() / 2) +EgtRotate( nPartId, ptRot, X_AX(), 90, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/ShowAll.lua b/ProgramData/EgtCAM5/Beam con BpxT5/ShowAll.lua new file mode 100644 index 0000000..15e9b5b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/ShowAll.lua @@ -0,0 +1,18 @@ +-- ClearAll.lua by Egaltech s.r.l. 2017/11/16 +-- Gestione visualizzazione di tutte le Travi + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +local nId = EgtGetFirstPart() +while nId do + EgtSetMode( nId, GDB_MD.STD) + -- EgtSetStatus( nId, GDB_ST.ON) + nId = EgtGetNextPart( nId) +end + +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/ShowBuilding.lua b/ProgramData/EgtCAM5/Beam con BpxT5/ShowBuilding.lua new file mode 100644 index 0000000..7bc2c09 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/ShowBuilding.lua @@ -0,0 +1,63 @@ +-- ShowBuilding.lua by Egaltech s.r.l. 2018/11/21 +-- Gestione visualizzazione travi come struttura + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- recupero il gruppo di assemblaggio +local AsseBaseId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'AsseBase') +if not AsseBaseId then return end + +-- recupero il primo oggetto nel gruppo e verifico se devo assemblare o disassemblare +local AsseId = EgtGetFirstInGroup( AsseBaseId) +if not AsseId then return end +local bMake = ( EgtGetGroupObjs( AsseId) == 0) + +-- ciclo sul gruppo di assemblaggio +while AsseId do + -- salvo il successivo nel gruppo dell'assemblato + local NextId = EgtGetNext( AsseId) + -- costruisco l'assemblato + if bMake then + -- recupero il pezzo sorgente + local SouId = EgtGetInfo( AsseId, GDB_SI.SOURCE, 'i') + if SouId then + EgtSetMode( SouId, GDB_MD.STD) + EgtSetStatus( SouId, GDB_ST.ON) + -- se già utilizzato, ne faccio una copia + if not EgtIsPart( SouId) then + local CopyId = EgtCopy( SouId, GDB_ID.ROOT) + if CopyId then + EgtRemoveInfo( CopyId, GDB_SI.BASE) + EgtRemoveInfo( CopyId, GDB_SI.LIST) + EgtSetInfo( CopyId, GDB_SI.COPY, SouId) + SouId = CopyId + EgtSetInfo( AsseId, GDB_SI.SOURCE, SouId) + end + end + EgtSetStatus( EgtGetFirstNameInGroup( SouId, 'Box') or GDB_ID.NULL, GDB_ST.OFF) + EgtGroupSwap( SouId, AsseId, true, true) + end + -- ritorno ai pezzi + else + local BasId = EgtGetInfo( AsseId, GDB_SI.BASE, 'i') + if BasId then + EgtGroupSwap( AsseId, BasId, true, true) + local CopId = EgtGetInfo( AsseId, GDB_SI.COPY, 'i') + if CopId then + EgtErase( AsseId) + EgtSetInfo( BasId, GDB_SI.SOURCE, CopId) + else + EgtSetStatus( EgtGetFirstNameInGroup( AsseId, 'Box') or GDB_ID.NULL, GDB_ST.ON) + end + end + end + -- passo al successivo + AsseId = NextId +end + +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam con BpxT5/Swap.lua b/ProgramData/EgtCAM5/Beam con BpxT5/Swap.lua new file mode 100644 index 0000000..c5d74a3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam con BpxT5/Swap.lua @@ -0,0 +1,31 @@ +-- Swap.lua by Egaltech s.r.l. 2017/11/02 +-- Gestione scambio testa coda di una Trave + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Swap Trave', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la trave ' .. sName, 'Swap Trave', 'ERROR') + return +end + +-- eseguo rotazione di 180 gradi attorno asse Z +EgtRotate( nPartId, b3Solid:getCenter(), Z_AX(), 180, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam.old/BatchProcess.lua b/ProgramData/EgtCAM5/Beam.old/BatchProcess.lua new file mode 100644 index 0000000..122870e --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/BatchProcess.lua @@ -0,0 +1,512 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2020/06/12 +-- Gestione calcolo batch disposizione e lavorazioni per Travi +-- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. +-- 2019/07/16 Aggiunta gestione modalità oltre 10 per impostazione macchina e uscita. +-- 2019/07/19 Aggiunta gestione collisioni. +-- 2019/07/24 Aggiunta gestione extra-corse. +-- 2019/08/29 Aggiunta possibilità di processare file NGE. +-- 2019/10/04 Migliorato log dei parametri ricevuti. +-- 2019/10/07 Aggiunta gestione Flag 4 = Check+Generate. +-- 2019/10/09 In ImportBtl aggiunto flag per usare UserAttr. +-- 2019/12/09 Gestione conservazione modifiche su barre. +-- 2019/12/20 Gestione LOAD90 tramite file ausiliario (btm). +-- 2019/12/28 Tolta uscita in caso di errore su features. +-- 2020/01/08 Aggiunta seconda sezione limite (BD.MAX_WIDTH2 x BD.MAX_HEIGHT2). +-- 2020/01/14 Si carica ultimo gruppo di lavoro. Corretto problema con nome non definito in segnalazione errore in generazione o stima. +-- 2020/01/30 File Diff con nome del btl. +-- 2020/02/12 Migliorie nella gestione degli errori. +-- 2020/06/12 Si esegue sempre Processing se parametri macchina TS3 successivi al btl. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--BEAM = {} +--BEAM.FILE = 'c:\\EgtData\\Varie\\TestEssetreFast\\TestFilippo\\BTL\\Bar_20_1.btl' +--BEAM.MACHINE = 'FAST' +--BEAM.FLAG = 3 + +-- Log dati in input +local sFlag = '' +if BEAM.FLAG == 0 then + sFlag = 'GENERATE' +elseif BEAM.FLAG == 1 then + sFlag = 'MODIFY' +elseif BEAM.FLAG == 2 then + sFlag = 'SIMULATE' +elseif BEAM.FLAG == 3 then + sFlag = 'CHECK' +elseif BEAM.FLAG == 4 then + sFlag = 'CHECK+GENERATE' +elseif BEAM.FLAG == 11 then + sFlag = 'TOOLS' +elseif BEAM.FLAG == 12 then + sFlag = 'JOBS' +else + sFlag = 'FLAG='..tostring( BEAM.FLAG) +end +local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. BEAM.MACHINE .. ', ' .. sFlag +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( BEAM.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 ( BEAM.FLAG == 1 or BEAM.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 ( BEAM.FLAG == 1 or BEAM.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-' .. BEAM.MACHINE +if not EgtSetCurrMachine( sMachine) then + BEAM.ERR = 11 + BEAM.MSG = 'Error selecting machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + BEAM.ERR = 12 + BEAM.MSG = 'Error not configured for beams machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Se modalità visualizzazione finestre per DB esco +if BEAM.FLAG > 10 then + BEAM.ERR = 0 + return +end + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Dati del file +local sDir, sTitle, sExt = EgtSplitPath( BEAM.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( BEAM.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( BEAM.FILE, EIB_FL.TS3_POS + EIB_FL.USEUATTR) then + BEAM.ERR = 13 + BEAM.MSG = 'Error importing BTL file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + -- faccio copia del file btl originale + EgtCopyFile( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + -- altrimenti Nge, lo apro + else + if not EgtOpenFile( BEAM.FILE) then + BEAM.ERR = 13 + BEAM.MSG = 'Error opening NGE file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + -- faccio copia del file originale + EgtCopyFile( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + end + + -- Aggiorno eventuali dati ausiliari + UpdateAuxData( sBtmFile) + + -- Recupero l'elenco ordinato delle travi + local vBeam = {} + local nPartId = EgtGetFirstPart() + while nPartId do + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + nPartId = EgtGetNextPart( nPartId) + end + if #vBeam == 0 then + BEAM.ERR = 14 + BEAM.MSG = 'Error no beams in the file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) + end + + -- Ne recupero le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + BEAM.ERR = 15 + BEAM.MSG = 'Box undefined for beam ' .. vBeam[i].Name + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + vBeam[i].Box = b3Solid + end + end + + -- Ne recupero la posizione + for i = 1, #vBeam do + local PosX = EgtGetInfo( vBeam[i].Id, 'POSX', 'd') + vBeam[i].PosX = PosX + end + + -- Eseguo eventuali rotazioni e inversioni testa-coda + for i = 1, #vBeam do + local b3Solid = vBeam[i].Box + -- rotazione + local dRotAng = EgtGetInfo( vBeam[i].Id, 'ROTATED', 'd') + if dRotAng and abs( dRotAng) > GEO.EPS_ANG_SMALL then + local ptRotCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptRotCen, X_AX(), dRotAng, GDB_RT.GLOB) + b3Solid:rotate( ptRotCen, X_AX(), dRotAng) + end + -- inversione + local dInvAng = 180 - ( EgtGetInfo( vBeam[i].Id, 'INVERTED', 'd') or 0) + if abs( dInvAng) > GEO.EPS_ANG_SMALL then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptInvCen, Z_AX(), dInvAng, GDB_RT.GLOB) + end + end + + -- Ne verifico le dimensioni + local dRawW = vBeam[1].Box:getDimY() + local dRawH = vBeam[1].Box:getDimZ() + local vBeamErr = {} + for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end + end + if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + table.remove( vBeam, vBeamErr[i]) + end + BEAM.ERR = 16 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Verifico sezione barra non troppo grande + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) and + ( dRawW > BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' .. + 'e (' .. EgtNumToString( BD.MAX_WIDTH2, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT2, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Verifico sezione barra non troppo piccola + if dRawW < BD.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < BD.MIN_HEIGHT - 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'sotto i limiti della macchina (' .. EgtNumToString( BD.MIN_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MIN_HEIGHT, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Lunghezza della barra + local dRawL = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'BARLEN', 'd') or 12000) + 0.1 + -- Sovramateriale di testa + local dOvmHead = vBeam[1].PosX or 0 + + -- Sistemo le travi nel grezzo + local bPbOk, sPbErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) + if not bPbOk then + BEAM.ERR = 18 + BEAM.MSG = sPbErr + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Imposto Nome file CN + local _, sName, _ = EgtSplitPath( BEAM.FILE) + EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + + -- Abilito Vmill + EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + + -- Lavoro le features + local bPfOk, Stats = BE.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 + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = 19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = -19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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 + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = 0 + BEAM.CUTID = nCutId + BEAM.TASKID = nTaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + end + -- Salvo il progetto + EgtSaveFile( sNgeFile) +end + +-- *** Eseguo simulazione con verifica collisione in cieco *** +if ( BEAM.FLAG == 0 and ( bToProcess or bToRecalc)) or BEAM.FLAG == 3 or BEAM.FLAG == 4 then + EgtOutLog( ' +++ Simulating with collision check >>>') + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.INIT then + BEAM.ERR = 19 + BEAM.MSG = 'Error in clamps disposition' + elseif nErr == MCH_SHE.COLLISION then + BEAM.ERR = 22 + BEAM.MSG = 'Head-part collision' + elseif nErr == MCH_SHE.OUTSTROKE then + BEAM.ERR = 23 + BEAM.MSG = 'Axis outstroke ' .. sErr + elseif nErr == MCH_SHE.SPECIAL then + BEAM.ERR = 24 + BEAM.MSG = 'Clamp move error ' .. sErr + else + BEAM.ERR = 25 + BEAM.MSG = 'General failure (contact supplier)' + end + BEAM.ROT = 0 + BEAM.CUTID = 0 + BEAM.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 + BEAM.CUTID = EgtGetVal( vItem[i], 'CUTID', 'i') or 0 + elseif string.find( vItem[i], 'TASKID', 1, true) then + BEAM.TASKID = EgtGetVal( vItem[i], 'TASKID', 'i') or 0 + end + end + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + return + end +end + +-- *** Genero programma CN *** ( se richiesto) +if BEAM.FLAG == 0 or BEAM.FLAG == 4 then + EgtOutLog( ' +++ Generating NC part program >>>') + if not EgtGenerate( '', 'EgtCAM5 - ' .. sNgeFile) then + BEAM.ERR = 20 + local _, sName, _ = EgtSplitPath( BEAM.FILE) + BEAM.MSG = 'Error generating NC part program : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end +end + +-- *** Eseguo stima tempi *** +EgtOutLog( ' +++ Estimating T&L >>>') +if not EgtEstimate( '', 'EgtCAM5 - ' .. sNgeFile) then + + BEAM.ERR = 21 + local _, sName, _ = EgtSplitPath( BEAM.FILE) + BEAM.MSG = 'Error estimating production time : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.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 BEAM.FLAG == 1 or BEAM.FLAG == 2 then + EgtSetView( SCE_VD.ISO_SW, false) +end + +-- Completamento senza errori e avvisi +if nWarnCnt == 0 then + BEAM.ERR = 0 + BEAM.MSG = '---' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) +end + +-- Scrittura tempo totale stimato di lavorazione +WriteTimeToLogFile( Ttot) + +EgtOutLog( ' +++ BatchProcess completed') diff --git a/ProgramData/EgtCAM5/Beam.old/BatchProcessNew.lua b/ProgramData/EgtCAM5/Beam.old/BatchProcessNew.lua new file mode 100644 index 0000000..7e4f574 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/BatchProcessNew.lua @@ -0,0 +1,557 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2021/01/15 +-- Gestione calcolo batch disposizione e lavorazioni per Travi +-- 2021/01/07 Per nuova interfaccia Egt. +-- 2021/01/15 CREATE_BAR ora FLAG = 6 (prima 5). + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--BEAM = {} +--BEAM.FILE = 'c:\\EgtData\\Varie\\TestEssetreFast\\TestFilippo\\BTL\\Bar_20_1.btl' +--BEAM.MACHINE = 'Essetre-FAST' +--BEAM.FLAG = 3 + +-- Log dati in input +local sFlag = '' +if BEAM.FLAG == 0 then + sFlag = 'GENERATE' +elseif BEAM.FLAG == 1 then + sFlag = 'MODIFY' +elseif BEAM.FLAG == 2 then + sFlag = 'SIMULATE' +elseif BEAM.FLAG == 3 then + sFlag = 'CHECK' +elseif BEAM.FLAG == 4 then + sFlag = 'CHECK+GENERATE' +elseif BEAM.FLAG == 6 then + sFlag = 'CREATE_BAR' +else + sFlag = 'FLAG='..tostring( BEAM.FLAG) +end +local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. BEAM.MACHINE .. ', ' .. sFlag +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( BEAM.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 ( BEAM.FLAG == 1 or BEAM.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 ( BEAM.FLAG == 1 or BEAM.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') + +-- Se necessario, impostazione della macchina corrente +if BEAM.FLAG ~= 6 then + EgtResetCurrMachGroup() + local sMachine = BEAM.MACHINE + if not EgtSetCurrMachine( sMachine) then + BEAM.ERR = 11 + BEAM.MSG = 'Error selecting machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + BEAM.ERR = 12 + BEAM.MSG = 'Error not configured for beams machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Dati del file +local sDir, sTitle, sExt = EgtSplitPath( BEAM.FILE) +local bBtl = ( string.upper( sExt or '') ~= '.BWE') +local sNgeFile = sDir..sTitle..'.bwe' +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( BEAM.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 aggiornare + 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 >>>') + + -- Flag di barra da creare + local bCreateBar + -- Lunghezza della barra ed elenco travi + local dBarLen + local vBeam = {} + + -- Se necessario, apro il file Bwe + if BEAM.FLAG ~= 6 then + if not EgtOpenFile( BEAM.FILE) then + BEAM.ERR = 13 + BEAM.MSG = 'Error opening BWE file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + -- Faccio copia del file originale + EgtCopyFile( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + + -- Aggiorno eventuali dati ausiliari + UpdateAuxData( sBtmFile) + + -- Se già presente un gruppo di lavoro + if EgtGetFirstMachGroup() then + -- Barra già presente + bCreateBar = false + -- Rendo corrente il gruppo di lavoro + EgtSetCurrMachGroup() + -- Area tavola + local b3Tab = EgtGetTableArea() + -- Calcolo posizione estremo TR della tavola rispetto a sua origine in BL + BD.OriTR = Point3d( b3Tab:getDimX(), b3Tab:getDimY(), 0) + -- Calcolo minimo grezzo scaricabile + local nRawId = EgtGetFirstRawPart() + if not nRawId then + BEAM.ERR = 14 + BEAM.MSG = 'Error no Raw Oarts in the file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + local b3Raw = EgtGetRawPartBBox( nRawId) + BE.CalcMinUnloadableRaw( b3Raw:getDimY(), b3Raw:getDimZ()) + -- altrimenti devo recuperare i pezzi per creare la barra + else + -- Barra da creare + bCreateBar = true + -- Recupero l'elenco ordinato delle travi + local nPartId = EgtGetFirstPart() + while nPartId do + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + nPartId = EgtGetNextPart( nPartId) + end + if #vBeam == 0 then + BEAM.ERR = 14 + BEAM.MSG = 'Error no beams in the file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) + end + -- Ne recupero le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + BEAM.ERR = 15 + BEAM.MSG = 'Box undefined for beam ' .. vBeam[i].Name + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + vBeam[i].Box = b3Solid + end + end + -- Assegno lunghezza della barra + dBarLen = vBeam[1].Box:getDimX() + 10 + if dBarLen < 1500 then + dBarLen = 2000 + end + -- Assegno posizione prima ed unica trave + vBeam[1].PosX = 10 + end + + -- Altrimenti, opero sul progetto corrente + else + -- Recupero l'identificativo del gruppo di lavoro corrente + local nMGrpId = EgtGetCurrMachGroup() + -- Barra da creare + bCreateBar = true + -- Lunghezza della barra + dBarLen = EgtGetInfo( nMGrpId, 'BARLEN', 'd') + -- Recupero l'elenco ordinato delle travi da inserire nella barra + for i = 1, 100 do + local sKey = 'PART'..tostring( i) + local sVal = EgtGetInfo( nMGrpId, sKey) + local vVal = EgtSplitString( sVal or '') + if not vVal or #vVal < 2 then break end + local nPartId = tonumber( vVal[1]) + local dPosX = tonumber( vVal[2]) + table.insert( vBeam, { Id = nPartId, PosX = dPosX, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + if #vBeam == 0 then + BEAM.ERR = 14 + BEAM.MSG = 'Error : no beams in the project' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + return + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) + end + -- Ne recupero le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + BEAM.ERR = 15 + BEAM.MSG = 'Box undefined for beam ' .. vBeam[i].Name + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + return + else + vBeam[i].Box = b3Solid + end + end + end + + -- Se devo creare la barra + if bCreateBar then + -- Ne verifico le dimensioni + local dRawW = vBeam[1].Box:getDimY() + local dRawH = vBeam[1].Box:getDimZ() + local vBeamErr = {} + for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end + end + if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + table.remove( vBeam, vBeamErr[i]) + end + BEAM.ERR = 16 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Verifico sezione barra non troppo grande + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) and + ( dRawW > BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + c 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' .. + c 'e (' .. EgtNumToString( BD.MAX_WIDTH2, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT2, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Verifico sezione barra non troppo piccola + if dRawW < BD.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < BD.MIN_HEIGHT - 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + c 'sotto i limiti della macchina (' .. EgtNumToString( BD.MIN_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MIN_HEIGHT, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Lunghezza della barra + local dRawL = dBarLen + 0.1 + -- Sovramateriale di testa + local dOvmHead = vBeam[1].PosX or 0 + + -- Sistemo le travi nel grezzo + local bPbOk, sPbErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam, BEAM.FLAG == 6) + if not bPbOk then + BEAM.ERR = 18 + BEAM.MSG = sPbErr + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + -- Scrivo altezza e larghezza barra nel gruppo di lavoro corrente + local nMGrpId = EgtGetCurrMachGroup() + EgtSetInfo(nMGrpId, 'BARHEIGHT', dRawW) + EgtSetInfo(nMGrpId, 'BARWIDTH', dRawH) + end + end + + -- Se richiesta solo barra, esco + if BEAM.FLAG == 6 then + -- Completamento senza errori e avvisi + if nWarnCnt == 0 then + BEAM.ERR = 0 + BEAM.MSG = '---' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + end + EgtOutLog( ' +++ BatchProcess completed') + return + end + + -- Imposto Nome file CN + local _, sName, _ = EgtSplitPath( BEAM.FILE) + EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + + -- Abilito Vmill + EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + + -- Lavoro le features + local bPfOk, Stats = BE.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 + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = 19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = -19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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', 'i') + 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', 'i') + if bIsFea and nTaskId then + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = 0 + BEAM.CUTID = nCutId + BEAM.TASKID = nTaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + end + -- Salvo il progetto + EgtSaveFile( sNgeFile) +end + +-- *** Eseguo simulazione con verifica collisione in cieco *** +if ( BEAM.FLAG == 0 and ( bToProcess or bToRecalc)) or BEAM.FLAG == 3 or BEAM.FLAG == 4 then + EgtOutLog( ' +++ Simulating with collision check >>>') + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.INIT then + BEAM.ERR = 19 + BEAM.MSG = 'Error in clamps disposition' + elseif nErr == MCH_SHE.COLLISION then + BEAM.ERR = 22 + BEAM.MSG = 'Head-part collision' + elseif nErr == MCH_SHE.OUTSTROKE then + BEAM.ERR = 23 + BEAM.MSG = 'Axis outstroke ' .. sErr + elseif nErr == MCH_SHE.SPECIAL then + BEAM.ERR = 24 + BEAM.MSG = 'Clamp move error ' .. sErr + else + BEAM.ERR = 25 + BEAM.MSG = 'General failure (contact supplier)' + end + BEAM.ROT = 0 + BEAM.CUTID = 0 + BEAM.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 + BEAM.CUTID = EgtGetVal( vItem[i], 'CUTID', 'i') or 0 + elseif string.find( vItem[i], 'TASKID', 1, true) then + BEAM.TASKID = EgtGetVal( vItem[i], 'TASKID', 'i') or 0 + end + end + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + return + end +end + +-- *** Genero programma CN *** ( se richiesto) +if BEAM.FLAG == 0 or BEAM.FLAG == 4 then + EgtOutLog( ' +++ Generating NC part program >>>') + if not EgtGenerate( '', 'EgtCAM5 - ' .. sNgeFile) then + BEAM.ERR = 20 + local _, sName, _ = EgtSplitPath( BEAM.FILE) + BEAM.MSG = 'Error generating NC part program : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end +end + +-- *** Eseguo stima tempi *** +EgtOutLog( ' +++ Estimating T&L >>>') +if not EgtEstimate( '', 'EgtCAM5 - ' .. sNgeFile) then + + BEAM.ERR = 21 + local _, sName, _ = EgtSplitPath( BEAM.FILE) + BEAM.MSG = 'Error estimating production time : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end +local Ttot = EgtGetInfo( EgtGetCurrMachGroup(), 'Ttot', 'd') +local sTime = 'Total Time = ' .. EgtNumToString( Ttot, 1) +EgtOutLog( sTime) + +-- Imposto la vista ISO 3d, se richiesto +if BEAM.FLAG == 1 or BEAM.FLAG == 2 then + EgtSetView( SCE_VD.ISO_SW, false) +end + +-- Completamento senza errori e avvisi +if nWarnCnt == 0 then + BEAM.ERR = 0 + BEAM.MSG = '---' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) +end + +-- Scrittura tempo totale stimato di lavorazione +WriteTimeToLogFile( Ttot) + +EgtOutLog( ' +++ BatchProcess completed') diff --git a/ProgramData/EgtCAM5/Beam.old/Beam.ini b/ProgramData/EgtCAM5/Beam.old/Beam.ini new file mode 100644 index 0000000..bc2ede0 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/Beam.ini @@ -0,0 +1,8 @@ +[Beam] +BtlEnable=1 +BaseDir=C:\EgtData\Beam +BtlExec=BatchProcess.lua +Button1=Process.lua,Images\Process.png,Lavora Travi +Button2=Swap.lua,Images\Swap.png,Scambia estremi trave +Button3=Rotate.lua,Images\Rotate.png,Ruota trave +Button4=BeamMachinings,Images\BeamMachinings.png,Lista lavorazioni diff --git a/ProgramData/EgtCAM5/Beam.old/Images/BeamMachinings.png b/ProgramData/EgtCAM5/Beam.old/Images/BeamMachinings.png new file mode 100644 index 0000000..5ab6b0c Binary files /dev/null and b/ProgramData/EgtCAM5/Beam.old/Images/BeamMachinings.png differ diff --git a/ProgramData/EgtCAM5/Beam.old/Images/Process.png b/ProgramData/EgtCAM5/Beam.old/Images/Process.png new file mode 100644 index 0000000..13070d5 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam.old/Images/Process.png differ diff --git a/ProgramData/EgtCAM5/Beam.old/Images/Rotate.png b/ProgramData/EgtCAM5/Beam.old/Images/Rotate.png new file mode 100644 index 0000000..bd1532e Binary files /dev/null and b/ProgramData/EgtCAM5/Beam.old/Images/Rotate.png differ diff --git a/ProgramData/EgtCAM5/Beam.old/Images/Swap.png b/ProgramData/EgtCAM5/Beam.old/Images/Swap.png new file mode 100644 index 0000000..04fa8f8 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam.old/Images/Swap.png differ diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/BeamExec.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/BeamExec.lua new file mode 100644 index 0000000..562b156 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/BeamExec.lua @@ -0,0 +1,1245 @@ +-- BeamExec.lua by Egaltech s.r.l. 2021/01/21 +-- Libreria esecuzione lavorazioni per Travi +-- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. +-- 2019/09/04 Corretto controllo feature di testa e coda con sovramateriale di testa elevato. +-- 2019/09/25 Aggiunta gestione StepJoint e StepJointNotch. +-- 2020/01/21 Aggiunta gestione ScarfJoint. +-- 2020/02/10 Aggiunta gestione FrenchRidgeLap. +-- 2020/02/11 Aggiunta gestione BlockHausFront. +-- 2020/04/02 Fori di testa dal basso non danno errore e fanno ribaltare la trave. +-- 2020/04/07 Aggiunta gestione TyroleanDovetail. +-- 2020/04/14 Aggiunta gestione Dovetail. +-- 2020/05/16 Migliorie ordinamento fori. +-- 2020/05/16 Gestione rotazione di 90deg. +-- 2020/05/21 Correzione rotazione di 90deg (caso DY > DZ). +-- 2020/05/25 Correzione rotazione di 90deg dopo scarico su carico. +-- 2020/06/02 Per dati foro si chiama funzione GetData di ProcessDrill (per gestire variazioni di diametro da UserParams). +-- 2020/07/25 Ricalcolati flag head e tail della prima parte del foro dopo lo split. +-- 2020/07/27 Modifica a ordinamento fori. +-- 2020/10/07 Aggiunta distanza libera dietro il pezzo (BDST) scritta nel suo grezzo. +-- 2020/10/15 Per foro sdoppiato ricalcolo anche flag Head oltre a Tail . +-- 2020/10/23 Corretto spostamento foro per tenone quando tenone nullo. +-- 2020/12/29 Aggiunta gestione fori in doppio. + +-- Tabella per definizione modulo +local BeamExec = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali e libero tutti gli altri +_G.package.loaded.BeamData = nil +_G.package.loaded.CutData = nil +_G.package.loaded.MillingData = nil +_G.package.loaded.PocketingData = nil +_G.package.loaded.DrillData = nil +_G.package.loaded.SawingData = nil +local BD = require( 'BeamData') + +-- Carico le librerie +_G.package.loaded.MachiningLib = nil +local BM = require( 'MachiningLib') +_G.package.loaded.BeamLib = nil +local BL = require( 'BeamLib') +_G.package.loaded.DiceCut = nil +local DC = require( 'DiceCut') +_G.package.loaded.FacesBySaw = nil +local Fbs = require( 'FacesBySaw') +_G.package.loaded.ProcessHeadCut = nil +local Hcut= require( 'ProcessHeadCut') +_G.package.loaded.ProcessSplit = nil +local Split = require( 'ProcessSplit') +_G.package.loaded.ProcessCut = nil +local Cut = require( 'ProcessCut') +_G.package.loaded.ProcessDoubleCut = nil +local DoubleCut = require( 'ProcessDoubleCut') +_G.package.loaded.ProcessLongCut = nil +local LongCut = require( 'ProcessLongCut') +_G.package.loaded.ProcessLongDoubleCut = nil +local Long2Cut = require( 'ProcessLongDoubleCut') +_G.package.loaded.ProcessSawCut = nil +local SawCut = require( 'ProcessSawCut') +_G.package.loaded.ProcessRidgeLap = nil +local RidgeLap = require( 'ProcessRidgeLap') +_G.package.loaded.ProcessLapJoint = nil +local LapJoint = require( 'ProcessLapJoint') +_G.package.loaded.ProcessChamfer = nil +local Chamfer = require( 'ProcessChamfer') +_G.package.loaded.ProcessDrill = nil +local Drill = require( 'ProcessDrill') +_G.package.loaded.ProcessFrenchRidgeLap = nil +local FrenchRidgeLap = require( 'ProcessFrenchRidgeLap') +_G.package.loaded.ProcessBlockHausFront = nil +local BlockHausFront = require( 'ProcessBlockHausFront') +_G.package.loaded.ProcessTenon = nil +local Tenon = require( 'ProcessTenon') +_G.package.loaded.ProcessMortise = nil +local Mortise = require( 'ProcessMortise') +_G.package.loaded.ProcessDtTenon = nil +local DtTenon = require( 'ProcessDtTenon') +_G.package.loaded.ProcessDtMortise = nil +local DtMortise = require( 'ProcessDtMortise') +_G.package.loaded.ProcessMark = nil +local Mark = require( 'ProcessMark') +_G.package.loaded.ProcessText = nil +local Text = require( 'ProcessText') +_G.package.loaded.ProcessScarfJoint = nil +local ScarfJoint = require( 'ProcessScarfJoint') +_G.package.loaded.ProcessSimpleScarf = nil +local Scarf = require( 'ProcessSimpleScarf') +_G.package.loaded.ProcessStepJoint = nil +local StepJoint = require( 'ProcessStepJoint') +_G.package.loaded.ProcessStepJointNotch = nil +local StJoNotch = require( 'ProcessStepJointNotch') +_G.package.loaded.ProcessProfFront = nil +local ProfFront = require( 'ProcessProfFront') +_G.package.loaded.ProcessProfConcave = nil +local ProfConcave = require( 'ProcessProfConcave') +_G.package.loaded.ProcessProfConvex = nil +local ProfConvex = require( 'ProcessProfConvex') +_G.package.loaded.ProcessProfCamb = nil +local ProfCamb = require( 'ProcessProfCamb') +_G.package.loaded.ProcessProfHead = nil +local ProfHead = require( 'ProcessProfHead') +_G.package.loaded.ProcessRoundArch = nil +local RoundArch = require( 'ProcessRoundArch') +_G.package.loaded.ProcessTyroleanDovetail = nil +local TyroleanDovetail = require( 'ProcessTyroleanDovetail') +_G.package.loaded.ProcessDovetail = nil +local Dovetail = require( 'ProcessDovetail') +_G.package.loaded.ProcessFreeContour = nil +local FreeContour = require( 'ProcessFreeContour') +_G.package.loaded.ProcessDecor = nil +local Decor = require( 'ProcessDecor') + +EgtOutLog( ' BeamExec started', 1) +EgtMdbSetGeneralParam( MCH_GP.MAXDEPTHSAFE, BD.COLL_SIC) +EgtMdbSave() + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle travi nel grezzo *** +------------------------------------------------------------------------------------------------------------- +function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam, bMachGroupOk) + + -- Determinazione minimo grezzo scaricabile + BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) + + -- Creazione nuovo gruppo di lavoro + if not bMachGroupOk then + local sMgName = EgtGetMachGroupNewName( 'Mach_1') + local NewMgId = EgtAddMachGroup( sMgName) + if not NewMgId then + local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName + return false, sOut + end + end + + -- Impostazione della tavola + EgtSetTable( 'Tab') + + -- Area tavola + local b3Tab = EgtGetTableArea() + -- Calcolo posizione estremo TR della tavola rispetto a sua origine in BL + BD.OriTR = Point3d( b3Tab:getDimX(), b3Tab:getDimY(), 0) + + -- Impostazione dell'attrezzaggio di default + EgtImportSetup() + + -- Inserimento dei pezzi con il loro grezzo + local Cnt = 0 + local Len = dRawL + local nPrevRaw, dPrevDelta + local DeltaS = dOvmHead + local DeltaE = BD.OVM_MID + for i = 1, #vBeam do + -- assegno identificativo pezzo + local Pz = vBeam[i].Id + -- dati del pezzo + local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT) + local b3Solid = vBeam[i].Box + if b3Part:isEmpty() or b3Solid:isEmpty() then break end + EgtOutLog( 'PartSez=' .. EgtNumToString( b3Part:getDimY(), 1) .. 'x' .. EgtNumToString( b3Part:getDimZ(), 1), 3) + -- se sezione compatibile e lunghezza disponibile sufficiente + local PartLen = b3Solid:getDimX() + local PartWidth = b3Solid:getDimY() + local PartHeight = b3Solid:getDimZ() + local NextLen = Len - DeltaS - PartLen - DeltaE + if (( abs( PartWidth - dRawW) < 10 * GEO.EPS_SMALL and abs( PartHeight - dRawH) < 10 * GEO.EPS_SMALL) or + ( abs( PartHeight - dRawW) < 10 * GEO.EPS_SMALL and abs( PartWidth - dRawH) < 10 * GEO.EPS_SMALL)) and + NextLen + DeltaE >= 0 then + -- eventuale sovramateriale di testa + if vBeam[i].PosX then + DeltaS = max( vBeam[i].PosX - ( dRawL - Len), 0) + end + -- dimensioni del grezzo + local CrawLen = min( PartLen + DeltaS + DeltaE, Len) + local Delta = CrawLen - PartLen - DeltaS + -- creo e posiziono il grezzo + local nRaw = EgtAddRawPart( Point3d(0,0,0), CrawLen, dRawW, dRawH, BD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, BD.OriTR, MCH_CR.TR) + EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) + -- assegno ordine in lavorazione + Cnt = Cnt + 1 + EgtSetInfo( nRaw, 'ORD', Cnt) + -- creo o pulisco gruppo geometrie aggiuntive + if not BL.CreateOrEmptyAddGroup( Pz) then + local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz) + return false, sOut + end + -- aggiungo faccia per taglio iniziale al pezzo + BL.AddPartStartFace( Pz, b3Solid) + -- se sovramateriale di testa, lo notifico + if DeltaS > 0.09 then + EgtSetInfo( nRaw, 'HOVM', DeltaS) + if nPrevRaw then + EgtSetInfo( nPrevRaw, 'BDST', DeltaS + dPrevDelta) + end + end + -- aggiungo faccia per taglio finale al pezzo + BL.AddPartEndFace( Pz, b3Solid) + -- inserisco il pezzo nel grezzo + EgtDeselectPartObjs( Pz) + local ptPos = b3Part:getMin() - b3Solid:getMin() + Vector3d( Delta, ( dRawW - PartWidth) / 2, ( dRawH - PartHeight) / 2) + EgtAddPartToRawPart( Pz, ptPos, nRaw) + if abs( PartWidth - dRawW) > 10 * GEO.EPS_SMALL then + -- rotazione attorno a centro geometria complessiva del pezzo + EgtRotatePartInRawPart( Pz, X_AX(), 90) + -- correggo per eccentricità solido rispetto a geometria complessiva del pezzo + local vtEccOri = b3Solid:getCenter() - b3Part:getCenter() + local vtEccRot = Vector3d( vtEccOri) + vtEccRot:rotate( X_AX(), 90) + EgtMovePartInRawPart( Pz, ( vtEccOri - vtEccRot)) + end + -- aggiorno la lunghezza residua della barra + Len = Len - CrawLen + -- aggiorno grezzo precedente + nPrevRaw = nRaw + dPrevDelta = Delta + end + -- se rimasto troppo poco grezzo, esco + --if Len < BD.MinRaw then break end + DeltaS = 0 + end + if nPrevRaw then + EgtSetInfo( nPrevRaw, 'BDST', 10000) + end + + -- Se rimasto materiale aggiungo grezzo dell'avanzo + if Len > 10 then + local nRaw = EgtAddRawPart( Point3d(0,0,0), Len, dRawW, dRawH, BD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, BD.OriTR, MCH_CR.TR) + EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) + -- assegno ordine in lavorazione + Cnt = Cnt + 1 + EgtSetInfo( nRaw, 'ORD', Cnt) + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) + if BD.GetMinUnloadableRaw then + BD.MinRaw = BD.GetMinUnloadableRaw( dRawW, dRawH) + else + local H_S = 200 + local H_L = 400 + -- Determinazione minimo grezzo scaricabile + if dRawH <= H_S then + BD.MinRaw = BD.MINRAW_S + elseif dRawH <= H_L then + local Coeff = ( dRawH - H_S) / ( H_L - H_S) + BD.MinRaw = ( 1 - Coeff) * BD.MINRAW_S + Coeff * BD.MINRAW_L + else + BD.MinRaw = BD.MINRAW_L + end + end +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function Verify90DegRotation( nRawId) + if not nRawId then return false end + -- dimensioni sezione trave in posizione normale (rotazione 0°) + local dRawW = EgtGetRawPartBBox( nRawId):getDimY() + local dRawH = EgtGetRawPartBBox( nRawId):getDimZ() + -- verifica dell'altezza rispetto alla massima larghezza + return ( dRawH < BD.MAX_WIDTH + 10 * GEO.EPS_SMALL and dRawW < BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) or + ( dRawH < BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL and dRawW < BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) +end + +------------------------------------------------------------------------------------------------------------- +local function IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- feature sempre di testa o coda per il gruppo + if Proc.Grp == 1 or Proc.Grp == 2 then + return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- feature sempre di testa o coda nonostante il gruppo + if ( Proc.Grp == 3 or Proc.Grp == 4) and + ( Proc.Prc == 38 or Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then + return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- gestioni speciali + if LapJoint.Identify( Proc) then + return LapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if Drill.Identify( Proc) then + return Drill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if RoundArch.Identify( Proc) then + return RoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if Dovetail.Identify( Proc) then + return Dovetail.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if FreeContour.Identify( Proc) then + return FreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + -- non è di testa + return false +end + +------------------------------------------------------------------------------------------------------------- +local function IsTailFeature( Proc, b3Raw, dCurrOvmH) + -- feature sempre di testa o coda per il gruppo + if Proc.Grp == 1 or Proc.Grp == 2 then + return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- feature sempre di testa o coda nonostante il gruppo + if ( Proc.Grp == 3 or Proc.Grp == 4) and + ( Proc.Prc == 38 or Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then + return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- gestioni speciali + if LapJoint.Identify( Proc) then + return LapJoint.IsTailFeature( Proc, b3Raw) + end + if Drill.Identify( Proc) then + return Drill.IsTailFeature( Proc, b3Raw) + end + if DtMortise.Identify( Proc) then + return DtMortise.IsTailFeature( Proc, b3Raw) + end + if RoundArch.Identify( Proc) then + return RoundArch.IsTailFeature( Proc, b3Raw) + end + if Dovetail.Identify( Proc) then + return Dovetail.IsTailFeature( Proc, b3Raw) + end + if FreeContour.Identify( Proc) then + return FreeContour.IsTailFeature( Proc, b3Raw) + end + -- non è di coda + return false +end + +------------------------------------------------------------------------------------------------------------- +local function CollectFeatures( PartId, b3Raw, dCurrOvmH) + -- recupero le feature + local vProc = {} + local LayerId = {} + LayerId[1] = BL.GetAddGroup( PartId) + LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings') + for nInd = 1, 2 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.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 + Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH) + Proc.Tail = IsTailFeature( Proc, b3Raw, dCurrOvmH) + table.insert( vProc, Proc) + -- se foro + if Drill.Identify( Proc) then + -- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento) + Proc.Diam, Proc.Fcs, Proc.Fce = Drill.GetData( Proc, b3Raw) + -- verifico se necessaria seconda lavorazione da parte opposta per foro più lungo della punta + if Drill.Split( Proc, b3Raw) then + -- aggiorno flags prima parte foro (dati tabelle sempre per riferimento) + Proc.Flg = 2 + Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH) + Proc.Tail = IsTailFeature( Proc, b3Raw, dCurrOvmH) + -- definisco dati seconda parte + local Proc2 = {} + Proc2.Id = ProcId + Proc2.Grp = nGrp + Proc2.Prc = nPrc + Proc2.Flg = -2 + Proc2.Box = BBox3d( Proc.Box) + Proc2.Fct = Proc.Fct + Proc2.Diam = Proc.Diam + Proc2.Head = Drill.IsHeadFeature( Proc2, b3Raw, dCurrOvmH) + Proc2.Tail = Drill.IsTailFeature( Proc2, b3Raw, dCurrOvmH) + Proc2.Fcs = Proc.Fce + Proc2.Fce = Proc.Fcs + Proc2.CutId = Proc.CutId + Proc2.TaskId = Proc.TaskId + table.insert( vProc, Proc2) + end + end + else + Proc.Head = false + Proc.Tail = false + Proc.Flg = 0 + table.insert( vProc, Proc) + EgtOutLog( ' Feature ' .. tostring( Proc.Id) .. ' is empty (no geometry)') + end + end + end + ProcId = EgtGetNext( ProcId) + end + end + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function OrderFeatures( vProc, b3Raw) + + local dDrillPenalty = EgtIf( BD.PRESS_ROLLER, 200, 100) + local dSmallDrillRange = EgtIf( b3Raw:getDimX() < BD.LEN_SHORT_PART, 200, 600) + + -- funzione di confronto + -- secondo centro box in X (taglio di intestazione prima di altri tagli di testa e taglio di separazione però prima di altri tagli di coda) + local function CompareFeatures( B1, B2) + -- se primo disabilitato va sempre alla fine + if B1.Flg == 0 then + return false + end + -- se secondo disabilitato va sempre alla fine + if B2.Flg == 0 then + return true + end + -- se primo è intestazione va sempre prima + if Hcut.Identify( B1) then + return true + end + -- se l'altro è intestazione va sempre prima + if Hcut.Identify( B2) then + return false + end + -- se uno di testa e non l'altro, privilegio quello di testa + if B1.Head ~= B2.Head then + return B1.Head + end + -- se entrambi di testa e primo è scasso o mortasa va messo dopo + if B1.Head and B2.Head and ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1)) then + return false + end + -- se entrambi di testa e secondo è scasso o mortasa va messo dopo + if B1.Head and B2.Head and ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2)) then + return true + end + -- se primo è feature di coda e l'altro è separazione o non è feature di coda + if B1.Tail and ( Split.Identify( B2) or not B2.Tail) then + return false + end + -- se secondo è feature di coda e l'altro è separazione o non è feature di coda + if B2.Tail and ( Split.Identify( B1) or not B1.Tail) then + return true + end + -- se primo è scasso o mortasa di coda, sempre dopo tutto + if B1.Tail and ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1)) then + return false + end + -- se secondo è scasso o mortasa di coda, sempre dopo tutto + if B2.Tail and ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2)) then + return true + end + -- se primo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda + if abs( B1.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + -- se anche l'altra è lunga, faccio prima quello a Zmax + if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + return B1.Box:getMax():getZ() > B2.Box:getMax():getZ() + else + return B1.Box:getMin():getX() + 50 > B2.Box:getCenter():getX() + end + end + -- se secondo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda + if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + return B1.Box:getCenter():getX() > B2.Box:getMin():getX() + 50 + end + -- se primo è foro e l'altro no, lo penalizzo + if B1.Prc == 40 and B2.Prc ~= 40 then + return B1.Box:getCenter():getX() - dDrillPenalty > B2.Box:getMax():getX() + end + -- se primo è altro e secondo è foro, lo premio + if B1.Prc ~= 40 and B2.Prc == 40 then + return B1.Box:getMax():getX() + dDrillPenalty > B2.Box:getCenter():getX() + end + -- se entrambi fori con posizione praticamente uguale ordino secondo diametro e faccia di inizio (Fcs) + if B1.Prc == 40 and B2.Prc == 40 and abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) < dSmallDrillRange then + if abs( B1.Diam - B2.Diam) < 1.0 then + if B1.Fcs == B2.Fcs then + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + else + return B1.Fcs > B2.Fcs + end + else + return ( B1.Diam > B2.Diam) + end + end + -- se entrambi tenoni e si intersecano, metto prima tenone vero e poi base tenone + if Tenon.Identify( B1) and Tenon.Identify( B2) and + B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then + return ( B1.Prc == 50 and B2.Prc == 52) + end + -- confronto standard + if abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) > 0.4 * ( B1.Box:getDimX() + B2.Box:getDimX()) then + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + elseif abs( B1.Box:getCenter():getY() - B2.Box:getCenter():getY()) > 0.2 * ( B1.Box:getDimY() + B2.Box:getDimY()) then + return B1.Box:getCenter():getY() > B2.Box:getCenter():getY() + elseif abs( B1.Box:getCenter():getZ() - B2.Box:getCenter():getZ()) > 0.1 * ( B1.Box:getDimZ() + B2.Box:getDimZ()) then + return B1.Box:getCenter():getZ() > B2.Box:getCenter():getZ() + else + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + end + end + + -- eseguo ordinamento + table.sort( vProc, CompareFeatures) + + -- riunisco fori con lo stesso diametro e non troppo lontani + local dDrillRange = dSmallDrillRange + if BD.GO_FAST == 2 then + dDrillRange = 6000 + elseif BD.PRESS_ROLLER then + dDrillRange = 2000 + end + for i = 1, #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 40 then + for j = i + 1, #vProc do + local ProcJ = vProc[j] + if ProcJ.Prc == 40 and ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and + abs( ProcJ.Diam - ProcI.Diam) < 1.0 and abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < dDrillRange then + if j > i + 1 then + local ProcK = vProc[i+1] + if ProcK.Prc ~= 40 or abs( ProcK.Diam - ProcJ.Diam) > 1.0 then + table.insert( vProc, i + 1, table.remove( vProc, j)) + end + end + end + end + end + end + -- riunisco fori da fare in doppio + local i = 1 + while i < #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 40 then + local DouId = EgtGetInfo( ProcI.Id, 'DOU', 'i') + if DouId then + for j = i + 1, #vProc do + if vProc[j].Id == DouId then + table.insert( vProc, i, table.remove( vProc, j)) + i = i + 1 + break + end + end + end + end + i = i + 1 + end + -- riunisco marcature, testi e decori non troppo lontani + local dMarkRange = 300 + for i = 1, #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 60 or ProcI.Prc == 61 or ProcI.Prc == 959 then + for j = i + 1, #vProc do + local ProcJ = vProc[j] + if ( ProcJ.Prc == 60 or ProcJ.Prc == 61 or ProcJ.Prc == 959) and + ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and + abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < dMarkRange then + if j > i + 1 then + table.insert( vProc, i + 1, table.remove( vProc, j)) + end + break + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +local function ClassifyFeatures( vProc, b3Raw, Stats) + local bAllOk = true + local bSomeDown = false + local bSomeSide = false + local bSplitRot = false + local nHeading + local nSplitting + for i = 1, #vProc do + local Proc = vProc[i] + local bOk = true + local bDown = false + local bSide = false + local bDownSideOnHeadOk = false + -- se senza geometria (già disabilitato + if Proc.Flg == 0 then + bOk = false + -- se intestatura + elseif Hcut.Identify( Proc) then + nHeading = i + -- se separazione + elseif Split.Identify( Proc) then + nSplitting = i + -- se taglio + elseif Cut.Identify( Proc) then + bOk, bDown = Cut.Classify( Proc, b3Raw) + -- se doppio taglio + elseif DoubleCut.Identify( Proc) then + bOk, bDown = DoubleCut.Classify( Proc, b3Raw) + -- se taglio longitudinale + elseif LongCut.Identify( Proc) then + bOk, bDown = LongCut.Classify( Proc) + -- se doppio taglio longitudinale + elseif Long2Cut.Identify( Proc) then + bOk, bDown = Long2Cut.Classify( Proc) + -- se taglio con lama + elseif SawCut.Identify( Proc) then + bOk, bDown = SawCut.Classify( Proc) + -- se mezzo-legno di testa + elseif RidgeLap.Identify( Proc) then + bOk, bDown = RidgeLap.Classify( Proc, b3Raw) + -- se scanalatura, scanalatura frontale, tacca, tacca cantonale, mezzo-legno, scanalatura-battuta, + -- mezzolegno tipo chalet-tavola di chiusura, rivestimento, mezzolegno chalet, tasca, taglio triangolato + elseif LapJoint.Identify( Proc) then + bOk, bDown = LapJoint.Classify( Proc, b3Raw) + -- se foratura + elseif Drill.Identify( Proc) then + bOk, bDown, bSide = Drill.Classify( Proc, b3Raw) + bDownSideOnHeadOk = true + -- se tenone + elseif Tenon.Identify( Proc) then + bOk, bDown = Tenon.Classify( Proc, b3Raw) + -- se giunzione francese + elseif FrenchRidgeLap.Identify( Proc) then + bOk, bDown = FrenchRidgeLap.Classify( Proc) + -- se block house front + elseif BlockHausFront.Identify( Proc) then + bOk, bDown = BlockHausFront.Classify( Proc) + -- se mortasa (anche frontale) + elseif Mortise.Identify( Proc) then + bOk, bDown = Mortise.Classify( Proc) + -- se tenone a coda di rondine + elseif DtTenon.Identify( Proc) then + bOk, bDown = DtTenon.Classify( Proc, b3Raw) + -- se mortasa a coda di rondine (anche frontale) + elseif DtMortise.Identify( Proc) then + bOk, bDown = DtMortise.Classify( Proc) + -- se marcatura + elseif Mark.Identify( Proc) then + bOk, bDown = Mark.Classify( Proc) + -- se testo + elseif Text.Identify( Proc) then + bOk, bDown = Text.Classify( Proc) + -- se giunto Gerber + elseif ScarfJoint.Identify( Proc) then + bOk, bDown = ScarfJoint.Classify( Proc) + -- se giunto Gerber + elseif Scarf.Identify( Proc) then + bOk, bDown = Scarf.Classify( Proc) + -- se giunto a gradino + elseif StepJoint.Identify( Proc) then + bOk, bDown = StepJoint.Classify( Proc) + -- se tacca a gradino + elseif StJoNotch.Identify( Proc) then + bOk, bDown = StJoNotch.Classify( Proc) + -- se arco + elseif RoundArch.Identify( Proc) then + bOk, bDown = RoundArch.Classify( Proc) + -- se incastro tirolo + elseif TyroleanDovetail.Identify( Proc) then + bOk, bDown = TyroleanDovetail.Classify( Proc, b3Raw) + -- se giunto coda di rondine + elseif Dovetail.Identify( Proc) then + bOk, bDown = Dovetail.Classify( Proc, b3Raw) + -- se profilo front + elseif ProfFront.Identify( Proc) then + bOk, bDown, bSide = ProfFront.Classify( Proc, b3Raw) + -- se profilo concavo + elseif ProfConcave.Identify( Proc) then + bOk, bDown, bSide = ProfConcave.Classify( Proc, b3Raw) + -- se profilo convesso + elseif ProfConvex.Identify( Proc) then + bOk, bDown, bSide = ProfConvex.Classify( Proc, b3Raw) + -- se profilo caudato + elseif ProfCamb.Identify( Proc) then + bOk, bDown, bSide = ProfCamb.Classify( Proc, b3Raw) + -- se profilo head + elseif ProfHead.Identify( Proc) then + bOk, bDown, bSide = ProfHead.Classify( Proc, b3Raw) + -- se contorno libero + elseif FreeContour.Identify( Proc) then + bOk, bDown, bSide = FreeContour.Classify( Proc, b3Raw) + -- se decorazione + elseif Decor.Identify( Proc) then + bOk, bDown = Decor.Classify( Proc) + end + -- assegno risultato + if bOk then + -- non ammessa feature di testa da lavorare ribaltata o ruotata + if Proc.Head and ( bDown or bSide) and not bDownSideOnHeadOk then + Proc.Flg = 0 + Proc.Down = true + bAllOk = false + table.insert( Stats, {Err = 1, Msg='Error : impossible to machine by orientation', CutId=Proc.CutId, TaskId=Proc.TaskId}) + -- gestione feature di coda da lavorare ribaltata + elseif Proc.Tail and bDown then + Proc.Down = true + bSomeDown = true + bSplitRot = true + -- gestione feature di coda da lavorare ruotata + elseif Proc.Tail and bSide then + Proc.Side = true + bSomeSide = true + bSplitRot = true + -- caso normale + else + Proc.Down = bDown + Proc.Side = bSide + if bDown then bSomeDown = true end + if bSide then bSomeSide = true end + end + elseif Proc.Flg == 0 then + bAllOk = false + Proc.ErrMsg = 'Error : out of the part' + table.insert( Stats, {Err = 1, Msg=Proc.ErrMsg, CutId=Proc.CutId, TaskId=Proc.TaskId}) + else + Proc.Flg = 0 + bAllOk = false + if not Proc.ErrMsg then Proc.ErrMsg = 'Error : impossible to machine' end + table.insert( Stats, {Err = 1, Msg=Proc.ErrMsg, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + end + -- se necessario ribaltamento, assegno intestatura alla fase ribaltata + if bSomeDown and nHeading then + vProc[nHeading].Down = true + -- se altrimenti necessaria rotazione (senza ribaltamento), assegno intestatura alla fase ribaltata (creata ad hoc) + elseif bSomeSide and nHeading then + vProc[nHeading].Down = true + bSomeDown = true + end + -- se necessaria separazione del ribaltato o ruotato, la assegno sempre alla fase ribaltata + if bSplitRot and nSplitting then + vProc[nSplitting].Down = true + bSomeDown = true + end + return bAllOk, bSomeDown, bSomeSide, bSplitRot +end + +------------------------------------------------------------------------------------------------------------- +local function PrintFeatures( vProc, b3Raw) + EgtOutLog( ' RawBox=' .. tostring( b3Raw)) + for i = 1, #vProc do + local Proc = vProc[i] + local sOut = string.format( ' Proc=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s', + Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId, + Proc.Flg, EgtIf( Proc.Down, 'T', 'F'), EgtIf( Proc.Side, 'T', 'F'), EgtIf( Proc.Head, 'T', 'F'), EgtIf( Proc.Tail, 'T', 'F'), + Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, tostring( Proc.Box)) + EgtOutLog( sOut) + end +end + +------------------------------------------------------------------------------------------------------------- +local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut, b3Raw) + local bOk = true + local sErr = '' + local bNewPhase = false + -- se intestatura ( 1-340-X ) + EgtOutLog( ' * Process ' .. tostring( Proc.Id) .. ' *', 1) + if Hcut.Identify( Proc) then + -- esecuzione taglio di testa + bOk, sErr = Hcut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut) + -- se separazione ( 2-350-X ) + elseif Split.Identify( Proc) then + -- esecuzione separazione o eliminazione grezzo residuo + bOk, _, sErr = Split.Make( Proc, nPhase, nRawId, nPartId) + -- richiedo il passaggio alla seconda fase di lavorazione di questa trave + bNewPhase = true + -- se taglio ( 1/2-010-X) + elseif Cut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se doppio taglio ( 1/2-011-X) + elseif DoubleCut.Identify( Proc) then + -- esecuzione doppio taglio + bOk, sErr = DoubleCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se taglio longitudinale ( 0/3/4-010-X) + elseif LongCut.Identify( Proc) then + -- esecuzione taglio longitudinale + bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) + -- se doppio taglio longitudinale ( 0-012-X) + elseif Long2Cut.Identify( Proc) then + -- se due facce longitudinali, eseguo doppio taglio longitudinale + if Long2Cut.GetLongFacesCount( Proc) == 2 then + bOk, sErr = Long2Cut.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti eseguo singolo taglio longitudinale + else + bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) + end + -- se taglio con lama ( 0/3/4-013-X) + elseif SawCut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = SawCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mezzo-legno di testa ( 1/2-030-X) + elseif RidgeLap.Identify( Proc) then + -- esecuzione mezzo-legno di testa + bOk, sErr = RidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se fessura ( 3/4-016-X) o se fessura frontale ( 3/4-017-X) o se tacca ( 3/4-020-X) o se tacca cantonale ( 3/4-025-X) + -- o se mezzo-legno ( 3/4-030-X) o se scanalatura/battuta ( 3/4-032-X) o se mezzo legno tipo chalet/tavola di chiusura ( 3/4-033-X) + -- o se rivestimento ( 3/4-034-X) o se mezzolegno chalet ( 4-037-X) o se tasca ( 4-039-X) o se taglio triangolato ( 4-120-X) + elseif LapJoint.Identify( Proc) then + -- esecuzione mezzo-legno o scanalatura + bOk, sErr = LapJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se smusso ( 3/4-036-X) + elseif Chamfer.Identify( Proc) then + -- esecuzione smusso + bOk, sErr = Chamfer.Make( Proc, nPhase, nRawId, nPartId) + -- se foratura ( 3/4-040-X) + elseif Drill.Identify( Proc) then + -- esecuzione foratura + bOk, sErr = Drill.Make( Proc, nPhase, nRawId, nPartId) + -- se giunzione francese ( 1/2-035-X) + elseif FrenchRidgeLap.Identify( Proc) then + -- esecuzione giunzione francese + bOk, sErr = FrenchRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se block house front ( 3/4-038-X) + elseif BlockHausFront.Identify( Proc) then + -- esecuzione giunzione francese + bOk, sErr = BlockHausFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se tenone ( 1/2-050-X) + elseif Tenon.Identify( Proc) then + -- esecuzione tenone + bOk, sErr = Tenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mortasa ( 3/4-050-X) anche frontale ( 3/4-051-X) + elseif Mortise.Identify( Proc) then + -- esecuzione mortasa + bOk, sErr = Mortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se tenone a coda di rondine ( 1/2-055-X) + elseif DtTenon.Identify( Proc) then + -- esecuzione tenone + bOk, sErr = DtTenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mortasa a coda di rondine ( 3/4-055-X) anche frontale ( 3/4-056-X) + elseif DtMortise.Identify( Proc) then + -- esecuzione mortasa + bOk, sErr = DtMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se marcatura ( 3/4-060-X) + elseif Mark.Identify( Proc) then + -- esecuzione marcatura + bOk, sErr = Mark.Make( Proc, nPhase, nRawId, nPartId) + -- se testo ( 4-061-X) + elseif Text.Identify( Proc) then + -- esecuzione testo + bOk, sErr = Text.Make( Proc, nPhase, nRawId, nPartId) + -- se giunto Gerber ( 1/2-071-X) + elseif ScarfJoint.Identify( Proc) then + -- esecuzione giunto Gerber + bOk, sErr = ScarfJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se giunto Gerber ( 1/2-070-X) + elseif Scarf.Identify( Proc) then + -- esecuzione giunto Gerber + bOk, sErr = Scarf.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se giunto a gradino ( 1/2-080-X) + elseif StepJoint.Identify( Proc) then + -- esecuzione giunto a gradino + bOk, sErr = StepJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se tacca a gradino ( 3/4-080-X) + elseif StJoNotch.Identify( Proc) then + -- esecuzione tacca a gradino + bOk, sErr = StJoNotch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo Front ( 3/4-100-X) + elseif ProfFront.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo concavo ( 3/4-101-X) + elseif ProfConcave.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo convesso ( 3/4-102-X) + elseif ProfConvex.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo caudato ( 3/4-103-X) + elseif ProfCamb.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se arco ( 4-104-X) + elseif RoundArch.Identify( Proc) then + -- esecuzione arco + bOk, sErr = RoundArch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo Head ( 3/4-106-X) + elseif ProfHead.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se incastro tirolo ( 1/2/3/4-136-X) + elseif TyroleanDovetail.Identify( Proc) then + bOk, sErr = TyroleanDovetail.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se giunto coda di rondine ( 1/2/3/4-138-X) + elseif Dovetail.Identify( Proc) then + bOk, sErr = Dovetail.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se contorno libero ( 0/3/4-250-X) + elseif FreeContour.Identify( Proc) then + -- esecuzione contorno + bOk, sErr = FreeContour.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se decorazione ( 0/3/4-959-X) + elseif Decor.Identify( Proc) then + -- esecuzione decorazione + bOk, sErr = Decor.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti feature sconosciuta + else + sErr = 'Error on process ' .. tostring( Proc.Id) .. ' unknown type (' .. tonumber( Proc.Grp) .. '-' .. tonumber( Proc.Prc) .. ')' + EgtOutLog( sErr) + bOk = false + end + return bOk, sErr, bNewPhase +end + +------------------------------------------------------------------------------------------------------------- +local function VerifyNeedForHeadCut( vProc, bSomeDown, bSomeSide) + -- verifico se necessaria la rotazione di 90 gradi + if not bSomeSide then + return false + end + -- verifico se viene dopo un pezzo diviso quando ruotato (quindi con rimanenza scaricata sul carico) + local nPrevPhase = EgtGetCurrPhase() - 1 + local nPrevDispId = EgtGetPhaseDisposition( nPrevPhase) or GDB_ID.NULL + local nPrevType = EgtGetInfo( nPrevDispId, 'TYPE') + if nPrevType ~= 'MID2' and nPrevType ~= 'END2' then + return false + end + -- verifico se c'è una sola lavorazione ribaltata (quindi è il taglio di testa) + local nDownCnt = 0 + for i = 1, #vProc do + if vProc[i].Down then + nDownCnt = nDownCnt + 1 + end + end + return ( nDownCnt == 1) +end + +------------------------------------------------------------------------------------------------------------- +local function SetCutsOnFrontMortises( vProc) + -- ciclo sulle feature + for i = 1, #vProc do + if vProc[i].Fct > 0 and Cut.Identify( vProc[i]) then + for j = 1, #vProc do + if vProc[j].Fct > 0 and Mortise.FrontIdentify( vProc[j]) then + -- se esiste intersezione tra le due features + if vProc[i].Box:getMin():getX() < vProc[j].Box:getMax():getX() + 100 * GEO.EPS_SMALL and + vProc[j].Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL then + -- recupero il piano del taglio + local ptC1, vtN1 = Cut.GetCutPlane( vProc[i]) + -- recupero il piano frontale della mortasa + local ptC2, vtN2 = Mortise.GetCutPlane( vProc[j]) + -- verifico se i piani coincidono + local bSamePlane = ( ptC1 and vtN1 and ptC2 and vtN2 and AreSameVectorApprox( vtN1, vtN2) and ( ptC2 - ptC1) * vtN1 < 1.0) + if bSamePlane then + vProc[i].CutFront = vProc[j].Id + end + -- log + local sMsg = string.format( 'Cut %d meet Mortise %d', vProc[i].Id, vProc[j].Id) .. EgtIf( bSamePlane, ' with same plane', '') + EgtOutLog( sMsg, 3) + end + elseif vProc[j].Fct > 0 and DtMortise.FrontIdentify( vProc[j]) then + -- se esiste intersezione tra le due features + if vProc[i].Box:getMin():getX() < vProc[j].Box:getMax():getX() + 100 * GEO.EPS_SMALL and + vProc[j].Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL then + -- recupero il piano del taglio + local ptC1, vtN1 = Cut.GetCutPlane( vProc[i]) + -- recupero il piano frontale della mortasa + local ptC2, vtN2 = DtMortise.GetCutPlane( vProc[j]) + -- verifico se i piani coincidono + local bSamePlane = ( ptC1 and vtN1 and ptC2 and vtN2 and AreSameVectorApprox( vtN1, vtN2) and ( ptC2 - ptC1) * vtN1 < 1.0) + if bSamePlane then + vProc[i].CutFront = vProc[j].Id + end + -- log + local sMsg = string.format( 'Cut %d meet DtMortise %d', vProc[i].Id, vProc[j].Id) .. EgtIf( bSamePlane, ' with same plane', '') + EgtOutLog( sMsg, 3) + end + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +local function MoveDrillsOnTenon( vProc) + -- se non richiesto spostamento fori su tenone, esco + if not BD.OFFSET_DRILL_TENON or abs( BD.OFFSET_DRILL_TENON) < 0.1 then return end + -- ciclo sulle feature + for i = 1, #vProc do + if vProc[i].Flg ~= 0 and Tenon.Identify( vProc[i]) then + for j = 1, #vProc do + if Drill.Identify( vProc[j]) then + -- se esiste intersezione tra tenone e foro + if vProc[i].Box:getMin():getX() < vProc[j].Box:getMax():getX() + 100 * GEO.EPS_SMALL and + vProc[j].Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL then + -- verifico se foro già spostato + if not EgtExistsInfo( vProc[j].Id, 'MOV') then + -- recupero curva ausiliaria del foro + local AuxDriId = EgtGetInfo( vProc[j].Id, 'AUXID', 'i') + AuxDriId = EgtIf( AuxDriId, AuxDriId + vProc[j].Id, nil) + -- recupero versore normale del tenone + local AuxTenId = EgtGetInfo( vProc[i].Id, 'AUXID', 'i') + AuxTenId = EgtIf( AuxTenId, AuxTenId + vProc[i].Id, GDB_ID.NULL) + local vtExtr = EgtCurveExtrusion( AuxTenId, GDB_RT.GLOB) + -- se tutto ok, eseguo spostamento + if AuxDriId and vtExtr then + local vtMove = -vtExtr * BD.OFFSET_DRILL_TENON + EgtMove( AuxDriId, vtMove, GDB_RT.GLOB) + EgtSetInfo( vProc[j].Id, 'MOV', vtMove) + end + end + end + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamExec.ProcessFeatures() + -- verifica se possibile rotazione di 90 gradi + BD.ROT90 = BD.ROT90 and Verify90DegRotation( EgtGetFirstRawPart()) + -- ciclo sui pezzi + local nTotErr = 0 + local Stats = {} + local nOrd = 1 + local nRawId = EgtGetFirstRawPart() + while nRawId do + -- verifico che il grezzo contenga pezzi oppure sia abbastanza lungo da essere scaricato coi carrelli + local nPartId = EgtGetFirstPartInRawPart( nRawId) + if not nPartId and EgtGetRawPartBBox( nRawId):getDimX() < BD.MinRaw then break end + -- aggiungo la fase, se non è la prima + if nOrd == 1 then + EgtSetCurrPhase( 1) + else + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) + end + local nPhase = EgtGetCurrPhase() + local nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', EgtIf( nPartId, 'START', 'REST')) + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( nRawId) .. ' Part=' .. tostring( nPartId) .. ' ***', 1) + -- ingombro del grezzo e sovramateriale di testa + local b3Raw = EgtGetRawPartBBox( nRawId) + local dCurrOvmH = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 + -- recupero le feature di lavorazione della trave + local vProc = CollectFeatures( nPartId, b3Raw, dCurrOvmH) + -- le ordino lungo X + OrderFeatures( vProc, b3Raw) + -- le classifico + local bAllOk, bSomeDown, bSomeSide, bSplitRot = ClassifyFeatures( vProc, b3Raw, Stats) + if not bAllOk then + nTotErr = nTotErr + 1 + end + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc, b3Raw) + end + -- verifico se comunque necessario taglio di testa + local bNeedHCut = VerifyNeedForHeadCut( vProc, bSomeDown, bSomeSide) + -- inserisco corrispondenze di tagli coincidenti con mortase normali o a coda di rondine di testa + SetCutsOnFrontMortises( vProc) + -- eventuale spostamento fori sui tenoni + MoveDrillsOnTenon( vProc) + -- se richiesto ribaltamento (oppure rotazione) + if ( bSomeDown or bSomeSide) and not BD.DOWN_HEAD then + -- ribalto le travi della fase corrente + local nRId = nRawId + while nRId do + EgtRotateRawPart( nRId, X_AX(), 180) + nRId = EgtGetNextRawPart( nRId) + end + EgtSetInfo( nDispId, 'ROT', -2) + -- inserisco le lavorazioni da lavorare ribaltate + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and Proc.Down then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut, b3Raw) + if not bOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + elseif sMsg and #sMsg > 0 then + table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + else + table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + EgtRotateRawPart( nRawId, X_AX(), 180) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'MID2') + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtSetInfo( nDispId, 'ROT', -2) + end + end + end + -- se separazione non ancora effettuata, aggiungo nuova fase con le travi in posizione standard + if not bSplitRot then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) + -- altrimenti + else + -- aggiungo nuova fase con le travi in posizione standard + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + local nType = 'MID' + if bSplitRot then nType = EgtIf( bSomeSide, 'MID2', 'END2') end + EgtSetInfo( nDispId, 'TYPE', nType) + EgtSetInfo( nDispId, 'ORD', nOrd) + end + -- se richiesta rotazione + if bSomeSide and not BD.DOWN_HEAD then + -- vettore movimento grezzi per rotazione di 90deg + local dDeltaYZ = EgtGetRawPartBBox( nRawId):getDimY() - EgtGetRawPartBBox( nRawId):getDimZ() + local vtMove = Vector3d( 0, dDeltaYZ / 2, dDeltaYZ / 2) + local bPreMove = ( dDeltaYZ < 0) + -- ruoto le travi della fase corrente + local nRId = nRawId + while nRId do + if bPreMove then EgtMoveRawPart( nRId, vtMove) end + EgtRotateRawPart( nRId, X_AX(), 90) + if not bPreMove then EgtMoveRawPart( nRId, vtMove) end + nRId = EgtGetNextRawPart( nRId) + end + EgtSetInfo( nDispId, 'ROT', -1) + -- inserisco le lavorazioni da lavorare ruotate + local nSideMchOk = 0 + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and Proc.Side then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, false, b3Raw) + if not bOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + elseif sMsg and #sMsg > 0 then + table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + else + table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + if bOk then nSideMchOk = nSideMchOk + 1 end + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + if bPreMove then EgtMoveRawPart( nRawId, vtMove) end + EgtRotateRawPart( nRawId, X_AX(), 90) + if not bPreMove then EgtMoveRawPart( nRawId, vtMove) end + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'MID2') + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtSetInfo( nDispId, 'ROT', -1) + end + end + end + -- se non sono state inserite lavorazioni di fianco, elimino la fase perchè inutile e dannosa + if nSideMchOk == 0 then + EgtRemoveLastPhase() + end + -- se separazione non ancora effettuata, aggiungo nuova fase con le travi in posizione standard + if not bSplitRot then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) + -- altrimenti + else + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', EgtIf( not bSplitRot, 'MID', 'END2')) + EgtSetInfo( nDispId, 'ORD', nOrd) + end + -- inserisco le lavorazioni non ribaltate della trave + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and ( not ( Proc.Down or Proc.Side) or BD.DOWN_HEAD) then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, false, 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 + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'END') + EgtSetInfo( nDispId, 'ORD', nOrd) + end + end + end + -- passo al grezzo successivo + nOrd = nOrd + 1 + nRawId = EgtGetNextRawPart( nRawId) + end + + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + local bApplOk, sApplErrors = EgtApplyAllMachinings() + if not bApplOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err = 1, Msg=sApplErrors, Rot=0, CutId=0, TaskId=0}) + end + + return ( nTotErr == 0), Stats +end + +------------------------------------------------------------------------------------------------------------- +return BeamExec diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/BeamLib.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/BeamLib.lua new file mode 100644 index 0000000..80fa494 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/BeamLib.lua @@ -0,0 +1,981 @@ +-- BeamLib.lua by Egaltech s.r.l. 2021/01/06 +-- Libreria globale per Travi +-- 2020/07/28 Corretto calcolo attacchi e uscite di lame per non uscire dalla faccia sotto. +-- 2020/08/18 Aggiunto a GetNearestParalOpposite e GetNearestOrthoOpposite parametro opzionale vtNorm. +-- 2020/11/03 Aggiunta funzione IsEndOrEnd2Phase. +-- 2020/11/18 Correzioni a GetParallelOpposite e a GetFaceElevation. +-- 2021/01/06 Cambiato limite per attacco Tg con lama e CalcLeadInOutGeom rinominata in CalcLeadInOutPerpGeom. + +-- Tabella per definizione modulo +local BeamLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' BeamLib started', 1) + +-- Dati +local BD = require( 'BeamData') + +------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetAddGroup( PartId) + -- recupero il nome del gruppo di lavoro corrente + local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL) + if not sMchGrp then return nil, nil end + -- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco + local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp) + -- restituisco Id e Nome + return AddGrpId, sMchGrp +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.CreateOrEmptyAddGroup( PartId) + -- recupero i dati del gruppo aggiuntivo + local AddGrpId, sMchGrp = BeamLib.GetAddGroup( PartId) + if not sMchGrp then return false end + -- se esiste lo svuoto + if AddGrpId then + return EgtEmptyGroup( AddGrpId) + end + -- altrimenti lo creo + AddGrpId = EgtGroup( PartId or GDB_ID.NULL) + if not AddGrpId then return false end + -- assegno nome, flag di layer per gruppo di lavoro e colore + EgtSetName( AddGrpId, sMchGrp) + EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup()) + EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 50)) + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPartStartFace( PartId, b3Solid) + -- recupero gruppo per geometria aggiuntiva + local AddGrpId = BeamLib.GetAddGroup( PartId) + if not AddGrpId then + local sErr = 'Error on process StartFace impossible to find AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo nuovo taglio iniziale + local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMax(), X_AX(), b3Solid, GDB_RT.GLOB) + if not nStmId then + local sErr = 'Error on process StartFace impossible to create Face' + EgtOutLog( sErr) + return false, sErr + end + -- applico gli opportuni attributi di feature + EgtSetName( nStmId, 'StartCut') + EgtSetInfo( nStmId, 'GRP', 1) + EgtSetInfo( nStmId, 'PRC', 340) + -- verifico se sostituisce un taglio di testa già presente + local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PartId, 'Processings') or GDB_ID.NULL) + while nProcId do + local nGrp = EgtGetInfo( nProcId, 'GRP', 'i') or 0 + local nProc = EgtGetInfo( nProcId, 'PRC', 'i') or 0 + if ( nGrp == 1 or nGrp == 2) and nProc == 10 then + local ptC, vtN = EgtSurfTmFacetCenter( nProcId, 0, GDB_ID.ROOT) + if ptC and vtN and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL then + EgtSetInfo( nStmId, 'ORI', nProcId) + end + end + nProcId = EgtGetNext( nProcId) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPartEndFace( PartId, b3Solid) + -- recupero gruppo per geometria aggiuntiva + local AddGrpId = BeamLib.GetAddGroup( PartId) + if not AddGrpId then + local sErr = 'Error on process EndFace impossible to find AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo nuovo taglio finale + local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMin(), -X_AX(), b3Solid, GDB_RT.GLOB) + if not nStmId then + local sErr = 'Error on process EndFace impossible to create Face' + EgtOutLog( sErr) + return false, sErr + end + -- applico gli opportuni attributi di feature + EgtSetName( nStmId, 'EndCut') + EgtSetInfo( nStmId, 'GRP', 2) + EgtSetInfo( nStmId, 'PRC', 350) + -- verifico se sostituisce un taglio di coda già presente + local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PartId, 'Processings') or GDB_ID.NULL) + while nProcId do + local nGrp = EgtGetInfo( nProcId, 'GRP', 'i') or 0 + local nProc = EgtGetInfo( nProcId, 'PRC', 'i') or 0 + if ( nGrp == 1 or nGrp == 2) and nProc == 10 then + local ptC, vtN = EgtSurfTmFacetCenter( nProcId, 0, GDB_ID.ROOT) + if ptC and vtN and AreSameVectorApprox( vtN, -X_AX()) and abs( ptC:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL then + EgtSetInfo( nStmId, 'ORI', nProcId) + end + end + nProcId = EgtGetNext( nProcId) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPhaseWithRawParts( nFirstRawId, OriTR, dDeltaSucc) + EgtAddPhase() + local nRawId = nFirstRawId + local dRawMove = 0 + while nRawId do + EgtKeepRawPart( nRawId) + EgtMoveToCornerRawPart( nRawId, OriTR, MCH_CR.TR) + EgtMoveRawPart( nRawId, Vector3d( - dRawMove, 0, 0)) + if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end + dRawMove = dRawMove + EgtGetRawPartBBox( nRawId):getDimX() + nRawId = EgtGetNextRawPart( nRawId) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartOnTop( nCrvId) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- cerco l'estremo più alto e lo imposto come inizio + local dUmax = 0 + local dZmax = - GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf, 0.5 do + local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) + if ptP and ptP:getZ() > dZmax + GEO.EPS_SMALL then + dZmax = ptP:getZ() + dUmax = dU + end + end + if abs( dUmax - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUmax) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartOnLonger( nCrvId) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- cerco l'entità più lunga e la imposto come inizio + local dUmax = 0 + local dLmax = - GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf - 1 do + local ptP1 = EgtUP( nCrvId, dU, GDB_ID.ROOT) + local ptP2 = EgtUP( nCrvId, dU + 0.5, GDB_ID.ROOT) + local ptP3 = EgtUP( nCrvId, dU + 1.0, GDB_ID.ROOT) + local dL = dist( ptP1, ptP2) + dist( ptP2, ptP3) + if dL > dLmax + GEO.EPS_SMALL then + dLmax = dL + dUmax = dU + end + end + if abs( dUmax - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUmax) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw, bDown) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- recupero il versore normale al piano di lavoro o estrusione + local vtN = EgtCurveExtrusion( nCrvId, GDB_ID.ROOT) + -- coefficienti per riportare la distanza nel piano di lavoro + local dCoeffX = 1 / ( sqrt( 1 - vtN:getX() * vtN:getX())) + local dCoeffY = 1 / ( sqrt( 1 - vtN:getY() * vtN:getY())) + local dCoeffZ = 1 / ( sqrt( 1 - vtN:getZ() * vtN:getZ())) + -- cerco l'estremo più vicino al box e lo imposto come inizio (se da sotto escludo Zmax e viceversa) + local dUopt = 0 + local dDopt = GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf, 0.5 do + local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) + if ptP then + local vtMin = ptP - b3Raw:getMin() + local vtMax = ptP - b3Raw:getMax() + local dD = abs( vtMin:getX()) * dCoeffX + dD = min( abs( vtMax:getX()) * dCoeffX, dD) + dD = min( abs( vtMin:getY()) * dCoeffY, dD) + dD = min( abs( vtMax:getY()) * dCoeffY, dD) + if bDown then + dD = min( abs( vtMin:getZ()) * dCoeffZ, dD) + else + dD = min( abs( vtMax:getZ()) * dCoeffZ, dD) + end + if dD < dDopt + GEO.EPS_SMALL then + dDopt = dD + dUopt = dU + end + end + end + if abs( dUopt - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUopt) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetPointDirDepth( nPartId, ptP, vtDir) + -- recupero il solido del grezzo + local nSolId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, 'Box') + if not nSolId then return end + -- interseco con la retta + local bOk, vType, vPar = EgtLineSurfTmInters( ptP, vtDir, nSolId, GDB_RT.GLOB) + if not bOk then return end + if not vPar or #vPar == 0 then return -2 end + local dLenIn, dLenOut + for i = 1, #vPar do + if vPar[i] < 0 then + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = -1 + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN then + dLenIn = -2 + end + else + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = vPar[i] + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN or vType[i] == GDB_SLT.TOUCH then + dLenOut = vPar[i] + end + end + end + return dLenIn, dLenOut +end + +--------------------------------------------------------------------- +function BeamLib.GetNearestParalOpposite( vtRef, vtNorm) + -- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa + local vtMyRef = Vector3d( vtRef) + if vtNorm then + vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm + vtMyRef:normalize() + end + -- devo confrontare la componente orizzontale con quella verticale + local dHorSq = vtMyRef:getX() * vtMyRef:getX() + vtMyRef:getY() * vtMyRef:getY() + local dVertSq =vtMyRef:getZ() * vtMyRef:getZ() + -- se prevalente la componente orizzontale + if dHorSq >= dVertSq then + if abs( vtMyRef:getX()) > abs( vtMyRef:getY()) then + if vtMyRef:getX() > 0 then + return MCH_MILL_FU.PARAL_LEFT + else + return MCH_MILL_FU.PARAL_RIGHT + end + else + if vtMyRef:getY() > 0 then + return MCH_MILL_FU.PARAL_FRONT + else + return MCH_MILL_FU.PARAL_BACK + end + end + -- altrimenti prevale la verticale + else + if vtMyRef:getZ() > 0 then + return MCH_MILL_FU.PARAL_DOWN + else + return MCH_MILL_FU.PARAL_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetNearestOrthoOpposite( vtRef, vtNorm) + -- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa + local vtMyRef = Vector3d( vtRef) + if vtNorm then + vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm + vtMyRef:normalize() + end + -- devo confrontare la componente orizzontale con quella verticale + local dHorSq = vtMyRef:getX() * vtMyRef:getX() + vtMyRef:getY() * vtMyRef:getY() + local dVertSq = vtMyRef:getZ() * vtMyRef:getZ() + -- se prevalente la componente orizzontale + if dHorSq >= dVertSq then + if abs( vtMyRef:getX()) >= abs( vtMyRef:getY()) then + if vtMyRef:getX() > 0 then + return MCH_MILL_FU.ORTHO_LEFT + else + return MCH_MILL_FU.ORTHO_RIGHT + end + else + if vtMyRef:getY() > 0 then + return MCH_MILL_FU.ORTHO_FRONT + else + return MCH_MILL_FU.ORTHO_BACK + end + end + -- altrimenti prevale la verticale + else + if vtMyRef:getZ() > 0 then + return MCH_MILL_FU.ORTHO_DOWN + else + return MCH_MILL_FU.ORTHO_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetOrtupOpposite( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return MCH_MILL_FU.ORTUP_LEFT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return MCH_MILL_FU.ORTUP_RIGHT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return MCH_MILL_FU.ORTUP_FRONT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return MCH_MILL_FU.ORTUP_BACK + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return MCH_MILL_FU.ORTUP_DOWN + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return MCH_MILL_FU.ORTUP_TOP + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetParallelOpposite( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return MCH_MILL_FU.PARAL_LEFT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return MCH_MILL_FU.PARAL_RIGHT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return MCH_MILL_FU.PARAL_FRONT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return MCH_MILL_FU.PARAL_BACK + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return MCH_MILL_FU.PARAL_DOWN + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return MCH_MILL_FU.PARAL_TOP + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetVersRef( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return X_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return -X_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return Y_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return -Y_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return Z_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return -Z_AX() + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetBoxFaceNorm( b3Box, ptP, vtV) + local vtNx = V_NULL() + if abs( ptP:getX() - b3Box:getMin():getX()) < 10 * GEO.EPS_SMALL then + vtNx = -X_AX() + elseif abs( ptP:getX() - b3Box:getMax():getX()) < 10 * GEO.EPS_SMALL then + vtNx = X_AX() + end + local vtNy = V_NULL() + if abs( ptP:getY() - b3Box:getMin():getY()) < 10 * GEO.EPS_SMALL then + vtNy = -Y_AX() + elseif abs( ptP:getY() - b3Box:getMax():getY()) < 10 * GEO.EPS_SMALL then + vtNy = Y_AX() + end + local vtNz = V_NULL() + if abs( ptP:getZ() - b3Box:getMin():getZ()) < 10 * GEO.EPS_SMALL then + vtNz = -Z_AX() + elseif abs( ptP:getZ() - b3Box:getMax():getZ()) < 10 * GEO.EPS_SMALL then + vtNz = Z_AX() + end + local dNxDotV = vtNx * vtV + local dNyDotV = vtNy * vtV + local dNzDotV = vtNz * vtV + if dNxDotV > dNyDotV and dNxDotV > dNzDotV then + return vtNx + elseif dNyDotV > dNzDotV and dNyDotV > dNxDotV then + return vtNy + else + return vtNz + end +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceElevation( nSurfId, nFac, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFac, GDB_ID.ROOT) + if not ptC or not vtN then return 0 end + local frOCS = Frame3d( ptC, vtN) ; + local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS) + local dElev = b3Box:getMax():getZ() + if nPartId then + if EgtSurfTmFacetCount( nSurfId) > 1 then + local _, dCenElev = BeamLib.GetPointDirDepth( nPartId, ptC, vtN) + if dCenElev and dCenElev > dElev then + dElev = dCenElev + end + else + local b3Solid = EgtGetBBoxRef( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD, frOCS) + if b3Solid and b3Solid:getMax():getZ() > dElev then + dElev = b3Solid:getMax():getZ() + end + end + end + return dElev +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc, dCosSideAng) + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nSurfId) + if not dCosSideAng then + dCosSideAng = -0.09 + end + -- recupero le normali delle facce + local vvtN = {} + for i = 1, nFacCnt do + local vtN = EgtSurfTmFacetNormVersor( nSurfId, i - 1, GDB_ID.ROOT) + vvtN[i] = vtN ; + end + -- adiacenze e sottosquadra delle facce + local vAdj = {} + local vUcut = {} + local vOrtho = {} + for i = 1, nFacCnt do + -- recupero le adiacenze del loop esterno + local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + vAdj[i] = nCount + -- ne determino eventuale sottosquadra ( dal valore passato o - 3deg) e ortogonalità + local bUcut = false + local bOrtho = true + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + local vtN = vvtN[i] + local vtN2 = vvtN[vFacAdj[j]+1] + local dResV = vtN * vtN2 + if dResV < dCosSideAng - GEO.EPS_SMALL then + bUcut = true + end + if abs( dResV) > 2 * GEO.EPS_SMALL then + bOrtho = false + end + end + end + vUcut[i] = bUcut + vOrtho[i] = bOrtho + end + -- se 4 facce tutte con adiacenza 2, allora è un tunnel + if nFacCnt == 4 then + if vAdj[1] == 2 and vAdj[2] == 2 and vAdj[3] == 2 and vAdj[4] == 2 then + -- se tutte le facce sono ortogonali tra loro esco con un flag che ne indica questa propietà + if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true and vOrtho[4] == true then + return -1, GEO.INFINITO, true + else + return -1, GEO.INFINITO + end + end + end + -- se 3 facce con una che ha 2 adiacenze e le altre hanno 1 adiacenza, allora è una semi-fessura + if bCompare3Fc and nFacCnt == 3 then + local nCount2Adc = 0 + local nCount1Adc = 0 + -- ottengo il numero di facce con due adiacenze e il numero di facce con una adiacenza + for i = 1, #vAdj do + if vAdj[i] == 2 then + nCount2Adc = nCount2Adc + 1 + elseif vAdj[i] == 1 then + nCount1Adc = nCount1Adc + 1 + end + end + -- se il numero di adiacenze corrisponde + if nCount2Adc == 1 and nCount1Adc == 2 then + if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true then + return -1, GEO.INFINITO, true + else + return -1, GEO.INFINITO + end + end + end + -- recupero le facce non in sottosquadra e con il maggior numero di adiacenze + local nFacInd = {} + local nMaxAdj = -1 + local nSupAdj = -1 + for i = 1, nFacCnt do + if not vUcut[i] then + if vAdj[i] > nMaxAdj then + nFacInd = {} + nFacInd[1] = i - 1 + nMaxAdj = vAdj[i] + elseif vAdj[i] == nMaxAdj and nMaxAdj > 0 then + table.insert( nFacInd, i - 1) + end + end + if vAdj[i] > nSupAdj then + nSupAdj = vAdj[i] + end + end + -- verifico non ci sia una faccia in sottosquadra con adiacenza superiore + if nSupAdj > nMaxAdj then + return -2, GEO.INFINITO + end + -- premio la faccia con minore elevazione + local nFacOpt, nFacOpt2 + local dMinElev, dMinElev2 = GEO.INFINITO, GEO.INFINITO + local dtElev = {} + for i = 1, #nFacInd do + local dElev = BeamLib.GetFaceElevation( nSurfId, nFacInd[i], nPartId) + table.insert( dtElev, dElev) + if dElev < dMinElev then + if dMinElev < dMinElev2 then + nFacOpt2 = nFacOpt + dMinElev2 = dMinElev + end + nFacOpt = nFacInd[i] + dMinElev = dElev + elseif dElev < dMinElev2 then + nFacOpt2 = nFacInd[i] + dMinElev2 = dElev + end + end + -- faccio una ulteriore verifica + -- se le elevazioni di max 3 facce sono in un range minimo o al di sotto dell'elevazione ritenuta fattibile, + -- premio quella che non è sottosquadra e che ha la X minore + local bDiffSmall = true + for i = 1, #dtElev do + if dtElev[i] > dMinElev + 5 or dtElev[i] > 80 then + bDiffSmall = false + end + end + -- se tutte sono nel range minimo posso prendere la faccia che ha la componente Z magiore, e se sono uguali, prendo quella con componente X minore + local dMaxZ, dMaxZ2 = -1.1, -1.1 + if bDiffSmall and #nFacInd <= 3 then + for i = 1, #nFacInd do + if vvtN[nFacInd[i]+1]:getZ() > dMaxZ then + if dMaxZ > dMaxZ2 then + nFacOpt2 = nFacOpt + dMinElev2 = dMinElev + dMaxZ2 = dMaxZ + end + nFacOpt = nFacInd[i] + dMinElev = dtElev[i] + dMaxZ = vvtN[nFacInd[i]+1]:getZ() + elseif vvtN[nFacInd[i]+1]:getZ() > dMaxZ2 then + nFacOpt2 = nFacInd[i] + dMinElev2 = dtElev[i] + dMaxZ2 = vvtN[nFacInd[i]+1]:getZ() + end + end + -- se hanno uguale Z premio quella con la componente X minore + if abs( dMaxZ - dMaxZ2) < 10*GEO.EPS_SMALL then + if abs(vvtN[nFacOpt+1]:getX()) > abs(vvtN[nFacOpt2+1]:getX()) then + nFacOpt, nFacOpt2 = nFacOpt2, nFacOpt + dMinElev, dMinElev2 = dMinElev2, dMinElev + end + end + end + + return nFacOpt, dMinElev, nFacOpt2, dMinElev2 +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceHvRefDim( nSurfId, nFacet) + -- recupero centro e normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + if not ptC or not vtN then return end + -- riferimento tipo OCS della faccia (X orizz, Y max pendenza, Z normale) + local frHV = Frame3d( ptC, vtN) + if frHV:getVersY():getZ() < 0 then + frHV:rotate( ptC, vtN, 180) + end + -- determino l'ingombro in questo riferimento + local b3HV = EgtSurfTmGetFacetBBoxRef( nSurfId, nFacet, GDB_BB.STANDARD, frHV) + -- restituisco i valori calcolati + return frHV, b3HV:getDimX(), b3HV:getDimY() +end + +--------------------------------------------------------------------- +function BeamLib.CalcLeadInOutPerpGeom( ptP1, ptP2, vtV1, vtV2, vtN, dRad, vtRef, dCutExtra, b3Box) + -- Mi assicuro che i vettori ingresso/uscita giacciano nel piano + vtV1 = vtV1 - vtV1 * vtN * vtN ; vtV1:normalize() + vtV2 = vtV2 - vtV2 * vtN * vtN ; vtV2:normalize() + -- Versore tangente al taglio + local vtTg = ptP2 - ptP1 ; + vtTg = vtTg - vtTg * vtN * vtN ; vtTg:normalize() + -- Sistema di riferimento intrinseco al taglio + local vtX = vtTg ^ vtN + local frFace = Frame3d( ptP1, vtX, vtTg, vtN) + EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Versori di attacco e uscita + local dCos1 = vtV1 * vtRef + local dCos2 = vtV2 * vtRef + local vtLi, vtLo + if abs( dCos1 - dCos2) < 0.001 then + if abs( vtV1:getZ()) < abs( vtV2:getZ()) then + vtLi = vtV1 + vtLo = vtV1 + else + vtLi = vtV2 + vtLo = vtV2 + end + elseif dCos1 > dCos2 then + vtLi = vtV1 + vtLo = vtV1 + else + vtLi = vtV2 + vtLo = vtV2 + end + local bRight = ( vtX * vtLi > 0) + -- Versori di attacco e uscita nel riferimento intrinseco al taglio + local vtLiL = Vector3d( vtLi) ; vtLiL:toLoc( frFace) + local vtLoL = Vector3d( vtLo) ; vtLoL:toLoc( frFace) + -- Spostamento punti per effetto dell'extra o della deficienza di taglio + ptP1 = ptP1 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) + ptP2 = ptP2 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) + -- Non va considerata l'uscita dalla faccia sotto, pertanto va abbassata + local b3MyBox = BBox3d( b3Box) ; b3MyBox:Add( b3MyBox:getMin() - 1000 * Z_AX()) + -- Attacco + local dLiTang = 10000 + local dLiPerp = 10000 + local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtLi, b3MyBox) + if bLiOk and #vLiPar > 0 then + -- con la prima faccia di uscita + local dLen = vLiPar[#vLiPar] + local ptInt = ptP1 + vtLi * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3MyBox, ptInt, vtLi) + EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLi * vtFN) + local dLiLen = dLen + dAddLen + EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) + dLiTang = - dLiLen * vtLiL:getY() + dLiPerp = EgtIf( bRight, dLiLen, - dLiLen) * vtLiL:getX() + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtLi, b3Mod) + if bLiOk2 and #vLiPar2 > 0 then + local dLen2 = vLiPar2[#vLiPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP1 + vtLi * dLen2, vtLi) + EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLi * vtFN2) + local dLiLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) + local dLiTang2 = - dLiLen2 * vtLiL:getY() + local dLiPerp2 = EgtIf( bRight, dLiLen2, - dLiLen2) * vtLiL:getX() + if dLiLen2 < dLiLen then + dLiTang = dLiTang2 + dLiPerp = dLiPerp2 + end + end + end + -- Lunghezza di uscita + local dLoTang = 10000 + local dLoPerp = 10000 + local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtLo, b3MyBox) + if bLoOk and #vLoPar > 0 then + -- con la prima faccia di uscita + local dLen = vLoPar[#vLoPar] + local ptInt = ptP2 + vtLo * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3MyBox, ptInt, vtLo) + EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLo * vtFN) + local dLoLen = dLen + dAddLen + EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) + dLoTang = dLoLen * vtLoL:getY() + dLoPerp = EgtIf( bRight, dLoLen, - dLoLen) * vtLoL:getX() + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtLo, b3Mod) + if bLoOk2 and #vLoPar2 > 0 then + local dLen2 = vLoPar2[#vLoPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP2 + vtLo * dLen2, vtLo) + EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLo * vtFN2) + local dLoLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) + local dLoTang2 = dLoLen2 * vtLoL:getY() + local dLoPerp2 = EgtIf( bRight, dLoLen2, - dLoLen2) * vtLoL:getX() + if dLoLen2 < dLoLen then + dLoTang = dLoTang2 + dLoPerp = dLoPerp2 + end + end + end + return dLiTang, dLiPerp, dLoTang, dLoPerp +end + +--------------------------------------------------------------------- +function BeamLib.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dRad, vtRef, dCutExtra, b3Box) + -- Versore tangente al taglio + local vtTg = ptP2 - ptP1 ; + vtTg = vtTg - vtTg * vtN * vtN ; vtTg:normalize() + -- Sistema di riferimento intrinseco al taglio + local vtX = vtTg ^ vtN + local frFace = Frame3d( ptP1, vtX, vtTg, vtN) + if ( vtX * vtRef < 0) then + vtX = - vtX + end + EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Spostamento punti per effetto dell'extra o della deficienza di taglio + ptP1 = ptP1 - vtX * dCutExtra + ptP2 = ptP2 - vtX * dCutExtra + -- Non va considerata l'uscita dalla faccia sotto, pertanto va abbassata + local b3MyBox = BBox3d( b3Box) ; b3MyBox:Add( b3MyBox:getMin() - 1000 * Z_AX()) + -- Attacco + local dLiTang = 10000 + local dLiPerp = 0 + local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtTg, b3MyBox) + if bLiOk and #vLiPar > 0 then + local dLen = vLiPar[1] + local ptInt = ptP1 + vtTg * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3MyBox, ptInt, -vtTg) + EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) + local dLiLen = dLen + dAddLen + EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) + dLiTang = - dLiLen + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtTg, b3Mod) + if bLiOk2 and #vLiPar2 > 0 then + local dLen2 = vLiPar2[1] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP1 + vtTg * dLen2, -vtTg) + EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) + local dLiLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) + if -dLiLen2 < -dLiLen then + dLiTang = - dLiLen2 + end + end + end + -- Lunghezza di uscita + local dLoTang = 10000 + local dLoPerp = 0 + local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtTg, b3MyBox) + if bLoOk and #vLoPar > 0 then + local dLen = vLoPar[#vLoPar] + local ptInt = ptP2 + vtTg * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3MyBox, ptInt, vtTg) + EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) + local dLoLen = dLen + dAddLen + EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) + dLoTang = dLoLen + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtTg, b3Mod) + if bLoOk2 and #vLoPar2 > 0 then + local dLen2 = vLoPar2[#vLoPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP2 + vtTg * dLen2, vtTg) + EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) + local dLoLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) + if dLoLen2 < dLoLen then + dLoTang = dLoLen2 + end + end + end + return dLiTang, dLiPerp, dLoTang, dLoPerp +end + +--------------------------------------------------------------------- +function BeamLib.MakeOneFaceBySaw( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDwnUp, dCutExtra, dCutSic, dCutOffset, dAccStart, sNotes, b3Raw) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + -- risolvo parametro ambiguo + local nOrthoOpposite + local vtOrthO + if isVector3d( Par5) then + nOrthoOpposite = BeamLib.GetNearestOrthoOpposite( Par5, vtN) + vtOrthO = Vector3d( Par5) + else + nOrthoOpposite = Par5 + vtOrthO = BeamLib.GetVersRef( Par5) + end + -- linea o bilinea di lavorazione (qui uso nOrthoOpposite per ripetere esattamente il calcolo del Mach) + local ptP1, ptPm, ptP2, vtV1, vtV2, dLen, dWidth = EgtSurfTmFacetOppositeSide( nSurfId, nFacet, BeamLib.GetVersRef( nOrthoOpposite), GDB_ID.ROOT) + if not dLen or dLen < 1.1 or not dWidth or dWidth < 1.1 then + local sWarn = 'Face ' .. string.format( '%d,%d', nSurfId, nFacet) .. ' skipped : too small' + EgtOutLog( sWarn, 1) + return true, '' + end + vtV1 = - vtV1 + local bInvert = ( ptP2:getZ() < ptP1:getZ() - 100 * GEO.EPS_SMALL) + if bInvert then + ptP1, ptP2 = ptP2, ptP1 + vtV1, vtV2 = vtV2, vtV1 + end + local vtTg = ptP2 - ptP1 ; vtTg:normalize() + local dAllStart = 0 + local dAllEnd = 0 + -- se bilinea, scarto la parte più allineata con la direzione ortogonale + if ( ( ptPm - ptP1) - ( ptPm - ptP1) * vtTg * vtTg):len() > 100 * GEO.EPS_SMALL then + local vtTg1 = ptPm - ptP1 ; vtTg1:normalize() + local vtTg2 = ptP2 - ptPm ; vtTg2:normalize() + local dDist1 = dist( ptP1, ptPm) + local dDist2 = dist( ptP2, ptPm) + --if dDist1 * ( vtTg1 ^ vtOrthO):len() > dDist2 * ( vtTg2 ^ vtOrthO):len() then + if abs( vtTg1 * vtOrthO) < abs( vtTg2 * vtOrthO) then + ptP2 = Point3d( ptPm) + dAllEnd = - dDist2 - 10 * GEO.EPS_SMALL + else + ptP1 = Point3d( ptPm) + dAllStart = - dDist1 - 10 * GEO.EPS_SMALL + end + vtTg = ptP2 - ptP1 ; vtTg:normalize() + end + -- verifico se lavorazione con lama sotto e testa sopra + if not dVzLimDwnUp then dVzLimDwnUp = -0.5 end + local bDownUp = ( vtN:getZ() < dVzLimDwnUp) + local nFaceUse = nOrthoOpposite + if bDownUp then nFaceUse = BeamLib.GetOrtupOpposite( nOrthoOpposite) end + local bWsRight = ( bInvert ~= bDownUp) + local nWorkSide = EgtIf( bWsRight, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) + -- Versore di riferimento + local vtRef = Vector3d( vtTg) + vtRef:rotate( vtN, EgtIf( bInvert, -90, 90)) + -- Versore esterno + local vtOut = vtRef - vtRef * vtTg * vtTg ; vtOut:normalize() + -- Versore ausiliario (direzione braccio) + local vtAux = Vector3d( vtN:getX(), vtN:getY(), 0) ; vtAux:normalize() + vtAux:rotate( Z_AX(), EgtIf( bWsRight, 90, -90)) + if vtAux:isSmall() then + vtAux = Vector3d( vtOut:getX(), vtOut:getY(), 0) ; vtAux:normalize() + else + if abs( vtAux * vtOut) < GEO.EPS_SMALL then + if abs( vtTg:getZ()) > 0.5 then + if vtAux * vtRef < 0 then + vtAux = - vtAux + end + elseif vtAux * vtTg > 0 then + vtAux = - vtAux + end + elseif vtAux * vtOut < 0 then + vtAux = - vtAux + end + end + -- parametri di attacco/uscita + local b3Box = BBox3d( b3Raw) + b3Box:expand( dCutSic) + local dLiTang, dLiPerp, dLoTang, dLoPerp + local ptP1act = ptP1 + vtN * dCutOffset + local ptP2act = ptP2 + vtN * dCutOffset + if ( vtV1:getZ() > -0.5 or vtV2:getZ() > -0.5) and ( abs( vtV1:getY()) > 0.707 or abs( vtV2:getY()) > 0.707 or vtN:getZ() < 0.707 or abs( vtTg:getZ()) > 0.5) then + dLiTang, dLiPerp, dLoTang, dLoPerp = BeamLib.CalcLeadInOutPerpGeom( ptP1act, ptP2act, vtV1, vtV2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + else + dLiTang, dLiPerp, dLoTang, dLoPerp = BeamLib.CalcLeadInOutTangGeom( ptP1act, ptP2act, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + end + -- posizione braccio + EgtOutLog( 'vtN=' .. tostring( vtN) .. ' vtRef=' .. tostring( vtRef) .. ' vtOut=' .. tostring( vtOut) .. ' vtAux=' .. tostring( vtAux), 3) + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM or vtRef:getZ() < 0.866 then + if abs( vtAux:getX()) > abs( vtAux:getY()) then + nSCC = EgtIf( ( vtAux:getX() > 0), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + else + nSCC = EgtIf( ( vtAux:getY() > 0), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + end + -- inserisco la lavorazione di taglio + local sName = 'Cut_' .. ( EgtGetName( nSurfId) or tostring( nSurfId)) .. '_' .. tostring( nFacet + 1) + local nMchFId = EgtAddMachining( sName, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + sName = EgtGetOperationName( nMchFId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nSurfId, nFacet}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, bInvert) + EgtSetMachiningParam( MCH_MP.WORKSIDE, nWorkSide) + -- affondamento aggiuntivo + EgtSetMachiningParam( MCH_MP.OFFSR, -dCutExtra) + -- offset longitudinale + EgtSetMachiningParam( MCH_MP.OFFSL, EgtIf( bDownUp, -dCutOffset, dCutOffset)) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLiTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLiPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLoTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLoPerp) + -- imposto allungamenti iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAllStart - dAccStart) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAllEnd) + -- eventuali note + if sNotes and #sNotes > 0 then EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, sName, nMchFId +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.UpdateHCING( nRawId, dHCI, dDist) + local dOldHCI = EgtGetInfo( nRawId, 'HCING', 'd') or 0 + if dDist and dDist > dOldHCI + 10 then + return + end + if dHCI > dOldHCI then + EgtSetInfo( nRawId, 'HCING', dHCI) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.UpdateTCING( nRawId, dTCI) + local dOldTCI = EgtGetInfo( nRawId, 'TCING', 'd') or 0 + if dTCI > dOldTCI then + EgtSetInfo( nRawId, 'TCING', dTCI) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetNzLimDownUp( b3Raw) + if not BD.C_SIMM then + return EgtIf( b3Raw:getDimZ() < 200, -0.5, -0.258) + else + return -0.484 + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.IsSplittedPartPhase( nPhase) + local sVal = BeamLib.GetPhaseType( nPhase) + return ( sVal == 'END' or sVal == 'MID2' or sVal == 'END2') +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.IsPartFinalPhase( nPhase) + local sVal = BeamLib.GetPhaseType( nPhase) + return ( sVal == 'END' or sVal == 'END2') +end + +--------------------------------------------------------------------- +function BeamLib.GetPhaseType( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '') +end + +------------------------------------------------------------------------------------------------------------- +return BeamLib diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/DiceCut.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/DiceCut.lua new file mode 100644 index 0000000..6f99bad --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/DiceCut.lua @@ -0,0 +1,632 @@ +-- DiceCut.lua by Egaltech s.r.l. 2021/01/21 +-- Gestione dei piano paralleli nei tagli lunghi: equidistanziamento dei piani paralleli + +-- Tabella per definizione modulo +local DiceCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' DiceCut started', 1) + +-- Dati +local BD = require( 'BeamData') + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- creo i piani paralleli +-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptC: il punto centrale del piano della feature +-- vtN: il versore normale del piano della feature +-- nCopyPlane: 0 => genera una copia del piano passato, 1=> non genera una copia del piano passato +-- dOffset: offset dei piani paralleli +-- nStep: numero massimo di step +-- Color: colre del fascio di piani +-- dTolerance*: distanza tra i piani paralleli e i piani di taglio (se non esistono altre superfici può essere omesso) +-- bNoTolOnFirstCut*: elimina la tolleranza per il primo piano del fascio (se non esistono altre superfici può essere omesso) +-- ptCCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +local function GetParallelPlanes( nParent, BBoxRawPart, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) + local ptMyCCut + local AreaMin = 5*5 + if ptCCut and vtNCut then + if dTolerance then + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + ptMyCCut = Point3d( ptCCut) + end + local ptMyCCut1 + if ptCCut1 and vtNCut1 then + ptMyCCut1 = Point3d( ptCCut1 + 0 * vtNCut1) + end + local TabellaTmSurfParallel = {} + local i = nCopyPlane + while i < nStep do + local SurfId = EgtSurfTmPlaneInBBox( nParent, ptC + ( i * dOffset) * vtN, vtN, BBoxRawPart, GDB_RT.GLOB) + local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL) + if nFacet == 0 then + -- se sono al primo taglio do una possibilità in più di girare + if i > nCopyPlane then + break + end + end + if nFacet > 0 and vtNCut and ptMyCCut and EgtSurfArea(SurfId) > AreaMin then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut, -vtNCut, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut, -vtNCut, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and vtNCut1 and ptMyCCut1 and EgtSurfArea(SurfId) > AreaMin then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut1, -vtNCut1, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut1, -vtNCut1, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and EgtSurfArea(SurfId) > AreaMin then + table.insert( TabellaTmSurfParallel, SurfId) + EgtSetColor( SurfId, Color) + else + EgtErase( SurfId) + end + if dOffset == 0 then + break + end + i = i + 1 + end + return TabellaTmSurfParallel +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrderedCutTable: +-- nParent: il layer +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function GetOrderedCutTable( nParent, TabParallelPlanes, TabOrtoPlanes) + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + local TabellaOrderParallelCut1 = {} + + for IndexTmP=1, StepParallel do + TabellaOrderParallelCut1[IndexTmP] = {} + for IndexOrto=1, StepOrto do + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT) + local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + if Copy1Id and ptOrtoN then + EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB) + EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + local nFacet1 = EgtSurfTmFacetCount( Copy1Id) + local nFacet2 = EgtSurfTmFacetCount( Copy2Id) + if nFacet1 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + elseif nFacet2 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + break + else + table.insert( TabellaOrderParallelCut1[IndexTmP], Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + end + end + end + table.insert(TabellaOrderParallelCut1[IndexTmP], TabParallelPlanes[IndexTmP]) + end + return TabellaOrderParallelCut1 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrtoCutCenter: +-- idFacet: l'id della faccia +-- ptC: il punto centrale della faccia +-- vtN: il versore normale della faccia +-- vtO: il versore dei piani ortogonali +-- dOffsetEff: offset della distanza dal punto centrale +-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset +local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dNzLimDwnUp) + local FrameLocal = Frame3d( EgtSurfTmFacetCenter( FacetId, 0, GDB_ID.ROOT)) + EgtSetGridFrame(FrameLocal) + local IdAuxLocal = EgtGroup(EgtGetParent( FacetId), FrameLocal) + EgtSetName( IdAuxLocal, "AuxLocal") + local BoxLocal = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, FrameLocal) + local ptS = EgtGP( EgtSurfTmBBox( IdAuxLocal, BoxLocal, GDB_RT.GRID), GDB_ID.ROOT) + EgtErase( IdAuxLocal) + EgtSetGridFrame(Frame3d()) + -- riferimento intrinseco + local asseX = vtO + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + -- ingombro della faccia secondo questo riferimento + local Box = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, Frame) + local dLen = Box:getDimX() + local dWidth = Box:getDimY() + + -- se faccia non troppo lunga, con un lato piccolo e non diretta troppo verso il basso, non servono dice + local dMaxLen = BD.MAX_LEN_DICE or 600 + if dLen < dMaxLen and dWidth < dMaxLen and + ( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > dNzLimDwnUp then + return nil, nil, nil + end + + local N = ceil( dLen / dOffsetEff) + local dOffsetRel = dLen / N + local dCopyPlane + local dCenOffs = ( Box:getMax():getX() + Box:getMin():getX()) / 2 + + if dLen <= dOffsetRel then + --dOffsetRel = 0 + dCopyPlane = 1 + elseif dLen <= 2 * dOffsetRel then + dOffsetRel = dOffsetEff + dCopyPlane = 0 + else + if N % 2 == 0 then + dCopyPlane = 0 + elseif N % 2 == 1 then + dCopyPlane = 0.5 + end + end + + + return dOffsetRel, dCopyPlane, dCenOffs, ptS +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- TableMesh: +-- TableOrto: tabella delle superfici dei piani ortogonali +-- TableParallel: tabella delle superfici dei piani paralleli +-- Forma una tabella unica delle superfici di taglio inserendo strati di tagli ortogonali alternati da strati di taglio parallelo +local function TableMesh( TableOrto, TableParallel) + local TableUnited = {} + for i=1, #TableOrto do + table.insert( TableUnited, TableOrto[i]) + table.insert( TableUnited, TableParallel[i]) + end + return TableUnited +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- FindValue: +-- tab: tabella da scansionare +-- val: valore da cercare +-- Verifica se tab contiene val, a supporto della funzione SortOrtoCutsByNormalMethod +local function FindValue( tab, val) + for index, value in ipairs( tab) do + if value == val then + return true + end + end + return false +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- SortOrtoCutsByNormalMethod: +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio sfruttando il prodotto dei versori normali (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function SortOrtoCutsByNormalMethod( TabParallelPlanes, TabOrtoPlanes) + -- tabella dei tagli ordinati + local TabOrderOrtoCut = {} + -- tabella ausiliaria dei dati inseriti nell'ordine + local TabAux = {} + -- ciclo di ordinamento + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + for IndexTmP=1, StepParallel do + TabOrderOrtoCut[IndexTmP] = {} + local ptParalN, vtNParalN = EgtSurfTmFacetCenter( TabParallelPlanes[IndexTmP][1], 0, GDB_ID.ROOT) + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- controlla che l'elemento da valutare non sia gia' stato inserito nella tabella + if not FindValue( TabAux, OrtoPlaneId) then + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( OrtoPlaneId, 0, GDB_ID.ROOT) + local scalarProduct = ( ptOrtoN - ptParalN) * vtNParalN + if scalarProduct > 0 then + table.insert( TabOrderOrtoCut[IndexTmP], OrtoPlaneId) + table.insert( TabAux, OrtoPlaneId) + end + end + end + end + end + -- cancello dal DB geometrico i tagli non inseriti + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- ricerco il taglio tra gli inseriti + if not FindValue( TabAux, OrtoPlaneId) then + EgtErase( OrtoPlaneId) + end + end + end + return TabOrderOrtoCut +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- VerifyFirstOrthoCut : +-- CutTable: tabella dei tagli +-- OffsetP: offset della distanza dal punto centrale +-- BBoxRawPart: il grezzo della barra +-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua +local function VerifyFirstOrthoCut( CutTable, OffsetP, BBoxRawPart, dNzLimDwnUp) + + if not CutTable[1] or not CutTable[2] then return end + + local CutOId = CutTable[1][1] + local Cut1Id = CutTable[2][1] + local Cut2Id = CutTable[2][2] + + if CutOId and Cut1Id and Cut2Id then + -- centri e normali delle due semifacce + local ptC1, vtN1 = EgtSurfTmFacetCenter( Cut1Id, 0, GDB_ID.ROOT) + local ptC2, vtN2 = EgtSurfTmFacetCenter( Cut2Id, 0, GDB_ID.ROOT) + -- normale alla faccia ortogonale + local _, vtO = EgtSurfTmFacetCenter( CutOId, 0, GDB_ID.ROOT) + vtO = vtO - vtO * vtN1 * vtN1 ; vtO:normalize() + -- calcolo lunghezza prima semi-faccia + local asseX1 = vtO + local asseY1 = vtN1 ^ asseX1 + local Frame1 = Frame3d( ptC1, ptC1+asseX1, ptC1+asseY1) + local Box1 = EgtGetBBoxRef( Cut1Id, GDB_BB.STANDARD, Frame1) + local x1 = Box1:getDimX() + -- calcolo lunghezza seconda semi-faccia + local asseX2 = vtO + local asseY2 = vtN2 ^ asseX2 + local Frame2 = Frame3d( ptC2, ptC2+asseX2, ptC2+asseY2) + local Box2 = EgtGetBBoxRef( Cut2Id, GDB_BB.STANDARD, Frame2) + local x2 = Box2:getDimX() + -- lunghezza totale faccia + local dLongSize = x1 + x2 + -- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti + if dLongSize <= OffsetP + 1.0 and vtN1:getZ() > dNzLimDwnUp then + local nParent = EgtGetParent( Cut1Id) + local SurfId = EgtSurfTmBySewing( nParent, { Cut1Id, Cut2Id}) + EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) + EgtErase( CutOId) + table.remove( CutTable[1], 1) + table.remove( CutTable[2], 1) + table.remove( CutTable[2], 1) + table.insert( CutTable[2], 1, SurfId) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- ricavo i vertici del box +local function CalcolaPuntiEstremiBox( BBoxRawPart) + local ptMin = BBoxRawPart:getMin() + local ptMax = BBoxRawPart:getMax() + local TBoxPoint = {} + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMin:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMin:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMax:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMax:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMin:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMin:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMax:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMax:getY(), ptMax:getZ()), On = true}) + return TBoxPoint +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- restituisce i punti che devono essere presi in considerazione per la costruzione del BoundingBox +local function VerificaEstremiGrezzo( ptC, vtN, TPoint) + for i = 1, #TPoint do + if ( TPoint[i].P - ptC) * vtN < 0 then + TPoint[i].On = false + end + end + return TPoint +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature +-- le funzioni commentate permettono di vedere la creazione di BoundingBox +local function DistanzaMassima( nParent, ptC1, vtN1, ptC2, vtN2, BBoxRawPart, TPoint) + -- calcolo il riferimento nel piano 1 + local Frame1 = Frame3d( ptC1, vtN1) + -- determino l'ingombro in questo riferimento della parte di trave compresa nel o nei piani + local BB1 = BBox3d() + -- punti di vertice della trave compresi + for i = 1, #TPoint do + if TPoint[i].On then + local ptP = Point3d( TPoint[i].P) + ptP:toLoc( Frame1) + BB1:Add( ptP) + end + end + -- eventuale altra faccia + if ptC2 and vtN2 then + local IdAux = EgtGroup( nParent) + local IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, ptC2, vtN2, BBoxRawPart, GDB_RT.GLOB) + EgtCutSurfTmPlane( IdSurf2, ptC1, -vtN1, false, GDB_RT.GLOB) + if IdSurf2 then + local BB2 = EgtGetBBoxRef( IdSurf2, GDB_BB.STANDARD, Frame1) + BB1:Add( BB2) + end + EgtErase( IdAux) + end + if not BB1:isEmpty() then + return ( BB1:getMax():getZ() + 0.1) + end + + return 0 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- DiceCut.GetDice : +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptCPlanes: il punto centrale del piano della feature +-- vtNPlanes: il versore normale del piano della feature +-- bGetOrtoPlanes*: se voglio calcolare i piani ortogonali al piano passato (se non esistono altre superfici può essere omesso) +-- ptCBond*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNBond*: il versore normale della superfice limitante (se non esistono altre superfici può essere omesso) +-- dOrthoMaxDim : massima profondità taglio se faccia singola perpendicolare facce laterali trave +-- dCustMaxDimDice: dimensione massima customizzata, sostituisce il parametro BD.MAX_DIM_DICE +---------------------------------------------------------------------------------------------------------------------------------------------------- +function DiceCut.GetDice( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, bGetOrtoPlanes, ptCBond, vtNBond, dOrthoMaxDim, dCustMaxDimDice) + + local dMaxDimDice = EgtIf( dCustMaxDimDice and dCustMaxDimDice < BD.MAX_DIM_DICE, dCustMaxDimDice, BD.MAX_DIM_DICE) + local dTolerance = 0 -- distanza di sicurezza per i tagli ortogonali + local OffsetP = dMaxDimDice -- distanza tra i piani paralleli + local StepP = 100 -- numero massimo di piani paralleli da generare + local OffsetO = dMaxDimDice -- distanza tra i piani ortogonali + local StepO = 100 -- numero massimo di piani ortogonali da generare + + --Ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo + local TBoxPoint = CalcolaPuntiEstremiBox( BBoxRawPart) + TBoxPoint = VerificaEstremiGrezzo( ptCPlanes, vtNPlanes, TBoxPoint) + if ptCBond and vtNBond then + TBoxPoint = VerificaEstremiGrezzo( ptCBond, vtNBond, TBoxPoint) + end + local dElevP = DistanzaMassima( nParent, ptCPlanes, vtNPlanes, ptCBond, vtNBond, BBoxRawPart, TBoxPoint) + local dElevO + if ptCBond and vtNBond then + dElevO = DistanzaMassima( nParent, ptCBond, vtNBond, ptCPlanes, vtNPlanes, BBoxRawPart, TBoxPoint) + end + + -- inclinazione limite per taglio da sotto + local dNzLimDwnUp = BL.GetNzLimDownUp( BBoxRawPart) + + -- se normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda + if abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then + OffsetO = dOrthoMaxDim or BD.MAX_DIM_HTCUT + end + + -- aggiungo piccolo extra agli offset + OffsetP = OffsetP + 10 * GEO.EPS_SMALL + OffsetO = OffsetO + 10 * GEO.EPS_SMALL + + -- se seconda faccia non definita, forzo calcolo piani ortogonali + if not ptCBond or not vtNBond then + bGetOrtoPlanes = true + end + + -- se piani non ortogonali, diminuisco la distanza di offset opportunamente + local originalOffsetP = OffsetP + if not bGetOrtoPlanes then + local dCoeff = ( vtNPlanes ^ vtNBond):len() + OffsetP = OffsetP * dCoeff + OffsetO = OffsetO * dCoeff + end + + local n = ceil( dElevP / OffsetP) + OffsetP = dElevP / n + if dElevO then + local m = ceil( dElevO / OffsetO) + OffsetO = dElevO / m + end + + -- elenco di tutte le superfici generate dai tagli + local TabFUCHSIA = {} + local TabGREEN = {} + + -- PIANI PARALLELI alla faccia di taglio + local TabellaTmSurfP = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, 0, OffsetP, StepP, Color3d( FUCHSIA(), 60), dTolerance, true, ptCBond, vtNBond) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfP, TabFromIn[i]) + end + + -- PIANI ORTOGONALI alla faccia di taglio + -- orientamento definito da seconda faccia + if not bGetOrtoPlanes then + local TabellaTmSurfOrto = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCBond, vtNBond, 0, OffsetO, StepO, Color3d( GREEN(), 60), dTolerance, false, ptCPlanes, vtNPlanes) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfOrto, TabFromIn[i]) + end + local TabellaOrderParallelCut = GetOrderedCutTable( nParent, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati + local TabellaOrderOrtoCut = GetOrderedCutTable( nParent, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato + + TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato + TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati + + -- orientamento da definire + else + for PlnInd = 1, #TabellaTmSurfP do + -- piano interno + local ptCInner, vtNInner = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd], 0, GDB_ID.ROOT) + -- eventuale piano esterno + local ptCOuter, vtNOuter = nil, nil + if PlnInd > 1 then + ptCOuter, vtNOuter = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd-1], 0, GDB_ID.ROOT) + vtNOuter = -vtNOuter + end + -- calcolo la direzione dei piani ortogonali + local vtO = VectorFromUprightOrtho( vtNInner) + if vtNInner:getZ() > -0.0175 or vtNInner:getZ() < dNzLimDwnUp or abs( vtNInner:getY()) > 0.8 then + vtO:rotate( vtNInner, 90) + -- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente + if abs( vtO:getY()) > 1.5 * abs( vtO:getX()) and vtNInner:getZ() > dNzLimDwnUp then + vtO:rotate( vtNInner, 90) + -- se faccia principale verso il basso (almeno -3deg), lo inverto per iniziare da sopra + if vtNInner:getZ() < -0.05 then + vtO = -vtO + end + else + if ptCInner:getX() > BBoxRawPart:getCenter():getX() then + if vtO:getX() < 0 then vtO = - vtO end + else + if vtO:getX() > 0 then vtO = - vtO end + end + end + end + -- calcolo le dimensioni dell'offset e dove posizionare la prima faccia: + -- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato + -- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato + -- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero + local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, OffsetO, dNzLimDwnUp) + + if OffsetRel and CopyPlane and dCenOffs then + ptCInner = ptCInner + dCenOffs * vtO + local TabRight = GetParallelPlanes( nParent, BBoxRawPart, ptCStart, vtO, CopyPlane, -OffsetRel, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + if CopyPlane == 0 then + CopyPlane = 1 + end + local TabLeft = GetParallelPlanes( nParent, BBoxRawPart, ptCStart, vtO, CopyPlane, OffsetRel, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + -- carico la tabella con gli indici riordinati + local TempOrtoTab = {} + for i = #TabLeft, 1, -1 do + table.insert( TempOrtoTab, TabLeft[i]) + end + for i = 1, #TabRight do + table.insert( TempOrtoTab, TabRight[i]) + end + -- creo una tabella per ogni piano per generare i tagli sulla Inner + local TempParTab = GetOrderedCutTable( nParent, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) + for i = 1, #TempParTab do + table.insert( TabFUCHSIA, TempParTab[i]) + end + table.insert( TabGREEN, TempOrtoTab) + else + table.insert( TabFUCHSIA, {TabellaTmSurfP[PlnInd]}) + table.insert( TabGREEN, {}) + end + end + end + + -- Se sono state costruite non più di una faccia parallela e una faccia perpendicolare, allora non servono e tengo le originali + if #TabGREEN == 1 and #TabGREEN[1] <= 1 and #TabFUCHSIA == 1 and #TabFUCHSIA[1] <= 1 then + if #TabGREEN[1] == 1 then + EgtErase( TabGREEN[1][1]) + end + TabGREEN = {} + if #TabFUCHSIA[1] == 1 then + EgtErase( TabFUCHSIA[1][1]) + end + TabFUCHSIA = {} + end + + -- Si uniscono le tabelle dei tagli ortogonali e paralleli in una sola tabella + local UltimateTable = TableMesh( TabGREEN, TabFUCHSIA) + + -- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato + if not bGetOrtoPlanes then + VerifyFirstOrthoCut( UltimateTable, originalOffsetP, BBoxRawPart, dNzLimDwnUp) + end + + return UltimateTable +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- PrintOrderCut: +-- TabellaOrderCut: tabella delle superfici di taglio +-- stampo l'ordine dei piani di taglio ricevendo una tabella con gli strati parallelo/ortogonali già ordinati +function DiceCut.PrintOrderCut( TabellaOrderCut) + local Step = #TabellaOrderCut + if Step > 0 then + EgtOutLog( " L'ordine delle superfici da tagliare è il seguente:") + else + EgtOutLog( ' Non sono necessarie superfici aggiuntive di taglio.') + end + for i = 1, Step do + if i % 2 == 1 then + EgtOutLog( ' *** Strato di taglio ' .. EgtNumToString( ( i + 1) / 2, 0)) + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli ortogonali: ') + else + EgtOutLog( ' Tagli ortogonali assenti') + end + else + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli paralleli: ') + else + EgtOutLog( ' Tagli paralleli assenti') + end + end + for j=1, #TabellaOrderCut[i] do + EgtOutLog( ' Indice faccia ' .. (TabellaOrderCut[i][j] or 0)) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +local function DiceCutTest() + + -- salvo l'indice del layer Trimesh selezionato + local SelectedIndex = EgtGetFirstSelectedObj() + -- verifico che sia selezionato un elemento + if not SelectedIndex then return end + + -- salvo l'indice del layer Processing + local nParent = EgtGetParent( SelectedIndex) + -- salvo l'indice del layer Part + local nRawPart = EgtGetParent( nParent) + local nBox = EgtGetFirstNameInGroup( nRawPart, 'Box') + -- carico il bounding box della trave + -- local BBoxRawPart = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD ) + local BBoxRawPart = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD ) + -- seleziono il Part e il Layer di destinazione + EgtSetCurrPartLayer( nRawPart, nParent) + + -- conto il numero di facce da processare + local nFacet = EgtSurfTmFacetCount( SelectedIndex) + EgtOutLog( ' Numero facce ' .. nFacet, 1) + + -- salvo + local TabPlanesFeatures = {} + for i = 1, nFacet do + local ptC, vtN = EgtSurfTmFacetCenter( SelectedIndex, i - 1, GDB_ID.ROOT) + table.insert( TabPlanesFeatures, { ptC = ptC, vtN = vtN}) + end + local ptC1 = Point3d( TabPlanesFeatures[1].ptC) + local vtN1 = Vector3d( TabPlanesFeatures[1].vtN) + + local CutTable = {} + if nFacet == 1 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, true) + elseif nFacet == 2 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN) + end + + if EgtGetDebugLevel() > 1 then + DiceCut.PrintOrderCut( CutTable) + end + + EgtDeselectAll() + + EgtDraw() +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +--DiceCutTest() + +return DiceCut diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/FacesBySaw.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/FacesBySaw.lua new file mode 100644 index 0000000..718d54e --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/FacesBySaw.lua @@ -0,0 +1,170 @@ +-- FacesBySaw.lua by Egaltech s.r.l. 2020/11/13 +-- Gestione taglio con lama di feature con una, due o tre facce + +-- Tabella per definizione modulo +local FacesBySaw = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' FacesBySaw started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +function FacesBySaw.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, sCutName) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico il numero di facce della tacca + if Proc.Fct < 2 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw facet number not supported' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero dati su giunzione tra facce + local bTouch, ptT1, ptT2, dAngT = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if not bTouch then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw faces not touching' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo direzione di lavoro + local vtRef = {} + local vtTg = ptT2 - ptT1 ; + vtRef[1] = vtN[1] ^ vtTg + if vtRef[1] * vtN[2] < 0 then vtRef[1] = - vtRef[1] end + vtRef[2] = vtN[2] ^ vtTg + if vtRef[2] * vtN[1] < 0 then vtRef[2] = - vtRef[2] end + -- determino quale faccia è più grande + local ptPs = ( ptT1 + ptT2) / 2 + local dSqDim1 = ( ptC[1] - ptPs):sqlen() + local dSqDim2 = ( ptC[2] - ptPs):sqlen() + local nBigInd = EgtIf( dSqDim1 >= dSqDim2, 1, 2) + local nSmaInd = 3 - nBigInd + local nUpInd = EgtIf( vtN[1]:getZ() >= vtN[2]:getZ(), 1, 2) + local nOtInd = 3 - nUpInd + -- metto in relazione la scelta facce con il confronto del versore Z con la scelta in base alla grandezza faccia + -- se la faccia più grande è messa secondaria e il suo versore Z non è negativo + if nOtInd == nBigInd and vtN[nBigInd]:getZ() > -( 5 * GEO.EPS_SMALL) and vtN[nSmaInd]:getZ() < 0.866 then + nOtInd = nSmaInd + nUpInd = nBigInd + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( sCutName) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 5 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- calcolo extra taglio + local dCutExtra = 0 + if dAngT < -91 and dAngT > -179 then + dCutExtra = - dSawThick / tan( 180 + dAngT) + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nUpInd], vtN[nUpInd], false, ptC[nOtInd], vtN[nOtInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- assegno il modo di tagliare + local vtOrthO = EgtIf( ( i % 2) == 1, vtRef[nOtInd], vtRef[nUpInd]) + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthO, nil, dCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + nUpInd = EgtIf( vtN[1]:getZ() >= vtN[2]:getZ(), 1, 2) + nOtInd = 3 - nUpInd + -- se prima faccia lavorata è da sotto scambio le facce + if vtN[nOtInd]:getZ() < -0.5 then + nUpInd, nOtInd = nOtInd, nUpInd + end + -- lavoro la prima faccia + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, nOtInd-1, sCutting, dSawDiam, vtRef[nOtInd], nil, dCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + -- lavoro seconda faccia + bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, nUpInd-1, sCutting, dSawDiam, vtRef[nUpInd], nil, dCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + elseif Proc.Box:getCenter():getX() > b3Solid:getCenter():getX() then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + local dDist = b3Solid:getMax():getX() - Proc.Box:getMax():getX() + BL.UpdateHCING( nRawId, dOffs, dDist) + end + end + return true +end + +--------------------------------------------------------------------- +function FacesBySaw.MakeThree( Proc, nPhase, nRawId, nPartId, sCutName) + return false +end + +return FacesBySaw \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/MachiningLib.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/MachiningLib.lua new file mode 100644 index 0000000..1a28162 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/MachiningLib.lua @@ -0,0 +1,126 @@ +-- MachiningLib.lua by Egaltech s.r.l. 2020/11/13 +-- Libreria ricerca lavorazioni per Travi + +-- Tabella per definizione modulo +local MachiningLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' MachiningLib started', 1) + +-- Dati +local BD = require( 'BeamData') +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, dMaxDiam) + 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() + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + if ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and + ( not sTuuidMstr or sTuuidMstr == sTuuid) and + ( not dMaxDiam or dTDiam < dMaxDiam + GEO.EPS_SMALL) then + return Milling.Name, dTMaxDepth, dTDiam + 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, dDepth, bDown) + -- ricerca sulle forature, dal diametro maggiore al minore + local sDrType = 'Drill' .. EgtIf( bDown, '_H2', '') + for i = #Drillings, 1, -1 do + local Drilling = Drillings[i] + if Drilling.On and Drilling.Type == sDrType and SetCurrMachiningAndTool( Drilling.Name) then + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + local dMaxToolLength = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + local dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dDiamTh = EgtTdbGetCurrToolThDiam() + local dLenTh = 72 + if EgtTdbGetCurrToolThLength then dLenTh = EgtTdbGetCurrToolThLength() end + local dFreeLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) - dLenTh - EgtMdbGetGeneralParam( MCH_GP.MAXDEPTHSAFE) + if dTDiam < dDiam + 10 * GEO.EPS_SMALL and dTDiam > dDiam - BD.DRILL_TOL - 10 * GEO.EPS_SMALL then + if not dDepth or dTMaxMat > dDepth - GEO.EPS_SMALL then + return Drilling.Name, Drilling.Type, dTMaxMat, dMaxToolLength, dToolDiam, dDiamTh, dFreeLen + end + end + end + end + -- ricerca sulle svuotature, dal diametro maggiore al minore + local sPkType = 'Pocket' .. EgtIf( bDown, '_H2', '') + for i = #Drillings, 1, -1 do + local Drilling = Drillings[i] + if Drilling.On and Drilling.Type == sPkType and SetCurrMachiningAndTool( Drilling.Name) then + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxDepth = EgtTdbGetCurrToolMaxDepth() + local dMaxToolLength = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + local dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dDiamTh = EgtTdbGetCurrToolThDiam() + local dFreeLen = dTMaxDepth + if dTDiam < dDiam - 10 * GEO.EPS_SMALL then + if not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL then + return Drilling.Name, Drilling.Type, dTMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dFreeLen + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +return MachiningLib diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessBlockHausFront.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessBlockHausFront.lua new file mode 100644 index 0000000..9a002ab --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessBlockHausFront.lua @@ -0,0 +1,306 @@ +-- ProcessBlockHausFront.lua by Egaltech s.r.l. 2020/08/03 +-- Gestione calcolo giunzione block house in testa + +-- Tabella per definizione modulo +local ProcessBlockHausFront = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessBlockHausFront started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessBlockHausFront.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 38) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessBlockHausFront.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + -- do errore perchè non è ancora gestita la rotazione di 90° + -- considerazioni: al momento non è possibile sapere se ci sono due rastremature o una quindi se è rivolta verso il basso + -- viene dato errore, altrimenti si potrebbe imporre la rotazione di 180 (ovviamente con una sola rastrematura rivolta verso il basso) + if abs(vtN:getZ()) > abs(vtN:getX()) and abs(vtN:getZ()) > abs(vtN:getY()) and vtN:getZ() < -0.5 then + return false + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessBlockHausFront.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + local dMinZedFace = 1 + for i = 1, nFacetCnt do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinZedFace then + dMinZedFace = dXVal + vFaceOrd[3] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + bHead = ( vtN[vFaceOrd[1]]:getX() > 0) + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- recupero la geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato + local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), 'b') + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + local dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < (#vCuts-1) or (i == #vCuts) then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 00 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + -- altrimenti di fianco + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + -- altrimenti di fianco + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessBlockHausFront diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessChamfer.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessChamfer.lua new file mode 100644 index 0000000..b44c13a --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessChamfer.lua @@ -0,0 +1,193 @@ +-- ProcessChamfer.lua by Egaltech s.r.l. 2020/09/01 +-- Gestione calcolo profilo libero per Travi + +-- Tabella per definizione modulo +local ProcessChamfer = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessChamfer started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessChamfer.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 36) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessChamfer.Make( Proc, nPhase, nRawId, nPartId) + -- verifico se ha geometria ausiliaria (onde) + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Chamfer') + 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 dMillDiam = 10 + local dMaxMat = 20 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + end + + -- se onde + if AuxId then + -- inserisco la lavorazione + local sName = 'Chm_' .. ( 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 + -- impongo lavorazione dall'alto + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- lavoro tenendo l'utensile a sinistra + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto lavorazione a metà tagliente e senza step + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat / 2) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto attacchi e uscite + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, 3) + EgtSetMachiningParam( MCH_MP.LITANG, 6) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- altrimenti smusso standard + else + -- normale ed elevazione della faccia principale + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + local _, dElev = BL.GetPointDirDepth( nPartId, ptC, vtN) + local bFront = ( vtN:getY() < 0) + -- limitazioni su inizio e fine derivanti da altre facce + local bLimXmin = false + local bLimXmax = false + if Proc.Fct >= 3 then + bLimXmin = true + bLimXmax = true + elseif Proc.Fct >= 2 then + local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if vtN1:getX() > 0 then + bLimXmin = true + else + bLimXmax = true + end + end + -- calcolo eventuali accorciamenti per facce limitanti + local dAllExtr + if dElev < dMillDiam / 2 then + dAllExtr = -sqrt( dMillDiam * dElev - dElev * dElev) + else + dAllExtr = -dMillDiam / 2 + end + local dStartAll = 0 + local dEndAll = 0 + if vtN:getY() < 0 then + if bLimXmax then dStartAll = dAllExtr end + if bLimXmin then dEndAll = dAllExtr end + else + if bLimXmax then dEndAll = dAllExtr end + if bLimXmin then dStartAll = dAllExtr end + end + -- determino numero di parti + local dLen = Proc.Box:getDimX() + -- calcolo la differenza tra lunghezza faccia 0 e lunghezza feature + -- per far corrispondere i punti di inizio-fine delle lavorazioni multiple (a passi) + local dAddLen = (( dH - dLen) / EgtIf( bLimXmax and bLimXmin , 2, 1)) + local dStartAccDist = BD.LONGCUT_ENDLEN + local dEndAccDist = BD.LONGCUT_ENDLEN + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + dC = dLen / ( nC + 2) + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + dC = dLen / 2 + else + nC = 1 + dC = 0 + end + end + -- eseguo le diverse parti + for i = 1, nC do + -- inserisco la lavorazione + local sName = 'Chm_' .. ( 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 + -- lavoro tenendo l'utensile a sinistra + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto lavorazione un poco sotto + local sDepth = 'TH+'..EgtNumToString( BD.CUT_EXTRA) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, sDepth) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- imposto attacchi e uscite + local dSal, dEal + if bFront then + dSal = EgtIf( i == 1, dStartAll, -( i - 1) * dC - dAddLen + 0.5) + dEal = EgtIf( i == nC, dEndAll, -( nC - i) * dC - dAddLen + 0.5) + else + dSal = EgtIf( i == nC, dStartAll, -( nC - i) * dC - dAddLen + 0.5) + dEal = EgtIf( i == 1, dEndAll, -( i - 1) * dC - dAddLen + 0.5) + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.LIPERP, dMillDiam / 4) + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + local nSCC = EgtIf( ( BD.C_SIMM or i == 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + + return true +end + +--------------------------------------------------------------------- +return ProcessChamfer diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessCut.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessCut.lua new file mode 100644 index 0000000..cdda749 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessCut.lua @@ -0,0 +1,503 @@ +-- ProcessCut.lua by Egaltech s.r.l. 2021/01/20 +-- Gestione calcolo singoli tagli di lama per Travi + +-- Tabella per definizione modulo +local ProcessCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local LongCut = require( 'ProcessLongCut') + +EgtOutLog( ' ProcessCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessCut.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessCut.Classify( Proc, b3Raw) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN:getZ() <= - 0.5 and abs( vtN:getY()) > 0.1 then + local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0) + if DimH > BD.MAX_DIM_DICE then + return true, true + end + end + -- verifico se c'è un taglio da sotto e se è nei limiti + local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw) + local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) + if bDownCut then + local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0) + -- confronto anche qua la distanza maggiore della faccia con la massima distanza del DiceCut + -- e se il rapporto supera il 2 (implica che genera 3 tagli) dichiaro impossibile la lavorazione + if DimH and BD.MAX_DIM_DICE and abs( BD.MAX_DIM_DICE) > 20 * GEO.EPS_SMALL and abs( DimH / BD.MAX_DIM_DICE) > 2 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Piano di taglio della feature +function ProcessCut.GetCutPlane( Proc) + if ProcessCut.Identify( Proc) then + return EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + else + return nil, nil + end +end + +--------------------------------------------------------------------- +-- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) +local function VerifyCurveForChamfer( AuxId) + if not AuxId then + return -2 + end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + return -1 + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- va bene solo se direzione estrusione orizzontale + if abs( vtExtr:getZ()) > 0.1 then + return 0 + end + return 1 +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico le entità curva associate (max 2) + local sVal = EgtGetInfo( Proc.Id, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local AuxId, Aux2Id + if vsAuxId and #vsAuxId >=1 then + AuxId = tonumber( vsAuxId[1]) + end + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if AuxId then AuxId = AuxId + Proc.Id end + if Aux2Id then Aux2Id = Aux2Id + Proc.Id end + local nRes = VerifyCurveForChamfer( AuxId) + if nRes == 0 and Aux2Id then + AuxId = Aux2Id + nRes = VerifyCurveForChamfer( AuxId) + end + if nRes == -2 then + return true + end + if nRes == -1 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + if nRes == 0 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true, nil +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) + if bFromBottom == nil then bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtN:getZ() > 0.25) end + local bFillAreaPiece + local bFillTail + -- se taglio di testa + if Proc.Head then + -- se coincide con il taglio di separazione precedente, non va fatto + if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- altrimenti taglio di coda + else + -- se coincide con taglio di separazione, non va fatto + if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + end + -- se coincide con un taglio frontale non va fatto + if Proc.CutFront then + return true + end + -- se pezzo ancora attaccato alla trave, per non rovinare quello successivo + if not BL.IsSplittedPartPhase( nPhase) then + -- se non da sotto + if not bDownCut then + bFillAreaPiece = bCustDiceCut + -- se true il controllo è già stato fatto dal modulo che ha chiamato il ProcessCut + if not bFillAreaPiece then + -- se poco inclinata ( inclinazione inferiore a 21.56 deg) + if vtN:getZ() > 0.93 then + -- se la faccia occupa tutta la trave in X e Y o occupa sicuramente la faccia in Y e almeno 3/4 della lunghezza in X e sborda in X e non interessa la faccia inferiore, + -- si possono far partire i tagli a cubetti dalla testa o lasciare il cordoncino centrale + if ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) or + ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) and + ( Proc.Box:getDimX() > 0.75 * b3Solid:getDimX() or Proc.Box:getDimX() > 1500.000))) and + abs( Proc.Box:getMin():getY() - b3Solid:getMin():getY()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getY() - b3Solid:getMax():getY()) < 10*GEO.EPS_SMALL and + b3Solid:getMin():getZ() < Proc.Box:getMin():getZ() - 100 * GEO.EPS_SMALL then + bFillAreaPiece = true + end + -- se praticamente verticale di fianco ( inclinazione inferiore a 21.56deg) + elseif abs( vtN:getY()) > 0.93 then + -- se la faccia occupa tutta la trave in X e Z o occupa sicuramente la faccia in Z e almeno 3/4 della faccia in X e sborda in X, + if ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) or + ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) and + Proc.Box:getDimX() > 0.75 * b3Solid:getDimX())) and + abs( Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getZ() - b3Solid:getMax():getZ()) < 10*GEO.EPS_SMALL then + local sErr = 'Error : Impossible to machine by orientation (on side)' + EgtOutLog( sErr) + return false, sErr + end + end + end + -- se quasi orizzontale ( inclinazione inferiore a 30) + if vtN:getZ() > 0.866 then + -- se la faccia termina davanti o dietro la trave e arriva in coda e non interessa la faccia inferiore, forzo il taglio a cubetti a partire dal davanti + if ( abs( Proc.Box:getMin():getY() - b3Solid:getMin():getY()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getY() - b3Solid:getMax():getY()) < 10*GEO.EPS_SMALL) and + abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and b3Solid:getMin():getZ() < Proc.Box:getMin():getZ() - 100 * GEO.EPS_SMALL then + bFillTail = true + end + -- se verticale quasi completamente di fianco ( inclinazione inferiore a 30) + elseif abs( vtN:getY()) > 0.866 then + -- se la faccia termina davanti o dietro la trave e arriva in coda e non interessa la faccia inferiore, forzo il taglio a cubetti a partire dal davanti + if ( abs( Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getZ() - b3Solid:getMax():getZ()) < 10*GEO.EPS_SMALL) and + abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL then + local sErr = 'Error : Impossible to machine by orientation (on side)' + EgtOutLog( sErr) + return false, sErr + end + end + end + end + -- se ho il parametro Q04 = 1 e il taglio copre la lunghezza della trave allora lancio il processo dell'L10 + local nAsLongCut = EgtGetInfo( Proc.Id, 'Q04', 'i') or 0 + if nAsLongCut == 1 and bFillAreaPiece then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, true) + end + -- se vero taglio, eventuale inserimento smussi + if Proc.Prc == 10 then + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( Proc.Head, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 2 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + local dMaxVertDepth = dMaxDepth - ( BD.DECR_VERT_CUT or 0) + -- determino la direzione di taglio preferenziale + local _, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0) + local bHorizCut = (( dCutV < dMaxVertDepth - BD.CUT_EXTRA and dCutH > dMaxDepth - BD.CUT_EXTRA) and not bDownCut) + -- verifico se necessari tagli supplementari + EgtOutLog( string.format( 'MaxDepth=%.1f MaxVertDepth=%.1f CutH=%.1f CutV=%.1f', dMaxDepth, dMaxVertDepth, dCutH, dCutV), 3) + local vCuts = {} + if dCutH > dMaxDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC or dCutV > dMaxVertDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC then + local ptExtra, vtExtra + local bAutoCalcSurf = true + if bFillAreaPiece or bFillTail then + local ptMiddle = ( b3Solid:getMin() + b3Solid:getMax()) / 2 + ptExtra = Point3d( b3Solid:getMin():getX() + 5*GEO.EPS_SMALL, ptMiddle:getY(), ptMiddle:getZ()) + vtExtra = X_AX() + bAutoCalcSurf = false + end + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxDepth - BD.CUT_EXTRA) + -- se taglio sborda in coda e non è stato inserito nessun taglio a cubetti, lo rilancio con le dimensioni customizzate + if ( bFillTail or bCustDiceCut) and #vCuts == 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxDepth - BD.CUT_EXTRA, Proc.Box:getDimY()) + end + end + -- se il ProcessCut viene lanciato dal ProcessSawCut e non ci sono tagli a cubetti, esco + if bCustDiceCut and #vCuts == 0 then + return false, -1 + end + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + local bOrthInv = false + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + if ( i % 2) == 1 then + local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) + if ( vtN:getY() > 0.707 and vtO:getY() < -0.05) or + ( vtN:getY() < -0.707 and vtO:getY() > 0.05) then + EgtInvertSurf( vCuts[i][j]) + bOrthInv = true + end + end + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local vtOrthoO + local bNoPerpCuts = false + if i % 2 == 1 then + vtOrthoO = Vector3d( vtN) + else + local vtO + if #vCuts[i-1] > 0 then + vtO = EgtSurfTmFacetNormVersor( vCuts[i-1][1], 0, GDB_ID.ROOT) + elseif vCuts[i+1] and #vCuts[i+1] > 0 then + -- lunghezza faccia nell'eventuale direzione ortogonale + local asseX = EgtSurfTmFacetNormVersor( vCuts[i+1][1], 0, GDB_ID.ROOT) + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + local b3Fac = EgtGetBBoxRef( vCuts[i][1], GDB_BB.STANDARD, Frame) + -- se lunghezza inferiore al limite, accetto la direzione + if b3Fac:getDimX() < dMaxDepth - BD.CUT_EXTRA then + vtO = asseX + else + bNoPerpCuts = true + end + else + bNoPerpCuts = true + end + if vtO then + vtOrthoO = Vector3d( vtO) * EgtIf( bOrthInv, -1, 1) + else + if bHorizCut then + vtOrthoO = Z_AX() + elseif vtN:getY() > -0.02 then + if not Proc.Head then + vtOrthoO = -Y_AX() + else + vtOrthoO = Y_AX() + end + else + vtOrthoO = -Y_AX() + end + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se taglio dal basso + if bDownCut then + -- se strato pari composto da 1 o 2 elementi + if ( i % 2) == 0 and #vCuts[i] <= 2 then + -- il primo elemento prende la direzione prevista, il secondo quella opposta + local vtNewOrthoO = Vector3d( vtOrthoO) + local dVzLimDwnUp = dNzLimDwnUp + if j ~= 1 then + vtNewOrthoO = -vtOrthoO + if not BD.C_SIMM then dVzLimDwnUp = -0.707 end + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtNewOrthoO, dVzLimDwnUp, BD.CUT_EXTRA_MIN, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- tutti gli altri casi vengono saltati + -- caso generale + else + -- in generale sta sollevato di pochissimo + local dExtraCut = -0.1 + -- se tagli paralleli + if ( i % 2) == 0 then + -- se non ci sono tagli ortogonali devo affondare + if bNoPerpCuts then + dExtraCut = BD.CUT_EXTRA + -- se altrimenti tagli ortogonali invertiti, devo approfondire dello spessore lama + elseif bOrthInv then + dExtraCut = dSawThick + -- se ultimo taglio, devo affondare + elseif j == #vCuts[i] then + dExtraCut = BD.CUT_EXTRA + end + end + local dVzLimDwnUp = dNzLimDwnUp + if not BD.C_SIMM and vtN:getZ() > 0.707 then dVzLimDwnUp = -0.708 end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, dVzLimDwnUp, dExtraCut, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + end + -- altrimenti tagli diretti della faccia + else + -- tagli molto di lato e inclinati sono permessi fino a -45deg + if abs( vtN:getX()) < 0.5 then dNzLimDwnUp = -0.707 end + -- lavoro la faccia + local vtOrthoO + if bFromBottom and dCutV < dMaxVertDepth - BD.CUT_EXTRA and vtN:getZ() > 0 then + vtOrthoO = -Z_AX() + elseif bHorizCut then + vtOrthoO = Z_AX() + elseif b3Solid:getDimX() < BD.LEN_SHORT_PART and abs( vtN:getY()) > 0.259 and vtN:getZ() > -0.174 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then + if Proc.Head then + vtOrthoO = X_AX() + else + vtOrthoO = -X_AX() + end + elseif vtN:getZ() < dNzLimDwnUp and abs( vtN:getY()) > 0.259 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then + if Proc.Head then + vtOrthoO = X_AX() + else + vtOrthoO = -X_AX() + end + elseif vtN:getY() > -0.02 then + if Proc.Head then + vtOrthoO = -Y_AX() + else + vtOrthoO = Y_AX() + end + else + if Proc.Head then + vtOrthoO = Y_AX() + else + vtOrthoO = -Y_AX() + end + end + -- taglio + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, dNzLimDwnUp, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda (se non chiamata da altre feature) + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if ProcessCut.Identify( Proc) and Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtN:getZ() > 0.5 then + dOffs = dOffs - 0.6 * Proc.Box:getDimX() + elseif vtN:getZ() < -0.5 then + dOffs = dOffs - 0.2 * Proc.Box:getDimX() + elseif ( abs( vtN:getY()) > 0.9 and vtN:getZ() > 0.2) then + dOffs = dOffs - 0.3 * Proc.Box:getDimX() + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtN:getZ() > 0.5 then + dOffs = dOffs - 0.6 * Proc.Box:getDimX() + elseif vtN:getZ() < -0.5 then + dOffs = dOffs - 0.2 * Proc.Box:getDimX() + elseif ( abs( vtN:getY()) > 0.9 and vtN:getZ() > 0.2) then + dOffs = dOffs - 0.3 * Proc.Box:getDimX() + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessCut diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDecor.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDecor.lua new file mode 100644 index 0000000..4a7ecd8 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDecor.lua @@ -0,0 +1,81 @@ +-- ProcessDecor.lua by Egaltech s.r.l. 2018/04/18 +-- Gestione calcolo decoro per Travi + +-- Tabella per definizione modulo +local ProcessDecor = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDecor started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDecor.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 959) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDecor.Classify( Proc) + -- recupero i dati della decorazione + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico sia una decorazione + if not vtExtr then + return false + end + -- verifico se la decorazione è lavorabile solo da sotto + local bDown = (( vtExtr:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDecor.Make( Proc, nPhase, nRawId, nPartId) + -- recupero i dati della decorazione + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico che la decorazione non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Decor from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sToFind = EgtGetInfo( Proc.Id, 'P15') + local sMilling = ML.FindMilling( sToFind) + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessDecor diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDoubleCut.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDoubleCut.lua new file mode 100644 index 0000000..4517370 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDoubleCut.lua @@ -0,0 +1,299 @@ +-- ProcessDoubleCut.lua by Egaltech s.r.l. 2021/12/25 +-- Gestione calcolo doppi tagli di lama per Travi + +-- Tabella per definizione modulo +local ProcessDoubleCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessDoubleCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDoubleCut.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 11) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDoubleCut.Classify( Proc, b3Raw) + --se una faccia, uso la classificazione dei tagli singoli + if Proc.Fct == 1 then return Cut.Classify( Proc, b3Raw) end + -- verifico se convesso + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = ( not bAdj or ( dAng > 0)) + if bConvex then return true, false end + -- verifico le normali delle facce per tagli da sotto + local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw) + for i = 1, 2 do + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) + if bDownCut then + -- dimensione della faccia perpendicolare alla linea di intersezione tra le facce + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, 2-i, GDB_ID.ROOT) + local vtX = vtN2 ^ vtN + local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2) + local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, i-1, GDB_BB.STANDARD, frRef) + if b3Ref:getDimY() > BD.MAX_DIM_DICE then + return true, true + end + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId then return true end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDoubleCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- se singola faccia, passo a quella lavorazione + if Proc.Fct == 1 then return Cut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- se convesso, lo tratto come due tagli singoli + if bConvex then + -- lavoro per prima la faccia più diretta in alto + local vOrd = { 1, 2} + if vtN[2]:getZ() > vtN[1]:getZ() then + vOrd = { 2, 1} + end + -- creo piano di taglio coincidente con la prima faccia e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[1]], vtN[vOrd[1]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + local b3Add = EgtGetBBoxGlob( AddId, GDB_BB.STANDARD) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = 10, Box = b3Add, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + end + -- creo piano di taglio coincidente con la seconda faccia e lo lavoro + AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[2]], vtN[vOrd[2]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + local b3Add = EgtGetBBoxGlob( AddId, GDB_BB.STANDARD) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = 10, Box = b3Add, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + end + -- altrimenti concavo + else + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- aggiorno nome e info + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local vtOrthOpp = vtN[nBigInd] + local vtNorm = vtN[nSmaInd] + if ( i % 2) ~= 1 then vtOrthOpp, vtNorm = vtNorm, vtOrthOpp end + if not bOnY then vtOrthOpp[2] = 0 end + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtOrthOpp, vtNorm) + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, EgtIf( bHead, 'HeadSide', 'TailSide')) + if not bOk then + return bOk, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda (se non convesso, altrimenti già fatto nei tagli singoli) + if not bConvex then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.4 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.4 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessDoubleCut diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDovetail.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDovetail.lua new file mode 100644 index 0000000..77e9400 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDovetail.lua @@ -0,0 +1,1777 @@ +-- ProcessDovetail.lua by Egaltech s.r.l. 2020/10/14 +-- Gestione calcolo giunzione coda di rondine + +-- Tabella per definizione modulo +local ProcessDovetail = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessDovetail started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sUseRoughTool = '' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDovetail.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 138) +end + +--------------------------------------------------------------------- +local function AssignQValues( Proc) + + -- reset delle variabili assegnazione parametri Q + sUseRoughTool = '' + + if Proc.Prc == 138 then + sUseRoughTool = 'Q02' -- d + end +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc, sUseRoughTool) + + local bForceUseRough = false + -- verifico se devo usare il truciolatore + -- 2020-03-20 forzata disabilitazione uso truciolatore se parametro Q non è presente + if #sUseRoughTool == 0 or EgtGetInfo( Proc.Id, sUseRoughTool, 'i') == 2 then + bForceUseRough = true + end + + return bForceUseRough +end + +--------------------------------------------------------------------- +local function OrderFaces( Proc, vtN) + + local dMinXFace = 0.99 + local dPosXFace = 0 + local dNegXFace = 0 + local vFaceOrd = { 0, 0, 0} + + -- se 2 facce : ordine (1=0, 2=interna, 3=intermedia) + if #vtN <= 2 then + for i = 1, #vtN do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinXFace then + dMinXFace = dXVal + vFaceOrd[3] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, #vtN do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- se 3 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia) + elseif #vtN == 3 then + for i = 1, #vtN do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinXFace then + dMinXFace = dXVal + vFaceOrd[3] = i + end + if dXVal > dPosXFace then + dPosXFace = dXVal + vFaceOrd[2] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + if vFaceOrd[2] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing internal face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, #vtN do + if i ~= vFaceOrd[3] and i ~= vFaceOrd[2] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + vFaceOrd[1] = i + end + end + end + -- se 4 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia, 4=esterna) + else + for i = 1, #vtN do + if vtN[i]:getX() > dPosXFace then + dPosXFace = vtN[i]:getX() + vFaceOrd[2] = i + end + if vtN[i]:getX() < dNegXFace then + dNegXFace = vtN[i]:getX() + vFaceOrd[4] = i + end + end + if vFaceOrd[2] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing internal face' + EgtOutLog( sErr) + return false, sErr + end + if vFaceOrd[4] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing external face' + EgtOutLog( sErr) + return false, sErr + end + local nMidFace = 3 + for i = 1, #vtN do + if i ~= vFaceOrd[2] and i ~= vFaceOrd[4] then + vFaceOrd[nMidFace] = i + nMidFace = 1 + end + end + if vFaceOrd[1] == 0 or vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing middle face' + EgtOutLog( sErr) + return false, sErr + end + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[1] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' wrong angle between middle faces' + EgtOutLog( sErr) + return false, sErr + end + end + return true, '', vFaceOrd +end + +--------------------------------------------------------------------- +local function VerifyIfRoughMill( dLargeFace, vtN, bCalcElev, dAngOnSide) + local bUseRoughMill = false + local sMilling + -- recupero la lavorazione + if dAngOnSide then + if bCalcElev then + local dCollSic = BD.COLL_SIC + -- se direzione tende verso una delle 3 direzioni azzero l'altezza extra + if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end + sMilling = ML.FindMilling( 'ProfTCone', dLargeFace + dCollSic) + else + sMilling = ML.FindMilling( 'ProfTCone') + end + else + if bCalcElev then + local dCollSic = BD.COLL_SIC + -- se direzione tende verso una delle 3 direzioni azzero l'altezza extra + if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end + sMilling = ML.FindMilling( 'Long2Cut', dLargeFace + dCollSic) + else + sMilling = ML.FindMilling( 'Long2Cut') + end + dAngOnSide = 0 + end + if sMilling then + -- recupero i dati dell'utensile + local dToolDiam = 100 + local dToolLength = 0 + local dMaxDepth = 0 + local dMaxMat = 50 + local dSideAngle = 0 + local dMachStep = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + -- ottengo il passo della lavorazione + dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep + end + end + if dMachStep <= 0.1 then + dMachStep = dMaxMat * 0.5 + end + -- se ho già fatto la ricerca lavorazione considerando l'elevazione controllo solo l'angolo + if bCalcElev then + -- se angolo spoglia compatibile + if abs( dSideAngle - dAngOnSide) < GEO.EPS_SMALL then + return true, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep + end + else + -- se altezza taglio utensile maggiore altezza faccia e angolo spoglia compatibile + if ( dMaxDepth > dLargeFace + 10 * GEO.EPS_SMALL) and ( abs( dSideAngle - dAngOnSide) < GEO.EPS_SMALL) then + return true, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep + end + end + end + + return false +end + +--------------------------------------------------------------------- +local function AddFaceToSurf( Proc, nPartId, b3Solid) + + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + -- punto medio sulla faccia + local ptN = Point3d( b3Solid:getMin():getX(), ( b3Solid:getMin():getY() + b3Solid:getMax():getY())/2, ( b3Solid:getMin():getZ() + b3Solid:getMax():getZ())/2) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN, -X_AX(), b3Solid, GDB_ID.ROOT) + -- se esiste la superfice aggiunta, la ritaglio la superficie con le facce + if nSurfInt then + -- inverto la normale + EgtInvertSurf( nSurfInt) + for i = 1, Proc.Fct do + local ptN, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) + end + -- unisco la nuova superfice + if nSurfInt then + local bOk = EgtSurfTmAdd( nNewProc, nSurfInt) + if bOk then + EgtErase( nSurfInt) + Proc.Id = nNewProc + Proc.Fct = EgtSurfTmFacetCount( nNewProc) + end + end + end +end + +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessDovetail.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() > 0.1 then + return true + end + end + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 *b3Raw:getDimX()) then + return false + end + -- se una o due facce ora è sicuramente di testa + if Proc.Fct <= 2 then + return true + end + -- deve avere la normale principale diretta verso la testa + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN:getX() < 0.499 then + return false + elseif Proc.Fct >= 5 then + return true + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDovetail.IsTailFeature( Proc, b3Raw) + -- recupero identificativo del pezzo + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() < -0.1 then + -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione + if b3Solid:getDimX() > BD.LEN_SHORT_PART then + return true + else + -- aggiungo faccia + AddFaceToSurf( Proc, nPartId, b3Solid) + return false + end + end + end + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then + return false + end + -- se due facce e interessa veramente la coda, allora di coda + if Proc.Fct <= 2 then + if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then + -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione + if b3Solid:getDimX() > BD.LEN_SHORT_PART then + return true + else + -- aggiungo faccia + AddFaceToSurf( Proc, nPartId, b3Solid) + return false + end + end + end + -- deve avere la normale principale diretta verso la coda + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN:getX() > -0.499 then + return false + else + -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione + if b3Solid:getDimX() > BD.LEN_SHORT_PART then + return true + else + -- aggiungo faccia + AddFaceToSurf( Proc, nPartId, b3Solid) + return false + end + end +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDovetail.Classify( Proc, b3Raw) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- verifico se sono presenti i parametri Q per l'uso forzato del truciolatore + local bForceUseRough = EvaluateQParam( Proc, sUseRoughTool) + -- verifico le normali delle facce + local nFlatFaceNeg + local bDown = false + -- individuo se c'è faccia rivolta verso Z- + for i = 1, Proc.Fct do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < -0.99 then + nFlatFaceNeg = i - 1 + break + end + end + -- se trovata faccia rivolta verso Z- + if nFlatFaceNeg then + -- se 3 o più facce sicuramente è in mezzo, setto il ribaltamento senza ulteriori controlli + if Proc.Fct >= 3 then + bDown = true + -- altrimenti è in testa o coda e verifico se lavorabile da sotto + else + -- prendo le dimensioni della faccia + local nOtherFace = 1 - nFlatFaceNeg + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT) + -- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama e non fattibile con truciolatore + if dAng > -89.99 and dAng < 0 then + bDown = true + -- altrimenti, verifico se lunghezza faccia piatta è compatibile con il taglio di lama + else + local dLargeFace = Proc.Box:getDimX() + local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeFace, -Z_AX(), true) + -- se forzato uso truciolatore + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + end + end + -- altrimenti controllo la componente in Z delle facce + else + local vtN = {} + for i = 1, Proc.Fct do + vtN[i] = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT) + end + for i = 1, Proc.Fct do + local nFacet = i - 1 + -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + if abs( vtN[i]:getZ()) > abs( vtN[i]:getX()) and abs( vtN[i]:getZ()) > abs( vtN[i]:getY()) and vtN[i]:getZ() < -0.5 then + -- se ho due facce e feature agli estremi verifico che la lunghezza faccia sia compatibile col taglio di lama + -- o con truciolatore in base al valore del Q + if Proc.Fct == 2 and ( Proc.Head or Proc.Tail) then + -- prendo le dimensioni della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local nOtherFace = EgtIf( nFacet == 0, nFacet + 1, nFacet - 1) + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) + -- se angolo interno acuto + if dAng < 0 and dAng < -90 - 5 * GEO.EPS_SMALL then + -- se forzato truciolatore allora controllo se posso fare con utensile tronco di cono + local dLargeface = Proc.Box:getDimX() + local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true, (90+dAng)) + -- se forzato uso truciolatore + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + -- altrimenti angolo interno a 90 + else + local dDist = dist( ptP1, ptP2) + local dLargeface + local dDeltadH = abs( dDist - dH) + local dDeltadV = abs( dDist - dV) + -- prendo la dimensione diversa dalla lunghezza di adiacenza + if dDeltadH < dDeltadV then + dLargeface = dV + else + dLargeface = dH + end + -- se (anche) la direzione in z dell'altra faccia è negativa verifico se posso farla di fresa (in base alle impostazioni del Q) + if vtN[nOtherFace+1]:getZ() < -0.001 then + -- se forzato uso truciolatore verifico se posso fare di truciolatore + if bForceUseRough then + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) + bDown = not bUseRough + -- altrimenti posso usare lama, ma (anche) la direzione in z dell'altra faccia è negativa, quindi non è lavorabile, setto il ribaltamento + else + bDown = true + end + else + local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) + -- se forzato uso truciolatore + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + end + end + elseif Proc.Fct == 3 and ( Proc.Head or Proc.Tail) then + -- ordino le 3 facce: (1=altra intermedia, 2=interna, 3=intermedia) + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1 end + -- se le due facce intermedie sono compatibili con la lunghezza lama da sotto + -- prendo le dimensioni della facce + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vFaceOrd[3]-1, GDB_ID.ROOT) + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3]-1, vFaceOrd[1]-1, GDB_ID.ROOT) + -- prendo la dimensione uguale dalla lunghezza di adiacenza + local dLargeface = dist( ptP1, ptP2) + local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) + -- se forzato uso truciolatore e non riesco a farlo + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + elseif not Proc.Head and not Proc.Tail then + bDown = true + end + end + end + end + return true, bDown +end + +--------------------------------------------------------------------- +local function MakeCutsByDice( Proc, b3Raw, vCuts, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) + + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + vtOrthoO = Vector3d( vtRef2) + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( i == ( #vCuts - 1) or i == #vCuts) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < ( #vCuts - 1) or i == #vCuts then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -( dTrim + dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + + return true +end + +--------------------------------------------------------------------- +local function MachChainFacesByBlade( Proc, nCFaceSide, nCFaceInt1, nCFaceInt2, sCutting, bHead, vtRef, dTrim, dDepth) + + -- inserisco la lavorazione di taglio per la laterale negativa + local sName = 'Cut_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. EgtIf( nCFaceSide > 0, tostring( nCFaceSide) .. '_', '') .. tostring( nCFaceInt1) .. '-' .. tostring( nCFaceInt2) + local nMchFId = EgtAddMachining( sName, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nCFaceInt1 - 1},{ Proc.Id, nCFaceInt2 - 1}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) + local nSCC = EgtIf( vtRef:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + -- imposto posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- affondamento aggiuntivo + EgtSetMachiningParam( MCH_MP.OFFSR, -dTrim) + -- offset longitudinale + EgtSetMachiningParam( MCH_MP.OFFSL, 0) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto affondamento + if dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + else + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + end + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, 180) + EgtSetMachiningParam( MCH_MP.LOTANG, 0) + EgtSetMachiningParam( MCH_MP.LOPERP, 180) + local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nCFaceInt1 - 1, GDB_ID.ROOT) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nCFaceInt2 - 1, GDB_ID.ROOT) + local dNyMax = EgtIf( abs( vtN1:getY()) > abs( vtN2:getY()), vtN1:getY(), vtN2:getY()) + local dNzMax = EgtIf( abs( vtN1:getZ()) > abs( vtN2:getZ()), vtN1:getZ(), vtN2:getZ()) + if dNzMax < 0 and bHead == ( dNyMax < 0) then + EgtSetMachiningParam( MCH_MP.LITANG, 340) + EgtSetMachiningParam( MCH_MP.LIPERP, -100) + elseif dNzMax < 0 and bHead == ( dNyMax > 0) then + EgtSetMachiningParam( MCH_MP.LOTANG, 340) + EgtSetMachiningParam( MCH_MP.LOPERP, -100) + end + -- imposto allungamenti iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 50) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 50) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + + return true +end + +--------------------------------------------------------------------- +local function MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1, sErr1 end + ---- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + local vtRef2nd + if Proc.Fct > 2 and vFaceOrd[1] ~= 0 then + vtRef2nd = Vector3d( 0, vtN[vFaceOrd[1]]:getY(), vtN[vFaceOrd[1]]:getZ()) + vtRef2nd:normalize() + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + + -- calcolo la distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 and dAng > -89.9 then + dTrim = 0 + else + dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + end + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) + if not bOk then return false, sErr end + end + if vFaceOrd[1] ~= 0 then + bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[1] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 and dAng > -89.9 then + dTrim = 0 + else + dTrim = ((dToolThick* vtN[vFaceOrd[1]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + end + end + + -- se esistono faccia interna ed altra intermedia, verifico se richiedono taglio a cubetti + local vCuts2 = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[1] ~= 0 then + vCuts2 = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[1] ~= 0 then + vCuts2 = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], true) + end + if #vCuts2 > 0 then + local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts2, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) + if not bOk then return false, sErr end + end + + -- se non ha fatto nessun taglio a cubetti e ho 3 facce + if #vCuts == 0 and #vCuts2 == 0 and Proc.Fct > 2 then + -- lavoro la faccia interna (di fondo) indirettamente lavorando le due facce intermedie + local bOk, sErr = MachChainFacesByBlade( Proc, 0, vFaceOrd[3], vFaceOrd[1], sCutting, bHead, vtRef, ( dTrim + dFinalExtraTrim)) + if not bOk then return false, sErr end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- taglio sulla seconda faccia intermedia + if vFaceOrd[1] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- se altrimenti non ha fatto una parte dei tagli a cubetti + elseif #vCuts == 0 and #vCuts2 == 0 then + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nDirVect = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr + bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nDirVect, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeMillCut( Proc, i, j, k, sMilling, + nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut, bHead, vtRef) + local sWarn = '' + local bUnderCut = bUCut + -- inserisco la lavorazione di fresatura + -- per evitare nomi lavorazioni coincidenti, concateno anche il Proc.Id se il nome (del Proc.Id) è presente + local s2ndName = EgtGetName( Proc.Id) or '' + local sName = EgtIf( bUnderCut, 'MillTCone_', 'Mill_') .. ( EgtIf( #s2ndName > 0, s2ndName, tostring( Proc.Id))) .. ( EgtIf( #s2ndName > 0, '_' .. tostring( Proc.Id), '')) .. '_' .. tostring(i) .. '_' .. tostring(j) + local kStep = k or 0 + if kStep > 0 then + sName = sName .. '_' .. tostring(k) + end + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + local vtDirRef + -- imposto i parametri lavorazione in base alle facce lavorate + if vFaceOrd and #vFaceOrd > 0 then + -- aggiungo geometria e imposto uso faccia + EgtSetMachiningGeometry( {{ Proc.Id, vFaceOrd[3]-1},{ Proc.Id, vFaceOrd[1]-1}}) + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) + -- setto vettore direzione per posizione braccio porta testa + vtDirRef = vtRef + -- imposto lato corezione e inversione percorso + if kStep % 2 == 1 then + -- imposto lato sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + -- imposto lato destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- tolgo inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + -- imposto affondamento + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH' .. EgtIf( dOffs < 0, '', '-') .. EgtNumToString( dOffs, 4)) + else + -- aggiungo geometria e imposto uso faccia + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + local nFaceUse = BL.GetNearestOrthoOpposite( TabNAD[j][1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- setto vettore direzione per posizione braccio porta testa + vtDirRef = rfFac:getVersZ() + -- imposto lato corezione e inversione percorso + if kStep % 2 == 1 then + -- imposto lato destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + -- imposto lato sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- tolgo inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + -- imposto affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dOffs) + end + -- imposto posizione braccio porta testa + local nSCC = EgtIf( vtDirRef:getY() > (100 * GEO.EPS_ZERO), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + --imposto passo 0 + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto offset radiale in base all'angolo tra le due facce e alla posizione in Z + il passo laterale + dOffrRad = dOffrRad + dAddOffsRad + -- per le passate intermedie aggiungo un delta sull'offset radiale perchè c'è già il taglio di lama precedente + EgtSetMachiningParam( MCH_MP.OFFSR, dOffrRad + EgtIf( bPrevByBlade and ( i < nStep) and ( kStep < 1), 0.5, 0)) + -- imposto offset longotudinale a 0 + EgtSetMachiningParam( MCH_MP.OFFSL, 0) + -- imposto gli attacchi + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( 60 + 0.5 * dToolDiam)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( 60 + 0.5 * dToolDiam)) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill solo in ultima passata in Z locale + local sUserNotes + if i < nStep then + sUserNotes = 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + else + sUserNotes = 'VMRS=0;' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + _, sWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, + bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces, + vFaceOrd, bHead, sMillingMaster, dToolDiamMaster, dMaxMatMaster, + dSideAngleMaster, dMachStepMaster, nMainFace, dElevMain) + local sWarn = '' + local sMilling + local dToolDiam = 100 + local dSideAngle = 0 + local dMaxMat = 50 + local dMaxDepth = 50 + local dMachStep = 0 + local bUCutMax + -- dati della facce + local vtN = {} + local ptC = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + end + -- se non ho passato la lavorazione ( già verificata) + if not sMillingMaster then + -- se il flag del sottosquadra è nil, cerco se tra le facce c'è un angolo sottosquadra + if bUCut == nil then + for i = 1, nFacetCnt do + for j = i + 1, nFacetCnt do + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, (i-1), (j-1), GDB_ID.ROOT) + if bAdj and dAng and dAng < -90.1 then + bUCut = true + break + end + end + end + end + -- recupero l'angolo di spoglia dell'utensile a tronco di cono + -- recupero la lavorazione + local sMchFind = 'Long2Cut' + if bUCut then + sMchFind = 'ProfTCone' + end + sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep + end + end + if dMachStep <= 0.1 then + dMachStep = dMaxMat * 0.5 + end + else + sMilling = sMillingMaster + dToolDiam = dToolDiamMaster + dMaxMat = dMaxMatMaster + dSideAngle = dSideAngleMaster + dMachStep = dMachStepMaster + end + local nFacInd, dFacElev + if nMainFace and dElevMain then + nFacInd = nMainFace + dFacElev = dElevMain + else + -- se devo lavorare facce concatenate + if bJoinFaces then + nFacInd = vFaceOrd[2] - 1 + -- calcolo l'elevazione + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + if dLenIn > 0 then + dFacElev = dLenIn + elseif dLenOut then + dFacElev = dLenOut + end + else + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, sin(dSideAngle)) + if not nFacInd or nFacInd < 0 then + -- provo eliminando i sottosquadra + nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, -2) + if not nFacInd or nFacInd < 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MachSideFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + else + bUCutMax = true + end + end + end + end + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local TabNAD = {} + local bPrevByBlade = false + -- se non ho la forzatura a usare solo truciolatore e tagli lama consentiti + -- inserisco tagli di lama come antischeggia sulle altre facce + if not bForceUseRough and bUseBlade then + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dToolThick + end + end + -- controllo versore faccia di riferimento, è lungo l'asse trave + local vtRef = Vector3d( vtN[nFacInd+1]) + if not AreSameVectorApprox( vtN[nFacInd+1], X_AX()) and not AreSameVectorApprox( vtN[nFacInd+1], -X_AX()) then + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[nFacInd+1]:getY(), vtN[nFacInd+1]:getZ()) + end + vtRef:normalize() + -- ciclo inserimento tagli antischeggia sulle facce + for i = 1, nFacetCnt do + if ( i - 1) == nFacInd then + TabNAD[i] = { vtN[i]} + else + local dExtraZed = EgtIf( bForceMakeMill, 1, 0.1) + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) + if dAng then + TabNAD[i] = { vtN[i], dAng, dist( ptP1, ptP2)} + end + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + dExtraZed = 0.1 + else + dTrim = ((dToolThick* vtN[nFacInd+1]) * vtN[i] * vtN[i]):len() + end + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, ( i - 1), sCutting, dSawDiam, nOrthoOpposite, nil, -( dTrim + dExtraZed), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + bPrevByBlade = true + end + end + -- altrimenti solo taglio truciolatore + else + for i = 1, nFacetCnt do + if ( i - 1) == nFacInd then + TabNAD[i] = { vtN[i]} + else + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) + if dAng then + TabNAD[i] = { vtN[i], dAng, dist( ptP1, ptP2)} + end + end + end + end + local vtRef + -- se devo lavorare facce concatenate + if bJoinFaces then + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + end + -- creo percorsi di lavorazione + local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dMachStep) + local dStep = dFacElev / nStep + local dLargeVal + local nLenSideMax + -- se non devo fare fresature + if not bForceMakeMill then nStep = 0 end + for i = 1, nStep do + local dOffs = ( i * dStep) - dFacElev + if i == nStep then dOffs = 0 end + local dOffsSide = 0 + local dDelta = 100000 + local dElevface + for j = 1, nFacetCnt do + if ( j - 1) ~= nFacInd then + local dParzElev = dOffs + -- calcolo la larghezza (solo 1 volta) + if i == 1 then + -- se ho un sottosquadra maggiore dell'angolo di spoglia utensile + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dParzElev = dFacElev + end + if bJoinFaces then + -- calcolo l'elevazione di ogni singola faccia dal punto medio + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[j], vtN[j]) + if dLenIn > 0 then + dElevface = dLenIn + elseif dLenOut then + dElevface = dLenOut + end + if not dLargeVal or dElevface > dLargeVal then + dLargeVal = dElevface + end + else + local dDeltadH = abs( TabNAD[j][3] - dH) + local dDeltadV = abs( TabNAD[j][3] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + nLenSideMax = j + end + else + if dDeltadV < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + nLenSideMax = j + end + end + end + end + -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) + dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) + end + end + local dRefLarge + -- se ho facce concatenate verifico che la massima larghezza sia comunque superiore al diametro utensile + if bJoinFaces then + dRefLarge = dToolDiam + dLargeVal = EgtIf( dLargeVal > ( dToolDiam + dOffsSide), dLargeVal, dToolDiam + dOffsSide) + else + dRefLarge = EgtIf( nFacetCnt == 2, dToolDiam, ( 2 * dToolDiam)) + end + -- se ho 2 facce o la larghezza è più grande dell'utensile allora posso lavorare il passo + if nFacetCnt == 2 or ( dLargeVal - dOffsSide) >= dToolDiam then + -- se ho facce concatenate + if bJoinFaces then + local dOffrRad = 0 + -- se larghezza faccia consente passi laterali extra + if ( dLargeVal - dOffsSide) > dRefLarge then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) + local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide + for k = nStepSide, 1, -1 do + local dAddOffsRad = ( k * dStepSide) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, 1, k, sMilling, + nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut, bHead, vtRef) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- inserisco la lavorazione di fresatura a contatto con la faccia + local bOk, sErr = MakeMillCut( Proc, i, 1, nil, sMilling, + nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, + dOffrRad, 0, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut, bHead, vtRef) + if not bOk then + return false, sErr + end + sWarn = sErr + else + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + -- calcolo l'offset radiale in base all'affondamento e all'angolo spoglia + local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dOffrRad = -( tan( 90 + TabNAD[j][2]) * dFacElev) + end + -- se lato lavorato è il più lungo e la larghezza cava consente passi laterali extra + if j == nLenSideMax and ( dLargeVal - dOffsSide) > dRefLarge then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / ( dToolDiam * 0.5)) + local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide + for k = nStepSide, 1, -1 do + local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- inserisco la lavorazione di fresatura a contatto con la faccia + local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, 0, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + end + -- altrimenti passo saltato esco con errore + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' + EgtOutLog( sErr) + return false, sErr + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +local function Make2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) + -- verifico le normali delle facce + -- individuo se c'è faccia rivolta verso Z- + local nFlatFaceNeg + local vtN = {} + local ptC = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + if vtN[i]:getZ() < -0.99 then + nFlatFaceNeg = i - 1 + end + end + -- se trovata faccia rivolta verso Z- faccio controllo di lavorabilità da sotto + if nFlatFaceNeg then + -- prendo le dimensioni della faccia + local dLargeFace = Proc.Box:getDimX() + local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough, sMilling = VerifyIfRoughMill( dLargeFace, -Z_AX(), true) + -- se non forzato truciolatore provo la lama + if not bForceUseRough and bUseBlade then + return MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + -- altrimenti provo con il truciolatore + else + -- se non ho la lavorazione esco + if not sMilling then + local sErr = 'Error, machining or tool not found ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- Calcolo uso faccia + local nOtherInd = 2 - nFlatFaceNeg + local nFaceUse = BL.GetNearestParalOpposite( vtN[nOtherInd]) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFlatFaceNeg}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- annullo offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- applico allungamento iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YP + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- altrimenti non ho faccia (antivento) da sotto + else + for i = 1, Proc.Fct do + local nFacet = i - 1 + -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + if abs( vtN[i]:getZ()) > abs( vtN[i]:getX()) and abs( vtN[i]:getZ()) > abs( vtN[i]:getY()) and vtN[i]:getZ() < -0.5 then + -- lavoro con lama o truciolatore in base al Q + -- prendo le dimensioni della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local nOtherFace = 1 - nFacet + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) + local dLargeFace = Proc.Box:getDimX() + local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUCut = ( dAng < 0) and ( dAng < -90 - 5 * GEO.EPS_SMALL) + local bOCut = ( dAng < 0) and ( dAng > -90 + 5 * GEO.EPS_SMALL) + local bForceMakeMill = bUCut or bForceUseRough + -- 2020.04.18 da indicazioni di Fabio Sq. : se angolo interno acuto lo lavoro con utensile a tronco di cono + -- e, se consentito uso lama, preceduto anche due tagli antischeggia (solo in caso di 3 facce, con 2 facce disattivo gli antischeggia) + local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, X_AX(), true, EgtIf( bUCut, ( 90 + dAng), nil)) + -- se devo farlo con fresatura + if bForceMakeMill then + -- se non ho lavorazione (se per esempio l'angolo di spoglia utensile non è uguale a quello tra le due facce) do errore + if not sMilling then + local sErr = 'Error, machining or tool not found ' .. sName + EgtOutLog( sErr) + return false, sErr + end + -- genero lavorazioni + local bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + bUseBlade, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, nOtherFace, dLargeFace) + if not bOk then return false, sErr end + elseif bUseBlade then + local bOk, sErr = MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + -- se fallita di lama e di fresa è fattibile, eseguo con la fresa + if not bOk and sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + bUseBlade, true, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, nOtherFace, dLargeFace) + if not bOk then return false, sErr end + else + return false, sErr + end + end + return true + -- altrimenti non in Z negativa + else + -- se nessuna entità ha z negativa + if i == Proc.Fct then + -- verifico angolo tra le facce + local nOtherFace = nFacet - 1 + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) + local dLargeFace = Proc.Box:getDimX() + -- ordino le facce, se 2 facce: (1=0, 2=interna, 3=intermedia) + local bOk, sErr, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk then return bOk, sErr end + local bUCut = ( dAng < 0) and ( dAng < -90 - 5 * GEO.EPS_SMALL) + local bOCut = ( dAng < 0) and ( dAng > -90 + 5 * GEO.EPS_SMALL) + local bForceMakeMill = bUCut or bForceUseRough + -- 2020.04.18 da indicazioni di Fabio Sq. : se angolo interno acuto lo lavoro con utensile a tronco di cono + -- e, se consentito uso lama, preceduto anche due tagli antischeggia (solo in caso di 3 facce, con 2 facce disattivo gli antischeggia) + -- se devo farlo con fresatura + if bForceMakeMill then + local bOk, sErr + bOk = false + -- se angolo ( tra le due facce è) ottuso + if bOCut then + local ptPs = ( ptP1 + ptP2) / 2 + -- calcolo l'elevazione di ogni singola faccia dal punto medio della linea di adiacenza + -- prendo l'elevazione sul punto medio della prima faccia + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[vFaceOrd[2]]) + if dLenIn > 0 then + dLargeFace = dLenIn + elseif dLedOut then + dLargeFace = dLedOut + end + -- verifico la possibilità di lavorare con utensile + local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, vtN[vFaceOrd[2]], true) + -- se ho trovato lavorazione applicata a faccia definita + if sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, vFaceOrd[2]-1, dLargeFace) + end + -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima + if not bOk then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false) + end + if not bOk then return false, sErr end + + -- prendo l'elevazione sul punto medio della seconda faccia + dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[vFaceOrd[3]]) + if dLenIn > 0 then + dLargeFace = dLenIn + elseif dLedOut then + dLargeFace = dLedOut + end + -- verifico la possibilità di lavorare con utensile + bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, vtN[vFaceOrd[3]], true) + -- se ho trovato lavorazione applicata a faccia definita + if sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, vFaceOrd[3]-1, dLargeFace) + end + -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima + if not bOk then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false) + end + if not bOk then return false, sErr end + else + -- verifico la possibilità di lavorare con utensile (orizzontale) + local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, X_AX(), true, EgtIf( bUCut, ( 90 + dAng), nil)) + -- se ho trovato lavorazione applicata a faccia definita + if sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, vFaceOrd[2]-1, dLargeFace) + end + -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima + if not bOk then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false) + end + if not bOk then return false, sErr end + end + else + return MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + end + end + end + end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + + -- recupero la geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return true end + AuxId = AuxId + Proc.Id + -- recupero il centro e la normale della faccia ausiliaria + local ptC, vtN = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + if not vtN then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' wrong Normal of AuxSurface' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se di testa o coda + local bHead = ( vtN:getX() > 0) + -- recupero la lavorazione per la geometria ausiliaria + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se già fatto con altro componente della stessa feature + local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring( AuxId), 'b') + if bAuxMachined then return true end + -- verifico se coincide con taglio di testa + if bHead and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- verifico se coincide con taglio di coda + if not bHead and AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + -- inserisco la lavorazione + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + -- imposto la nota nel gruppo aggiuntivo di lavorazione per evitare di tagliare una seconda volta + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + return true +end + +--------------------------------------------------------------------- +local function MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, nSidePosFct, nMiddleFct, nSideNegFct, vtRef, nFacetCnt) + + local sWarn = '' + -- recupero la lavorazione + local sMchFind = 'Long2Cut' + local sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 100 + local dMaxMat = 50 + local dSideAngle = 0 + local dMachStep = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + -- ottengo il passo della lavorazione + dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep + end + end + if dMachStep <= 0.1 then + dMachStep = dMaxMat * 0.5 + end + local nFacInd = nMiddleFct - 1 + local dFacElev + -- calcolo elevazione + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[nMiddleFct], vtN[nMiddleFct]) + if dLenIn > 0 then + dFacElev = dLenIn + elseif dLenOut then + dFacElev = dLenOut + end + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local TabNAD = {} + TabNAD[nMiddleFct] = { vtN[nMiddleFct]} + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, ( nSideNegFct or 0) - 1, GDB_ID.ROOT) + if dAng then + TabNAD[nSideNegFct] = { vtN[nSideNegFct], dAng, dist( ptP1, ptP2)} + end + bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (nSidePosFct-1), GDB_ID.ROOT) + if dAng then + TabNAD[nSidePosFct] = { vtN[nSidePosFct], dAng, dist( ptP1, ptP2)} + end + -- creo percorsi di lavorazione + local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dMachStep) + local dStep = dFacElev / nStep + local dLargeVal + local nLenSideMax + for i = 1, nStep do + local dOffs = ( i * dStep) - dFacElev + if i == nStep then dOffs = 0 end + local dOffsSide = 0 + local dDelta = 100000 + local dElevface + for j = 1, nFacetCnt do + if j == nSideNegFct or j == nSidePosFct then + local dParzElev = dOffs + -- calcolo la larghezza (solo 1 volta) + if i == 1 then + local dDeltadH = abs( TabNAD[j][3] - dH) + local dDeltadV = abs( TabNAD[j][3] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + nLenSideMax = j + end + else + if dDeltadV < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + nLenSideMax = j + end + end + end + -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) + dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) + end + end + local dRefLarge = EgtIf( nSideNegFct, ( 2 * dToolDiam), dToolDiam) + -- se la larghezza è più grande dell'utensile allora posso lavorare il passo + if ( dLargeVal - dOffsSide) >= dToolDiam then + for j = 1, nFacetCnt do + if j == nSideNegFct or j == nSidePosFct then + -- calcolo l'offset radiale in base all'affondamento e all'angolo spoglia + local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) + -- se lato lavorato è il più lungo e la larghezza cava consente passi laterali extra + if j == nLenSideMax and ( dLargeVal - dOffsSide) > dRefLarge then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * EgtIf( nSideNegFct, 0.5, 1)) + local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide + for k = nStepSide, 1, -1 do + local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + true, false) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- inserisco la lavorazione di fresatura a contatto con la faccia + local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, 0, nStep, dToolDiam, dStep, + true, false) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- altrimenti passo saltato esco con errore + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' + EgtOutLog( sErr) + return false, sErr + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bUseBlade) + + local ptC = {} + local vtN = {} + -- dati delle facce e ordinamento facce { } + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le 4 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia, 4=esterna) + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1, sErr1 end + -- vettori di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + local vtRef2nd = Vector3d( 0, vtN[vFaceOrd[1]]:getY(), vtN[vFaceOrd[1]]:getZ()) + vtRef2nd:normalize() + -- se non forzato uso truciolatore e abilitato il taglio di lama faccio le due pareti con antischeggia + -- lavoro le facce laterali indirettamente lavorando le due facce intermedie + if not bForceUseRough and bUseBlade then + -- recupero la lavorazione con lama + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + local dTrim = -0.3 + -- se ho la faccia laterale negativa + if vFaceOrd[4] ~= 0 then + -- inserisco la lavorazione di taglio per la faccia laterale negativa, faccio in modo che la testa rimanga nella stessa posizione per entrambe i tagli + local bOk, sErr = MachChainFacesByBlade( Proc, vFaceOrd[4], vFaceOrd[3], vFaceOrd[1], sCutting, true, vtRef, dTrim, dToolThick) + if not bOk then return false, sErr end + end + -- se ho la faccia laterale positiva + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione di taglio per la faccia laterale positiva + local bOk, sErr = MachChainFacesByBlade( Proc, vFaceOrd[2], vFaceOrd[3], vFaceOrd[1], sCutting, true, vtRef, dTrim) + if not bOk then return false, sErr end + end + end + -- lavoro le facce intermedie + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione di fresatura per la faccia intermedia + local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[2], vFaceOrd[3], vFaceOrd[4], vtRef, Proc.Fct) + if not bOk then return false, sErr end + end + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione di fresatura per la faccia intermedia + local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[2], vFaceOrd[1], vFaceOrd[4], vtRef, Proc.Fct) + if not bOk then return false, sErr end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bInMiddle) + -- flag per lavorazioni sulla testa o coda + local bUseBlade = false + local bForceMakeMill = bForceUseRough + local bUCut = false + local bOCut = false + local bJoinFaces = true + -- modifiche ai flag per lavorazione in mezzo + if bInMiddle then + -- abilito la lama per i tagli antischeggia + bUseBlade = true + -- abilito la fresatura + bForceMakeMill = true + -- disabilito il concatenamento delle facce intermedie + bJoinFaces = false + -- annullo il flag del sottosquadra per forzare la ricerca all'interno della funzione + bUCut = nil + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce, se 3 facce: (1=altra intermedia, 2=interna, 3=intermedia) + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1, sErr1 end + -- verifica se di testa o coda + local bHead = false + if not bInMiddle then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + end + -- se non in mezzo può essere necessario lavorare come in mezzo + if not bInMiddle then + -- calcolo l'elevazione + local dSideElev = 0 + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + if dLenIn > 0 then + dSideElev = dLenIn + elseif dLenOut then + dSideElev = dLenOut + end + -- determino il massimo affondamento con l'utensile + local sMchFind = 'Long2Cut' + sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 10 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se l'elevazione supera l'affondamento, lavoro perpendicolare all'asse trave + if dSideElev > dMaxDepth then + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bUseBlade) + end + end + + -- lavoro le restanti facce in modo standard + return MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces, + vFaceOrd, bHead) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- verifico se sono presenti i parametri Q per l'uso forzato del truciolatore + local bForceUseRough = EvaluateQParam( Proc, sUseRoughTool) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + if Proc.Fct < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + + -- se ha due facce ( allora è di testa o coda) + if Proc.Fct == 2 then + -- eventuale taglio di testa o coda + local bAuxOk, sAuxErr = MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + if not bAuxOk then return bAuxOk, sAuxErr end + -- lavorazione della feature + local bOk, sErr = Make2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) + if not bOk then return bOk, sErr end + -- se ha 3 facce ed è di testa o coda + elseif Proc.Fct == 3 and ( Proc.Head or Proc.Tail) then + -- eventuale taglio di testa o coda + local bAuxOk, sAuxErr = MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + if not bAuxOk then return bAuxOk, sAuxErr end + -- lavorazione della feature + if bForceUseRough then + local bOk, sErr = MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) + if not bOk then return bOk, sErr end + else + local bOk, sErr = MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + if not bOk then return bOk, sErr end + end + -- se ha 3 facce (e interna) + elseif Proc.Fct == 3 then + local bOk, sErr = MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, true) + if not bOk then return bOk, sErr end + -- altrimenti 4 facce (e interna) + else + local bOk, sErr = MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, true) + if not bOk then return bOk, sErr end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dTCI) + end + + return true +end + +--------------------------------------------------------------------- +return ProcessDovetail diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDrill.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDrill.lua new file mode 100644 index 0000000..f919e38 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDrill.lua @@ -0,0 +1,438 @@ +-- ProcessDrill.lua by Egaltech s.r.l. 2021/01/13 +-- Gestione calcolo forature per Travi + +-- Tabella per definizione modulo +local ProcessDrill = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessDrill started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDrill.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 40) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDrill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + return false + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- se entrata principale + if Proc.Flg > 0 then + local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + return ( ( nFcs == 5 or nFcs == 6) and vtExtr:getX() > 0.5) + -- altrimenti entrata opposta + else + local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + return ( ( nFce == 5 or nFce == 6) and vtExtr:getX() < -0.5) + end + +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDrill.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.OVM_MID + BD.MAX_DIST_HTFEA then + return false + end + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + return false + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- se entrata principale + if Proc.Flg == 2 or ( Proc.Flg == 1 and vtExtr:getZ() >= BD.DRILL_VZ_MIN) then + local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + return ( ( nFcs == 5 or nFcs == 6) and vtExtr:getX() < -0.5) + -- altrimenti entrata opposta + else + local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + return ( ( nFce == 5 or nFce == 6) and vtExtr:getX() > 0.5) + end +end + +--------------------------------------------------------------------- +-- Recupero dati foro e adattamento se speciale +function ProcessDrill.GetData( Proc, b3Raw) + -- 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 BD.USER_HOLE_DIAM and BD.USER_HOLE_DIAM > 1 then + EgtModifyArcRadius( AuxId, BD.USER_HOLE_DIAM / 2) + 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 + +--------------------------------------------------------------------- +-- Verifica se da lavorare in due metà +function ProcessDrill.Split( 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 bOpen = ( Proc.Fce ~= 0) + -- recupero flag abilitazione split (0=auto,1=no) + local bTrySplit = ( EgtGetInfo( Proc.Id, 'Q02', 'i') ~= 1) + if not bTrySplit then + return false + end + -- abilitazione foratura da sotto + local bDrillDown = ( BD.DOWN_HEAD and ( Proc.Down or vtExtr:getZ() < 0.1 or EgtExistsInfo( Proc.Id, 'MAIN')) and not EgtExistsInfo( Proc.Id, 'DOU')) + -- recupero la lavorazione + local sDrilling, _, dMaxMat = ML.FindDrilling( dDiam, 0, bDrillDown) + if not sDrilling then dMaxMat = 0 end + -- restituisco se va fatto in doppio (solo fori orizzontali) + local bHoriz = ( abs( vtExtr:getZ()) < abs( BD.DRILL_VZ_MIN) and + ( abs( vtExtr:getY()) * b3Raw:getDimZ() > abs( vtExtr:getZ()) * b3Raw:getDimY() or Proc.Fce == 5 or Proc.Fce == 6)) + local bSlant = ( abs( vtExtr:getX()) > BD.DRILL_VX_MAX) + return ( bOpen and ( bHoriz or BD.ROT90) and not bSlant) +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) + -- se lavorato in doppio, devo considerare il lato più sfavorevole + if Proc.Flg == -2 or ( BD.ROT90 and Proc.Flg == 2) then + if vtExtr:getZ() > 0 then + vtExtr = - vtExtr + ptCen = ptCen + vtExtr * dLen + end + end + -- 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()) > BD.DRILL_VX_MAX then + return false, false, false + end + local bOpen = ( Proc.Fce ~= 0) + local bFaceDown = ( ptCen:getZ() < b3Raw:getMin():getZ() + 2 and (( not Proc.Head and not Proc.Tail) or ( BD.ROT90 and ( Proc.Flg == 2 or Proc.Flg == -2)))) + -- verifico se il foro è sotto e quindi va spostato o sopra o sul fianco + if (( vtExtr:getZ() < BD.DRILL_VZ_MIN or bFaceDown) and ( not bOpen or Proc.Flg ~= 1)) then + if not bOpen then + return true, true, false + else + return true, not BD.ROT90, BD.ROT90 + end + else + return true, false, false + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) + -- 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 : 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) + if Proc.Flg == -2 then vtExtr = - vtExtr end + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- verifico che il foro non sia fattibile solo da sotto + local bToInvert = ( vtExtr:getZ() < BD.DRILL_VZ_MIN) and not BD.DOWN_HEAD + if bToInvert and ( not bOpen or Proc.Flg ~= 1) then + local sErr = 'Error : drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- se il foro può non essere passante (bOpen vale false) inverto + if Proc.Fcs == 0 then bToInvert = true end + if bToInvert then vtExtr = - vtExtr end + -- se foro è splittato ed è la parte opposta, inverto + if Proc.Flg == -2 then bToInvert = true end + -- profondità geometria foro + local dDepth = dLen + local dDepth2 = dLen + if Proc.Flg == 2 or Proc.Flg == -2 then + dDepth = dLen / 2 + BD.DRILL_OVERLAP + end + local dCheckDepth = dDepth + local dCheckDepth2 = dDepth2 + local nErrorCode = 0 + -- se troppo inclinata sulla X o Y va troppo dietro o Z va in negativo o se il foro è splittato, + -- annullo il valore della profondità nella ricerca utensile + if abs(vtExtr:getX()) > 0.707 or vtExtr:getY() > 0.5 or vtExtr:getZ() < BD.DRILL_VZ_MIN or abs(Proc.Flg) == 2 then + dCheckDepth = nil + dCheckDepth2 = nil + end + -- abilitazione foratura da sotto + local bDrillDown = ( BD.DOWN_HEAD and ( Proc.Down or vtExtr:getZ() < -0.1 or vtExtr:getY() > 0 or EgtExistsInfo( Proc.Id, 'MAIN')) and not EgtExistsInfo( Proc.Id, 'DOU')) + -- primo gruppo di controlli con lunghezza utensile calcolata + -- recupero la lavorazione + local sDrilling, nType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, dCheckDepth, bDrillDown) + if not sDrilling then + -- se ho passato altezza di taglio utensile allora rifaccio la ricerca senza passare altezza utensile + if dCheckDepth then + dCheckDepth = nil + sDrilling, nType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, 0, bDrillDown) + end + if not sDrilling then + nErrorCode = 1 + end + end + -- se esiste la lavorazione e la lunghezza utensile massima supera il valore limite del BeamData e la componente Z supera i 10 gradi + -- allora ricerco un utensile senza lunghezza massima + if nErrorCode == 0 and dMaxToolLength > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then + -- se non ho passato altezza di taglio utensile allora la lunghezza utensile non è idonea per il taglio + if not dCheckDepth then + nErrorCode = 2 + -- rifaccio ricerca lavorazione senza specificare la profondità (dovrebbe trovare l'utensile più corto) + else + sDrilling, nType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, 0, bDrillDown) + if not sDrilling then + nErrorCode = 1 + end + -- ultimo controllo sulla lunghezza utensile + if dMaxToolLength > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then + nErrorCode = 2 + end + end + end + -- secondo gruppo di controlli con lunghezza utensile calcolata + -- recupero la lavorazione + local sDrilling2, nType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 + if dDepth2 > dDepth + BD.DRILL_OVERLAP then + sDrilling2, nType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, dCheckDepth2, bDrillDown) + if not sDrilling2 then + -- se ho passato altezza di taglio utensile allora rifaccio la ricerca senza passare altezza utensile + if dCheckDepth2 then + dCheckDepth2 = nil + sDrilling2, nType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, 0, bDrillDown) + end + if not sDrilling2 then + nErrorCode = 1 + end + end + -- se esiste la lavorazione e la lunghezza utensile massima supera il valore limite del BeamData e la componente Z supera i 10 gradi + -- allora ricerco un utensile senza lunghezza massima + if nErrorCode == 0 and dMaxToolLength2 > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then + -- se non ho passato altezza di taglio utensile allora la lunghezza utensile non è idonea per il taglio + if not dCheckDepth2 then + nErrorCode = 2 + -- rifaccio ricerca lavorazione senza specificare la profondità (dovrebbe trovare l'utensile più corto) + else + sDrilling2, nType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, 0, bDrillDown) + if not sDrilling2 then + nErrorCode = 1 + end + -- ultimo controllo sulla lunghezza utensile + if dMaxToolLength2 > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then + nErrorCode = 2 + end + end + end + end + -- se esiste il parametro massima lunghezza per fori da dietro e il foro è passante e non è ancora stato invertito + -- ed è orizzontale ed è orientato principalmente verso Y+ e non è la parte splittata e l'utensile supera una certa lunghezza + -- lo inverto per premiare l'entrata davanti + local bCommonCompare = BD.MAX_TOOL_LEN_BACK_HOR_MACH and bOpen and abs(vtExtr:getX()) < 0.5 and abs(vtExtr:getZ()) < 0.5 + if nErrorCode == 0 and not bToInvert and bCommonCompare and vtExtr:getY() > 0.866 and Proc.Flg == 1 and dMaxToolLength > BD.MAX_TOOL_LEN_BACK_HOR_MACH then + bToInvert = true + vtExtr = - vtExtr + --------------------------------------------------------------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------------------------------------------------------------- + -- 14/12/2020 richiesta di Fabio Squaratti: con foro orizzontale passante e parametro Q02 = 0 (settato per fare in due parti), + -- se punta più lunga del parametro BD.MAX_TOOL_LEN_BACK_HOR_MACH alloro ignoro la doppia foratura contrapposta e faccio foratura solo dal davanti + -- Questo implica che il valore del parametro Q02 = 0 non è vincolante perchè basta che l'utensile supera il parametro allora la foratura si comporta + -- come se il parametro Q02 sia = 1 + --------------------------------------------------------------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------------------------------------------------------------- + elseif nErrorCode == 0 and not bToInvert and bCommonCompare and abs(vtExtr:getY()) > 0.866 and Proc.Flg == 2 and dMaxToolLength2 > BD.MAX_TOOL_LEN_BACK_HOR_MACH then + sDrilling = sDrilling2 + nType = nType2 + dMaxDepth = dMaxDepth2 + dToolDiam = dToolDiam2 + dDiamTh = dDiamTh2 + dToolFreeLen = dToolFreeLen2 + dDepth = dDepth2 + if vtExtr:getY() > 0 then + bToInvert = true + vtExtr = - vtExtr + end + -- se sono al secondo mezzo foro con utensile che supera la lunghezza di riferimento non lo eseguo + elseif nErrorCode == 0 and bCommonCompare and abs(vtExtr:getY()) > 0.866 and Proc.Flg == -2 and dMaxToolLength2 > BD.MAX_TOOL_LEN_BACK_HOR_MACH then + return true, '' + end + if nErrorCode == 1 then + local sErr = 'Error : drilling not found in library' + EgtOutLog( sErr) + return false, sErr + elseif nErrorCode == 2 then + local sErr = 'Error : tool too long to machine with big angle from vertical' + EgtOutLog( sErr) + return false, sErr + end + local dSubL1 = 0 + local dSubL2 = 0 + local dSubL3 = 0 + local dDeltaRad = ( Proc.Diam - dToolDiam) / 2 + -- se foro non su testa o coda e inclinato, limito il massimo affondamento + local bInvertFcse = ( bToInvert and Proc.Flg ~= -2) + if ( not bInvertFcse and Proc.Fcs ~= 5 and Proc.Fcs ~= 6) or ( bInvertFcse and Proc.Fce ~= 5 and Proc.Fce ~= 6) then + local CosB = abs( vtExtr:getX()) + if CosB < BD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dSubL1 = ( dDiamTh / 2 + dDeltaRad + 2) * TgA + else + dMaxDepth = 0 + end + end + -- se foro davanti o dietro e inclinato, limito il massimo affondamento + if dMaxDepth > 0 and abs( vtExtr:getY()) > abs( vtExtr:getZ()) then + local CosB = abs( vtExtr:getZ()) + if CosB < BD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dSubL2 = ( dDiamTh / 2 + dDeltaRad + 2) * TgA + else + dMaxDepth = 0 + end + end + -- se foro sopra o sotto e inclinato, limito il massimo affondamento + if dMaxDepth > 0 and abs( vtExtr:getZ()) > abs( vtExtr:getY()) then + local CosB = abs( vtExtr:getY()) + if CosB < BD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dSubL3 = ( dDiamTh / 2 + dDeltaRad + 2) * TgA + else + dMaxDepth = 0 + end + end + local dSubL = max( dSubL1, dSubL2, dSubL3) + if dMaxDepth > 0 then + dMaxDepth = min( dMaxDepth, dToolFreeLen - dSubL) + 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.NONE + if not BD.C_SIMM then + nSCC = MCH_SCC.ADIR_YM + if AreSameVectorApprox( vtExtr, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtExtr:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtExtr:getY() > 0.1 then + nSCC = MCH_SCC.ADIR_YP + end + else + nSCC = MCH_SCC.NONE + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- aggiusto l'affondamento + local sMyWarn + 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 + -- se lavorazione in doppio + if EgtExistsInfo( Proc.Id, 'MAIN') then + sUserNotes = sUserNotes .. 'Double;' + elseif EgtExistsInfo( Proc.Id, 'DOU') then + sUserNotes = sUserNotes .. 'Main;' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + local bOk = EgtApplyMachining( true, false) + if not bOk and BD.DOWN_HEAD then + if nType == 'Drill' then + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + bOk = EgtApplyMachining( true, false) + end + if not bOk 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/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDtMortise.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDtMortise.lua new file mode 100644 index 0000000..88e4c6d --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDtMortise.lua @@ -0,0 +1,390 @@ +-- ProcessDtMortise.lua by Egaltech s.r.l. 2021/01/28 +-- Gestione calcolo mortase a coda di rondine per Travi + +-- Tabella per definizione modulo +local ProcessDtMortise = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessDtMortise started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- settaggi interni ( poi andrà utilizzato parametro ACTIVE_AS proveniente da parametri utente di TechnoEssetre) +local bMakeAntiSplitPath = true +local bMakeAsByArc = true + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDtMortise.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 55) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 56)) +end + +--------------------------------------------------------------------- +-- Riconoscimento della sola feature frontale +function ProcessDtMortise.FrontIdentify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 56) +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDtMortise.IsTailFeature( Proc, b3Raw) + -- la mortasa di fronte è già stata classificata nel chiamante + -- controllo la mortasa standard + if Proc.Box:getMin():getX() < b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + -- recupero la curva di profilo + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtStart = EgtSV( AuxId, GDB_ID.ROOT) + local vtEnd = EgtEV( AuxId, GDB_ID.ROOT) + local vtDir = -vtStart + vtEnd ; vtDir:normalize() + -- se l'asse della mortasa è inclinato indietro più di 8 deg è considerata di coda + return ( vtDir:getX() < -0.15) + end + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDtMortise.Classify( Proc) + -- recupero i dati della curva di contorno della faccia di fondo + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se la mortasa è lavorabile solo da sotto + local bDown = ( vtExtr:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +-- Piano di taglio della feature +function ProcessDtMortise.GetCutPlane( Proc) + if ProcessDtMortise.FrontIdentify( Proc) then + return EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + else + return nil, nil + end +end + +--------------------------------------------------------------------- +local function CalcTopPath( nProcId, AuxId, nAddGrpId, dAltMort, dSideAng, b3Solid) + -- copio la curva di base + local NewAuxId = EgtCopyGlob( AuxId, nAddGrpId) + if not NewAuxId then return end + -- ne allungo gli estremi + EgtExtendCurveStartByLen( NewAuxId, 100) + EgtExtendCurveEndByLen( NewAuxId, 100) + -- eseguo traslazione e offset per portarla sul top + local vtMove = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) * ( dAltMort - 10 * GEO.EPS_SMALL) + EgtMove( NewAuxId, vtMove, GDB_RT.GLOB) + local dOffset = dAltMort * tan( dSideAng) + if not EgtOffsetCurve( NewAuxId, dOffset) then return end + -- la limito entro la trave + local refBox = Frame3d( b3Solid:getMin()) + local vtBoxDiag = b3Solid:getMax() - b3Solid:getMin() + local nCount + NewAuxId, nCount = EgtTrimFlatCurveWithBox( NewAuxId, refBox, vtBoxDiag, true, true, GDB_RT.GLOB) + -- se divisa in più parti, le unisco congiungendole con segmenti + if nCount > 1 then + if EgtGetType( NewAuxId) ~= GDB_TY.CRV_COMPO then + NewAuxId = EgtCurveCompo( nAddGrpId, NewAuxId) + end + for i = 2, nCount do + local CrvId = NewAuxId + i - 1 + local ptStart = EgtSP( CrvId) + EgtAddCurveCompoLine( NewAuxId, ptStart) + EgtAddCurveCompoCurve( NewAuxId, CrvId) + end + end + return NewAuxId +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDtMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Missing profile geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del top + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico che la mortasa non sia orientata verso il basso (-5 deg) o che ci sia una testa da sotto + local bFaceDown = ( vtExtr:getZ() < - 0.1) + if bFaceDown and not BD.DOWN_HEAD then + local sErr = 'Machining from bottom impossible : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- verifico se di tipo pocket + local bPocket = ( EgtGetInfo( Proc.Id, 'P05', 'i') == 1) + if bPocket then bMakeAntiSplitPath = false end + -- verifico se frontale + local bFront = ( Proc.Prc == 56) + -- se mortasa di fronte, eseguo il taglio della faccia + if bFront then + -- verifico esista la faccia di taglio + local ptCutC, vtCutN = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if ptCutC and vtCutN and AreSameVectorApprox( vtExtr, vtCutN) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptCutC, vtCutN, b3Solid, GDB_RT.GLOB) + local b3Cut = EgtGetBBoxGlob( AddId or GDB_ID.NULL, GDB_BB.STANDARD) + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Cut, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getZ() > 0.25) + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH, bFromBottom) + if not bOk then return bOk, sErr end + end + end + -- recupero il raggio minimo della mortasa + local dMinRad = 1000 + local nSt, nEnd = EgtCurveDomain( AuxId) + for i = nSt, nEnd - 1 do + local dRad = EgtCurveCompoRadius( AuxId, i) + if dRad > 0 and dRad < dMinRad then + dMinRad = dRad + end + end + -- recupero la lavorazione : prima ricerca per sola tipologia + local sMchExt = EgtIf( bFaceDown or ( BD.DOWN_HEAD and vtExtr:getZ() < 0.1), '_H2', '') + local sMilling = ML.FindMilling( 'DtMortise'..sMchExt) + if not sMilling then + local sErr = 'Milling not found in library : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione : seconda ricerca con tipologia e diametro massimo + sMilling = ML.FindMilling( 'DtMortise'..sMchExt, nil, nil, 2 * dMinRad) + if not sMilling then + local sErr = 'Radius too small : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile e l'angolo di spoglia + local dToolDiam = 100 + local dMaxMat = 30 + local dSideAng = 0 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolDiam = max( dToolDiam, 10) + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- se con tasca, la lavoro + if bPocket then + -- recupero il contorno della tasca (seconda curva ausiliaria) + local sVal = EgtGetInfo( Proc.Id, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local Aux2Id + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if Aux2Id then Aux2Id = Aux2Id + Proc.Id end + if not Aux2Id or ( EgtGetType( Aux2Id) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Missing pocket geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sPocketing + if Proc.Prc ~= 53 then + sPocketing = ML.FindPocketing( 'Mortise'..sMchExt, dToolDiam) + end + if not sPocketing then + sPocketing = ML.FindPocketing( 'Pocket'..sMchExt, dToolDiam) + end + if not sPocketing then + local sErr = 'Error : Mortise or Pocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di svuotatura + local sName = 'DtMtPck_' .. ( 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( {{ Aux2Id, -1}}) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- se parametro interno abilitato e il percorso non è chiuso, aggiungo percorso e lavorazione antischeggia + if bMakeAntiSplitPath and not EgtCurveIsClosed( AuxId) then + -- recupero il riferimento della faccia di fondo + local rfFac0 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + -- ottengo il box con la normale della faccia 0 + local bBoxF0 = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfFac0) + -- recupero l'altezza della mortasa + local dAltMort = bBoxF0:getDimZ() + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo il percorso top mortise + local nAuxId1 = CalcTopPath( Proc.Id, AuxId, nAddGrpId, dAltMort, dSideAng, b3Solid) + -- se esiste il percorso + if nAuxId1 then + -- creo percorso sulla parte alta della mortasa + local dToolRadDelta = dAltMort * tan( dSideAng) + local dTopDiam = dToolDiam + 2 * dToolRadDelta + -- recupero punto iniziale e finale del percorso + local ptStart = EgtSP( nAuxId1, GDB_RT.GLOB) + local ptEnd = EgtEP( nAuxId1, GDB_RT.GLOB) + if ptStart and ptEnd then + local nId1 + -- se richiesti due segmenti di linea + if not bMakeAsByArc then + -- determino il punto comune dei due segmenti + local vtDelta = ( ptEnd - ptStart) / 4 + vtDelta:rotate( vtExtr, -90) + local ptMid = ( ptStart + ptEnd) / 2 + vtDelta + -- creo la spezzata formata dai due segmenti + nId1 = EgtCurveCompoFromPoints( nAddGrpId, { ptStart, ptMid, ptEnd}, GDB_RT.GLOB) + -- altrimenti richiesto arco + else + -- direzione del segmento + local vtDir = ptEnd - ptStart ; + local dLen = vtDir:len() + vtDir:normalize() + -- direzioni tangenti iniziale e finale + local vtStart = EgtSV( nAuxId1, GDB_RT.GLOB) + local vtEnd = EgtEV( nAuxId1, GDB_RT.GLOB) + -- angoli + local dAngStart = acos( vtStart * vtDir) + local dAngEnd = acos( vtEnd * vtDir) + local dMaxAng = min( 30, dAngStart, dAngEnd) + if dLen < dTopDiam then + dMaxAng = min( dMaxAng, asin( dLen / dTopDiam)) + end + local vtTg = vtDir ; vtTg:rotate( vtExtr, -dMaxAng) + -- creo l'arco + nId1 = EgtArc2PV( nAddGrpId, ptStart, ptEnd, vtTg, GDB_RT.GLOB) + end + if not nId1 then + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + EgtModifyCurveExtrusion( nId1, vtExtr, GDB_RT.GLOB) + -- inserisco la lavorazione di contornatura anti splint + local sNameF = 'DtMtAS_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nId1, -1}}) + -- setto affondamento pari all'altezza della mortsasa + EgtSetMachiningParam( MCH_MP.DEPTH, dAltMort) + -- setto offset radiale con aggiunto un ulteriore allargamento di 1mm + EgtSetMachiningParam( MCH_MP.OFFSR, dToolRadDelta - 1) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, false, true)) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dAltMort, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + else + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + else + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + end + -- verifico se necessarie più passate (distanza all'imbocco ortogonale all'asse) + local vtDiff = EgtEP( AuxId, GDB_RT.GLOB) - EgtSP( AuxId, GDB_RT.GLOB) + local vtAx = EgtEV( AuxId, GDB_RT.GLOB) - EgtSV( AuxId, GDB_RT.GLOB) + vtAx:normalize() + local vtOrtDiff = vtDiff - vtDiff * vtAx * vtAx + local dDist = vtOrtDiff:len() + -- calcolo le passate + local nPass = ceil( dDist / ( 1.9 * dToolDiam)) + local dStep = ( dDist - 0.95 * dToolDiam) / ( 2 * nPass) + for i = nPass, 1, -1 do + -- inserisco la lavorazione di contornatura + local sNameF = 'DtMt_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nPass) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto offset + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, false, true)) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessDtMortise diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDtTenon.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDtTenon.lua new file mode 100644 index 0000000..69cce17 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessDtTenon.lua @@ -0,0 +1,314 @@ +-- ProcessTenon.lua by Egaltech s.r.l. 2020/11/08 +-- Gestione calcolo tenone a coda di rondine per Travi + +-- Tabella per definizione modulo +local ProcessDtTenon = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTenon started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + + +--------------------------------------------------------------------- +local function VerifyOrientation( Proc, vtN, b3Raw) + -- se trave molto bassa + if b3Raw:getDimZ() <= 120 then + -- se tenone praticamente in asse, accetto fino a -45 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.7072) + -- altrimenti accetto fino a -30deg + else + return ( vtN:getZ() >= -0.51) + end + -- se trave bassa + elseif b3Raw:getDimZ() <= 200 then + -- se tenone praticamente in asse, accetto fino a -30 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.51) + -- altrimenti accetto fino a -20deg + else + return ( vtN:getZ() >= -0.343) + end + -- se trave media + elseif b3Raw:getDimZ() <= 300 then + -- se tenone praticamente in asse, accetto fino a -20 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.343) + -- altrimenti, accetto fino a -10 deg + else + return ( vtN:getZ() >= -0.174) + end + -- altrimenti + else + -- accetto fino a -5deg + return ( vtN:getZ() >= -0.088) + end +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDtTenon.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 55) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDtTenon.Classify( Proc, b3Raw) + -- recupero i dati della curva di contorno della faccia top + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se il tenone è lavorabile solo da sotto + local bDown = not VerifyOrientation( Proc, vtExtr, b3Raw) + return true, bDown +end + +--------------------------------------------------------------------- +local function ApplyPocket( Proc, sPocketing, nStep, dSurfStep, nIdSurf, vtExtr) + + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. nStep + local nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nIdSurf, -1}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + if dSurfStep > 0 then + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dSurfStep, 2) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDtTenon.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') 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') + 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 + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + -- verifico che il tenone non sia orientato verso il basso + if not VerifyOrientation( Proc, vtExtr, b3Raw) then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' DtTenon from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza del tenone + local frDtTen = Frame3d( ptBC, vtExtr) + local b3DtTen = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frDtTen) + local dDtTenH = b3DtTen:getDimZ() + -- assegno centro e normale della faccia top + local vtN = vtExtr + local ptC = ptBC + vtN * dDtTenH + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- porto inizio curva a Zmax + BL.PutStartOnTop( AuxId) + -- se tenone inclinato o non esattamente alle estremità, necessario taglio di lama sulla testa + if not AreSameOrOppositeVectorApprox( vtN, X_AX()) or + ( Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dOvmHead - 100 * GEO.EPS_SMALL and + Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 100 * GEO.EPS_SMALL) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla testa del tenone e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC, vtN, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- se pezzo piccolo, in coda e piano inclinato attorno a Z applico svuotatura + if b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getX() < 0 and abs( vtExtr:getY()) > 0.173 then + local sPocketing = ML.FindPocketing( 'OpenPocket') + local dMaxDepth = 100 + local dStep = 30 + local nSurfStep + -- acquisisco i dati necessari dall'utensile + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dStep + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- acquisisco elevazione + local dElev = BL.GetFaceElevation( AddId, 0, nPartId) + nSurfStep = ceil( dElev / dMaxDepth) + dSurfStep = dElev / nSurfStep + local bOk = true + local sErr + -- copio superfice al passo superfice e ci applico la lavorazione + for i = nSurfStep, 2, -1 do + local nAddIdTmp = EgtSurfTmPlaneInBBox( nAddGrpId, ptC+((dSurfStep*(i-1))*vtN), vtN, b3Solid, GDB_RT.GLOB) + if nAddIdTmp then + EgtSetName( nAddIdTmp, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( nAddIdTmp, 'TASKID', Proc.TaskId) + -- aggiungo lavorazione + bOk, sErr = ApplyPocket( Proc, sPocketing, i, (dSurfStep + 0), nAddIdTmp, vtExtr) + if not bOk then + break + end + end + end + if not bOk then + return false, sErr + end + -- faccio ultima superfice + bOk, sErr = ApplyPocket( Proc, sPocketing, 1, EgtIf( nSurfStep > 1, ( dSurfStep + 0), 0), AddId, vtExtr) + if not bOk then + return false, sErr + end + -- altrimenti applico taglio di lama + else + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getZ() > 0.25) + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom) + if not bOk then return bOk, sErr end + end + end + end + -- recupero la lavorazione + local sMchExt = EgtIf( vtExtr:getZ() < 0.51 and BD.DOWN_HEAD, '_H2', '') + local sMilling = ML.FindMilling( 'DtTenon'..sMchExt) + 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 dTDiam = 50 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- calcolo distanza massima della curva dal punto più lontano della base tenone Dt (facet 0) + local dMaxDist = 0 + local nLoopId, nLoopCnt = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id)) + if nLoopId then + local dUmin, dUmax = EgtCurveDomain( nLoopId) + for dU = dUmin, dUmax do + local ptP = EgtUP( nLoopId, dU, GDB_ID.ROOT) + local ptNear = EgtNP( AuxId, ptP, GDB_ID.ROOT) + local dDist = dist( ptP, ptNear) + if dDist > dMaxDist then + dMaxDist = dDist + end + end + for i = 1, nLoopCnt do + EgtErase( nLoopId + i - 1) + end + else + local b3DtAux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frDtTen) + dMaxDist = 2 * ( b3DtTen:getRadius() - b3DtAux:getRadius()) + end + EgtOutLog( 'MaxDist=' .. EgtNumToString( dMaxDist, 3), 3) + -- Cicli di lavorazione (max 6) + local MAX_PASS = 6 + local nStep = min( ceil( dMaxDist / ( 0.7 * dTDiam)), MAX_PASS) + local dStep = min( dMaxDist, 0.7 * dTDiam * MAX_PASS) / nStep + for i = nStep, 1, -1 do + -- inserisco la passata di lavorazione + local sNameR = 'DtTn_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchRId = EgtAddMachining( sNameR, sMilling) + if not nMchRId then + local sErr = 'Error adding machining ' .. sNameR .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo i parametri + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dDtTenH, 1) .. ';') + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = MCH_SCC.ADIR_YM + if abs( vtExtr:getY()) > 0.088 then + nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchRId, false) + return false, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if abs( vtN:getY()) > 0.1 or ( b3Raw:getDimZ() - Proc.Box:getDimZ()) < BD.MIN_HEIGHT then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessDtTenon diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessFreeContour.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessFreeContour.lua new file mode 100644 index 0000000..02404dc --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessFreeContour.lua @@ -0,0 +1,655 @@ +-- ProcessFreeContour.lua by Egaltech s.r.l. 2020/11/20 +-- Gestione calcolo profilo libero per Travi + +-- Tabella per definizione modulo +local ProcessFreeContour = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessFreeContour started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sDepthChamferMill = 'Q02' -- d +local sOverMaterialForFinish = 'Q03' -- d +local sPreemptiveChamfer = 'Q00' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessFreeContour.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 250) +end +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessFreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- se pocket, ne verifico la direzione di lavorazione + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + if bPocket then + 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) + return ( vtN:getX() >= 0.5) + end + -- deve occupare una buona parte dell'area + if Proc.Box:getDimY() * Proc.Box:getDimZ() > 0.45 * b3Raw:getDimY() * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessFreeContour.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- se pocket, ne verifico la direzione di lavorazione + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + if bPocket then + 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) + return ( vtN:getX() <= - 0.5) + end + -- deve occupare una buona parte dell'area + if Proc.Box:getDimY() * Proc.Box:getDimZ() > 0.45 * b3Raw:getDimY() * b3Raw:getDimZ() then + return true + end + -- non è di coda + return false +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 true, bDown, false + -- se altrimenti profilo orizzontale + elseif abs( vtN:getZ()) < 0.5 then + return true, false, false + -- se altrimenti profilo verticale che non interessa tutta la sezione + elseif Proc.Box:getDimZ() < 0.9 * b3Raw:getDimZ() then + local bDown = ( vtN:getZ() < - 0.5) + return true, bDown, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'FreeContour') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error : not horizontal chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : Mark not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +local function CalcSpecialAdd( nCrv, bStartVsEnd, dToolDiam) + -- recupero il dominio della curva + local nUi, nUf = EgtCurveDomain( nCrv) + if not nUi then return 0 end + -- indici punti da analizzare + local nOut = EgtIf( bStartVsEnd, nUi, nUf) + local nIn = EgtIf( bStartVsEnd, nUi + 1, nUf - 1) + -- tangenti prima e dopo il punto interno + local vtPrev = EgtUV( nCrv, nIn, -1) + local vtNext = EgtUV( nCrv, nIn, 1) + -- se c'è perdita di tangenza (delta angolare oltre i 5 gradi) + if vtPrev * vtNext < 0.996 then + -- lunghezza del tratto + local ptP0 = EgtUP( nCrv, nOut) + local ptP1 = EgtUP( nCrv, nIn) + local dDist = dist( ptP0, ptP1) + -- se corto rispetto al raggio utensile, ritorno allugamento opportuno + if dDist < 0.6 * dToolDiam then + return ( 0.6 * dToolDiam - dDist + 1) + end + end + return 0 +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : 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 : 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) + local bDown = ( b3Aux:getMin():getZ() < b3Raw:getMin():getZ() + 5) + -- verifico se in testa o coda + local bHead = Proc.Head + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, true, sDepthChamferMill, sPreemptiveChamfer) + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'FreeContour') + if not sMilling then + local sErr = 'Error : FreeContour not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 10 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- ne verifico la lunghezza per eventuale spezzatura e lavorazione in doppio + local nStep = 1 + local dStep = 0 + local dLenMax = BD.LONGCUT_ENDLEN + if b3Aux:getDimX() > dLenMax then + local dCrvLen = EgtCurveLength( AuxId) + nStep = ceil( dCrvLen / dLenMax) + dStep = dCrvLen / nStep + EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) + end + -- eventuale spezzatura sul tratto più lungo se curva chiusa + BL.PutStartOnLonger( AuxId) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local bCross = false + if abs( vtExtr:getY()) > 0.707 then + if b3Aux:getDimY() > b3Raw:getDimY() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimY()) + end + if bDown then + nSide = -1 + else + nSide = 1 + end + elseif abs( vtExtr:getZ()) > 0.707 then + if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimZ()) + end + end + local dOriDepth = dDepth + local nDouble = 1 + local bCanDouble = abs( vtExtr:getY()) > 0.707 and bCross + local bStripOnSide = false + if bCross then + if nStep > 1 or ( bDown and b3Aux:getDimX() > 0.5 * b3Raw:getDimX()) then + -- devo lasciare un codolo + dDepth = dDepth - BD.DIM_STRIP + bStripOnSide = true + else + -- devo affondare un poco oltre + dDepth = dDepth + BD.CUT_EXTRA + end + end + -- se parametro beamdata forza codolo in centro e lavorazione orizzontale e se larghezza trave è sufficientemente larga + if BD.DIM_TO_CENTER_STRIP and BD.DIM_TO_CENTER_STRIP > 10 * GEO.EPS_SMALL and nStep > 1 and + bCanDouble and b3Raw:getDimY() > BD.DIM_TO_CENTER_STRIP - 0.1 then + nDouble = 2 + dDepth = min( ( b3Raw:getDimY() - BD.DIM_STRIP) * 0.5, dMaxDepth) + else + -- se altezza geometria supera capacità taglio utensile ed è orizzontale setto per eseguire codolo in centro + if dDepth > dMaxDepth then + if bCanDouble then + nDouble = 2 + dDepth = min( 0.5 * dDepth, dMaxDepth) + else + dDepth = dMaxDepth + end + end + end + -- se utensile orizzontale verso Y+, non in doppio e codolo da lasciare, devo invertire per lavorare sempre da Y- + if vtExtr:getY() > 0.707 and nDouble == 1 and bStripOnSide then + bToolInv = true + end + -- verifico se primo e ultimo tratti corti e con angolo + local dStartAddSpec = CalcSpecialAdd( AuxId, true, dToolDiam) + local dEndAddSpec = CalcSpecialAdd( AuxId, false, dToolDiam) + -- se devo inserire il chamfer + if nChamfer > 0 and Proc.Grp ~= 0 and dOriDepth > dDepthCham then + local bDoubleCham = false + local dExtra = 2 + -- eseguo + for i = 1, nStep do + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + end + if Proc.Grp == 3 then + if not bToolInv then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + end + if Proc.Grp == 4 then + if not bToolInv then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- eventuale accorciamento di testa + if i > 1 then + local dStartAddLen = - ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen + 1) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddSpec + 1) + end + -- eventuale accorciamento di coda + if i < nStep then + local dEndAddLen = - ( nStep - i) * dStep + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen + 1) + else + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddSpec + 1) + end + -- posizione braccio porta testa + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + if Proc.Grp == 3 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + elseif Proc.Grp == 4 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- eventuale accorciamento di testa + if i < nStep then + local dEndAddLen = - ( nStep - i) * dStep + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen + 1) + else + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddSpec + 1) + end + -- eventuale accorciamento di coda + if i > 1 then + local dStartAddLen = - ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen + 1) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddSpec + 1) + end + -- posizione braccio porta testa + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + end + -- verifico se devo fare sgrossatura più finitura + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- eseguo + for i = 1, nStep do + for j = 1, nDouble do + local sName + local nMchId + local bEnableCham + -- se ho smusso abilitato e profondità geometria minore della profondità smusso, + -- applico lavorazione smusso + if nChamfer > 0 and dOriDepth <= dDepthCham then + -- inserisco la lavorazione + sName = 'FreeCham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + dOffsetPar = 0 + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham) + bEnableCham = true + else + -- inserisco la lavorazione + sName = 'Free_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- eventuale accorciamento di testa + if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then + local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( j == 1, dStartAddSpec, dEndAddSpec)) + end + -- eventuale accorciamento di coda + if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then + local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + else + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( j == 1, dEndAddSpec, dStartAddSpec)) + end + -- se estrusione da sotto, inverto direzione fresa + if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- se seconda passata, inverto direzione di lavoro + if j == 2 then + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- 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 + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- acquisisco parametro sovramateriale + local bFinish + local dOriOffset = 0 + -- se parametro sovramateriale è maggiore di 0 abilito la finitura extra + if not bEnableCham and dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + elseif bEnableCham and Proc.Grp ~= 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, dDepthCham) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sNewName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByPocket( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- 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, nPhase, nRawId, nPartId, dOvmHead) + -- recupero la tipologia + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- se svuotatura + if bPocket then + return MakeByPocket( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- altrimenti contornatura + else + return MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead) + end +end + +--------------------------------------------------------------------- +return ProcessFreeContour diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessFrenchRidgeLap.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessFrenchRidgeLap.lua new file mode 100644 index 0000000..8d301b2 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessFrenchRidgeLap.lua @@ -0,0 +1,278 @@ +-- ProcessFrenchRidgeLap.lua by Egaltech s.r.l. 2020/02/11 +-- Gestione calcolo giunzione francese + +-- Tabella per definizione modulo +local ProcessFrenchRidgeLap = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessFrenchRidgeLap started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessFrenchRidgeLap.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 35) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessFrenchRidgeLap.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessFrenchRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getX()) > GEO.EPS_SMALL and abs( vtN[i]:getY()) > GEO.EPS_SMALL and abs( vtN[i]:getZ()) > GEO.EPS_SMALL then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + bHead = ( vtN[vFaceOrd[1]]:getX() > 0) + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + local dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < (#vCuts-1) or (i == #vCuts) then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO = Vector3d( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + else + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO = Vector3d( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + -- altrimenti di fianco + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + -- altrimenti di fianco + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessFrenchRidgeLap diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessHeadCut.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessHeadCut.lua new file mode 100644 index 0000000..7a0a34a --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessHeadCut.lua @@ -0,0 +1,215 @@ +-- ProcessSplit.lua by Egaltech s.r.l. 2020/06/16 +-- Gestione calcolo tagli di testa per Travi + +-- Tabella per definizione modulo +local ProcessHeadCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessHeadCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessHeadCut.Identify( Proc) + return ( Proc.Grp == 1 and Proc.Prc == 340) +end + +--------------------------------------------------------------------- +-- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) +local function VerifyCurveForChamfer( AuxId) + if not AuxId then + return -2 + end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + return -1 + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- va bene solo se direzione estrusione orizzontale + if abs( vtExtr:getZ()) > 0.1 then + return 0 + end + return 1 +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( nOriId, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico le entità curva associate (max 2) + local sVal = EgtGetInfo( nOriId, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local AuxId, Aux2Id + if vsAuxId and #vsAuxId >=1 then + AuxId = tonumber( vsAuxId[1]) + end + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if AuxId then AuxId = AuxId + nOriId end + if Aux2Id then Aux2Id = Aux2Id + nOriId end + local nRes = VerifyCurveForChamfer( AuxId) + if nRes == 0 and Aux2Id then + AuxId = Aux2Id + nRes = VerifyCurveForChamfer( AuxId) + end + if nRes == -2 then + return true + end + if nRes == -1 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + if nRes == 0 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true, nil +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessHeadCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bNeedHCut) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- inserimento smussi + local nOriId = EgtGetInfo( Proc.Id, 'ORI', 'i') + if nOriId then + local bOkc, sErrC = MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 50 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- caratteristiche taglio + local bHorizCut = ( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL and b3Raw:getDimZ() < dMaxDepth - BD.CUT_EXTRA) + local dDimYRef = EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, dMaxDepth - BD.CUT_EXTRA, BD.MAX_DIM_HTCUT_HBEAM) + local bDoubleCut = ( not bHorizCut and b3Raw:getDimY() > dDimYRef + 10 * GEO.EPS_SMALL) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- se non obbligatorio e coincide con inizio grezzo, non va fatto + if not bNeedHCut and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX()) < 10 * GEO.EPS_SMALL then + return true + end + -- flag di lavorazione faccia + local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_FRONT) + -- determino se più tagli con offset + local nCuts = max( ceil( dOvmHead / ( BD.MAX_LEN_SCRAP_START or BD.MAX_LEN_SCRAP)), 1) + local dOffsL = dOvmHead / nCuts + -- calcolo extra taglio ed accorciamento + local dCutExtra = 0 + local dAccStart = 0 + if b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL or b3Raw:getDimY() < 2 * BD.MAX_DIM_HTCUT_HBEAM + 10 * GEO.EPS_SMALL then + dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN, BD.CUT_EXTRA) + dAccStart = 0 + else + dCutExtra = - ( b3Raw:getDimY() - dMaxDepth - BD.CUT_EXTRA) + local dSawRad = dSawDiam / 2 + local dKL = dSawRad - dMaxDepth + b3Raw:getDimY() / 2 + BD.CUT_EXTRA_MIN + dAccStart = sqrt( dSawRad * dSawRad - dKL * dKL) + end + -- se necessari tagli in doppio, eseguo gli opposti + if bDoubleCut then + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_BACK, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, '', b3Raw) + if not bOk then return false, sErr end + end + end + -- eseguo i tagli necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, '', b3Raw) + if not bOk then return false, sErr end + end + return true +end + +--------------------------------------------------------------------- +return ProcessHeadCut diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessLapJoint.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessLapJoint.lua new file mode 100644 index 0000000..437982a --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessLapJoint.lua @@ -0,0 +1,3879 @@ +-- ProcessLapJoint.lua by Egaltech s.r.l. 2021/01/26 +-- Gestione calcolo mezzo-legno per Travi +-- 2019/10/08 Agg. gestione OpenPocket. +-- 2021/01/24 Con sega a catena ora sempre impostato asse A. + +-- Tabella per definizione modulo +local ProcessLapJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') +local DoubleCut = require( 'ProcessDoubleCut') +local LongCut = require( 'ProcessLongCut') +local Long2Cut = require( 'ProcessLongDoubleCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessLapJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sForceUseBlade = '' -- i +local sDepthChamferMill = '' -- d +local sPreemptiveChamfer = '' -- i +local sUseMill = '' -- i +local sUseRoughTool = '' -- i +local sUseRoughToolWithBAxis90 = '' -- i +local sUseRoughToolWithBAxis0 = '' -- i +local sInsertBoreOnCorner = '' -- 1 +local sMakeContourWithSmallTool = '' -- i +local sMakeOnlyContourOrFullPocket = '' -- i +local sMakeBySideRoughTool = '' -- i +local sAntisplintMode = '' -- i + +-- variabile smussi +local bMadeChamfer + +-- Settaggi interni +local bTrySidePocketAtFirst = true + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLapJoint.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 33) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or + ( Proc.Grp == 4 and Proc.Prc == 37) or + ( Proc.Grp == 4 and Proc.Prc == 39) or + ( Proc.Grp == 4 and Proc.Prc == 120)) +end + +--------------------------------------------------------------------- +local function AssignQValues( Proc) + + -- reset delle variabili assegnazione parametri Q + sForceUseBlade = '' + sDepthChamferMill = '' + sPreemptiveChamfer = '' + sUseMill = '' + sUseRoughTool = '' + sUseRoughToolWithBAxis90 = '' + sUseRoughToolWithBAxis0 = '' + sInsertBoreOnCorner = '' + sMakeContourWithSmallTool = '' + sMakeOnlyContourOrFullPocket = '' + sMakeBySideRoughTool = '' + sAntisplintMode = '' + + if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then + sForceUseBlade = 'Q01' -- i + sDepthChamferMill = 'Q04' -- d + sPreemptiveChamfer = 'Q05' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then + sDepthChamferMill = 'Q01' -- d + sPreemptiveChamfer = 'Q02' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then + sDepthChamferMill = 'Q01' -- d + sUseMill = 'Q02' -- i + sUseRoughTool = 'Q03' -- i + sUseRoughToolWithBAxis90 = 'Q04' -- i + sUseRoughToolWithBAxis0 = 'Q05' -- i + sInsertBoreOnCorner = 'Q06' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25 then + sInsertBoreOnCorner = 'Q01' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then + sMakeContourWithSmallTool = 'Q01' -- i + sMakeOnlyContourOrFullPocket = 'Q02' -- i + sMakeBySideRoughTool = 'Q03' -- i + sAntisplintMode = 'Q06' -- i + sDepthChamferMill = 'Q07' -- d + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then + sMakeBySideRoughTool = 'Q01' -- i + end + -- le altre features gestite non hanno parametri Q nei parametri globali +end + +--------------------------------------------------------------------- +local function TestElleShape3( Proc) + -- valida solo nel caso di tre facce + if Proc.Fct ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +local function TestElleShape4( Proc) + -- valida solo nel caso di quattro facce + if Proc.Fct ~= 4 then return false end + -- determino se L con due facce terminali o O + local nFac3Adj = 0 + local dMinArea3 = GEO.INFINITO * GEO.INFINITO + local dMaxArea2 = 0 + for i = 1, 4 do + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, i - 1, GDB_ID.ROOT) + local dArea = dH * dV + if nCount == 2 then + dMaxArea2 = max( dMaxArea2, dArea) + elseif nCount == 3 then + dMinArea3 = min( dMinArea3, dArea) + nFac3Adj = nFac3Adj + 1 + end + end + if nFac3Adj ~= 2 then return false end + -- verifico se L profonda oppure lunga + if dMinArea3 < dMaxArea2 then + return 1 + else + return 2 + end +end + +--------------------------------------------------------------------- +local function VerifySawChain( Proc, dMinDim, dMaxDim, vtOrtho) + local bUseSawChain = false + local sMchFind = 'Sawing' + local sSawing = ML.FindSawing(sMchFind) + local dMaxMat = 0 + local dSawCornerRad = 0 + local dSawThick = 0 + local dMaxDepth = 200 + -- se non trova una lavorazione di sawing esco + if not sSawing then + return bUseSawChain + else + -- recupero i dati dell'utensile + local dToolLength = 0 + local dSawWidth = 75 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dSawCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) or dSawCornerRad + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + if dSawThick < dMinDim + 10 * GEO.EPS_SMALL and dSawWidth < dMaxDim + 10 * GEO.EPS_SMALL then + bUseSawChain = true + end + end + end + return bUseSawChain, sSawing, dMaxMat, dSawCornerRad, dSawThick, dMaxDepth +end + +--------------------------------------------------------------------- +local function VerifyIfPocket( Proc, dDiam, vtOrtho, sMchFindMaster) + local bUsePocketing = false + local sMchFind = 'Pocket' + if sMchFindMaster and #sMchFindMaster > 0 then + sMchFind = sMchFindMaster + end +-- local dCollSic = 2 * BD.COLL_SIC +-- if abs( vtOrtho:getX()) > 0.996 or abs( vtOrtho:getY()) > 0.996 or abs( vtOrtho:getZ()) > 0.996 then dCollSic = BD.COLL_SIC end + local sPocketing = ML.FindPocketing( sMchFind, dDiam) + local dMaxMat = 0 + -- se non trova una svuotatura adatta + if not sPocketing then + return bUsePocketing + else + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + bUsePocketing = true + end + end + return bUsePocketing, sPocketing, dMaxMat +end + +--------------------------------------------------------------------- +local function VerifyIfByBHSideMill( Proc) + local bUseBHSideMill = false + local bHead = true + local sMilling + local dMaxMat = 10 + -- se non feature BlockHausHalfLap e non abilitato parametro Q per lavorarlo di fianco esco + local nUseSideTool = EgtGetInfo( Proc.Id, sMakeBySideRoughTool, 'i') or 0 + if Proc.Prc ~= 37 and nUseSideTool == 0 then + return false + end + -- verifico se U + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) + -- se U e lunghezza non richiede spezzatura + if bIsU and Proc.Box:getDimX() <= BD.LONGCUT_MAXLEN then + -- recupero la lavorazione + sMilling = ML.FindMilling( 'BHSideMill') + if sMilling then + -- recupero i dati dell'utensile + local dToolLength = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + end + -- verifico se la feature è abbastanza vicino a testa/coda da permettere la lavorazione con questo utensile + -- recupero l'ingombro della trave + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if b3Solid then + local dMinXF = Proc.Box:getMin():getX() + local dMaxXF = Proc.Box:getMax():getX() + local dMinT = b3Solid:getMin():getX() + local dMaxT = b3Solid:getMax():getX() + -- determino se è più vicino alla testa o al bordo + bHead = ( dMaxT - dMinXF) < ( dMaxXF - dMinT) + -- determino se è compatibile con il massimo affondamento dell'utensile + bUseBHSideMill = EgtIf( bHead, (dMaxT - dMinXF), (dMaxXF - dMinT)) < dMaxDepth + end + end + end + return bUseBHSideMill, bHead, sMilling, dMaxMat +end + +--------------------------------------------------------------------- +local function GetTunnelDimension( Proc, nPartId) + -- ottengo i versori delle 4 facce e ottengo l'orientamento del tunnel + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( Proc.Id) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- variabili dimensioni fessura e id faccia lunga + local dDimMin + local dDimMax + local nLongIdFace = 0 + local bOppoFace = false + -- ottengo il versore ortogonale + local ptN1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + local vtOrtho = vtN1 ^ vtN2 + if vtOrtho:isSmall() then + _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT) + vtOrtho = vtN1 ^ vtN2 + bOppoFace = true + end + -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta la profondità della fessura + local frFc = Frame3d( ptN1, vtOrtho) ; + local bBoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) + local dDepth = bBoxLoc:getDimZ() + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- mi assicuro che la Z del punto utilizzato per creare la superficie sia alla Z media del bounding box locale + local ptN2 = Point3d(ptN1) + ptN2:toLoc(frFc) + ptN2 = Point3d( ptN2:getX(), ptN2:getY(), ( bBoxLoc:getMin():getZ() + bBoxLoc:getMax():getZ())/2) + ptN2:toGlob(frFc) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN2, vtOrtho, b3Solid, GDB_ID.ROOT) + -- ritaglio la superficie con le facce della fessura + for i = 1, nFacCnt do + local ptN, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) + end + local _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT) + dDimMin = min( DimH, DimV) + dDimMax = max( DimH, DimV) + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacCnt-1, GDB_ID.ROOT) + -- se faccia pari alla larghezza fessura + if abs(DimH - dDimMax) < GEO.EPS_SMALL or abs(DimV - dDimMax) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + -- altrimenti verifico anche con la faccia precedente + else + local nFaceToCheck = EgtIf( bOppoFace, nFacCnt-3, nFacCnt-2) + -- prendo le dimensioni della faccia e poi confronto con il minimo + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFaceToCheck, GDB_ID.ROOT) + -- se trovato con il minimo, questa seconda faccia non è la più lunga + if abs(DimH - dDimMin) < GEO.EPS_SMALL or abs(DimV - dDimMin) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + else + nLongIdFace = nFaceToCheck + end + end + if not dDimMax then + return dDimMin, dDimMax, dDepth, nil, nil + end + return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt +end + +--------------------------------------------------------------------- +local function GetFaceAdj( Proc, nFacInd, dH, dV, bOutLog) + + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + return -1, sErr + end + if bOutLog then + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + end + -- Riordino le dimensioni per avere dH > dV + if dH < dV then + dH, dV = dV, dH + end + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > 0.5 * dH then + nFacAdj = vAdj[i] + if bOutLog then + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) + end + break + end + end + end + if not nFacAdj then + local sErr = 'Error : main face without long adjacent face' + return -1, sErr + end + return nFacAdj +end + +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() > 0.1 then + return true + end + end + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 *b3Raw:getDimX()) then + return false + end + -- se una o due facce ora è sicuramente di testa + if Proc.Fct <= 2 then + return true + end + -- deve avere la normale principale diretta verso la testa + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN and vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN and vtN:getX() < 0.499 then + return false + elseif Proc.Fct >= 5 then + return true + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessLapJoint.IsTailFeature( Proc, b3Raw) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() < -0.1 then + return true + end + end + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- se può essere fatto con utensile tipo lama + local bUseBHSideMill, bHead = VerifyIfByBHSideMill( Proc) + if bUseBHSideMill then + return not bHead + end + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then + return false + end + -- recupero identificativo del pezzo + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + -- se due facce e interessa veramente la coda, allora di coda + if Proc.Fct <= 2 then + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then + return true + end + end + -- deve avere la normale principale diretta verso la coda (oppure tunnel) + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN and vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if not vtN or vtN:getX() > -0.499 then + return false + else + return true + end +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLapJoint.Classify( Proc, b3Raw) + -- se 1 faccia + if Proc.Fct == 1 then + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + --local bDown = ( vtN:getZ() < BD.NZ_MINA) + --return true, bDown + return true, false + -- se 2 facce + elseif Proc.Fct == 2 then + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bSmall = ( ( Proc.Head or Proc.Tail) and Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) or + ( not ( Proc.Head or Proc.Tail) and Proc.Box:getDimY() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or + ( vtN[1]:getZ() < BD.NZ_MINA and ( vtN[2]:getZ() < -0.1 or not bSmall)) or + ( vtN[2]:getZ() < BD.NZ_MINA and ( vtN[1]:getZ() < -0.1 or not bSmall)) + return true, bDown + -- se più di 2 facce + else + local bClosedOrthoFaces + local nDeletedFace + -- recupero la faccia con il maggior numero di adiacenze e minor elevazione + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + else + return false + end + end + -- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche + if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + return false + end + -- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura + for i = 1, Proc.Fct do + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + -- elimino una faccia + nDeletedFace = i - 1 + if EgtSurfTmRemoveFacet( nNewProc, nDeletedFace) then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( nNewProc, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + EgtErase( nNewProc) + break + else + EgtErase( nNewProc) + return false + end + end + -- altrimenti esco + else + EgtErase( nNewProc) + break + end + end + -- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo + if bClosedOrthoFaces then + nFacInd = nDeletedFace + -- rendo nulla la faccia opzionale perchè si tratta di una fessura + nFacInd2 = nil + dElev = BL.GetFaceElevation( Proc.Id, nFacInd) + bClosedOrthoFaces = false -- non lo setto come tunnel + end + end + -- se facce formano un tunnel e sono ortogonali + if bClosedOrthoFaces then + -- ottengo le dimensioni del tunnel + local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId) + EgtErase(nSurfInt) + -- verifico se può essere fatto con svuotatura + if VerifyIfPocket( Proc, dDimMin, vtOrtho) then + return true, false + elseif VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho) then + return true, false + else + return false + end + else + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se può essere fatto con utensile tipo lama + local bUseBHSideMill, _, _, dMaxMat = VerifyIfByBHSideMill( Proc) + if bUseBHSideMill and ( dMaxMat <= dV + 15 * GEO.EPS_SMALL) then + return true, false + -- altrimenti controllo se deve essere ruotato con le altre lavorazioni + else + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- cerco se c'è faccia adiacente sul lato più lungo + local nFaceAdj = GetFaceAdj( Proc, nFacInd, dH, dV) or -1 + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2) + -- verifico se è lavorabile solo dal basso + local bDown = ( vtN:getZ() < BD.NZ_MINA) + -- se verso il basso, verifico se utilizzabile seconda faccia + if bDown then + if nFacInd2 and dElev2 < 2 * dElev then + local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINB) + elseif not nFacInd2 and bIsL and nFaceAdj >= 0 then + local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINB) + end + -- verifico se la faccia principale è sottosquadra, ha forma L e anche la faccia adiacente + elseif vtN:getZ() < -10 * GEO.EPS_SMALL and bIsL and nFaceAdj >= 0 then + -- box del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- se il numero di facce > 2 or il box della feature supera una certa distanza dalle teste allora controllo la z della faccia ausiiaria + if Proc.Fct > 2 or ( Proc.Box:getMax():getX() < b3Solid:getMin():getX() - 150) or ( Proc.Box:getMin():getX() > b3Solid:getMax():getX() + 150) then + local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINB) + end + end + return true, bDown + end + end + end +end + +--------------------------------------------------------------------- +-- Lavorazione con fresa +--------------------------------------------------------------------- +local function MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se orientata verso l'alto + local bUp = ( vtN:getZ() >= BD.NZ_MINA) + -- scelta faccia da lavorare + local nFacInd = 0 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'BirdsMouth') + if not sMilling then + local sErr = 'Error : BirdsMouth not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + if vtN:getX() > 0 then + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_LEFT, MCH_MILL_FU.PARAL_LEFT)) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.PARAL_RIGHT)) + end + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + if not bUp then EgtSetMachiningParam( MCH_MP.INVERT, true) end + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- predispongo lavorazione + local sMilling + -- verifico il parametro Q per uso fresa + local nUseRM = EgtGetInfo( Proc.Id, sUseMill, 'i') + if nUseRM and nUseRM == 1 then + sMilling = ML.FindMilling( 'LongSmallCut') + else + sMilling = ML.FindMilling( 'BirdsMouth') + end + -- recupero la lavorazione + local dTDiam = 0 + if not sMilling then + local sErr = 'Error : LongSmallCut & BirdsMouth not found in library' + EgtOutLog( sErr) + return false, sErr + else + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + end + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- dati medi + local ptM = ( ptC[1] + ptC[2]) / 2 + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error : LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- scelta faccia da lavorare + local nFacInd + -- se entrambe possibili + if bFaceOk[1] and bFaceOk[2] then + -- se in testa, scelgo quella orientata verso la testa + if Proc.Head then + if vtN[1]:getX() > vtN[2]:getX() then + nFacInd = 0 + else + nFacInd = 1 + end + -- se altrimenti in coda, scelgo quella orientata verso la coda + elseif Proc.Tail then + if vtN[1]:getX() < vtN[2]:getX() then + nFacInd = 0 + else + nFacInd = 1 + end + -- altrimenti, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+) + else + if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then + if ptM:getX() > b3Raw:getCenter():getX() then + nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1) + else + nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1) + end + else + nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1) + end + end + elseif bFaceOk[1] then + nFacInd = 0 + else + nFacInd = 1 + end + local nOthInd = 1 - nFacInd + local sName + local nMchFId + local nFaceUse + -- se forzato uso fresa controllo se posso fare in una o più passate + if nUseRM and nUseRM == 1 then + -- prendo la larghezza della faccia + local _, pPt1, pPt2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOthInd, GDB_ID.ROOT) + local dDistPoint = dist( pPt1, pPt2) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local dWidth = EgtIf( abs( dDistPoint - dH) < abs( dDistPoint - dV), dV, dH) + -- se larghezza faccia maggiore diametro utensile aggiungo una lavorazione + if dTDiam > 0 and dWidth > dTDiam then + -- inserisco la lavorazione di fresatura + sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_1' + nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- tolgo l'inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- aggiungo offset laterale + EgtSetMachiningParam( MCH_MP.OFFSR , (dTDiam/2)) + -- imposto posizione braccio porta testa + if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + -- inserisco la lavorazione di fresatura + sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- tolgo l'inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- imposto posizione braccio porta testa + if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + elseif Proc.Box:getCenter():getX() > b3Solid:getCenter():getX() then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + local dDist = b3Solid:getMax():getX() - Proc.Box:getMax():getX() + BL.UpdateHCING( nRawId, dOffs, dDist) + end + end + return true +end + +--------------------------------------------------------------------- +local function MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, nChamfer) + -- se interessa l'intera sezione della trave, necessaria sgrossatura + if nChamfer < 2 and Proc.Box:getDimY() > 0.9 * b3Raw:getDimY() and Proc.Box:getDimZ() > 0.9 * b3Raw:getDimZ() then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo sgrossatura e la lavoro + local AddId = EgtSurfTmConvexHullInBBox( nAddGrpId, Proc.Id, b3Raw, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local nCutFacet = EgtSurfTmFacetCount( AddId) + if nCutFacet == 1 then + return Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + elseif nCutFacet == 2 then + return DoubleCut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + end + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev, bSpecialApp, sMillMaster, nFacInd2, dFacElev2) + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj, sErr = GetFaceAdj( Proc, nFacInd, dH, dV, true) + if nFacAdj < 0 then + EgtOutLog( sErr) + return false, sErr + end + -- Determino se estremi aperti o chiusi e faccia adiacente da aggiungere alla lavorazione + local bOpenStart = false + local bOpenEnd = false + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) + local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacAdj, GDB_ID.ROOT) + -- Riordino le dimensioni per avere dH > dV + if dH2 < dV2 then + dH2, dV2 = dV2, dH2 + end + local nFacAdj2 + for j = 1, #vAdj2 do + if vAdj2[j] == nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + -- decommentare questa parte per concatenare due facce + --if bSpecialApp and vAdj2[j] >= 0 then + -- local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacAdj, vAdj2[j], GDB_ID.ROOT) + -- local dLen = dist( ptP1, ptP2) + -- if abs( dLen - dV2) < 10 * GEO.EPS_SMALL then + -- nFacAdj2 = vAdj2[j] + -- end + --end + end + -- Recupero la lavorazione di fresa + local sMilling + if bSpecialApp then + sMilling = sMillMaster + else + sMilling = ML.FindMilling( 'LongSmallCut') + if not sMilling then + sErr = 'Error : LongSmallCut not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dTDiam = 50 + local dMaxMat = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + end + -- Se massimo materiale utensile è molto inferiore dell'elevazione non faccio la lavorazione e do un warning + if dMaxMat > 0 and dMaxMat + 15 < dElev then + sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' ,skipped milling; elevation bigger than max tool depth' + return true, sWarn, dMaxMat + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + if nFacAdj2 then + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj},{ Proc.Id, nFacAdj2}}) + else + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + end + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + if bSpecialApp then + -- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita + if nFacAdj2 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2)) + -- confronto la faccia applicata nella lavorazione(faccia adiacente) con la seconda faccia passata nella funzione + -- se corrispondono allora aggiungo una estensione nei lati chiusi pari all'elevazione della stessa faccia corrispondente + if nFacAdj == nFacInd2 then + if not bOpenStart then + EgtSetMachiningParam( MCH_MP.LOPERP, dFacElev2) + end + if not bOpenEnd then + EgtSetMachiningParam( MCH_MP.LIPERP, dFacElev2) + end + end + end + -- applico elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, 0, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, 0, - dTDiam / 2)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, '', dTDiam +end + +--------------------------------------------------------------------- +local function ChooseCorner( Proc, nFacInd) + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + local tFacAdj = {} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + for j = i+1, #vAdj do + if vAdj[j] >= 0 then + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vAdj[i], vAdj[j], GDB_ID.ROOT) + if ptP1 and ptP2 and dAng < 0 then + local dLen = dist( ptP1, ptP2) + table.insert( tFacAdj, { vAdj[i], vAdj[j], dLen, ptP1, ptP2, dAng}) + end + end + end + end + end + -- tra le linee prendo quella più lunga + local dMaxLen = 0 + local nIdLine + for i = 1, #tFacAdj do + if tFacAdj[i][3] > dMaxLen then + nIdLine = i + dMaxLen = tFacAdj[i][3] + end + end + + return dMaxLen, nIdLine, tFacAdj +end + +--------------------------------------------------------------------- +local function MakeContourCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam) + + local sMyWarn = '' + local pAuxId = {} + local nAuxId + local AuxId + local ptApPoint + local sMilling + local dTrimDist + local dCollSic = BD.COLL_SIC + + -- ottengo gli angoli dove applicare il percorso con fresa più piccola + local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) + -- se non trovato nessun angolo interno valido esco + if #tFacAdj == 0 then + return true, sMyWarn + end + -- prendo il primo versore + local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra + if abs( vtN1:getX()) > 0.7 or abs( vtN1:getY()) > 0.7 or abs( vtN1:getZ()) > 0.7 then dCollSic = 0 end + + -- se fresatura da sotto salto la lavorazione + if vtN1:getZ() < BD.DRILL_VZ_MIN then + local sErr = 'Error : milling from bottom ' + EgtOutLog( sErr) + return false, sErr + end + + -- ciclo su tutti gli angoli trovati + for i = 1, #tFacAdj do + sMyWarn = '' + -- le 2 facce di contatto devono essere perpendicolari o non sottossquadra rispetto alla faccia di fondo + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][1], GDB_ID.ROOT) + local _, ptP1x, ptP2x, dAngx = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][2], GDB_ID.ROOT) + if ( dAng < 0 and 180 + dAng >= 90 - 10 * GEO.EPS_SMALL) and ( dAngx < 0 and 180 + dAngx >= 90 - 10 * GEO.EPS_SMALL) then + -- prendo la lunghezza di adiacenza delle due linee + local dLen1 = dist( ptP1, ptP2) + local dLen2 = dist( ptP1x, ptP2x) + -- cerco il punto tra le 3 facce: nIdEndPoint + local nIdIniPoint + local nIdEndPoint + if ptP1 and ptP2 then + if ( dist( ptP1, tFacAdj[i][4]) < GEO.EPS_SMALL) or ( dist( ptP2, tFacAdj[i][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptP1, tFacAdj[i][5]) < GEO.EPS_SMALL) or ( dist( ptP2, tFacAdj[i][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- se ho il punto comune + if nIdEndPoint then + -- recupero la lavorazione con elevazione pari all'altezza trovata + sMilling = ML.FindMilling( 'LongSmallCut', tFacAdj[i][3] + dCollSic) + if sMilling then + -- recupero i dati dell'utensile + local dTDiam = 50 + local dMaxMat = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + -- se il diametro trovato è minore della metà del diametro utilizzato in precendenza + if dTDiam < ( dDiam / 2) then + -- calcolo lunghezza minima in base all'angolo tra le due pareti + local dMinDist = (( dDiam / 2) / tan( ( 180 + tFacAdj[i][6]) / 2)) + 2 + -- se entrambe le linee sono maggiori delle lunghezza minima proseguo + if dLen1 >= dMinDist and dLen2 >= dMinDist then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[i][nIdEndPoint], ptP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptP2 + else + ptApPoint = ptP1 + end + -- prima linea + nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[i][nIdEndPoint], GDB_RT.GLOB) + -- calcolo arretramento + dTrimDist = dLen1 - dMinDist + -- se arretramento valido + if dTrimDist > 100 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , - dTrimDist, ptApPoint , GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- se il punto finale corrisponde con il punto comune, uso l'altro + if dist( tFacAdj[i][nIdEndPoint], ptP1x) < 10 * GEO.EPS_SMALL then + ptApPoint = ptP2x + else + ptApPoint = ptP1x + end + -- seconda linea + nAuxId = EgtLine( nAddGrpId, tFacAdj[i][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + -- calcolo arretramento + dTrimDist = dLen2 - dMinDist + -- se arretramento valido + if dTrimDist > 100 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , - dTrimDist, ptApPoint , GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- trasformo in percorso + if #pAuxId > 0 then + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + end + -- se c'è il percorso + if AuxId then + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtN1, GDB_RT.GLOB) + -- inserisco la lavorazione + local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if nMchId then + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN1:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4) + -- allungo inizio e fine di 0mm + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + -- setto affondamento 0 + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- setto non inversione del percorso + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( tFacAdj[i][3], 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + if EgtApplyMachining( true, false) then + _, sMyWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + -- altrimenti lavorazione non applicata + else + _, sMyWarn = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + end + -- altrimenti non è ctata inserita lavorazione + else + sMyWarn = 'warning adding machining ' .. sName .. '-' .. sMilling + end + -- altrimenti non c'è il percorso + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' + end + -- altrimenti + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' + end + -- altrimenti diametro trovato è simile a quello già utilizzato +-- else +-- sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' smaller tool not found' + end + -- altrimenti non è stata trovata lavorazione + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library' + end + -- altrimenti non è stato trovato il punto comune +-- else +-- sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' + end + -- altrimenti pareti sottosquadra o angolo aperto +-- else +-- sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' + end + if #sMyWarn > 0 then + EgtOutLog( sMyWarn) + end + end + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function MakeCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam) + + local sMyWarn = '' + local pAuxId = {} + local nAuxId + local AuxId + local ptApPoint + local dLenTrimExt + local sMilling + local dMaxDepth = 0 + + -- ottengo l'angolo di riferimento dove applicare il percorso di pulitura + local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) + -- se non trovato nessun angolo valido esco + if #tFacAdj == 0 then + return true, sMyWarn + end + -- prendo il primo versore + local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local _, vtN3 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local nIdIniPoint + local nIdEndPoint + if ptLocP1 and ptLocP2 then + if ( dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- versore direzione + local vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] + vtExtr:normalize() + -- inserisco le prime tre linee + if nIdIniPoint and nIdEndPoint then + -- se fresatura da sotto salto la lavorazione + if vtExtr:getZ() < BD.DRILL_VZ_MIN then + local sErr = 'Error : clean corner milling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- sommo i tre versori per avre una direzione media + vtExtr = vtN1 + vtN2 + vtN3 + vtExtr:normalize() + -- recupero la lavorazione non calcolando l'elevazione + sMilling = ML.FindMilling( 'CleanCorner', (dDiam*0.5)) + if not sMilling then + local sErr = 'Error : CleanCorner not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile ( temporaneo, per compensare errore nella lavorazione) + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth + end + -- l'altezza di taglio del tagliente corrisponde al raggio del raccordo che si riesce a coprire + -- quindi confronto l'elevazione con il raggio utensile utilizzato per la svuotatura + if dMaxDepth < (dDiam * 0.5) - 100 * GEO.EPS_SMALL then + sMyWarn = 'Warning : skip clean corner (the cut heigth is smaller to machine the corner radius)' + EgtOutLog( sMyWarn) + return false, sMyWarn + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdIniPoint], tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB) + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- inserisco le ultime tre linee + uscita discostata rispetto all'ingresso + -- trovo il secondo punto sulla superfice di riferimento + _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][2], GDB_ID.ROOT) + if ptLocP1 and ptLocP2 then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB) + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- piccolo scostamento di 2mm dall'angolo + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- ultima linea di risalita + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), tFacAdj[nIdLine][nIdIniPoint] + ( 2 * vtExtr), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- trasformo in percorso + if #pAuxId > 0 then + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + end + -- se non c'é il percorso do errore + if not AuxId then + local sErr = 'Error : impossible make clean corner path' + EgtOutLog( sErr) + return false, sErr + end + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- inserisco la lavorazione + local sName = 'Clean_' .. ( 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}}) + -- 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) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4) + -- allungo inizio e fine di 10mm + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- setto affondamento 0 + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + 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 + +--------------------------------------------------------------------- +local function MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam, bSpecialMach) + local sMyWarn = '' + -- ottengo l'angolo dove applicare il foro + local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) + -- se non trovato nessun angolo interno valido esco + if #tFacAdj == 0 then + return true, sMyWarn + end + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local nIdIniPoint + local nIdEndPoint + if ptLocP1 and ptLocP2 then + if ( dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- inserisco foro + if nIdIniPoint and nIdEndPoint then + local vtExtr + if bSpecialMach then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) + vtExtr = vtN0 + vtN1 + vtN2 + else + -- versore direzione + vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] + end + vtExtr:normalize() + -- se foratura da sotto salto la lavorazione + if vtExtr:getZ() < BD.DRILL_VZ_MIN then + local sErr = 'Error : drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sDrilling, nType = ML.FindDrilling( dDiam) + if not sDrilling then + local sErr = 'Error : drilling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 20 + local dDiamTool = 20 + local dDiamTh = 35 + local bIsDrilling + if EgtMdbSetCurrMachining( sDrilling) then + 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 + dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + dDiamTh = EgtTdbGetCurrToolThDiam() + end + end + -- se foro inclinato, limito il massimo affondamento + local CosB = abs( vtExtr:getX()) + if CosB < BD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dMaxDepth = dMaxDepth - dDiamTh / 2 * TgA + else + dMaxDepth = 0 + end + -- setto griglia + if bSpecialMach then + EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdEndPoint], vtExtr)) + else + EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdIniPoint], vtExtr)) + end + -- creo geometria + local AuxId = EgtCircle( nAddGrpId, {0,0,0}, EgtIf( bIsDrilling, dDiamTool/2, ( dDiamTool/2) + 0.1), GDB_RT.GRID) + -- riporto la griglia a globale + EgtSetGridFrame() + -- calcolo spessore + local dDepthBore = dMaxLen + if bSpecialMach then + -- calcolo l'elevazione + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, tFacAdj[nIdLine][nIdEndPoint], vtExtr) + if dLenIn > 0 then + dDepthBore = dLenIn + elseif dLedOut then + dDepthBore = dLedOut + end + EgtModifyCurveThickness( AuxId, dDepthBore) + else + EgtModifyCurveThickness( AuxId, -dMaxLen) + 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}}) + -- 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 dDepth + if bSpecialMach then + dDepth = dDepthBore + else + dDepth = dMaxLen + 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) + end + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione (coincide con affondamento) + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + 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 + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function ExtractExternalPaths( nPathInt, nNumIdAux, vtOrtho, b3Solid, nAddGrpId) + local nAuxId1, nAuxId2 + if nNumIdAux == 1 then + -- fondo tra loro le curve compatibili + EgtMergeCurvesInCurveCompo( nPathInt) + -- esplodo il percorso in modo da avere entià separate per poterle controllare + local nStartId, nNumIds = EgtExplodeCurveCompo( nPathInt) + if nStartId then + local sDeleteByDir + -- Se normale lungo la Z elimino le entità che hanno differenza in Z + if abs(vtOrtho:getZ()) > 0.7 then + sDeleteByDir = 'Z' + -- altrimenti se normale lungo la Y elimino le entità che hanno variazione in Y +-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.7 then + elseif abs(vtOrtho:getY()) > 0.7 then + sDeleteByDir = 'Y' + -- caso che non dovrebbe mai capitare ma gestito per completezza + -- altrimenti se normale lungo la X elimino le entità che hanno variazione in X +-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.7 then + elseif abs(vtOrtho:getX()) > 0.7 then + sDeleteByDir = 'X' + end + if sDeleteByDir then + for i = 1, nNumIds do + local ptP1 = EgtSP( ( nStartId + i - 1), GDB_RT.GLOB) + local ptP2 = EgtEP( ( nStartId + i - 1), GDB_RT.GLOB) + if sDeleteByDir == 'Z' then + -- se hanno variazione in Z cancello l'entità + if abs( ptP1:getZ() - ptP2:getZ()) > 10 * GEO.EPS_SMALL then + EgtErase( nStartId + i - 1) + end + elseif sDeleteByDir == 'Y' then + -- se hanno variazione in Y cancello l'entità + if abs( ptP1:getY() - ptP2:getY()) > 10 * GEO.EPS_SMALL then + EgtErase( nStartId + i - 1) + end + elseif sDeleteByDir == 'X' then + -- se hanno variazione in X cancello l'entità + if abs( ptP1:getX() - ptP2:getX()) > 10 * GEO.EPS_SMALL then + EgtErase( nStartId + i - 1) + end + end + end + -- ricreo i vari percorsi + local dLocalVal + local tPaths = {} + local nNumPaths + local dMaxVal + local dMinVal + for i = 1, nNumIds do + local ptP1 = EgtSP( ( nStartId + i - 1), GDB_RT.GLOB) + if ptP1 then + if sDeleteByDir == 'Z' then + local bInsTab + for j = 1, #tPaths do + local dLocalVal = tPaths[j][2] + if abs( ptP1:getZ() - dLocalVal) < 10 * GEO.EPS_SMALL then + local tLocIds = tPaths[j][1] + table.insert( tLocIds, ( nStartId + i - 1)) + tPaths[j][1] = tLocIds + bInsTab = true + end + end + -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella + if not bInsTab then + table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getZ()}) + dMaxVal = b3Solid:getMax():getZ() + dMinVal = b3Solid:getMin():getZ() + end + elseif sDeleteByDir == 'Y' then + local bInsTab + for j = 1, #tPaths do + local dLocalVal = tPaths[j][2] + if abs( ptP1:getY() - dLocalVal) < 10 * GEO.EPS_SMALL then + local tLocIds = tPaths[j][1] + table.insert( tLocIds, ( nStartId + i - 1)) + tPaths[j][1] = tLocIds + bInsTab = true + end + end + -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella + if not bInsTab then + table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getY()}) + dMaxVal = b3Solid:getMax():getY() + dMinVal = b3Solid:getMin():getY() + end + elseif sDeleteByDir == 'X' then + local bInsTab + for j = 1, #tPaths do + local dLocalVal = tPaths[j][2] + if abs( ptP1:getX() - dLocalVal) < 10 * GEO.EPS_SMALL then + local tLocIds = tPaths[j][1] + table.insert( tLocIds, ( nStartId + i - 1)) + tPaths[j][1] = tLocIds + bInsTab = true + end + end + -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella + if not bInsTab then + table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getX()}) + dMaxVal = b3Solid:getMax():getX() + dMinVal = b3Solid:getMin():getX() + end + end + end + end + + if tPaths then + local tChamPath = {} + -- elimino quelle che non corrispondono agli estremi + for i = 1, #tPaths do + -- se non corrisponde ai limiti elimino l'elemento + if abs( tPaths[i][2] - dMaxVal) > 10 * GEO.EPS_SMALL and abs( tPaths[i][2] - dMinVal) > 10 * GEO.EPS_SMALL then + tPaths[i] = nil + end + end + + for i = 1, #tPaths do + if tPaths[i] then + local tNoMatch = {} + local tPathLoc = tPaths[i][1] + local pIniLoc = EgtSP( tPathLoc[1], GDB_RT.GLOB) + local pEndLoc = EgtEP( tPathLoc[1], GDB_RT.GLOB) + -- ciclo sui percorsi per trovare i punti non coincidenti (se percorso non chiuso) + for j = 2, #tPathLoc do + -- prendo i punti del percorso successivo + local pAddIni = EgtSP( tPathLoc[j], GDB_RT.GLOB) + local pAddEnd = EgtEP( tPathLoc[j], GDB_RT.GLOB) + -- se consecutivi + if AreSamePointApprox( pEndLoc, pAddIni) then + pEndLoc = pAddEnd + elseif AreSamePointApprox( pIniLoc, pAddEnd) then + pIniLoc = pAddIni + else + table.insert( tNoMatch, tPathLoc[j]) + end + end + -- controllo eventuali percorsi scartati + for j = 1, #tNoMatch do + -- prendo i punti del percorso successivo + local pAddIni = EgtSP( tNoMatch[j], GDB_RT.GLOB) + local pAddEnd = EgtEP( tNoMatch[j], GDB_RT.GLOB) + -- se consecutivi + if AreSamePointApprox( pEndLoc, pAddIni) then + pEndLoc = pAddEnd + elseif AreSamePointApprox( pIniLoc, pAddEnd) then + pIniLoc = pAddIni + end + end + -- creo concatenamento partendo dal punto iniziale + local nIdLoc = EgtCurveCompoByReorder( nAddGrpId, tPathLoc, pIniLoc, true) + if nIdLoc then + table.insert( tChamPath, nIdLoc) + end + end + end + for i = 1, #tChamPath do + local ptP1 = EgtSP( tChamPath[i], GDB_RT.GLOB) + -- modifico estrusione percorso + if sDeleteByDir == 'Z' then + if abs(ptP1:getZ() - dMaxVal) < 10 * GEO.EPS_SMALL then + EgtModifyCurveExtrusion( tChamPath[i], Z_AX(), GDB_RT.GLOB) + else + EgtModifyCurveExtrusion( tChamPath[i], -Z_AX(), GDB_RT.GLOB) + end + elseif sDeleteByDir == 'Y' then + if abs(ptP1:getY() - dMaxVal) < 10 * GEO.EPS_SMALL then + EgtModifyCurveExtrusion( tChamPath[i], Y_AX(), GDB_RT.GLOB) + else + EgtModifyCurveExtrusion( tChamPath[i], -Y_AX(), GDB_RT.GLOB) + end + elseif sDeleteByDir == 'X' then + if abs(ptP1:getX() - dMaxVal) < 10 * GEO.EPS_SMALL then + EgtModifyCurveExtrusion( tChamPath[i], X_AX(), GDB_RT.GLOB) + else + EgtModifyCurveExtrusion( tChamPath[i], -X_AX(), GDB_RT.GLOB) + end + end + end + if #tChamPath == 1 then + return tChamPath[1], 1, nil + elseif #tChamPath == 2 then + return tChamPath[1], 2, tChamPath[2] + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + for i = 1, #tChamPath do + EgtErase( tChamPath[i]) + end + end + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + end + -- altrimenti cancello tutte le emtità e restituisco nil + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + end + end + end + + return nil, 0, nil +end + +--------------------------------------------------------------------- +local function MakeChamfer( Proc, b3FacesUsed, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + + -- Se variabile globale indica che lo smusso è gi stato fatto, esco + if bMadeChamfer then + return 0 + end + bMadeChamfer = true + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : Mark not found in library' + EgtOutLog( sErr) + return -1, sErr + end + -- ottengo le curve di contorno libero + local nAuxId1, nAuxId2, nNumIdAux + if b3FacesUsed then +-- nAuxId1, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) +-- EgtModifyCurveExtrusion( nAuxId1, vtOrtho, GDB_RT.GLOB) +-- SetOpenSide( nAuxId1, vtOrtho, b3Solid, nAddGrpId, true) +-- nNumIdAux = 2 + + -- estraggo i percorsi + nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId) + -- se percorso creato estraggo solo i percorsi delle facce interessate, non di testa + if nAuxId1 then + nAuxId1, nNumIdAux, nAuxId2 = ExtractExternalPaths( nAuxId1, nNumIdAux, vtOrtho, b3Solid, nAddGrpId) + end + else + nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId) + if not nNumIdAux then nNumIdAux = 0 end + end + + local dExtra = 2 + for i = 1, nNumIdAux do + local AuxId + local vtExtr + if b3FacesUsed then + if i == 1 then + AuxId = nAuxId1 + else + -- faccio la copia del percorso +-- AuxId = EgtCopyGlob( nAuxId1, nAddGrpId) + AuxId = nAuxId2 + end + if AuxId then + vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + end + else + AuxId = nAuxId1 + i - 1 + vtExtr, _, _ = EgtCurveArea( AuxId) + end + if vtExtr then + if not b3FacesUsed then + local fFrCurve = EgtGetGlobFrame( AuxId) + vtExtr:toGlob( fFrCurve) + end +-- if b3FacesUsed and i == nNumIdAux then +-- vtExtr = -vtExtr +-- end + -- Se normale entro certi limiti +-- if vtExtr:getZ() > -0.707 and ( abs(vtOrtho:getX()) > 0.99 or abs(vtOrtho:getY()) > 0.99 or abs(vtOrtho:getZ()) > 0.99) then + if vtExtr:getZ() > -0.707 and ( abs(vtExtr:getX()) > 0.99 or abs(vtExtr:getY()) > 0.99 or abs(vtExtr:getZ()) > 0.99) then + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchId = EgtAddMachining( sNameCh, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sMilling + EgtOutLog( sErr) + return -1, sErr + end + -- modifico estrusione percorso + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto posizione braccio porta testa + if vtExtr:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- assegno affondamento e offset radiale +-- EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra - EgtIf( b3FacesUsed, (dDepth / 2), 0)) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- se opero su 3 facce e sono al secondo e ultimo percorso inverto la lavorazione +-- if b3FacesUsed and i == nNumIdAux then +-- EgtSetMachiningParam( MCH_MP.INVERT, true) +-- end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return -1, sErr + end + -- se non perpendicolare emetto un warning + -- else + -- sWarn = 'Warning : chamfer skipped because not perpendicular to face or from bottom' + -- EgtOutLog( sWarn) + end + --emetto un warning + -- else + -- sWarn = 'Warning : chamfer skipped because not perpendicular to face' + -- EgtOutLog( sWarn) + end + end + + return 0 +end + +--------------------------------------------------------------------- +local function MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, + rfFac, dH, dV, dElev, bForceUseBlade, + dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, + bOrthoFacesMaster, nBottomFace, nChamfer, nAddGrpId, b3Solid, + dDepthCham, b3FacesUsed) + local bOrthoFaces + local sWarn + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ottengo la distanza tra la fine del pezzo e il pezzo successivo + local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or 5.4 + if b3FacesUsed then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd1, dFacElev1, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, b3FacesUsed) + if not nFacInd1 or nFacInd1 < 0 then + if nFacInd1 == -1 then + bOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeByPockets could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + else + bOrthoFaces = bOrthoFacesMaster + end + + if bOrthoFaces then + -- ottengo le dimensioni del tunnel + _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId) + -- verifico la direzione + -- se devo inserire il chamfer + if nChamfer > 0 then + local nOk, sErr = MakeChamfer( Proc, b3FacesUsed, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return false, sErr end + end + end + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Cerco una faccia adiacente alla principale sul lato più lungo + local nFacAdj + local dMaxLen = 0 + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > dMaxLen then + nFacAdj = vAdj[i] + dMaxLen = dLen + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) + end + end + end + if not nFacAdj then + local sErr = 'Error : long adjacent face not found' + EgtOutLog( sErr) + return false, sErr + end + -- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT) + if abs( vtN * rfFac:getVersX()) > abs( vtN * rfFac:getVersY()) then + dH, dV = dV, dH + end + -- Determino se estremi aperti o chiusi + local bOpenStart = false + local bOpenEnd = false + local vtNS, vtNE + -- se non ho la faccia di fondo ( che comporta essere una fessura) verifico se ho lati aperti + if not nBottomFace then + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) + for j = 1, #vAdj2 do + if vAdj2[j] == nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- se è chiusa acquisisco vettore faccia tappo + if not bOpenStart and vAdj2[i] >= 0 then + _, vtNS = EgtSurfTmFacetCenter( Proc.Id, vAdj2[i], GDB_ID.ROOT) + end + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + -- se è chiusa acquisisco vettore faccia tappo + if not bOpenEnd and vAdj2[k] >= 0 then + _, vtNE = EgtSurfTmFacetCenter( Proc.Id, vAdj2[k], GDB_ID.ROOT) + end + end + end + end + -- Recupero il massimo affondamento possibile con la lama + local dSawMaxDepth = 0 + local sCutting = ML.FindCutting( 'HeadSide') + if sCutting then + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawMaxDepth = EgtTdbGetCurrToolMaxDepth() or dSawMaxDepth + end + end + end + -- Se entrambi gli estremi sono aperti e possibile, lavoro con la lama + if bOpenStart and bOpenEnd and bForceUseBlade and dElev < dSawMaxDepth + 10 * GEO.EPS_SMALL then + -- Recupero la lavorazione di lama + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : HeadSide (cutting) not found in library' + EgtOutLog( sErr) + return false, sErr, 'MNF' + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 4 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + if dSawThick > dV + 10 * GEO.EPS_SMALL then + local sErr = 'Error : sawblade too thick' + EgtOutLog( sErr) + return false, sErr + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ()) + -- Eseguo i tagli + local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + local dOffs = ( i - 1) * dStep + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- in base all'elevazione calcolo l'impronta della lama + local dUsedBladeLen = sqrt( ((dSawDiam / 2)*(dSawDiam / 2)) - ( ( (dSawDiam / 2) - dElev) * ( (dSawDiam / 2) - dElev))) + -- controllo direzione taglio e se il minimo della feature sborda in coda + if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then + -- do avviso che la lama può sbordare nel pezzo successivo + sWarn = 'Warning on saw cut : Cut machining can damage next piece' + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + -- altrimenti con sega a catena + else + -- Recupero la lavorazione + local sSawing = ML.FindSawing( 'Sawing') + if not sSawing then + local sErr = 'Error : Sawing not found in library' + EgtOutLog( sErr) + return false, sErr, 'MNF' + end + -- Recupero i dati dell'utensile + local dSawWidth = 75 + local dSawThick = 8 + local dMaxDepth = 200 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + if dSawThick > dV + 10 * GEO.EPS_SMALL then + local sErr = 'Error : chainsaw too thick' + EgtOutLog( sErr) + return false, sErr + end + local bGoFromHead = true + -- se la lunghezza utensile non riesce ad arrivare sul fondo assegno la possibilità di lavorare di testa o di fianco + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + -- lavora di testa se è un tunnel, lavora di fianco se non è un tunnel + bGoFromHead = not bOrthoFaces + end + -- se continuo a lavorare di testa + if bGoFromHead then + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) + -- Calcolo normale faccia adiacente + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) + -- Verifico se necessarie più passate + local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- Applico la lavorazione con sega a catena a questa faccia + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- controllo direzione taglio e se il minimo della feature sborda in coda + if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL then + -- se ho lato partenza aperto e lato uscita chiuso e direzione lato chiuso è negativa, allora controllo uscita lama + if bOpenStart and not bOpenEnd and vtNE:getX() < -0.99 and dDistToNextPiece < (dSawWidth / 2) then + -- imposto accorciamento iniziale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dDistToNextPiece - 1 - (dSawWidth / 2)) + else + -- imposto accorciamento iniziale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + end + -- se ho lato uscita aperto e lato partenza chiuso e direzione lato partenza è negativa, allora controllo uscita lama + if bOpenEnd and not bOpenStart and vtNS:getX() < -0.99 and dDistToNextPiece < (dSawWidth / 2) then + -- imposto accorciamento finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dDistToNextPiece - 1 - (dSawWidth / 2)) + else + -- imposto accorciamento finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + end + else + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + end + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=90') + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se necessario, limito l'affondamento + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth - dElev + EgtOutLog( sWarn) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH '..EgtNumToString( dDepth, 1)) + end + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 2) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=0') + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + if EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + -- altrimenti segacatena di fianco + else + -- verifico se posso farlo con la sega-catena + local bMakeChainSaw, sSawing2, dMaxMat2, dSawCornerRad2, dSawThick2 = VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho) + if bMakeChainSaw then + -- Verifico se necessarie più passate + local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick2) + local dStep = 0 + if nStep > 1 then + dStep = ( dDimMin - dSawThick2) / ( nStep - 1) + end + for i = 1, nStep do + -- inserisco la lavorazione di sawing + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing2) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing2 + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLundIdFace}}) + -- imposto uso del lato faccia + -- al momento, dato che la fessura è passante da parte a parte, gestisco solo la lavorazione + -- dall'alto e di fronte (da dietro è disabilitata perchè ho exracorsa con la FAST). + -- Questa feature non è applicata su facce di testa e quindi non controllo l'entrata in X + if abs(vtOrtho:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + --elseif abs(vtOrtho:getZ()) < 0.707 and abs(vtOrtho:getY()) > 0.707 then + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + --elseif abs(vtOrtho:getZ()) <= 0.707 and vtOrtho:getY() < -0.707 then + -- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + --elseif abs(vtOrtho:getZ()) < 0.707 and vtOrtho:getX() > 0.707 then + -- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + --else + -- EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=90') + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se possibile aumento l'affondamento pari al raggio corner + 1 + if dMaxMat2 > (dDepth + dSawCornerRad2 + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad2 + 1)) + -- se massimo affondamento supera altezza fessura, uso massimo affondamento + elseif dMaxMat2 > (dDepth + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, (dMaxMat2 - 1)) + -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning + elseif dMaxMat2 < dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat2) + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- eseguo + if not EgtApplyMachining( true, false) then + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=0') + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + if EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + end + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw) + -- Recupero la lavorazione di lama + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : HeadSide (cutting) not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- eseguo il taglio + local bMadeASbyBld, sWarn, nIdMach = BL.MakeOneFaceBySaw( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, -0.5, BD.CUT_SIC, 0, 0, nil, b3Raw) + return bMadeASbyBld, sWarn, nIdMach, dSawThick +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc, bMakeVertCham, sDephtCham, sOnlyCham, sUseBlade) + local nChamfer = 0 + local bForceUseBlade = false + local sErr + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- verifico se devo usare lama invece della sega-catena + -- 2020-03-20 forzata abilitazione uso lama se parametro Q non è presente + if #sUseBlade == 0 or EgtGetInfo( Proc.Id, sUseBlade, 'i') == 1 then + bForceUseBlade = true + end + + return nChamfer, dDepth, sErr, bForceUseBlade +end + +--------------------------------------------------------------------- +local function MakePocket( Proc, nPartId, ptPs, tvtN, nFaceRef, sMchFind, nUseRoughTool, sMasterPocket, dPrevFaceElev, tDimAndRef, dAng) + + -- calcolo l'elevazione dal punto medio + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, tvtN[2]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + local dCollSic = 2 * BD.COLL_SIC + -- calcolo il diametro utensile + local dDiamTool + local dFaceDiamTool + if tDimAndRef then + -- prendo il valore dalle dimensioni minime delle facce + dFaceDiamTool = min( tDimAndRef[2][1], tDimAndRef[2][2]) + end + -- se ho lavorazione precedente ricalcolo grossolanamente l'elevazione + if dPrevFaceElev and dPrevFaceElev > 0 and dAng then + dElev = dElev + ( sqrt( ( dElev * dElev) - ( dPrevFaceElev * dPrevFaceElev)) * sin(dAng)) + elseif dPrevFaceElev and dPrevFaceElev > dElev then + dElev = dPrevFaceElev + end + local sPocketing + if sMasterPocket then + sPocketing = sMasterPocket + else + sPocketing = ML.FindPocketing( sMchFind, dFaceDiamTool, dElev + dCollSic) + end + if not sPocketing then + local sErr = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + dDiamTool = 20 + local dMaxDepth = 0 + local sTuuidPk + if EgtMdbSetCurrMachining( sPocketing) then + sTuuidPk = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidPk) or '') then + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- se nome svuotatura non è stato ricalcolato, confronto il diametro utensile utilizzato con il minimo faccia e se non sono compatibili esco + if sMasterPocket and dFaceDiamTool and dDiamTool >= dFaceDiamTool then + return false, '', sTuuidPk, dDiamTool, dElev + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef) + 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( {{ Proc.Id, (nFaceRef)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = MCH_SCC.ADIR_YM + if AreSameVectorApprox( tvtN[2], Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( tvtN[2]:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( EgtGetCurrPhase()), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif tvtN[2]:getY() > 0.1 then + nSCC = MCH_SCC.ADIR_YP + end + else + nSCC = MCH_SCC.NONE + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- se tasca aperta e non lavorata col truciolatore, imposto opportuno attacco + if sMchFind == 'OpenPocket' and nUseRoughTool == 0 then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dElev) + dElev = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn, sTuuidPk, dDiamTool +end + +--------------------------------------------------------------------- +local function MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtN, nBaseFace, nSideFace, ptPs, tDimAndRef, + b3Raw, nDiffWidth, nUseRoughTool, dAng, sPocketing, sTuuidPk, dPrevFaceElev) + + local sMchFind = 'Pocket' + local dAngLimit = 40 + + -- se feature é larga come trave imposto openpocket + if nDiffWidth == 0 then + sMchFind = 'OpenPocket' + -- altrimenti non è passante disabilito il truciolatore + else + nUseRoughTool = 0 + end + -- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto + if ( 180 + dAng) > 90.1 then + -- calcolo l'angolo dalla verticale dall'angolo tra le due facce, perchè la feature potrebbe essere ruotata sulla Z locale della + -- faccia principale e quindi la componente X del versore della faccia potrebbe dare un valore non coerente + local dDiffFromSqAng = dAng + 90 + -- se l'angolo dalla verticale si discosta di più dell'angolo limite impostato, utilizzo la svuotatura + if cos( dDiffFromSqAng) < cos( dAngLimit) then + -- applico la svuotatura + local bOk, sWarn, sTuuidPk, dDiamTool, dElev = MakePocket( Proc, nPartId, ptPs, tvtN, nSideFace, sMchFind, nUseRoughTool, sPocketing, dPrevFaceElev, tDimAndRef, dAng) + if not bOk then + -- se ho id utensile e diametro è perchè non ha fatto svuotatura perchè la faccia è più stretta del diametro utensile + -- e provo ad inserire singola passata di testa + if sTuuidPk and dDiamTool then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2Cut', dElev, sTuuidPk) + if not sMilling then + local sErr = 'Error : Long2Cut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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( {{ Proc.Id, nSideFace}}) + -- imposto uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite(tvtN[1]) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + -- imposto posizione braccio porta testa + if tvtN[2]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + else + return false, sWarn + end + else + return bOk, sWarn + end + -- altrimenti contornatura di fianco + else + local bOpenStart = false + local bOpenEnd = false + if nDiffWidth == 0 then + bOpenStart = true + bOpenEnd = true + else + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBaseFace))[1] + for j = 1, #vAdj2 do + if vAdj2[j] == (nSideFace) then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == (nSideFace) do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == (nSideFace) do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + end + end + local sMilling + if nUseRoughTool > 0 then + sMilling = ML.FindMilling( 'Long2Cut', nil, sTuuidPk) + else + sMilling = ML.FindMilling( 'LongSmallCut', nil, sTuuidPk) + end + if not sMilling then + local sErr = 'Error : Long2Cut & LongSmallCut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 50 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + end + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( tDimAndRef[1][3]:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, (nSideFace)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- setto inversione del percorso + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- setto a 0 eventuali offset + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- calcolo elevazione per allungamenti attacchi con fianchi chiusi + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, tvtN[2]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + -- applico gli allungamenti o accorciamenti + if bOpenStart then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dTDiam / 2) + if dElev > 0 then + EgtSetMachiningParam( MCH_MP.LIPERP, dElev) + end + end + if bOpenEnd then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dTDiam / 2) + if dElev > 0 then + EgtSetMachiningParam( MCH_MP.LOPERP, dElev) + end + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + return true +end + +--------------------------------------------------------------------- +local function SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId, bStartPoint) + + -- fondo tra loro le curve compatibili + EgtMergeCurvesInCurveCompo( nPathInt) + local nStartIdEnt, nNumEnt = EgtCurveDomain( nPathInt) + local pLastPIni, pLastPEnd + + -- faccio una copia della curva e la esplodo + if nStartIdEnt then + -- prendo i punti + for i = 1, nNumEnt do + local pPini = EgtUP( nPathInt, (i-1), GDB_RT.GLOB) + local pPend = EgtUP( nPathInt, EgtIf( i == nNumEnt, 0, i), GDB_RT.GLOB) + -- Se normale lungo la Z considero il box in X e Y + if abs(vtOrtho:getZ()) > 0.999 then + -- se corrisponde a X + if ( abs( pPini:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Y + elseif ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + -- altrimenti se normale lungo la Y considero il box in X e Z + elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.999 then + -- se corrisponde a X + if ( abs( pPini:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Z + elseif ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + -- caso che non dovrebbe mai capitare ma gestito per completezza + -- altrimenti se normale lungo la X considero il box in Y e Z + elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.999 then + -- se corrisponde a Y + if ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Z + elseif ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + end + end + -- se devo cambiare il punto di partenza + if bStartPoint and pLastPIni and pLastPEnd then + -- calcolo il punto medio con gli ultimi punti utilizzati + local ptPs = ( pLastPIni + pLastPEnd) / 2 + EgtChangeClosedCurveStartPoint( nPathInt, ptPs, GDB_RT.GLOB) + end + end +end + +--------------------------------------------------------------------- +local function CheckPocketTool( sMchFind, dDiam, dElev) + + local sPocketing = ML.FindPocketing( sMchFind, dDiam, dElev) + if sPocketing then + -- recupero i dati dell'utensile + local dTDiam = 50 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + return true, dTDiam + end + end + return false +end + +--------------------------------------------------------------------- +local function CheckDiamToolByFaces( Proc, nFacInd, dH, dV, bIsU, bIsL, dElev, nUseRoughTool) + local dMaxDimFace = max( dH, dV) + -- verifico che diametro utensile prende con la openpocket con la massima dimensione faccia + local bUseMaxTool, dMaxDiam + -- se è forzato l'uso del truciolatore non passo l'altezza di elevazione + if nUseRoughTool and nUseRoughTool == 1 then + bUseMaxTool, dMaxDiam = CheckPocketTool( 'OpenPocket', dMaxDimFace) + else + bUseMaxTool, dMaxDiam = CheckPocketTool( 'OpenPocket', dMaxDimFace, dElev) + end + -- se non trovato utensile esco + if not bUseMaxTool then + return false + end + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + -- se non ho facce adiacenti esco subito + if not vAdj or #vAdj == 0 then + return false + end + -- Normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- Cerco le facce adiacenti alla principale con angolo concavo >= 90 + local tWidth = {} + local tExtremPt = {} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + -- verifico l'angolo tra le facce ( esco se angolo compreso < 90) + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + if bAdj and dAng < -90 - 20 * GEO.EPS_ANG_SMALL then + return false + end + -- larghezza della faccia ortogonalmente alla adiacente + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT) + local vtX = vtN2 ^ vtN + local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2) + local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, nFacInd, GDB_BB.STANDARD, frRef) + if b3Ref then + table.insert( tWidth, b3Ref:getDimY()) + table.insert( tExtremPt, { ptP1, ptP2}) + end + end + end + -- se le facce di adiacenza non corrispondono con quelle della forma esco + if ( bIsU and #tWidth ~= 2) or ( bIsL and #tWidth ~= 1) then + return false + end + local dLargeVal = 0 + for i = 1, #tWidth do + dLargeVal = max( dLargeVal, tWidth[i]) + end + -- se facce U verifico se le distanze tra i punti sono minori delle distanze tra le facce + if bIsU then + local dLen11 = dist( tExtremPt[1][1], tExtremPt[2][1]) + local dLen12 = dist( tExtremPt[1][1], tExtremPt[2][2]) + local dLen21 = dist( tExtremPt[1][2], tExtremPt[2][1]) + local dLen22 = dist( tExtremPt[1][2], tExtremPt[2][2]) + dLargeVal = min( dLargeVal, dLen11, dLen12, dLen21, dLen22) + end + -- se forma a l e flag uso truciolatore, favorisco il suo utilizzo + if bIsL and nUseRoughTool == 1 then + return dMaxDiam, 'OpenPocket', nUseRoughTool, dMaxDiam + else + -- per essere accettabile, il diametro massimo deve essere minore della larghezza della faccia + if dMaxDiam < dLargeVal + 20 * GEO.EPS_SMALL then + return dMaxDiam, 'OpenPocket', nUseRoughTool, dMaxDiam + else + return false, '', 0, dMaxDiam + end + end +end + +--------------------------------------------------------------------- +local function MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFindMaster, b3FacesUsed, b3Solid, bOrthoFacesMaster) + + local bOrthoFaces + local sWarn + local sMchFind = 'Pocket' + local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt + local bBadMach = false + if sMchFindMaster and #sMchFindMaster > 0 then + sMchFind = sMchFindMaster + end + if b3FacesUsed then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, b3FacesUsed) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeByPockets could not find reference face' + EgtOutLog( sErr) + return -1, sErr + end + end + else + bOrthoFaces = bOrthoFacesMaster + end + + -- se è un tunnel provo a vedere se è possibile lavorarlo con la svuotatura + if bOrthoFaces then + -- ottengo le dimensioni del tunnel + dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId) + -- verifico la direzione + -- se devo inserire il chamfer + if nChamfer > 0 then + local nOk, sErr = MakeChamfer( Proc, b3FacesUsed, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return -1, sErr end + end + -- se smusso non è esclusivo + if nChamfer < 2 then + -- verifico se può essere fatto con svuotatura + local bMakePocket, sPocketing, dMaxMat = VerifyIfPocket( Proc, dDimMin, vtOrtho, sMchFind) + if bMakePocket then + -- gestione svuotatura da un solo lato o anche dal lato opposto (se non verticale) + -- estraggo il contorno dalla superfice per evitare i problemi con la svuotatura + -- e assegno l'estrusione + local nPathInt, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) + EgtModifyCurveExtrusion( nPathInt, vtOrtho, GDB_RT.GLOB) + -- se ho 3 facce, ciclo sulle entià del percorso per segnare quelle che sono aperte + if b3FacesUsed then + SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId) + end + -- variabili per parametri lavorazione + local dMachDepth + local dElev = 0 + local bDoubleSide + -- se possibile svuotare completamente da una sola parte + if dMaxMat > ( dDepth + 2) then + dMachDepth = (dDepth / 2) + 2 + dElev = dDepth + else + -- se direzione verso la verticale setto max affondamento possibile ed + -- emetto messaggio di warning perché non lavorabile interamente + if abs(vtOrtho:getZ()) >= 0.707 then + dMachDepth = dMaxMat - (dDepth / 2) + dElev = dMaxMat + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + -- altrimenti setto il flag per fare la svuotatura da due parti + else + -- se l'altezza utensile riesce a lavorare completamente da due parti + if dMaxMat > (dDepth / 2) then + dMachDepth = 1 + dElev = (dDepth / 2) + 1 + -- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione + else + dMachDepth = dMaxMat - (dDepth / 2) + dElev = dMaxMat + -- se sono in questo caso verifico la direzione, se le componenti x,y e z deviano molto + -- allora considero la lavorazione no idonea perchè potrebbe avere anche delle collisioni + if abs(vtOrtho:getX()) > 0.5 or abs(vtOrtho:getY()) > 0.5 or abs(vtOrtho:getZ()) > 0.5 then + bBadMach = true + end + end + bDoubleSide = true + end + end + -- se lavorazione non idonea esco + if b3FacesUsed and bBadMach then + local sErr = 'Impossible apply perpendicular pocketing: ' .. sPocketing + return -2, sErr + 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 -1, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nPathInt, -1}}) + -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) + local bInvertMach + if vtOrtho:getZ() < BD.NZ_MINA and abs(vtOrtho:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti + elseif not bDoubleSide and vtOrtho:getY() > GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + end + -- imposto posizione braccio porta testa + if vtOrtho:getY() < GEO.EPS_SMALL then + if bInvertMach then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + else + if bInvertMach then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + end + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- inverto il percorso di lavorazione per lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- imposto affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return -1, sErr + end + end + -- se posso applicare la svuotatura sul lato opposto + if bDoubleSide then + -- se anche lavorando dal lato opposto non riesco a svuotare completamente la fessura + -- setto i parametri affondamento ed emetto warning + if dMaxMat*2 < dDepth then + dMachDepth = dMaxMat - (dDepth / 2) + dElev = dMaxMat + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- inserisco la lavorazione di svuotatura + local sName = 'PockOppo_' .. ( 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 -1, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nPathInt, -1}}) + -- imposto direzione utensile opposta + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- imposto posizione braccio porta testa + if vtOrtho:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- inverto il percorso di lavorazione per lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- imposo affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return -1, sErr + end + end + end + return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace + end + end + end + + return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces +end + +--------------------------------------------------------------------- +local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePart) + local sWarn + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + local bClosedOrthoFaces + local nFacInd, dFacElev, nFacInd2, dFacElev2 + local nBottomFace + local sMchFindBackUp + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeMoreFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + -- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche + if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then + -- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura + for i = 1, Proc.Fct do + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + -- elimino una faccia + nBottomFace = i-1 + if EgtSurfTmRemoveFacet( nNewProc, nBottomFace) then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( nNewProc, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + EgtErase( nNewProc) + break + else + EgtErase( nNewProc) + local sErr = 'Error : MakeMoreFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + -- altrimenti esco + else + EgtErase( nNewProc) + break + end + end + -- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo + if bClosedOrthoFaces then + nFacInd = nBottomFace + -- rendo nulla la faccia opzionale perchè si tratta di una fessura + nFacInd2 = nil + dFacElev = BL.GetFaceElevation( Proc.Id, nFacInd) + bClosedOrthoFaces = false -- non setto come tunnel + end + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sErrCham, bForceUseBlade = EvaluateQParam( Proc, false, sDepthChamferMill, sPreemptiveChamfer, sForceUseBlade) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sErrCham + end + -- se è un tunnel provo a vedere se è possibile lavorarlo con la svuotatura o con la sega catena + if bClosedOrthoFaces then + local bTryWithBlades = true + -- lavoro fessura con svuotature (singola o doppia contrapposta) + local nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, 'Pocket', false, b3Solid, bClosedOrthoFaces) + if nOk < 0 then + return false, sErr + elseif nOk > 0 then + bTryWithBlades = false + end + -- Se la svuotatura precedente non è stata fatta e chamfer non è mutuamente esclusivo provo con la sega-catena + if bTryWithBlades and nChamfer < 2 then + -- verifico se posso farlo con la sega-catena + local bMakeChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick = VerifySawChain( Proc, dDimMin, dDimMax, vtOrtho) + if bMakeChainSaw then + -- Verifico se necessarie più passate + local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dDimMin - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- inserisco la lavorazione di sawing + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLundIdFace}}) + -- imposto uso del lato faccia + -- al momento, dato che la fessura è passante da parte a parte, gestisco solo la lavorazione + -- dall'alto e di fronte (da dietro è disabilitata perchè ho exracorsa con la FAST). + -- Questa feature non è applicata su facce di testa e quindi non controllo l'entrata in X + if abs(vtOrtho:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=90') + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se possibile aumento l'affondamento pari al raggio corner + 1 + if dMaxMat > (dDepth + dSawCornerRad + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad + 1)) + -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning + elseif dMaxMat < dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- eseguo + if not EgtApplyMachining( true, false) then + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=0') + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + if EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + end + end + -- altrimenti non è una fessura + else + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se U + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) + -- verifico se due facce o L con una o due facce di terminazione + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2) + -- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia + local bMakeBySideMill, bHead, sMilling, dMaxMat = VerifyIfByBHSideMill( Proc) + if bMakeBySideMill and ( dMaxMat <= dV + 15 * GEO.EPS_SMALL) then + -- se smusso non è esclusivo + if nChamfer < 2 then + -- inserisco la lavorazione di fresatura + local sName = 'BHMill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso del lato faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) + -- calcolo step effettivo ed elevazione + local dVcalc = dV - dMaxMat + local dStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMaxMat + local nStep = ceil( dVcalc / dStep) + dStep = dVcalc / nStep + EgtSetMachiningParam( MCH_MP.STEP, dStep) + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dVcalc + dStep, 2) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- altrimenti lavoro con svuotatura + else + local bSpecial3faces = false + -- verifico se lavorando la faccia principale rimane esclusa molta sezione trasversale complessiva della feature (da box) + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local bBoxF = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfFac) + if dH * dV < 0.9 * ( bBoxF:getDimX() * bBoxF:getDimY()) then + bSpecial3faces = true + end + -- se riconosciuta gestione 3 facce + -- e limitata per ora alla feature 20 + if bSpecial3faces and Proc.Prc == 20 then + -- se smusso non è esclusivo + if nChamfer < 2 then + -- entrambe le facce non devono essere orientate verso il basso + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + -- se orientata verso il basso, verifico l'alternativa + if vtN:getZ() < BD.NZ_MINA and vtN2:getZ() < BD.NZ_MINA then + local sErr = 'Error : special LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd2, GDB_ID.ROOT) + -- eventuali tagli preliminari + do + local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, nChamfer) + if not bOk then return false, sErr end + end + -- Recupero la lavorazione di fresa + local sMilling = ML.FindMilling( 'LongSmallCut') + if not sMilling then + local sErr = 'Error : LongSmallCut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero la lavorazione di svuotatura + local sMchFind = 'Pocket' + -- se forzato uso truciolatore + if EgtGetInfo( Proc.Id, sUseRoughTool, 'i') == 1 then + sMchFind = 'OpenPocket' + end + local dDiam = min( dH, dV) + local dDiam2 = min( dH2, dV2) + local dCollSic = 2 * BD.COLL_SIC + local dCollSic2 = 2 * BD.COLL_SIC + if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end + if abs( vtN2:getX()) > 0.7 or abs( vtN2:getY()) > 0.7 or abs( vtN2:getZ()) > 0.7 then dCollSic2 = 0 end + local sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2) + -- se non trova una svuotatura adatta provo ad assegnarla all'altra faccia + if not sPocketing then + dDiam, dDiam2 = dDiam2, dDiam + dCollSic, dCollSic2 = dCollSic2, dCollSic + nFacInd, nFacInd2 = nFacInd2, nFacInd + dH, dH2 = dH2, dH + dV, dV2 = dV2, dV + dFacElev, dFacElev2 = dFacElev2, dFacElev + rfFac, rfFac2 = rfFac2, rfFac + vtN, vtN2 = vtN2, vtN + sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2) + if not sPocketing then + local sErr = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- provo con contornatura + local dDiamTool = 20 + if bIsL then + local bOk, sErr + bOk, sWarn, dDiamTool = MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, true, sMilling, nFacInd2, dFacElev2) + if not bOk then return bOk, sWarn end + else + local sErr = 'Error : Impossible mill special LapJoint' + EgtOutLog( sErr) + return false, sErr + 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( {{ Proc.Id, nFacInd2}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev2, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- se abilitato dal parametro Q inserisco foro sullo spigolo + if EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 1 then + local bOk + bOk, sWarn = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, 0, nAddGrpId, dDiamTool, true) + if not bOk then return false, sWarn end + -- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura + elseif EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 2 then + local bOk + bOk, sWarn = MakeCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, 0, nAddGrpId, dDiamTool) + if not bOk then return false, sWarn end + end + end + -- altrimenti lavorazione di svuotatura o contornatura + else + local bUseOtherFace + -- se orientata verso il basso, verifico l'alternativa + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + dFacElev, dFacElev2 = dFacElev2, dFacElev + bUseOtherFace = true + end + -- verifico non sia orientata verso il basso o ci sia una testa dal basso + local bFaceDown = ( vtN:getZ() < BD.NZ_MINA) + if bFaceDown and not BD.DOWN_HEAD then + local sErr = 'Error : LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se forma a L e la componente in X è maggiore di 60° allora verifico se posso utilizzare la faccia secondaria + if bIsL and abs( vtN:getX()) > 0.866 then + -- se non ho scambiato la faccia + if not bUseOtherFace then + if nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + dFacElev, dFacElev2 = dFacElev2, dFacElev + -- altrimenti cerco la faccia secondaria per adiacenza alla principale + else + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj, sErr = GetFaceAdj( Proc, nFacInd, dH, dV) + if nFacAdj < 0 then + EgtOutLog( sErr) + return false, sErr + end + nFacInd = nFacAdj + dFacElev = BL.GetFaceElevation( Proc.Id, nFacInd) + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + end + -- altrimenti se ho già cambiato faccia do errore per impossibilità di lavorazione + else + local sErr = 'Error : impossible to machine by side angle too big that cause collision' + EgtOutLog( sErr) + return false, sErr + end + end + -- eventuali tagli preliminari + do + local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, nChamfer) + if not bOk then return false, sErr end + end + -- imposto altezza aggiuntiva di elevazione + local dCollSic = 8 * BD.COLL_SIC + if abs( vtN:getX()) > 0.996 or abs( vtN:getY()) > 0.996 or abs( vtN:getZ()) > 0.996 then + dCollSic = 0 + elseif abs( vtN:getX()) > 0.866 or abs( vtN:getY()) > 0.866 or abs( vtN:getZ()) > 0.866 then + dCollSic = 2 * BD.COLL_SIC + elseif abs( vtN:getX()) > 0.707 or abs( vtN:getY()) > 0.707 or abs( vtN:getZ()) > 0.707 then + dCollSic = 5 * BD.COLL_SIC + end + -- settaggio voluto da Alessandro + local sMchFind = EgtIf( bSinglePart, 'Pocket', 'OpenPocket') + sMchFindBackUp = sMchFind + local nUseRoughTool = EgtIf( bSinglePart, 0, 1) + -- fino a che nelle svuotature non si può decidere il punto di inizio faccio delle valutazioni + -- se ho passi multipli controllo il numero delle facce + if not bSinglePart then + -- se ho 3 o più facce allora re-imposto il tipo di svuotatura + if ( Proc.Fct == 3 and bIsU) or Proc.Fct > 3 then + sMchFind = 'Pocket' + end + end + local dDiam = min( dH, dV) + local dDiamMax + local nUseRT + -- 04/08/2020 su richiesta di Fabio Squaratti, se settato parametro uso truciolatore (parametro Q), non si devono prendere altre frese, + -- piuttosto si da errore con il truciolatore. + -- Sicuramente questa opzione si scontra facilmente con altre interpretazioni dello stasso parametro Q + -- per tornare comportamento precedente settare bNewCheck = false + local bNewCheck = true + -- se processo 20 e non sto usando il truciolatore + if bNewCheck and Proc.Prc == 20 and nUseRoughTool == 0 then + -- verifico se forzato uso truciolatore + nUseRT = EgtGetInfo( Proc.Id, sUseRoughTool, 'i') + if nUseRT and nUseRT ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + end + end + -- 03/12/2020 aggiunto controllo su feature 30 + -- se processo 30 e non sto usando il truciolatore + if bNewCheck and Proc.Prc == 30 and nUseRoughTool == 0 then + -- verifico se forzato uso truciolatore + nUseRT = EgtGetInfo( Proc.Id, sMakeBySideRoughTool, 'i') + if nUseRT and nUseRT ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + end + end + -- verifico dalla forma se non posso prendere utensile grande + if ( Proc.Fct == 3 and bIsU and bSinglePart) or ( Proc.Fct == 2 and bIsL) or Proc.Fct == 1 then + sMchFindBackUp = sMchFind + --ottengo un diametro utensile opportuno + dDiam, sMchFind, nUseRoughTool, dDiamMax = CheckDiamToolByFaces( Proc, nFacInd, dH, dV, bIsU, bIsL, ( dFacElev + dCollSic), nUseRoughTool) + if not dDiam and nUseRoughTool == 0 then + sMchFind = 'OpenPocket' + dDiam = min( dH, dV) + end + end + -- se processo 20 e non sto usando il truciolatore + if Proc.Prc == 20 and nUseRoughTool == 0 then + if nUseRT and nUseRT ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + if dDiamMax and Proc.Fct == 2 and bIsL then + dDiam = dDiamMax + end + end + end + --EgtOutLog( 'Mortise Find Diam =' .. EgtNumToString( dDiam)) + local sPocketing + if BD.DOWN_HEAD and sMchFind and vtN:getZ() < -BD.NZ_MINA then sMchFind = sMchFind .. '_H2' end + if nUseRoughTool == 1 then + sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam) + if sMyPocketing and dMyTMaxDepth > 0.8 * dFacElev + dCollSic then + sPocketing = sMyPocketing + end + else + sPocketing = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic) + end + -- se non trovata verifico affondamento + if not sPocketing and nUseRoughTool == 0 then + local sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam) + if sMyPocketing and dMyTMaxDepth > 0.8 * dFacElev + dCollSic then + sPocketing = sMyPocketing + end + end + -- se feature 16 e forzata lama e forma ad U, annulla la svuotatura + if Proc.Prc == 16 and bForceUseBlade and Proc.Fct == 3 and bIsU then + sPocketing = nil + end + -- se non trova una svuotatura adatta + if not sPocketing then + -- se forma a L provo con contornatura + if bIsL then + -- se smusso non è esclusivo + if nChamfer < 2 then + return MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev) + end + -- altrimenti, in base alla forma, provo con svuotature di fianco o con la sega a catena o lama + else + local bTryWithBlades = true + local nOk, bOk, sStat, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces + -- se feature 16 e abilitato il parametro Q01 (=1) provo prima con la lama e poi con la fresa + if Proc.Prc == 16 and bForceUseBlade then + -- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame + if bTryWithBlades and nChamfer < 2 then + bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, + rfFac, dH, dV, dFacElev, bForceUseBlade, + dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, + bOrthoFaces, nBottomFace, nChamfer, nAddGrpId, b3Solid, + dDepthCham, true) + if not bOk then + -- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e + -- se non è possibile allora provo in seguito con lama o segacatena + -- o passare subito dalla lavorazione con lama/sega catena + if Proc.Fct == 3 and bIsU then + -- lavoro con svuotature (singola o doppia contrapposta) + nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFind, true, b3Solid) + -- se lavorazione non idonee ( asse della feature troppo inclinato e impossibile lavorare completamente da due parti) + if nOk == -2 then + if not sMchFind then + sMchFind = sMchFindBackUp + end + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + elseif nOk < 0 then + return false, sErr + elseif nOk == 0 then + if sStat == 'MNF' then + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + else + return bOk, sWarn + end + else + bOk = true + return bOk, sErr + end + else + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + else + return bOk, sWarn + end + else + -- se devo inserire il chamfer + if ( ( Proc.Fct == 3 and bIsU) or (Proc.Fct == 2 and bIsL)) and nChamfer > 0 then + -- ottengo le dimensioni dello pseudotunnel + local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId) + local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return false, sErr end + end + bOk = true + return bOk, sWarn + end + else + -- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e + -- se non è possibile allora provo in seguito con lama o segacatena + -- o passare subito dalla lavorazione con lama/sega catena + if bTrySidePocketAtFirst and Proc.Fct == 3 and bIsU then + -- lavoro con svuotature (singola o doppia contrapposta) + nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFind, true, b3Solid) + if nOk == -2 then + if not sMchFind then + sMchFind = sMchFindBackUp + end + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr2 = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr2) + return false, sErr2 + end + bTryWithBlades = false + sWarn = sErr + elseif nOk < 0 then + return false, sErr + elseif nOk > 0 then + bTryWithBlades = false + sWarn = sErr + end + bOk = true + end + -- 03/09/2020 da conferma di Fabio Squaratti: Per ora solo sulla feature 016: + -- se ha fallito la fresatura (qua sopra) allora di defalut ( anche se il flag Q della lama è disattivato) prima provo la lama + if Proc.Prc == 16 then + bForceUseBlade = true + end + -- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame + if bTryWithBlades and nChamfer < 2 then + bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, + rfFac, dH, dV, dFacElev, bForceUseBlade, + dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, + bOrthoFaces, nBottomFace, nChamfer, nAddGrpId, b3Solid, + dDepthCham) + if not bOk and sStat == 'MNF' then + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr2 = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr2) + return false, sErr2 + end + else + return bOk, sWarn + end + -- altrimenti verifico se ho già svuotato dal fianco, se si esco + else + -- se non ho annullato la/le svuotatura/e dal fianco + if nOk ~= -2 then + return bOk, sWarn + end + end + end + end + else + -- se devo inserire il chamfer + if ( ( Proc.Fct == 3 and bIsU) or (Proc.Fct == 2 and bIsL)) and nChamfer > 0 then + -- ottengo le dimensioni dello pseudotunnel + local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId) + local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return false, sErr end + end + end + -- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo + -- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa + local bMadeASbyBld = false + if nChamfer < 2 and EgtGetInfo( Proc.Id, sAntisplintMode, 'i') == 1 and ( bIsU or bIsL) and + ( Proc.Box:getDimY() > b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > b3Raw:getDimZ() - 1) then + local nNumFac = EgtIf( bIsU, 2, 1) + local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra + -- se a U cerco di ottimizzare il lato di lavoro della lama + if bIsU then + if abs( vtN:getY()) > 0.996 then + nPrefSide = 0 + elseif abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then +-- elseif abs( vtN:getZ()) > 0.7 or abs( vtN:getY()) > 0.7 then + -- se X è negativa allora devo tenere il motore a destra + if vtN:getX() < -(10 * GEO.EPS_SMALL) then + nPrefSide = 2 + end + end + end + -- va eseguito sulle facce diverse dalla principale + local nPrevSCC = nil + for nFacet = 0, nNumFac do + if nFacet ~= nFacInd then + -- lavoro + local dSawThick = 0 + bMadeASbyBld, sWarn, nIdMach, dSawThick = MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw) + if not bMadeASbyBld then return false, sWarn end + -- verifico se da invertire + local bInvertMach = false + if bIsU then + if abs(vtN:getZ()) > 0.63 or abs(vtN:getY()) > 0.63 then +-- if abs(vtN:getZ()) > 0.7 or abs(vtN:getY()) > 0.7 then + -- prendo il vettore normale alla faccia + local _, vtNFc = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + -- valuto l'angolo tra le due facce + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT) + -- se superficie principale parallela al piano XZ + if nPrefSide == 0 then + -- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto) + if vtNFc:getX() * vtNFc:getZ() > 0 then + nPrefSide = 2 + -- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto) + else + nPrefSide = 1 + end + end + -- se faccia verso X+ e mandrino verso sinistra + if vtNFc:getX() > 0 and nPrefSide == 1 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + -- se faccia verso X- e mandrino verso destra + elseif vtNFc:getX() < 0 and nPrefSide == 2 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + end + end + end + -- eseguo inversione + if bInvertMach then + local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT) + local nWS = EgtGetMachiningParam( MCH_MP.WORKSIDE) + local nInvWS = EgtIf( nWS == MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT) + local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE) + local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT) + if not bOrtUp then + -- assegno i parametri invertiti + EgtSetMachiningParam( MCH_MP.WORKSIDE, nInvWS) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert) + -- setto l'offset pari allo spessore lama + EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick) + end + end + -- posizione del braccio : se primo taglio la recupero, altrimenti la imposto + if not nPrevSCC then + nPrevSCC = EgtGetMachiningParam( MCH_MP.SCC) + else + EgtSetMachiningParam( MCH_MP.SCC, nPrevSCC) + end + -- rieseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nIdMach, false) + return false, sErr + end + end + end + end + + -- se smusso non esclusivo + if nChamfer < 2 then + -- eseguo la svuotatura della faccia principale, mi restituisce id utensile, il diametro utensile per il foro opzionale + local tvtNx = {} + tvtNx[2] = vtN + local bOk + bOk, sWarn, sTuuidPk, dDiamTool = MakePocket( Proc, nPartId, ptC, tvtNx, nFacInd, sMchFind, nUseRoughTool, sPocketing, dFacElev + dCollSic) + if not bOk then return false, sWarn end + -- se ho più di 3 facce e non di forma ad u oppure ho 3 facce e di forma ad u + -- e non sono stati inseriti antischeggia di lama + -- controllo se c'è una faccia non ortogonale alla principale e la lavoro con una contornatura o svuotatura + if ( ( Proc.Fct > 3 and not bIsU) or ( Proc.Fct == 3 and bIsU)) and not bMadeASbyBld then + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + -- Cerco una faccia adiacente alla principale con angolo > 90 + local nFacAdj + local tDimAndRef = {} + tvtNx = {} + tvtNx[1] = vtN + tDimAndRef[1] = {dH, dV, rfFac} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + if bAdj and dAng < 0 and 180 + dAng > 90.1 then + local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vAdj[i], GDB_ID.ROOT) + _, tvtNx[2] = EgtSurfTmFacetCenter( Proc.Id, vAdj[i], GDB_ID.ROOT) + tDimAndRef[2] = {dH2, dV2, rfFac2} + local ptPs = ( ptP1 + ptP2) / 2 + local bOk + bOk, sWarn = MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtNx, nFacInd, vAdj[i], ptPs, tDimAndRef, + b3Raw, EgtIf( ( Proc.Fct == 3 and bIsU), 0, 2), nUseRoughTool, dAng, sPocketing, sTuuidPk, dFacElev) + if not bOk then return bOk, sWarn end + end + end + end + end + -- se abilitato dal parametro Q inserisco foro sullo spigolo + if EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 1 then + local bOk + bOk, sWarn = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool) + if not bOk then return false, sWarn end + -- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura + elseif EgtGetInfo( Proc.Id, sInsertBoreOnCorner, 'i') == 2 then + local bOk + bOk, sWarn = MakeCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool) + if not bOk then return false, sWarn end + -- altrimenti se abilitato dal parametro Q inserisco contorno con fresa più piccola + elseif EgtGetInfo( Proc.Id, sMakeContourWithSmallTool, 'i') == 1 then + local bOk + bOk, sWarn = MakeContourCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool) + if not bOk then return false, sWarn end + end + end + end + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- la divido in parti lungo X + local vAddId = {} + local nPart = max( ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN), 2) + local dPartLen = Proc.Box:getDimX() / nPart + local Xmin = Proc.Box:getMin():getX() + for i = 1, nPart do + -- eseguo divisione + local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i)) + if i > 1 then + local ptOn = Point3d( Xmin + ( i - 1) * dPartLen, 0, 0) + EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) + end + if i < nPart then + local ptOn = Point3d( Xmin + i * dPartLen, 0, 0) + EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) + end + table.insert( vAddId, AddId) + end + -- applico le lavorazioni sulle diverse parti + local sWarn + for i = 1, #vAddId do + local b3Box = EgtGetBBoxGlob( vAddId[i], GDB_BB.STANDARD) + local nFct = EgtSurfTmFacetCount( vAddId[i]) + local AddProc = { Id = vAddId[i], Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Box, Fct = nFct, Flg = Proc.Flg} + local bOk, sMyWarn = MakeMoreFaces( AddProc, nPhase, nRawId, nPartId, dOvmHead, false) + if not sWarn then sWarn = sMyWarn end + if not bOk then return bOk, sWarn end + end + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +--------------------------------------------------------------------- +function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- setto a nil la variabile smussi + bMadeChamfer = nil + -- limiti di fresatura semplice + local MAX_MILL_LIN = 80 + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- verifico forzatura lama + local bForcedBlade = EgtGetInfo( Proc.Id, sUseRoughTool, 'i') ~= 1 and EgtGetInfo( Proc.Id, sUseMill, 'i') ~= 1 + -- se ho attivo la lama e ho la feature 30, verifico i parametri Q propri della feature + if bForcedBlade and Proc.Prc == 30 then + local nBladeAntisplint = EgtGetInfo( Proc.Id, sAntisplintMode, 'i') or 0 + local nUseRoughToolOnSide = EgtGetInfo( Proc.Id, sMakeBySideRoughTool, 'i') or 0 + -- se antischeggia di fresa o abilitato sgrossatore di fianco + if nBladeAntisplint == 2 or nUseRoughToolOnSide == 1 then + bForcedBlade = false + end + end + -- se lunghezza richiede spezzatura + if Proc.Box:getDimX() > BD.LONGCUT_MAXLEN then + -- una faccia + if Proc.Fct == 1 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + -- due facce + elseif Proc.Fct == 2 then + -- determino se due facce lunghe oppure una lunga e l'altra terminale + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) + local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD) + if abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 then + -- leggo i parametri Q per utilizzare la fresa di fianco e/o lama + local nUseSideTool = EgtGetInfo( Proc.Id, sMakeBySideRoughTool, 'i') or 0 + local bUseBlade = EgtGetInfo( Proc.Id, sAntisplintMode, 'i') == 1 + return Long2Cut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nUseSideTool) + elseif b3Fac1:getDimX() < 1 then + -- la faccia 0 deve essere quella lunga + EgtSurfTmSwapFacets( Proc.Id, 0, 1) + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + elseif b3Fac2:getDimX() < 1 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + else + if bForcedBlade then + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + else + return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + end + end + -- tre o più facce + else + return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + end + + -- altrimenti lavorazione unica + else + -- una faccia + if Proc.Fct == 1 then + -- se piccola, con fresa + if not bForcedBlade and ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then + return MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) + -- altrimenti, con lama + else + return Cut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + end + -- due facce + elseif Proc.Fct == 2 then + -- determino l'angolo tra le facce + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + -- se ortogonali e non forzata lama, con fresa + if not bForcedBlade and bAdj and abs( dAng + 90) < 1 then + -- se piccole + if ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then + return MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) + else + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, true) + end + -- altrimenti, con lama + else + -- verifico se devo fare prima gli amussi + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se due facce o L con una o due facce di terminazione + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2) + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sErrCham = EvaluateQParam( Proc, false, sDepthChamferMill, sPreemptiveChamfer, sForceUseBlade) + if (Proc.Fct == 2 and bIsL) and nChamfer > 0 then + local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId) + local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return false, sErr end + end + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + end + -- tre o più facce + else + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, true) + end + end +end + +--------------------------------------------------------------------- +return ProcessLapJoint diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessLongCut.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessLongCut.lua new file mode 100644 index 0000000..1c2cde2 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessLongCut.lua @@ -0,0 +1,710 @@ +-- ProcessLongCut.lua by Egaltech s.r.l. 2021/01/14 +-- Gestione calcolo taglio longitudinale per Travi + +-- Tabella per definizione modulo +local ProcessLongCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessLongCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +local dLimMinPiece = BD.LEN_SHORT_PART or 1000 +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLongCut.Identify( Proc) + return (( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 10) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLongCut.Classify( Proc) + -- se una sola faccia non ci sono limiti + if Proc.Fct == 1 then + return true, false + end + -- verifico la normale della faccia principale + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 then + return true, true + end + return true, false +end + +--------------------------------------------------------------------- +local function MakeSideFace( nId, nFac, nSide, sMilling, dToolDiam, bForcedLim) + -- inserisco la lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( nId) or tostring( nId)) .. '_' .. tostring( nFac) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nId, nFac}}) + -- uso della faccia + local nFaceUse + if bForcedLim then + nFaceUse = MCH_MILL_FU.ORTHO_LEFT + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + else + nFaceUse = MCH_MILL_FU.PARAL_DOWN + if nSide == -2 then + nFaceUse = MCH_MILL_FU.PARAL_BACK + elseif nSide == 2 then + nFaceUse = MCH_MILL_FU.PARAL_FRONT + end + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- annullo offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +local function MakeByPocketing( Proc, nPhase, nRawId, nPartId) + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + -- cerco la svuotatura opportuna + local sPocketing = ML.FindPocketing( 'OpenPocket', Proc.Box:getDimX()) + 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 dMaxDepth = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + end + end + -- inserisco la lavorazione + 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( {{ Proc.Id, 0}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto attacco per tasca aperta + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev) + dFacElev = dMaxDepth + sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local _, dLen, dWidth = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + -- limitazioni su inizio e fine derivanti da altre facce + local bLimXmin = false + local bLimXmax = false + if Proc.Fct >= 3 then + bLimXmin = true + bLimXmax = true + elseif Proc.Fct >= 2 then + local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if vtN1:getX() > 0 then + bLimXmin = true + else + bLimXmax = true + end + end + -- Verifico lato di lavorazione (limite di lato a 45deg per pinze che schiacciano) + local nSide = 1 + if vtN:getZ() < - 0.5 then + nSide = -1 + elseif vtN:getY() < -0.7072 then + nSide = -2 + elseif vtN:getY() > 0.7072 then + nSide = 2 + end + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN:getY() < 0) + -- ottengo la distanza tra la fine del pezzo e il pezzo successivo + local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or 5.4 + local bForcedLim + local sWarn + ---------------------------------------------------------------------------------------------------------------------------------------- + -- 2020/09/15 Fabio Squaratti: se sono attivi entrambe i Q05 (lavorare con lama) e Q07 (lavorare con fresa di fianco anche da sopra) + -- allora vince il Q7, cioè si utilizza la fresa di fianco ( per i tagli da sopra) + + -- 2020/09/17 Fabio Squaratti: se lavorazione con fresa di fianco e se ci sono delle facce laterali, l'utensile deve arrivare + -- fino al punto più vicino della faccia laterale (prima l'arretramento era sempre del rggio utensile). + -- Questo viene fatto se Q07=1 o fresa da sotto + ---------------------------------------------------------------------------------------------------------------------------------------- + local bUseBlade = ( EgtGetInfo( Proc.Id, 'Q05', 'i') == 1) or bCustUseBlade + local nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q07', 'i') or 0 + -- se entrambe i Q sono attivi, disabilito lama + if nUseMillOnSide > 0 then bUseBlade = false end + + -- Se non limitato e da sopra e richiesto con doppio taglio di lama e superiore al limite minimo + if not bLimXmin and not bLimXmax and nSide == 1 and bUseBlade and b3Solid:getDimX() > dLimMinPiece - 1 then + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se la distanza dal pezzo successivo è inferiore della metà lama, dò un warning + if dDistToNextPiece < dToolDiam/2 then + sWarn = 'Warning on saw cut : Cut machining can damage next piece' + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + -- determino numero di parti + local dStartAccDist = BD.LONGCUT_ENDLEN + local dEndAccDist = BD.LONGCUT_ENDLEN + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + if dC < min( dStartAccDist, dEndAccDist) then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- determino l'utilizzo della faccia + local nFaceUse = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + local nFaceUse2 = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + -- si percorrono i lati alto e basso della faccia + local nM = 0 + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- ciclo sulle passate + local dOffset = ( dWidth + BD.DIM_STRIP_SMALL) / 2 ; + local dLioTang = 0 + local dLioPerp = ( dWidth - BD.DIM_STRIP_SMALL) / 2 + BD.CUT_SIC ; + for k = 1, 2 do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC) + local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC) + if ( not bFront and k == 1) or ( bFront and k == 2) then + dSal, dEal = dEal, dSal + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- se il flag uso lama custom abilitato (indica che questo script è lanciato dal ProcessCut) + -- controllo se componente X versore è maggiore di un valore limite cambio la direzione della forcella + if bCustUseBlade and abs(vtN:getX()) > 0.009 + 5*GEO.EPS_SMALL then + nSCC = EgtIf( ( not bFront and k == 1) or ( bFront and k == 2), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + -- se non è sotto e non uso fresa di fianco: lavorazione Long2Cut + elseif nSide ~= - 1 and nUseMillOnSide == 0 then + -- determino la massima elevazione + local dElev = BL.GetFaceElevation( Proc.Id, 0, nPartId) + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2Cut', dElev) + 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 dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se la fine (a sinistra) non è limitata e ho un pezzo successivo meno distante di metà raggio. setto la fine come limitata + if dDistToNextPiece < dToolDiam/2 and not bLimXmin then + bForcedLim = true + bLimXmin = true + end + -- se chiuso e corto, applico svuotatura con fresa opportuna + if bLimXmin and bLimXmax and Proc.Box:getDimX() < 2 * dToolDiam then + return MakeByPocketing( Proc, nPhase, nRawId, nPartId) + end + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + if ( bLimXmin and bFront) or ( bLimXmax and not bFront) then + dStartDist = dToolDiam / 2 + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + if ( bLimXmin and not bFront) or ( bLimXmax and bFront) then + dEndDist = dToolDiam / 2 + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + local nIncStep = 2 + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + -- se distanza rimanente è < della metà del minimo della distanza estremi allora aggiungo un passo in più + local dMinDist = EgtIf( min( dStartAccDist, dEndAccDist) / 2 > 300 , 300, min( dStartAccDist, dEndAccDist) / 2) + if dC <= dMinDist then + dC = dLen / ( nC + 1) + dStartAccDist = dC + dEndAccDist = dC + nIncStep = 1 + elseif dC < min( dStartAccDist, dEndAccDist) then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + if dC < dStartAccDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + if dC < dEndAccDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + nIncStep + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- determino l'utilizzo della faccia + local nFaceUse = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + -- si percorre il lato basso della faccia + local nM = 0 + local nCountMilHead = 0 + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC + if bFront then + nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + else + nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- ciclo sulle passate + local nO = 1 + local dStep = 0 + if dWidth + 2 * BD.CUT_EXTRA > 0.8 * dToolDiam then + nO = ceil(( dWidth + 2 * BD.CUT_EXTRA) / ( 0.6 * dToolDiam)) + if nO > 1 then + dStep = ( dWidth + 2 * BD.CUT_EXTRA) / nO + end + end + for k = nO, 1, -1 do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2CH_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == 1, -dStartDist, - dStartAccDist - ( i - 2) * dC) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + local dEal = EgtIf( i == nC, -dEndDist, - dEndAccDist - ( nC - i - 1) * dC) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, ( k - 1) * dStep - BD.CUT_EXTRA) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- verifico massimo affondamento rispetto ad elevazione + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in LongCut : depth (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + end + local dDepth = min( 0, dMaxDepth - dElev ) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- eventuale lavorazione della faccia limitante l'inizio + if i == 1 and not bStartFixed then + local vtIni = EgtIf( bFront, X_AX(), -X_AX()) + for j = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT) + if vtIni * vtN > 0 and nCountMilHead < 2 then + MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam) + nCountMilHead = nCountMilHead + 1 + end + end + if bForcedLim and nCountMilHead < 1 then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim) + nCountMilHead = nCountMilHead + 1 + end + end + end + + -- eventuale lavorazione della faccia limitante la fine + if not bEndFixed then + local vtFin = EgtIf( bFront, -X_AX(), X_AX()) + for j = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT) + if vtFin * vtN > 0 and nCountMilHead < 2 then + MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam) + nCountMilHead = nCountMilHead + 1 + end + end + if bForcedLim and nCountMilHead < 2 then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim) + nCountMilHead = nCountMilHead + 1 + end + end + -- altrimenti è sotto ( lavorazione Long2CutDown) o da sopra ma con fresa di fianco ( lavorazione Long2CutSide) + else + -- da Analisi con Fabio Squaratti 15/09/2020 + -- variabile che indica se ripassare sul raggio rimasto dalla lavorazione di fianco + local bRemoveToolRadius + -- se nExtendMach = 0 la lavorazione rimane arretrata dalla fine della faccia del raggio utensile + -- se nExtendMach = 1 la lavorazione arriva fino alla fine faccia (se non ha facce limite) ignorando il pezzo successivo + -- se nExtendMach = 2 la lavorazione viene estesa ma arretra per non segnare il pezzo successivo (se non ha facce limite) + local nExtendMach + -- recupero la lavorazione + local sMilling + local sPrefix + if nSide ~= - 1 then + sMilling = ML.FindMilling( 'Long2CutSide') + sPrefix = 'L2CS_' + nExtendMach = nUseMillOnSide + if nUseMillOnSide == 2 then + bRemoveToolRadius = true + end + -- lavorazione da sotto + else + sMilling = ML.FindMilling( 'Long2CutDown') + sPrefix = 'L2CD_' + nExtendMach = 1 + if nUseMillOnSide ~= 1 then + nExtendMach = 2 -- arretro il minimo indispensabile per non segnare il pezzo successivo (se non ha facce limite) + end + end + 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 dToolDiam = 0 + local dMaxDepth = 0 + local dThDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + end + end + local dDistToEnd = dToolDiam / 2 + -- se fresa di fianco o da sotto calcolo quanto l'utensile può andare vicino al limite se l'elevazione della faccia è minore del raggio utensile + if nUseMillOnSide <= 1 or nSide == -1 then + -- calcolo l'elevazione della faccia principale + local dFacElev = BL.GetFaceElevation( Proc.Id, 0, nPartId) + if dFacElev < dDistToEnd then + dDistToEnd = sqrt( ( ( dToolDiam / 2) * ( dToolDiam / 2)) - ( ( dToolDiam / 2 - dFacElev) * (dToolDiam / 2 - dFacElev))) + end + end + -- se la fine è già limitata allora setto per arretrare del raggio utensile + if bLimXmin then + nExtendMach = 0 + -- se la fine non è limitata e ho un pezzo successivo distante meno di metà raggio. setto la fine come limitata + elseif dDistToNextPiece < dDistToEnd and nExtendMach ~= 1 then + bLimXmin = true + end + -- larghezza faccia + local _, _, dWidth = BL.GetFaceHvRefDim( Proc.Id, 0) + -- aggiuntivo sull'affondamento + local dAgg = BD.CUT_EXTRA + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + if ( bLimXmin and bFront) or ( bLimXmax and not bFront) then + if ( bLimXmin and bFront) then + dStartDist = EgtIf( nExtendMach == 2, dDistToEnd - dDistToNextPiece + 0.5, dDistToEnd) + else + dStartDist = dDistToEnd + end + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + if ( bLimXmin and not bFront) or ( bLimXmax and bFront) then + if ( bLimXmin and not bFront) then + dEndDist = EgtIf( nExtendMach == 2, dDistToEnd - dDistToNextPiece + 0.5, dDistToEnd) + else + dEndDist = dDistToEnd + end + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino il numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- ciclo sulle parti + local nM = 0 + local bMakeMillHeadEnd + local bMakeMillHeadStart + for j = 1, nC do + -- Limitazioni della lavorazione + local nPos = EgtIf( bFront, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, -dEndDist, -dEndAccDist - ( nPos - 2) * dC) + local dEal = EgtIf( nPos == nC, -dStartDist, -dStartAccDist - ( nC - nPos - 1) * dC) + -- Posizione braccio portatesta + local nSCC + if bFront then + nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + else + nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = sPrefix .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- verifico massimo affondamento (tengo conto dell'inclinazione utensile e della pinza con estremità conica) + -- 08/09/2020 tolti i 3mm ( per la ghiera smussata) perchè nella verifica collisione vine creato un cilindro non smussato che rileva la collisione +-- local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * abs( vtN:getY() / vtN:getZ()) - 3) + local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * abs( vtN:getY() / vtN:getZ())) + if dWidth + dAgg > dMaxDepth - dCollSic then + sWarn = 'Warning in LongCut : depth (' .. EgtNumToString( dWidth + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth - dCollSic, 1) .. ')' + end + local dDepth = min( dMaxDepth - dCollSic, dWidth + dAgg) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale lavorazione della faccia limitante la fine + if j == EgtIf( bFront , 1, nC) and not bEndFixed and bRemoveToolRadius then + local vtFin = EgtIf( bFront, -X_AX(), X_AX()) + for i = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT) + if vtFin * vtN > 0 and not bMakeMillHeadEnd then + MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam) + bMakeMillHeadEnd = true + end + end + if bRemoveToolRadius and not bMakeMillHeadEnd then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bRemoveToolRadius) + end + end + -- eventuale lavorazione della faccia limitante l'inizio + if j == EgtIf( bFront , nC, 1) and not bStartFixed and bRemoveToolRadius then + local vtIni = EgtIf( bFront, X_AX(), -X_AX()) + for i = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT) + if vtIni * vtN > 0 and not bMakeMillHeadStart then + MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam) + bMakeMillHeadStart = true + end + end + if bRemoveToolRadius and not bMakeMillHeadStart then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bRemoveToolRadius) + end + end + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessLongCut diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessLongDoubleCut.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessLongDoubleCut.lua new file mode 100644 index 0000000..afab270 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessLongDoubleCut.lua @@ -0,0 +1,1009 @@ +-- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2020/12/04 +-- Gestione calcolo doppio taglio longitudinale per Travi + +-- Tabella per definizione modulo +local ProcessLong2Cut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessLongDoubleCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +local dLimMinPiece = BD.LEN_SHORT_PART or 1000 + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLong2Cut.Identify( Proc) + return ( Proc.Grp == 0 and Proc.Prc == 12) +end + +--------------------------------------------------------------------- +-- Identificazione delle facce della feature. +-- Ritorna quattro valori : +-- flag delle facce limitanti (0= no, 1= a destra, 2= a sinistra, 3= entrambe) +-- vettore indici facce longitudinali +-- vettore dei centri delle facce longitudinali +-- vettore dei centri delle normali +local function IdentifyFaces( Proc) + + local nFaceLimit = 0 + local tFaceLong = {} + local tptC = {} + local tvtN = {} + + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se è una faccia limite a sinistra + if vtN:getX() > GEO.EPS_SMALL then + nFaceLimit = nFaceLimit | 2 + -- se è una faccia limite a destra + elseif vtN:getX() < -GEO.EPS_SMALL then + nFaceLimit = nFaceLimit | 1 + -- altrimenti è una faccia longitudinale + else + local nInd = #tFaceLong + 1 + tFaceLong[nInd] = i-1 + tptC[nInd], tvtN[nInd] = EgtSurfTmFacetCenter( Proc.Id, ( i-1), GDB_ID.ROOT) + end + end + return nFaceLimit, tFaceLong, tptC, tvtN +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLong2Cut.Classify( Proc) + + local nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0 + + -- se richiesto utensile di fianco + if nUseMillOnSide > 0 then + + -- carico i dati delle face già inserite nelle opportune tabelle + local nFaceLimit, tFaceLong, _, vtN = IdentifyFaces( Proc) + + -- verifico posizione (+1=sopra, -1=sotto, 0=sui lati) + local nSide = 0 + if vtN[1]:getZ() > -10 * GEO.EPS_SMALL and vtN[2]:getZ() > -10 * GEO.EPS_SMALL then + nSide = 1 + elseif vtN[1]:getZ() < -10 * GEO.EPS_SMALL and vtN[2]:getZ() < -10 * GEO.EPS_SMALL then + nSide = -1 + end + -- angolo diedro per stabilire se taglio convesso + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, tFaceLong[1], tFaceLong[2], GDB_ID.ROOT) + local bConvex + if bAdj then + bConvex = ( dAng >= 0) + else + bConvex = true + end + -- se feature di fianco e facce concave per lavorazione impossibile + if nSide == 0 and not bConvex then + -- do errore perchè su un lato entra nel pezzo (entra nel lato sopra) + Proc.ErrMsg = 'Error : impossible to machinine with tool on side' + return false, false + end + end + + return true, false +end + +--------------------------------------------------------------------- +function ProcessLong2Cut.GetLongFacesCount( Proc) + local nLongFaces = 0 + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if abs( vtN:getX()) < GEO.EPS_SMALL then + nLongFaces = nLongFaces + 1 + end + end + return nLongFaces +end + +--------------------------------------------------------------------- +local function MakeSideFace( nId, nFac, nSide, sMilling, dToolDiam, nL2CSide) + -- inserisco la lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( nId) or tostring( nId)) .. '_' .. tostring( nFac) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nId, nFac}}) + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- uso della faccia + local nFaceUse = EgtIf( nSide == 1, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.ORTHO_LEFT) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- annullo offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30) + -- se faccia di fianco e testa da sotto, aumento la sicurezza + if nL2CSide == 0 and BD.DOWN_HEAD then + EgtSetMachiningParam( MCH_MP.STARTPOS, 80) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +local function MakeByPocketing( Proc, nPhase, nRawId, nPartId, nSide, nFacInd, dFacElev) + -- cerco la svuotatura opportuna + local sPockType = EgtIf( nSide ~=1 and BD.DOWN_HEAD, 'OpenPocket_H2', 'OpenPocket') + local sPocketing = ML.FindPocketing( sPockType, Proc.Box:getDimX()) + if not sPocketing then + local sErr = 'Error : OpenPocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + end + end + -- inserisco la lavorazione + 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( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto attacco per tasca aperta + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev) + dFacElev = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster, nUseSideToolMaster) + + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- carico i dati delle face già inserite nelle opportune tabelle + local nFaceLimit, tFaceLong, ptC, vtN = IdentifyFaces( Proc) + local dLen = Proc.Box:getDimX() + + -- verifico posizione (+1=sopra, -1=sotto, 0=sui lati) + local nSide = 0 + if vtN[1]:getZ() > -10 * GEO.EPS_SMALL and vtN[2]:getZ() > -10 * GEO.EPS_SMALL then + nSide = 1 + elseif vtN[1]:getZ() < -10 * GEO.EPS_SMALL and vtN[2]:getZ() < -10 * GEO.EPS_SMALL then + nSide = -1 + end + + -- angolo diedro per stabilire se taglio convesso + local bInt, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, tFaceLong[1], tFaceLong[2], GDB_ID.ROOT) + local bConvex + local bOrtho + local ptM + if bInt then + bConvex = ( dAng >= 0) + bOrtho = ( abs( dAng + 90) < 1) + ptM = ( ptP1 + ptP2) / 2 + else + bConvex = true + bOrtho = false + ptM = ( ptC[1] + ptC[2]) / 2 + end + local ptRef = ( ptC[1] + ptC[2]) / 2 + -- analisi del taglio + local vOrd = {} + local vFaceUse = {} + if nSide == 1 or ( nSide == -1 and BD.DOWN_HEAD) then + vOrd = EgtIf( ptC[1]:getY() < ptRef:getY(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + elseif nSide == -1 then + vOrd = EgtIf( ptC[1]:getY() < ptM:getY(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestParalOpposite( ptC[1] - ptM), BL.GetNearestParalOpposite( ptC[2] - ptM)} + else + local bFront = ( vtN[1]:getY() < 0) + if bFront then + vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + else + vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 2, 1}, { 1, 2}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + end + end + local vWidth = {} + _, _, vWidth[1] = BL.GetFaceHvRefDim( Proc.Id, tFaceLong[1]) + _, _, vWidth[2] = BL.GetFaceHvRefDim( Proc.Id, tFaceLong[2]) + + -- ottengo la distanza tra la fine del pezzo e il pezzo successivo + local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or 5.4 + local bForcedLim + local sWarn + ---------------------------------------------------------------------------------------------------------------------------------------- + -- 2020/09/17 Fabio Squaratti: se sono attivi entrambe i Q01 (lavorare con lama) e Q03 (lavorare con fresa di fianco anche da sopra) + -- allora vince il Q3, cioè si utilizza la fresa di fianco ( per i tagli da sopra) + + -- 2020/09/17 Fabio Squaratti: se lavorazione con fresa di fianco e se ci sono delle facce laterali, l'utensile deve arrivare + -- fino al punto più vicino della faccia laterale (prima l'arretramento era sempre del raggio utensile). + -- Questo viene fatto se Q03=1 o fresa da sotto + ---------------------------------------------------------------------------------------------------------------------------------------- + local bUseBlade + local nUseMillOnSide + -- se presenti utilizzo i parametri dell'eventuale lua "padre" + if bForcedBladeMaster ~= nil then + bUseBlade = bForcedBladeMaster + else + bUseBlade = EgtGetInfo( Proc.Id, 'Q01', 'i') == 1 + end + if nUseSideToolMaster ~= nil then + nUseMillOnSide = nUseSideToolMaster + else + nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0 + end + + -- se entrambe i Q sono attivi, disabilito lama + if nUseMillOnSide > 0 then bUseBlade = false end + + -- Se senza facce limitanti, da sopra e richiesto con doppio taglio di lama + if nFaceLimit == 0 and nSide == 1 and bUseBlade and b3Solid:getDimX() > dLimMinPiece - 1 then + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : HeadSide not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- se la distanza dal pezzo successivo è inferiore della metà lama, do un warning + if dDistToNextPiece < dToolDiam/2 then + sWarn = 'Warning : Cut machining can damage next piece' + EgtOutLog( sWarn) + end + -- determino numero di parti + local dStartAccDist = BD.LONGCUT_ENDLEN + local dEndAccDist = BD.LONGCUT_ENDLEN + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + if dC < min( dStartAccDist, dEndAccDist) then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + dStartAccDist = dLen / 2 + dEndAccDist = dStartAccDist + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + + local nM = 0 + -- se convesso lavoro ogni faccia in due metà lasciando attaccata la parte centrale + if bConvex then + -- si percorrono i lati alto e basso della faccia + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = EgtIf( ( i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- ciclo sulle due facce + for j = 1, #vOrd do + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN[vOrd[j]]:getY() < 0) + -- determino l'utilizzo della faccia + local nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + local nFaceUse2 = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + -- ciclo sulle passate + local dOffset = ( vWidth[vOrd[j]] + BD.DIM_STRIP_SMALL) / 2 ; + local dLioTang = 0 + local dLioPerp = ( vWidth[vOrd[j]] - BD.DIM_STRIP_SMALL) / 2 + BD.CUT_SIC ; + for k = 1, 2 do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) .. '_' .. tostring(j) + local nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vOrd[j]-1}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC) + local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC) + if ( not bFront and k == 1) or ( bFront and k == 2) then + dSal, dEal = dEal, dSal + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + end + -- altrimenti concavo + else + -- si percorrono i lati alto e basso della faccia + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = EgtIf( ( i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- ciclo sulle due facce + for j = 1, #vOrd do + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN[vOrd[j]]:getY() < 0) + -- determino l'utilizzo della faccia + local nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + local nFaceUse2 = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + -- ciclo sulle passate + local dOffset + local dLioPerp + if j == 1 then -- il primo taglio lo faccio completo se angolo interno maggiore di 90 + -- se angolo interno inferiore di 90° calcolo l'arretramento della lama + un piccolo delta di 0.3 + if dAng < - ( 90 + 10 * GEO.EPS_SMALL) then + dOffset = 0.3 + ((dToolThick* vtN[vOrd[1]]) * vtN[vOrd[2]] * vtN[vOrd[2]]):len() + else + dOffset = 0 + end + dLioPerp = vWidth[vOrd[j]] + BD.CUT_SIC + else -- il secondo ridotto della distanza minima e della componente spessore della lama + dOffset = BD.DIM_STRIP_SMALL + ((dToolThick* vtN[vOrd[1]]) - (dToolThick* vtN[vOrd[1]]) * vtN[vOrd[2]] * vtN[vOrd[2]]):len() + dLioPerp = vWidth[vOrd[j]] - dOffset + BD.CUT_SIC + end + local dLioTang = 0 + + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) + local nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vOrd[j]-1}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC) + local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC) + if ( bFront) then + dSal, dEal = dEal, dSal + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse2) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + end + -- se non è sotto e non uso fresa di fianco: lavorazione Long2Cut + elseif ( nSide ~= - 1 or BD.DOWN_HEAD) and nUseMillOnSide == 0 then + -- determino la massima elevazione + local dElev = 0 + local dFacElev1 = BL.GetFaceElevation( Proc.Id, tFaceLong[1], nPartId) + local dFacElev2 = BL.GetFaceElevation( Proc.Id, tFaceLong[2], nPartId) + -- 03/12/2020 + -- se facce concave e a 90 gradi, prendo l'elevazione minima + if bOrtho then + dElev = min( dFacElev1, dFacElev2) + else + dElev = max( dFacElev1, dFacElev2) + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2Cut', dElev) + if not sMilling then + local sErr = 'Error : Long2Cut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- se angolo compreso è inferiore ai 90 gradi do errore + if dAng < - ( 90 + 10 * GEO.EPS_SMALL) then + local sErr = 'Error : Impossible use a mill with angle less than 90' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se la fine (a sinistra) non è limitata e ho un pezzo successivo più distante da metà raggio. setto la fine come limitata + if dDistToNextPiece < dToolDiam/2 and nFaceLimit < 2 then + bForcedLim = true + nFaceLimit = nFaceLimit + 2 + end + -- se chiuso e corto, applico svuotatura con fresa opportuna + if nFaceLimit == 3 and Proc.Box:getDimX() < 2 * dToolDiam then + -- svuotatura della prima faccia longitudinale + local bOk, sErr = MakeByPocketing( Proc, nPhase, nRawId, nPartId, nSide, tFaceLong[1], dFacElev1) + -- svuotatura della seconda faccia longitudinale + if not bOk then return bOk, sErr end + return MakeByPocketing( Proc, nPhase, nRawId, nPartId, nSide, tFaceLong[2], dFacElev2) + end + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + -- se ho faccia limite a destra + if nFaceLimit == 1 or nFaceLimit == 3 then + dStartDist = dToolDiam / 2 + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + -- se ho faccia limite a sinistra + if nFaceLimit >= 2 then + dEndDist = dToolDiam / 2 + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino il numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + local nIncStep = 2 + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + -- se distanza rimanente è < della metà del minimo della distanza estremi allora aggiungo un passo in più + local dMinDist = EgtIf( min( dStartAccDist, dEndAccDist) / 2 > 300 , 300, min( dStartAccDist, dEndAccDist) / 2) + if dC < dMinDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + nIncStep = 1 + elseif dC < min( dStartAccDist, dEndAccDist) then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + if dC < dStartAccDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + if dC < dEndAccDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + nIncStep + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + local nIni, nFin = 1, 2 + local dLimitAngle = -0.5 - 20 * GEO.EPS_SMALL + -- se facce ortogonali (concave), mantengo la lavorazione di testa sulla faccia più grande purchè non superi di 30 gradi il sottosquadra + if bOrtho then + if vtN[vOrd[1]]:getZ() > 0.001 and vtN[vOrd[2]]:getZ() > 0.001 then + if vtN[vOrd[1]]:getZ() >= vtN[vOrd[2]]:getZ() then + nFin = 1 + else + nIni = 2 + end + else + if vtN[vOrd[1]]:getZ() < dLimitAngle then + nIni = 2 + elseif vtN[vOrd[2]]:getZ() < dLimitAngle then + nFin = 1 + else + if vtN[vOrd[1]]:getZ() >= vtN[vOrd[2]]:getZ() then + if vtN[vOrd[2]]:getZ() < dLimitAngle then + nFin = 1 + else + nIni = 2 + end + else + if vtN[vOrd[1]]:getZ() < dLimitAngle then + nIni = 2 + else + nFin = 1 + end + end + end + end + end + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + -- su entrambe le facce + for i = nIni, nFin do + -- Limitazioni della lavorazione + local nPos = EgtIf( i == 1, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC) + local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC) + -- Posizione braccio portatesta + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = EgtIf( ( j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- Verifico se da fare di fianco perchè normale troppo verso il basso (minore di -30deg) + local bSide = ( vtN[vOrd[i]]:getZ() < dLimitAngle and not BD.DOWN_HEAD) + -- ciclo sulle passate + local nO = 1 + local dStep = 0 + local dAgg = EgtIf( bConvex, 2 * BD.CUT_EXTRA, BD.CUT_EXTRA) + local dLargh = vWidth[vOrd[i]] + if not bSide and dLargh > 0.8 * dToolDiam then + nO = ceil( dLargh / ( 0.6 * dToolDiam)) + if nO > 1 then + dStep = dLargh / nO + end + end + for k = 1, nO do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, tFaceLong[vOrd[i]]}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + EgtOutLog( 'FaceUse='..tostring( vFaceUse[vOrd[i]])) + --EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bSide, BL.GetParallelOpposite( vFaceUse[vOrd[i]]), vFaceUse[vOrd[i]])) + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bSide, MCH_MILL_FU.PARAL_DOWN, vFaceUse[vOrd[i]])) + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bSide, true, false)) + -- imposto offset radiale (nullo se concavo o di lato) + local dOffsR = EgtIf( k < nO, ( nO - k) * dStep, EgtIf( bConvex, - BD.CUT_EXTRA, 0)) + if bSide then dOffsR = 0 end + EgtSetMachiningParam( MCH_MP.OFFSR, dOffsR) + -- se di lato, imposto offset longitudinale + if bSide then + EgtSetMachiningParam( MCH_MP.OFFSL, - BD.CUT_EXTRA) + end + -- attacco e uscita + local dLioPerp = EgtIf( bSide, dToolDiam, dLargh - dOffsR + BD.CUT_SIC) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- se faccia di fianco e testa da sotto, aumento la sicurezza + if nSide == 0 and BD.DOWN_HEAD then + EgtSetMachiningParam( MCH_MP.STARTPOS, 80) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante l'inizio (a destra) + if bConvex and j == 1 and not bStartFixed then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], 1, sMilling, dToolDiam, nSide) + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante la fine (a sinistra) + if bConvex and j == nC and not bEndFixed then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], -1, sMilling, dToolDiam, nSide) + end + end + end + -- altrimenti è sotto : lavorazione Long2CutDown + else + -- da Analisi con Fabio Squaratti 15/09/2020 + -- variabile che indica se ripassare sul raggio rimasto dalla lavorazione di fianco + local bRemoveToolRadius + -- se nExtendMach = 0 la lavorazione rimane arretrata dalla fine della faccia del raggio utensile + -- se nExtendMach = 1 la lavorazione arriva fino alla fine faccia (se non ha facce limite) ignorando il pezzo successivo + -- se nExtendMach = 2 la lavorazione viene estesa ma arretra per non segnare il pezzo successivo (se non ha facce limite) + local nExtendMach + -- recupero la lavorazione + local sMilling + local sPrefix + if nSide ~= - 1 then + sMilling = ML.FindMilling( 'Long2CutSide') + sPrefix = 'L2CS_' + nExtendMach = nUseMillOnSide + if nUseMillOnSide == 2 then + bRemoveToolRadius = true +-- nExtendMach = 0 -- arretro la lavorazione del raggio utensile (se non ha facce limite) + end + -- lavorazione da sotto + else + sMilling = ML.FindMilling( 'Long2CutDown') + sPrefix = 'L2CD_' + nExtendMach = 1 + if nUseMillOnSide ~= 1 then + nExtendMach = 2 -- arretro il minimo indispensabile per non segnare il pezzo successivo (se non ha facce limite) + end + end + if not sMilling then + local sErr = 'Error : Long2CutSide or Long2CutDown not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- se angolo compreso è inferiore ai 90 gradi do errore + if dAng < - ( 90 + 10 * GEO.EPS_SMALL) then + local sErr = 'Error : Impossible use a mill with angle less than 90' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + local dThDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + end + end + local dDistToEnd = dToolDiam / 2 + -- se fresa di fianco o da sotto calcolo quanto l'utensile può andare vicino al limite se l'elevazione della faccia è minore del raggio utensile + if nUseMillOnSide <= 1 or nSide == -1 then + -- calcolo l'elevazione della faccia principale + local dFacElev1 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[1]], nPartId) + local dFacElev2 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[2]], nPartId) + local dFacElev = max( dFacElev1, dFacElev2) + if dFacElev < dDistToEnd then + dDistToEnd = sqrt( ( ( dToolDiam / 2) * ( dToolDiam / 2)) - ( ( dToolDiam / 2 - dFacElev) * (dToolDiam / 2 - dFacElev))) + end + end + -- se la fine è già limitata allora setto per arretrare del raggio utensile + if nFaceLimit >= 2 then + nExtendMach = 0 + -- se la fine non è limitata e ho un pezzo successivo distante meno di metà raggio. setto la fine come limitata + elseif dDistToNextPiece < dDistToEnd and nExtendMach ~= 1 then + nFaceLimit = nFaceLimit + 2 + end + -- aggiuntivo sull'affondamento + local dAgg = EgtIf( bConvex, BD.CUT_EXTRA, 0) + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + -- se ho facce limite a destra + if nFaceLimit == 1 or nFaceLimit == 3 then + dStartDist = dDistToEnd + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + -- se ho facce limite a sinistra + if nFaceLimit >= 2 then + dEndDist = EgtIf( nExtendMach == 2, dDistToEnd - dDistToNextPiece + 0.5, dDistToEnd) + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino il numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + local nIni, nFin = 1, 2 + local nDir = 1 + -- se facce ortogonali (concave) controllo se con la lavorazione della prima faccia il diametro copre la seconda (e non la eseguo) + if bOrtho then + -- se da sotto scelgo la faccia (lavorta col fianco utensile) con direzione più sottosquadra + if nSide == -1 and vtN[vOrd[1]]:getZ() < -0.001 and vtN[vOrd[2]]:getZ() < -0.001 then + -- se gli angoli delle due facce sono uguali ( sotto il grado di differenza) sgelgo la faccia più vicina a un fianco + if abs(vtN[vOrd[1]]:getZ() - vtN[vOrd[2]]:getZ()) < 0.017 then + -- se punto medio più vicino al lato dietro + if b3Solid:getMax():getY() - ptM:getY() < ptM:getY() - b3Solid:getMin():getY() then + -- se prima faccia più vicina alla faccia dietro eseguo prima questa + if ptC[vOrd[1]]:getY() > ptC[vOrd[2]]:getY() then + if dToolDiam > vWidth[vOrd[2]] then + nFin = 1 + end + -- se è più lontana inverto la direzione di lavoro + else + -- inverto la direzione di lavorazione delle facce + nDir = -1 + nIni, nFin = 2, 1 + if dToolDiam > vWidth[vOrd[1]] then + nFin = 2 + end + end + -- altrimenti punto medio più vicino al lato davanti + else + -- se prima faccia più vicina alla faccia dietro inverto la direzione di lavorazione + if ptC[vOrd[1]]:getY() > ptC[vOrd[2]]:getY() then + -- inverto la direzione di lavorazione delle facce + nDir = -1 + nIni, nFin = 2, 1 + if dToolDiam > vWidth[vOrd[1]] then + nFin = 2 + end + else + if dToolDiam > vWidth[vOrd[2]] then + nFin = 1 + end + end + end + elseif vtN[vOrd[2]]:getZ() < vtN[vOrd[1]]:getZ() then + -- inverto la direzione di lavorazione delle facce + nDir = -1 + nIni, nFin = 2, 1 + if dToolDiam > vWidth[vOrd[1]] then + nFin = 2 + end + else + if dToolDiam > vWidth[vOrd[2]] then + nFin = 1 + end + end + -- in tutti gli altri casi + else + if dToolDiam > vWidth[vOrd[2]] then + nFin = 1 + end + end + end + -- su entrambe le facce + for i = nIni, nFin, nDir do + -- Limitazioni della lavorazione + local nPos = EgtIf( i == 1, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC) + local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC) + -- Posizione braccio portatesta + local nSCC = EgtIf( BD.C_SIMM, MCH_SCC.NONE, MCH_SCC.ADIR_XP) + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, tFaceLong[vOrd[i]]}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + if nUseMillOnSide > 0 and nSide ~= -1 then + if nSide == 1 then + if bConvex then + if vtN[vOrd[i]]:getZ() > 0.866 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_TOP) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + end + -- se concavo + else + local vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)]) + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end + else + if bConvex then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + if vtN[vOrd[i]]:getZ() >= 0 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end + else + -- lascio lo stesso le lavorazioni anche se viene intercettato l'errore + local vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)]) + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2) + if vtN[vOrd[i]]:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end + end + end + else + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]]) + end + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + local dNz = vtN[vOrd[i]]:getZ() + -- nel caso concavo, devo impostare la lunghezza di attacco ortogonale + if not bConvex then +-- local dLioPerp = vWidth[vOrd[i]] * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, sqrt( 1 - dNz * dNz) / abs( dNz)) + BD.COLL_SIC + local dLioPerp = vWidth[ EgtIf( vOrd[i] == 1, 2,1)] + BD.COLL_SIC + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + end + -- verifico massimo affondamento (tengo conto dell'inclinazione utensile e della pinza con estremità conica) + -- 08/09/2020 tolti i 3mm ( per la ghiera smussata) perchè nella verifica collisione vine creato un cilindro non smussato che rileva la collisione +-- local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * abs( vtN[vOrd[i]]:getY() / vtN[vOrd[i]]:getZ()) - 3) + local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( vtN[vOrd[i]]:getY() / dNz))) + if vWidth[vOrd[i]] + dAgg > dMaxDepth - dCollSic then + sWarn = 'Warning in LongDoubleCut : depth (' .. EgtNumToString( vWidth[vOrd[i]] + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth - dCollSic, 1) .. ')' + end + local dDepth = min( dMaxDepth - dCollSic, vWidth[vOrd[i]] + dAgg) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante l'inizio (a destra) + if bConvex and j == 1 and not bStartFixed and bRemoveToolRadius then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], 1, sMilling, dToolDiam) + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante la fine (a sinistra) + if bConvex and j == nC and not bEndFixed and bRemoveToolRadius then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], -1, sMilling, dToolDiam) + end + end + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessLong2Cut diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessMark.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessMark.lua new file mode 100644 index 0000000..13d7843 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessMark.lua @@ -0,0 +1,131 @@ +-- ProcessMark.lua by Egaltech s.r.l. 2020/05/28 +-- Gestione calcolo marcatura per Travi +-- 2020/05/28 Tipo di lavorazione passato da Mark a Text + +-- Tabella per definizione modulo +local ProcessMark = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessMark started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessMark.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 60) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessMark.Classify( Proc) + -- recupero il versore estrusione o normale se testo + local vtN + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtN = EgtCurveExtrusion( Proc.Id, GDB_ID.ROOT) + else + vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtN then + return false + end + -- verifico se la marcatura è lavorabile solo da sotto + local bDown = (( vtN:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessMark.Make( Proc, nPhase, nRawId, nPartId) + -- recupero eventuale geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero i dati della marcatura + local vtExtr + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + else + vtExtr = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtExtr then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che la marcatura non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Text') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale lavorazione su seconda geometria + if AuxId then + -- inserisco la lavorazione di fresatura + local sName2 = 'Decor2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchF2Id = EgtAddMachining( sName, sMilling) + if not nMchF2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + 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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchF2Id, false) + return false, sErr + end + -- se geometria a X maggiore, la sposto prima + local ptS1 = EgtSP( Proc.Id, GDB_ID.ROOT) + local ptS2 = EgtSP( AuxId, GDB_ID.ROOT) + if ptS2:getX() > ptS1:getX() then + EgtRelocateGlob( nMchF2Id, nMchFId, GDB_IN.BEFORE) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessMark diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessMortise.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessMortise.lua new file mode 100644 index 0000000..ac03fe8 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessMortise.lua @@ -0,0 +1,353 @@ +-- ProcessMortise.lua by Egaltech s.r.l. 2020/11/08 +-- Gestione calcolo mortase per Travi + +-- Tabella per definizione modulo +local ProcessMortise = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessMortise started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessMortise.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 50) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 51) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 53)) +end + +--------------------------------------------------------------------- +-- Riconoscimento della sola feature frontale +function ProcessMortise.FrontIdentify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 51) +end + +--------------------------------------------------------------------- +-- Classificazione della feature: decide se la feature è in una posizione che per lavorala +-- deve essere ribaltata o no +function ProcessMortise.Classify( Proc) + -- recupero e verifico il percorso supplementare + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero versore estrusione della curva supplementare e non più della superficie + -- perché quest'ultima potrebbe non avere il fondo e dare quindi un risultato non corretto + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtExtr then + return false + end + if not vtN then + return false + end + local bDown + -- Confronto le direzioni Z dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante + if abs( vtExtr:getZ() - vtN:getZ()) > GEO.EPS_SMALL then + bDown = false + -- altrimenti è chiusa + else + -- verifico se la mortasa è lavorabile solo da sotto + bDown = ( vtN:getZ() < - 0.1) + end + return true, bDown +end + +--------------------------------------------------------------------- +-- Piano di taglio della feature +function ProcessMortise.GetCutPlane( Proc) + if ProcessMortise.FrontIdentify( Proc) then + return EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + else + return nil, nil + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + local bForceOneSide + local bRevertSide + if AuxId then + AuxId = AuxId + Proc.Id + end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero versore estrusione della curva supplementare + local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT) + -- Se curva di contorno aperta + if not EgtCurveIsClosed( AuxId) then + local NewId, nCount = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id)) + if NewId then + -- elimino eventuali loop interni (non dovrebbero comunque esserci) + for i = 1, nCount - 1 do + EgtErase( NewId + i) + end + -- sostituisco il loop esterno alla curva originale + EgtModifyCurveExtrusion( NewId, vtExtr, GDB_ID.ROOT) + EgtRelocate( NewId, AuxId, GDB_IN.AFTER) + EgtErase( AuxId) + EgtChangeId( NewId, AuxId) + -- sistemo i lati aperti + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, 0)[1] + if vFacAdj then + local sOpen = '' + for i = 1, #vFacAdj do + if vFacAdj[i] < 0 then + sOpen = sOpen .. EgtIf( #sOpen > 0, ',', '') .. tostring( i - 1) + end + end + if #sOpen > 0 then + EgtSetInfo( AuxId, 'OPEN', sOpen) + end + end + end + end + -- verifico se frontale + local bFront = ( Proc.Prc == 51) + -- recupero i dati della faccia di fondo + local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + local ptC = ORIG() + local vtN = V_NULL() + if frMor then + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + end + -- Confronto le direzioni dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante + local bOpenBtm = not AreSameVectorApprox( vtExtr, vtN) + if bOpenBtm then + -- creo superficie chiusa + local nFlat = EgtSurfTmByFlatContour( EgtGetParent( AuxId), AuxId, 0.05) + if nFlat then + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + -- verifico se copiare la geometria lungo l'asse Z + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frMor) + local bxMax = b3Aux:getMax() + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local bxMin = b3Mor:getMin() + local dMove = bxMin:getZ()-bxMax:getZ() + -- se il percorso ausiliario è esterno al grezzo, lo riavvicino + if abs( dMove) > GEO.EPS_SMALL then + AuxId = EgtCopyGlob( AuxId, BL.GetAddGroup(nPartId)) + EgtMove( AuxId, Vector3d(0,0,-dMove)) + EgtMove( nFlat, Vector3d(0,0,-dMove)) + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + end + -- cancello le prove del misfatto (superficie piana) + EgtErase( nFlat) + end + end + -- scrivo info nel log + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- Se mortasa chiusa + if not bOpenBtm then + -- verifico che la mortasa non sia orientata verso il basso (limite -5 deg) + if vtN:getZ() < -0.1 and not BD.DOWN_HEAD then + local sErr = 'Error : Mortise from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- altrimenti passante + else + -- determino se la mortasa da lavorare sul lato opposto sia di angolo inferiore a quello consentito + if abs( vtN:getZ()) > 0.1 then + bForceOneSide = true + end + -- determino se è meglio lavorare la mortasa nel lato opposto + if vtN:getZ() < -GEO.EPS_SMALL then + bRevertSide = true + end + end + + -- se mortasa di fronte, eseguo il taglio della faccia + if bFront then + -- verifico esista la faccia di taglio + local ptCutC, vtCutN = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if ptCutC and vtCutN and AreSameVectorApprox( vtExtr, vtCutN) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptCutC, vtCutN, b3Solid, GDB_RT.GLOB) + local b3Cut = EgtGetBBoxGlob( AddId or GDB_ID.NULL, GDB_BB.STANDARD) + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Cut, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getZ() > 0.25) + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH, bFromBottom) + if not bOk then return bOk, sErr end + end + end + + -- determino altezza della mortasa + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local dMorH = b3Mor:getDimZ() + -- elevazione del punto centro + if not bFront then + local _, dCenElev = BL.GetPointDirDepth( nPartId, ptC, vtN) + dMorH = max( dMorH, dCenElev or 0) + end + -- determino larghezza della mortasa + if dL < dW then dL, dW = dW, dL end + -- recupero la lavorazione + local sMchExt = EgtIf( BD.DOWN_HEAD and vtN:getZ() < 0.1, '_H2', '') + local sPocketing + if Proc.Prc ~= 53 then + sPocketing = ML.FindPocketing( 'Mortise'..sMchExt, dW) + end + if not sPocketing then + sPocketing = ML.FindPocketing( 'Pocket'..sMchExt, dW) + end + if not sPocketing then + local sErr = 'Error : Mortise or Pocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local bCW = true + 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) + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'Mort_' .. ( 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 + -- verifico se invertire versore estrusione geometria + if bRevertSide then + EgtModifyCurveExtrusion( AuxId, -vtExtr, GDB_ID.ROOT) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo la direzione di lavoro + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + if bRevertSide then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + else + if bRevertSide then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + end + local sWarn + local nDepthMin + -- se la mortasa è passante e non è forzata a un solo lato, riduco l'affondamento a metà profondità + if bOpenBtm and not bForceOneSide then + dMorH = dMorH * 0.5 + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + if dMorH > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in mortise : elevation (' .. EgtNumToString( dMorH,1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth,1) .. ')' + -- se non ho invertito la direzione di estrusione + if not bRevertSide then + nDepthMin = dMaxDepth - EgtIf( bOpenBtm and not bForceOneSide, dMorH * 2, dMorH) + else + nDepthMin = dMaxDepth + end + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + dMorH = dMaxDepth + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + else + if bOpenBtm and not bForceOneSide then -- se mortasa passante setto metà profondità + nDepthMin = -dMorH + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + end + end + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMorH, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- Se non c'è il fondo e la lavorazione non ha lavorato tutta la superficie per limite altezza utensile + -- inserisco una ulteriore lavorazione contraria + if bOpenBtm and not bForceOneSide and nDepthMin and abs(nDepthMin) > 0 then + -- inserisco la lavorazione di svuotatura opposta + sName = 'Mort_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_Oppo' + nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + EgtOutLog( sErr) + return false, sErr + end + -- faccio la copia e la metto nel layer dedicato alle geometrie aggiunte + local AuxId_oppo = EgtCopyGlob( AuxId, BL.GetAddGroup(nPartId)) + -- inverto la direzione estrusione di questa + EgtModifyCurveExtrusion( AuxId_oppo, - vtExtr, GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId_oppo, -1}}) + -- sistemo la direzione di lavoro + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + -- se altezza mortasa differente da altezza massima lavorabile + if abs( dMorH - dMaxDepth) > GEO.EPS_SMALL then + nDepthMin = -dMorH + else -- se sono uguali setto + nDepthMin = -( dMorH - BD.CUT_EXTRA) + end + -- setto profondità + EgtSetMachiningParam( MCH_MP.DEPTH, -nDepthMin+BD.CUT_EXTRA) + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (-nDepthMin+BD.CUT_EXTRA), 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessMortise diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfCamb.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfCamb.lua new file mode 100644 index 0000000..ca59475 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfCamb.lua @@ -0,0 +1,649 @@ +-- ProcessProfCamb.lua by Egaltech s.r.l. 2020/11/19 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfCamb = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfCamb started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q01' -- i +local sEnableExtraBladeUpperFace = 'Q02' -- i +local sDepthChamferMill = 'Q03' -- d +local sOverMaterialForFinish = 'Q04' -- d +local sPreemptiveChamfer = 'Q05' -- i + +-- abilitazioni extra +local dMakeAntiSplintOnHead = 1 -- valore impronta antischeggia, per disattivare settare = nil o = 0 +local dActivateCompoAng = 0.175 -- valore componente Y per disattivare settare = nil + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfCamb.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 103) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfCamb.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtNF) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtNF) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtSP( AuxId, GDB_ID.ROOT) + vtNP * 5.0 + -- determino asse di rotazione + local vtRot = - Y_AX() + if vtNF:getX() < 0 then vtRot = - vtRot end + if vtNF:getZ() < -0.1 then + vtRot = - vtRot + elseif vtNF:getY() < -0.1 then + vtRot:rotate( X_AX(), 90) + elseif vtNF:getY() > 0.1 then + vtRot:rotate( X_AX(), -90) + end + -- miglioro l'inclinazione (ripartendo da faccia perpendicolare asse trave) + vtNP[2] = 0 vtNP[3] = 0 + local dRot = 45 + for i = 1, 4 do + local vtNP2 = Vector3d( vtNP) + vtNP2:rotate( vtRot, dRot) + local frRef = Frame3d( ptStart, vtNP2) + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frRef) + if b3Box:getMax():getZ() < -3 then + vtNP = Vector3d( vtNP2) + end + dRot = dRot / 2 + end + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideAndInvert( Proc, bHead, bForceInvert, nCutLengthMach) + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if bForceInvert or ( nMachMode == 1 and ptSP and ptEp) then + if bForceInvert or ( abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX())) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + -- se devo tagliare il percorso setto anche i parametri per l'antischeggia + if nCutLengthMach then + EgtSetMachiningParam( MCH_MP.OFFSR, 0.5) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, nCutLengthMach) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- ultima faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nLastFacet, GDB_ID.ROOT) + local nRefFacet = nLastFacet - 1 -- penultima faccia + local vtNF = EgtSurfTmFacetNormVersor( Proc.Id, nLastFacet, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nRefFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtNF:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, false, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + --variabili utilizzate in varie parti + local dToolMaxDepth = 0 + local dMillDiam = 0 + local sMilling + -- in base alla direzione iniziale della curva e al valore di entrata valido, setto l'antischeggia + local bMakeAs + local vtStart = EgtSV( AuxId, GDB_ID.ROOT) + if nSide == 0 then + if abs(vtStart:getY()) >= dActivateCompoAng and dMakeAntiSplintOnHead and abs(dMakeAntiSplintOnHead) > 0 then + bMakeAs = true + end + else + if abs(vtStart:getZ()) >= dActivateCompoAng and dMakeAntiSplintOnHead and abs(dMakeAntiSplintOnHead) > 0 then + bMakeAs = true + end + end + -- se smusso non è esclusivo, aggiungo sgrossatura con taglio di lama + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtNF) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId and BL.GetFaceElevation( AddId, 0, nPartId) > 20.0 then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH) + if not bOk then return bOk, sErr end + end + -- leggo anticipatamente i parametri utensile fresa per dare un valore opportuno all'elevazione della lama + -- recupero la lavorazione di fresatura + sMilling = ML.FindMilling( 'Prof') + 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 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- se non da sotto e abilitato dal parametro Q aggiungo taglio di lama + if nSide ~= -1 and nLastFacet and EgtGetInfo( Proc.Id, sEnableExtraBladeUpperFace, 'i') == 1 then + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + local vtOrthoO = Vector3d(vtN) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, nLastFacet, sCutting, dToolDiam, vtOrthoO, nil, -((dMillDiam/2)+1), BD.CUT_SIC, 0, 0, nil, b3Raw) + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName + if bMakeAs then + sName = 'Prof_As_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + else + sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + end + 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead) + end + -- se devo fare l'antischeggia in testa + if bMakeAs then + local sNewName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + -- copio lavorazione per ingresso antischeggia (la copia è la lavorazione finale) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + -- rendo corrente la precedente, la inverto e modifico il parametri di uscita + EgtSetCurrMachining( nMchId) + local dCrvLen = EgtCurveLength( AuxId) + if dCrvLen > abs(dMakeAntiSplintOnHead) then + ModifySideAndInvert( Proc, bHead, true, ( abs(dMakeAntiSplintOnHead) - dCrvLen)) + end + -- rendo corrente la copia (cioè la lavorazione completa) + EgtSetCurrMachining( nMch2Id) + nMchId = nMch2Id + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sNewName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName + if bMakeAs then + sName = 'ProfB_As_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + else + sName = 'ProfB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + end + 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead) + end + -- se devo fare l'antischeggia in testa + if bMakeAs then + local sNewName = 'ProfB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + -- copio lavorazione per ingresso antischeggia (la copia è la lavorazione finale) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + -- rendo corrente la precedente, la inverto e modifico il parametri di uscita + EgtSetCurrMachining( nMchId) + local dCrvLen = EgtCurveLength( AuxId) + if dCrvLen > abs(dMakeAntiSplintOnHead) then + ModifySideAndInvert( Proc, bHead, true, ( abs(dMakeAntiSplintOnHead) - dCrvLen)) + end + -- rendo corrente la copia (cioè la lavorazione completa) + EgtSetCurrMachining( nMch2Id) + nMchId = nMch2Id + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se non da sotto e parametro Q abilitato, inserisco lavorazione finitura angolo + if nSide ~= -1 and EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') == 1 then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, -0.5) + -- imposto tipo uso faccia + local nFaceUse = MCH_MILL_FU.ORTHO_DOWN + if nSide ~= 1 then + nFaceUse = EgtIf( vtN:getY() > 0.1, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then -- se feature di fianco o da sotto + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + -- altrimenti feature da sopra + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfCamb diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfConcave.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfConcave.lua new file mode 100644 index 0000000..1bb690f --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfConcave.lua @@ -0,0 +1,626 @@ +-- ProcessProfConcave.lua by Egaltech s.r.l. 2020/12/30 +-- Gestione calcolo profilo concavo per Travi + +-- Tabella per definizione modulo +local ProcessProfConcave = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfConcave started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q03' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q01' -- d +local sOverMaterialForFinish = 'Q02' -- d +local sPreemptiveChamfer = 'Q04' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfConcave.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 101) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfConcave.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, + bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + end + -- modifico attacco e uscita + if dLenIni and dLenLst then + -- se entità agli estremi sono inferiori del raggio utensile ed è abilitata la ripresa della faccia, + -- allungo attacco e/o uscita + local dStartAddLen = 0 + if bFirstTrim and dLenIni < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dStartAddLen = dToolDiam / 2 - dLenIni + dOffsetPar + 1 + end + local dEndAddLen = 0 + if bLastTrim and dLenLst < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dEndAddLen = dToolDiam / 2 - dLenLst + dOffsetPar + 1 + end + if bFlagInvert then + dStartAddLen, dEndAddLen = dEndAddLen, dStartAddLen + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) // 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- acquisisco informazioni sulle facce estreme + local _, _, dLenIni = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFirstFacet, GDB_ID.ROOT) + local _, _, dLenLst = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nLastFacet, GDB_ID.ROOT) + -- flag percorso invertito + local bFlagInvert = false + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, false, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo, aggiungo sgrossatura con taglio di lama + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId and BL.GetFaceElevation( AddId, 0, nPartId) > 20.0 then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- Recupero i dati dell'utensile + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sChamfer) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dExtra) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dExtra) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bLastTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + elseif vtN:getY() < -0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTUP_TOP) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (dToolMaxDepth/2), 1)) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bFirstTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then -- se feature di fianco o da sotto + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + -- altrimenti feature da sopra + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfConcave diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfConvex.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfConvex.lua new file mode 100644 index 0000000..ad309d6 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfConvex.lua @@ -0,0 +1,625 @@ +-- ProcessProfConvex.lua by Egaltech s.r.l. 2020/11/19 +-- Gestione calcolo profilo convesso per Travi + +-- Tabella per definizione modulo +local ProcessProfConvex = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfConvex started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q05' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q02' -- d +local sOverMaterialForFinish = 'Q04' -- d +local sPreemptiveChamfer = 'Q01' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfConvex.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 102) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfConvex.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, + bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + end + -- modifico attacco e uscita + if dLenIni and dLenLst then + -- se entità agli estremi sono inferiori del raggio utensile ed è abilitata la ripresa della faccia, + -- allungo attacco e/o uscita + local dStartAddLen = 0 + if bFirstTrim and dLenIni < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dStartAddLen = dToolDiam / 2 - dLenIni + dOffsetPar + 1 + end + local dEndAddLen = 0 + if bLastTrim and dLenLst < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dEndAddLen = dToolDiam / 2 - dLenLst + dOffsetPar + 1 + end + if bFlagInvert then + dStartAddLen, dEndAddLen = dEndAddLen, dStartAddLen + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) // 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- acquisisco informazioni sulle facce estreme + local _, _, dLenIni = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFirstFacet, GDB_ID.ROOT) + local _, _, dLenLst = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nLastFacet, GDB_ID.ROOT) + -- flag percorso invertito + local bFlagInvert = false + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, false, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo, aggiungo sgrossatura con taglio di lama + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId and BL.GetFaceElevation( AddId, 0, nPartId) > 20.0 then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- Recupero i dati dell'utensile + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sChamfer) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dExtra) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dExtra) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bLastTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + elseif vtN:getY() < -0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTUP_TOP) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (dToolMaxDepth/2), 1)) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bFirstTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfConvex diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfFront.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfFront.lua new file mode 100644 index 0000000..1ec1700 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfFront.lua @@ -0,0 +1,557 @@ +-- ProcessProfFront.lua by Egaltech s.r.l. 2020/12/30 +-- Gestione calcolo profilo frontale per Travi + +-- Tabella per definizione modulo +local ProcessProfFront = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfFront started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = '' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q01' -- d +local sOverMaterialForFinish = 'Q02' -- d +local sPreemptiveChamfer = 'Q03' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfFront.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 100) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfFront.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + local vtNP = Vector3d( vtN) + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideInvertLead( Proc, bHead, dToolDiam) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- ultima faccia + local nRefFacet = nLastFacet - 1 -- penultima faccia + -- determino la normale media + local CvxHullId = EgtSurfTmConvexHullInBBox( EgtGetParent( Proc.Id), Proc.Id, b3Raw, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( CvxHullId, 0, GDB_ID.ROOT) + EgtErase( CvxHullId) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + --EgtOutLog( 'vtN=' .. tostring( vtN)) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, false, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo, aggiungo sgrossatura con taglio di lama + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId and BL.GetFaceElevation( AddId, 0, nPartId) > 20.0 then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dMillDiam) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dMillDiam) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertdLead( Proc, bHead, dToolDiam) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bFirstTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + -- se non da sotto, inserisco lavorazione finitura angolo + --if nSide ~= -1 then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- setto inversione e lato lavoro per lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- imposto tipo uso faccia + local nFaceUse = MCH_MILL_FU.PARAL_DOWN + if nSide ~= 1 then + nFaceUse = EgtIf( vtN:getY() > 0.1, MCH_MILL_FU.PARAL_FRONT, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + -- aggiorno ingombro testa o coda per presa + --if nSide == 0 then + -- if bHead then + -- BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + -- else + -- BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + -- end + --end + return true +end + +--------------------------------------------------------------------- +return ProcessProfFront diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfHead.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfHead.lua new file mode 100644 index 0000000..ac27666 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessProfHead.lua @@ -0,0 +1,650 @@ +-- ProcessProfHead.lua by Egaltech s.r.l. 2020/12/30 +-- Gestione calcolo profilo di testa per Travi + +-- Tabella per definizione modulo +local ProcessProfHead = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfHead started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q03' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q01' -- d +local sOverMaterialForFinish = 'Q04' -- d +local sPreemptiveChamfer = 'Q02' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfHead.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 106) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfHead.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- assegno la normale + local vtNP = Vector3d( vtN) + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, + bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + end + -- modifico attacco e uscita + if dLenIni and dLenLst then + -- se entità agli estremi sono inferiori del raggio utensile ed è abilitata la ripresa della faccia, + -- allungo attacco e/o uscita + local dStartAddLen = 0 + if bFirstTrim and dLenIni < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dStartAddLen = dToolDiam / 2 - dLenIni + dOffsetPar + 1 + end + local dEndAddLen = 0 + if bLastTrim and dLenLst < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dEndAddLen = dToolDiam / 2 - dLenLst + dOffsetPar + 1 + end + if bFlagInvert then + dStartAddLen, dEndAddLen = dEndAddLen, dStartAddLen + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning on process ' .. tostring( Proc.Id) .. ' skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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 dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + -- determino la normale media + local CvxHullId = EgtSurfTmConvexHullInBBox( EgtGetParent( Proc.Id), Proc.Id, b3Raw, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( CvxHullId or GDB_ID.NULL, 0, GDB_ID.ROOT) + EgtErase( CvxHullId) + if not vtN then + local nRef= Proc.Fct // 3 + local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nRef, GDB_ID.ROOT) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, 2 * nRef, GDB_ID.ROOT) + vtN = vtN1 + vtN2 + vtN:normalize() + end + -- acquisisco informazioni sulle facce estreme + local _, _, dLenIni = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFirstFacet, GDB_ID.ROOT) + local _, _, dLenLst = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nLastFacet, GDB_ID.ROOT) + -- flag percorso invertito + local bFlagInvert = false + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi negli angoli + local vAngs = {} + for i = 1, Proc.Fct do + local _, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, i-1, i, GDB_ID.ROOT) + if ( dAng and dAng < -30) then + table.insert( vAngs, i - 1) + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sChamfer = VerifyCham( Proc, AuxId, nRawId, false, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo, aggiungo sgrossatura con taglio di lama + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId and BL.GetFaceElevation( AddId, 0, nPartId) > 20.0 then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- Recupero i dati dell'utensile + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sChamfer) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, + dLenLst, E( #vAngs > 0 and vAngs[1] == 0), ( #vAngs > 0 and vAngs[#vAngs] == (Proc.Fct-2)), bFlagInvert, dExtra) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, + dLenLst, ( #vAngs > 0 and vAngs[1] == 0), ( #vAngs > 0 and vAngs[#vAngs] == (Proc.Fct-2)), bFlagInvert, dExtra) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + 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 dToolMaxDepth = 0 + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, + dLenLst, ( #vAngs > 0 and vAngs[1] == 0), ( #vAngs > 0 and vAngs[#vAngs] == (Proc.Fct-2)), bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, + dLenLst, ( #vAngs > 0 and vAngs[1] == 0), ( #vAngs > 0 and vAngs[#vAngs] == (Proc.Fct-2)), bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and #vAngs > 0 then + -- dimensioni feature + local dLen = Proc.Box:getDimX() + local dDep = EgtIf( nSide == 1, Proc.Box:getDimZ(), Proc.Box:getDimY()) + -- se più alta che lunga o da sotto con il parametro Q abilitato + if ( dDep > dLen) or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1) then + for i = 1, #vAngs do + sName = 'ProfV'.. tostring( i)..'_'..( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dElev = EgtSurfTmFacetOppositeSide( Proc.Id, vAngs[i], EgtIf( bHead, X_AX(), -X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vAngs[i]}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dElev, 1)) + -- imposto posizione braccio + local nSCC = MCH_SCC.ADIR_YM + if nSide == 0 then + nSCC = EgtIf( vtN:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + -- altrimenti + elseif nSide ~= -1 then + for i = 1, #vAngs do + sName = 'ProfV'.. tostring( i)..'_'..( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dElev = EgtSurfTmFacetOppositeSide( Proc.Id, vAngs[i]+1, vtN, GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vAngs[i]+1}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dElev, 1)) + -- imposto posizione braccio + local nSCC = MCH_SCC.ADIR_YM + if nSide == 0 then + nSCC = EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfHead diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessRidgeLap.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessRidgeLap.lua new file mode 100644 index 0000000..eb0b408 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessRidgeLap.lua @@ -0,0 +1,205 @@ +-- ProcessRidgeLap.lua by Egaltech s.r.l. 2020/04/23 +-- Gestione calcolo mezzolegno di testa per Travi + +-- Tabella per definizione modulo +local ProcessRidgeLap = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessRidgeLap started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessRidgeLap.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 30) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessRidgeLap.Classify( Proc, b3Raw) + -- Se più corta del limite si può fare anche da sotto + if Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then + return true, false + end + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.707 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + return true + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getX()) < 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i-1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[3]]) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo riferimenti per facce inclinate + local vtRef = Vector3d( vtN[vFaceOrd[3]]) + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local nOrthoOpposite + if i % 2 == 1 then + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + else + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[3]]) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( EgtIf( bHead, X_AX(), -X_AX())) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtN[vFaceOrd[3]]:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtN[vFaceOrd[3]]:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessRidgeLap diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessRoundArch.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessRoundArch.lua new file mode 100644 index 0000000..420a423 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessRoundArch.lua @@ -0,0 +1,243 @@ +-- ProcessRoundArch.lua by Egaltech s.r.l. 2020/09/03 +-- Gestione calcolo archi per Travi + +-- Tabella per definizione modulo +local ProcessRoundArch = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessRoundArch started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessRoundArch.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 104) +end +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessRoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessRoundArch.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di coda + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessRoundArch.Classify( Proc) + -- se di testa o coda, è indifferente alla posizione + if Proc.Head or Proc.Tail then + return true, false + end + -- è intermedia, devo verificare la normale del centro + local nMidFacet = Proc.Fct // 2 + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se la feature è lavorabile solo da sotto + --local bDown = ( vtN:getZ() < - 0.1) + local bDown = false + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessRoundArch.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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) + local bDown = ( b3Aux:getMin():getZ() < b3Raw:getMin():getZ() + 5) + -- 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 + -- ne verifico la lunghezza per eventuale spezzatura e lavorazione in doppio + local nStep = 1 + local dStep = 0 + local dLenMax = BD.LONGCUT_ENDLEN + if b3Aux:getDimX() > dLenMax then + local dCrvLen = EgtCurveLength( AuxId) + nStep = ceil( dCrvLen / dLenMax) + dStep = dCrvLen / nStep + EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) + end + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local bCross = false + if abs( vtExtr:getY()) > 0.707 then + if b3Aux:getDimY() > b3Raw:getDimY() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimY()) + end + elseif abs( vtExtr:getZ()) > 0.707 then + if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimZ()) + end + end + local nDouble = 1 + local bCanDouble = abs( vtExtr:getY()) > 0.707 and bCross + local bStripOnSide = false + if bCross then + if nStep > 1 or ( bDown and b3Aux:getDimX() > 0.5 * b3Raw:getDimX()) then + -- devo lasciare un codolo + dDepth = dDepth - BD.DIM_STRIP + bStripOnSide = true + else + -- devo affondare un poco oltre + dDepth = dDepth + BD.CUT_EXTRA + end + end + -- se parametro beamdata forza codolo in centro e lavorazione orizzontale e se larghezza trave è sufficientemente larga + if BD.DIM_TO_CENTER_STRIP and BD.DIM_TO_CENTER_STRIP > 10 * GEO.EPS_SMALL and nStep > 1 and + bCanDouble and b3Raw:getDimY() > BD.DIM_TO_CENTER_STRIP - 0.1 then + nDouble = 2 + dDepth = min( ( b3Raw:getDimY() - BD.DIM_STRIP) * 0.5, dMaxDepth) + else + -- se altezza geometria supera capacità taglio utensile ed è orizzontale setto per eseguire codolo in centro + if dDepth > dMaxDepth then + if bCanDouble then + nDouble = 2 + dDepth = min( 0.5 * dDepth, dMaxDepth) + else + dDepth = dMaxDepth + end + end + end + -- se utensile orizzontale verso Y+, non in doppio e codolo da lasciare, devo invertire per lavorare sempre da Y- + if vtExtr:getY() > 0.707 and nDouble == 1 and bStripOnSide then + bToolInv = true + end + -- eseguo + for i = 1, nStep do + for j = 1, nDouble do + -- 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}}) + -- eventuale accorciamento di testa + if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then + local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + end + -- eventuale accorciamento di coda + if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then + local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- se estrusione da sotto, inverto direzione fresa + if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- se seconda passata, inverto direzione di lavoro + if j == 2 then + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + if bToolInv then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + -- posizione braccio porta testa + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessRoundArch diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessSawCut.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessSawCut.lua new file mode 100644 index 0000000..dfa0b8a --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessSawCut.lua @@ -0,0 +1,232 @@ +-- ProcessSawCut.lua by Egaltech s.r.l. 2021/01/15 +-- Gestione calcolo taglio di lama per Travi + +-- Tabella per definizione modulo +local ProcessSawCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local LongCut = require( 'ProcessLongCut') + +EgtOutLog( ' ProcessSawCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSawCut.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 13) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessSawCut.Classify( Proc, b3Raw) + -- recupero i dati del versore direzione di accesso della lavorazione + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtDir = EgtSV( AuxId, GDB_ID.ROOT) + return true, ( vtDir:getZ() <= - 0.088) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSawCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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à vettore + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.GEO_VECTOR then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing access direction' + EgtOutLog( sErr) + return false, sErr + end + local vtDir = EgtSV( AuxId, GDB_ID.ROOT) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local frFace = Frame3d( ptC, vtDir ^ vtN, vtDir, vtN) + local b3Face = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFace) + local dLen = b3Face:getDimX() + local dWidth = b3Face:getDimY() + -- se taglio di testa + if Proc.Head then + -- se coincide con il taglio di separazione precedente, non va fatto + if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- altrimenti taglio di coda + else + -- se coincide con taglio di separazione, non va fatto + if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + end + -- recupero flag per inizio e fine interni + local bInside = (( EgtGetInfo( Proc.Id, 'Q01', 'i') or 0) ~= 0) + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 2 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- determino se lavorazione da davanti o da dietro e se da sotto + local bFront = ( vtDir ^ vtN):getX() > 0 + local bDownUp = ( vtN:getZ() < -0.259) + local bFillAreaPiece + -- se non da sotto + if not bDownUp then + -- se poco inclinata ( inclinazione inferiore a 21.56 deg) + if vtN:getZ() > 0.93 then + -- verifico se la superfice è prevelentemente orizzontale con Z positiva e occupa tutta la trave o occupa sicuramente la faccia in Y + -- e almeno 3/4 della lunghezza in X e sborda in X e non interessa la faccia inferiore, + -- si possono far partire i tagli a cubetti dalla testa o lasciare il cordoncino centrale + if ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) or + ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) and + ( Proc.Box:getDimX() > 0.75 * b3Solid:getDimX() or Proc.Box:getDimX() > 1500.000))) and + abs( Proc.Box:getMin():getY() - b3Solid:getMin():getY()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getY() - b3Solid:getMax():getY()) < 10*GEO.EPS_SMALL and + b3Solid:getMin():getZ() < Proc.Box:getMin():getZ() - 100 * GEO.EPS_SMALL then + bFillAreaPiece = true + end + -- se praticamente verticale di fianco ( inclinazione inferiore a 21.56deg) + elseif abs( vtN:getY()) > 0.93 then + -- se la faccia occupa tutta la trave in X e Z o occupa sicuramente la faccia in Z e almeno 3/4 della faccia in X e sborda in X, + if ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) or + ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) and + ( Proc.Box:getDimX() > 0.75 * b3Solid:getDimX() or Proc.Box:getDimX() > 1500.000))) and + abs( Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getZ() - b3Solid:getMax():getZ()) < 10*GEO.EPS_SMALL then + local sErr = 'Error : Impossible to machine by orientation (on side)' + EgtOutLog( sErr) + return false, sErr + end + end + end + -- se ho il parametro Q04 = 1 e il taglio copre la lunghezza della trave allora lancio il processo dell'L10 + local nAsLongCut = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 + if nAsLongCut == 1 and bFillAreaPiece then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, true) + -- se non ho taglio lungo passo al Cut per taglio a cubetti + elseif bFillAreaPiece and abs(( vtDir ^ vtN):getY()) > 0.866 then + local bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, 0, false, true) + -- se è andata a buon fine oppure ha fallito esco + -- nel caso non ha fatto i tagli a cubetti (sErr vale -1) continuo + if bOk or ( not bOk and type(sErr) ~= 'number') then + return bOk, sErr + end + end + -- determino affondamento e distanza interna da inizio e fine + local dDepth = min( dWidth, dMaxDepth - BD.COLL_SIC) + local dInsDist = 0 + if bInside then + dInsDist = sqrt( dSawDiam * dDepth - dDepth * dDepth) + if 2 * dInsDist > dLen - 2 then + dInsDist = ( dLen - 2) / 2 + dDepth = dSawDiam / 2 - sqrt( dSawDiam * dSawDiam / 4 - dInsDist * dInsDist) + end + end + -- determino numero di parti + local dStartAccDist = BD.LONGCUT_ENDLEN + local dEndAccDist = BD.LONGCUT_ENDLEN + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + dC = dLen / ( nC + 2) + dStartAccDist = min( dC, dStartAccDist) + dEndAccDist = min( dC, dEndAccDist) + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + dStartAccDist = dLen / 2 + dEndAccDist = dStartAccDist + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- determino l'utilizzo della faccia + local nFaceUse = BL.GetNearestOrthoOpposite( vtDir) + if bDownUp then + nFaceUse = BL.GetOrtupOpposite( nFaceUse) + end + -- si percorrono i lati alto e basso della faccia + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- ciclo sulle passate + local dOffset = dWidth - dDepth ; + local dLioTang = 0 + local dLioPerp = dDepth + BD.CUT_SIC ; + -- inserisco le parti di lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nC) + local nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == 1, -dInsDist, -dStartAccDist - ( i - 2) * dC) + local dEal = EgtIf( i == nC, -dInsDist, -dEndAccDist - ( nC - i - 1) * dC) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- imposto offset longitudinale + if Proc.Grp == 0 then + EgtSetMachiningParam( MCH_MP.OFFSL, EgtIf( bDownUp, dSawThick / 2, -dSawThick / 2)) + end + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bFront ~= bDownUp, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + EgtSetMachiningParam( MCH_MP.INVERT, bFront) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessSawCut diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessScarfJoint.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessScarfJoint.lua new file mode 100644 index 0000000..125e3ab --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessScarfJoint.lua @@ -0,0 +1,506 @@ +-- ProcessScarfJoint.lua by Egaltech s.r.l. 2020/12/10 +-- Gestione calcolo giunto Gerber per Travi + +-- Tabella per definizione modulo +local ProcessScarfJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessScarfJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessScarfJoint.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 71) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessScarfJoint.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q02', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function ApplyDiceCut( vFaceOrd, nGoodFace1, nGoodFace4, nAddGrpId, b3Solid, ptC, vtN, Proc, vtRef, bHead, sCutting, dSawDiam, b3Raw, dNewDiceDim) + + local vCuts = {} + local bOk = true + local sErr = '' + + if nGoodFace1 and nGoodFace4 and nGoodFace1 > 0 and nGoodFace4 > 0 then + -- lavoro solo la faccia inclinata perché la faccia tappo completa la lavoro successivamente + -- questo evita di lavorare due volte la faccia tappo + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[4]], vtN[vFaceOrd[4]], false, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], nil, dNewDiceDim) + elseif nGoodFace4 and nGoodFace4 > 0 then + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[4]], vtN[vFaceOrd[4]], true, nil, nil, nil, dNewDiceDim) + end + + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- lavoro la faccia interna in ogni caso + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- lavoro la faccia opposta (definita dal parametro P11) + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + return bOk, sErr, vCuts +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessScarfJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + + -- verifico che ci siano almeno quattro facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 3 then + local sErr = 'Error : number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + + -- ordino le facce in base al loro numero e al parallelismo delle due facce principali + -- faccia 1: superficie tappo + -- faccia 2: superficie principale di fondo + -- faccia 3: superficie opposta alla faccia 1 + -- faccia 4: superficie principale superiore + -- faccia 5: superficie di testa + local vtRef + local vFaceOrd = { 0, 0, 0, 0, 0} + if nFacetCnt == 5 then -- se ho 5 facce controllo il parallelismo della faccia 2 e 4 + if not AreSameVectorApprox( vtN[2], vtN[4]) then + local sErr = 'Error : main faces are not parallel (btl import problems)' + EgtOutLog( sErr) + return false, sErr + end + -- carico gli id delle facce + for i = 1, nFacetCnt do + vFaceOrd[i] = i + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[4]]:getY(), vtN[vFaceOrd[4]]:getZ()) + elseif nFacetCnt == 4 then -- se ho 4 facce + if AreSameVectorApprox( vtN[1], vtN[3]) then -- sono nel caso in cui manca la faccia 1 + for i = 1, nFacetCnt do + vFaceOrd[i+1] = i + end + elseif AreSameVectorApprox( vtN[2], vtN[4]) then -- sono nel caso in cui manca la faccia 5 + for i = 1, nFacetCnt do + vFaceOrd[i] = i + end + else -- altrimenti ho una condizione di facce non previsto e do errore + local sErr = 'Error : crazy faces(4)' + EgtOutLog( sErr) + return false, sErr + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[4]]:getY(), vtN[vFaceOrd[4]]:getZ()) + elseif nFacetCnt == 3 then -- se ho 3 facce + if AreSameVectorApprox( vtN[1], vtN[3]) then -- sono nel caso in cui manca la faccia 1 + for i = 1, nFacetCnt do + vFaceOrd[i+1] = i + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[4]]:getY(), vtN[vFaceOrd[4]]:getZ()) + else + for i = 1, nFacetCnt do + vFaceOrd[i] = i + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[2]]:getY(), vtN[vFaceOrd[2]]:getZ()) + end + end + + -- determino se di testa o di coda + local bHead = ( vtN[1]:getX() > 0) + + -- normalizzo vettore di riferimento per le facce ortogonali all'asse trave + vtRef:normalize() + + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + + -- creo superfici partendo da punto e versore delle facce 4 (inclinata) e 1 (tappo) + local nFace1 + local nFace4 + local nGoodFace1 + local nGoodFace4 + if vtN[vFaceOrd[4]] then + nFace4 = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vFaceOrd[4]], vtN[vFaceOrd[4]], b3Solid, GDB_ID.ROOT) + end + if vtN[vFaceOrd[1]] then + nFace1 = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], b3Solid, GDB_ID.ROOT) + end + if nFace4 and nFace1 then + -- taglio la superficie di tappo e quella inclinata per capire se per il taglio a cubetti si devono considerare una o due superfici + local bOk = EgtCutSurfTmPlane( nFace1, ptC[vFaceOrd[4]], -vtN[vFaceOrd[4]], false, GDB_ID.ROOT) + bOk = bOk and EgtCutSurfTmPlane( nFace4, ptC[vFaceOrd[1]], -vtN[vFaceOrd[1]], false, GDB_ID.ROOT) + + if not bOk then + local sErr = 'Error : wrong cut surfaces' + EgtOutLog( sErr) + return false, sErr + end + + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + nGoodFace1 = EgtSurfTmFacetCount( nFace1) + nGoodFace4 = EgtSurfTmFacetCount( nFace4) + elseif nFace4 then + nGoodFace4 = EgtSurfTmFacetCount( nFace4) + elseif nFace1 then + nGoodFace1 = EgtSurfTmFacetCount( nFace1) + end + + local bOkd, sErrD, vCuts = ApplyDiceCut( vFaceOrd, nGoodFace1, nGoodFace4, nAddGrpId, b3Solid, ptC, vtN, Proc, vtRef, bHead, sCutting, dSawDiam, b3Raw) + if not bOkd then return bOkd, sErrD end + + if #vCuts == 0 then + -- se ho la faccia intermedia, per prima cosa verifico se ho intersezione con la faccia tappo + if nGoodFace4 ~= 0 then + -- taglio sulla faccia interna + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + -- se non ho intersezione con la faccia tappo posso fare il taglio sul fianco + if not nGoodFace1 or nGoodFace1 == 0 then + -- lavoro la faccia opposta (definita dal parametro P11) + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + -- inserisco la lavorazione + local vtRef2 = EgtIf( abs(vtRef:getZ()) < GEO.EPS_SMALL, Z_AX(), EgtIf( bHead, Y_AX(), -Y_AX())) + bOkd, sErrD = BL.MakeOneFaceBySaw( nFace4, nGoodFace4 - 1, sCutting, dSawDiam, vtRef2, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + else -- altrimenti se ho intersezione forzo il DiceCut ad essere eseguito con distanze più piccole + -- definisco la nuova dimensione massima del dice cut + local dNewDiceDim = EgtIf( abs(vtRef:getZ()) < GEO.EPS_SMALL, b3Raw:getDimZ(), b3Raw:getDimY()) + bOkd, sErrD = ApplyDiceCut( vFaceOrd, nGoodFace1, nGoodFace4, nAddGrpId, b3Solid, ptC, vtN, Proc, vtRef, bHead, sCutting, dSawDiam, b3Raw, dNewDiceDim) + if not bOkd then return bOkd, sErrD end + end + else + -- taglio sulla faccia interna + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + -- lavoro la faccia opposta (definita dal parametro P11) + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + end + end + + -- taglio sulla faccia esterna + if vFaceOrd[5] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[5]], X_AX()) and abs( ptC[vFaceOrd[5]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[5]], - X_AX()) and abs( ptC[vFaceOrd[5]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[5] - 1) + if DimV > DimH then + vtOrthoO = Vector3d( frHV:getVersX()) + else + vtOrthoO = Vector3d( vtRef) + end + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[5] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + + -- lavoro superficie principale di fondo con una svuotatura + if vFaceOrd[2] ~= 0 then + + local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vFaceOrd[2]-1, GDB_ID.ROOT) + -- calcolo la dimensione da passare + local dDiamMax + -- se normale verso Y (in orizzontale) + if abs(vtRef:getY()) > 0.866 then + dDiamMax = EgtIf( abs( frMor:getVersX():getZ()) < abs( frMor:getVersY():getY()), dL, dW) + else + dDiamMax = EgtIf( abs( frMor:getVersX():getY()) < abs( frMor:getVersY():getY()), dL, dW) + end + -- determino la distanza tra le due facce inclinate + local dDistFaces + if vFaceOrd[4] ~= 0 then + dDistFaces = abs((ptC[vFaceOrd[2]]-ptC[vFaceOrd[4]])*vtN[vFaceOrd[2]]) + end + -- recupero la lavorazione. considerando l dimensione del lato e l'affondamento + local sPocketing + if dDistFaces then + sPocketing = ML.FindPocketing( 'OpenPocket', dDiamMax, dDistFaces) + else + sPocketing = ML.FindPocketing( 'OpenPocket', dDiamMax) + end + + 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( {{ Proc.Id, vFaceOrd[2]-1}}) + -- imposto elevazione + if dDistFaces then + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dDistFaces, 1) .. ';') + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + dHCI = 0.75 * dHCI + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + dTCI = 0.75 * dTCI + BL.UpdateTCING( nRawId, dTCI) + end + + return true, sErrC +end + +--------------------------------------------------------------------- +return ProcessScarfJoint diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessSimpleScarf.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessSimpleScarf.lua new file mode 100644 index 0000000..fe8a3c3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessSimpleScarf.lua @@ -0,0 +1,324 @@ +-- ProcessSimpleScarf.lua by Egaltech s.r.l. 2020/06/04 +-- Gestione calcolo giunto Gerber per Travi + +-- Tabella per definizione modulo +local ProcessSimpleScarf = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessSimpleScarf started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSimpleScarf.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 70) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessSimpleScarf.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSimpleScarf.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Error : number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getY()) > 0.1 or abs( vtN[i]:getZ()) > 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error : missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + bHead = ( vtN[vFaceOrd[1]]:getX() > 0) + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO = Vector3d( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, 0, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true, sErrC +end + +--------------------------------------------------------------------- +return ProcessSimpleScarf diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessSplit.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessSplit.lua new file mode 100644 index 0000000..e885836 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessSplit.lua @@ -0,0 +1,233 @@ +-- ProcessSplit.lua by Egaltech s.r.l. 2021/01/02 +-- Gestione calcolo tagli di separazione per Travi + +-- Tabella per definizione modulo +local ProcessSplit = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessSplit started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSplit.Identify( Proc) + return ( Proc.Grp == 2 and Proc.Prc == 350) +end + +--------------------------------------------------------------------- +-- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) +local function VerifyCurveForChamfer( AuxId) + if not AuxId then + return -2 + end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + return -1 + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- va bene solo se direzione estrusione orizzontale + if abs( vtExtr:getZ()) > 0.1 then + return 0 + end + return 1 +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( nOriId, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico le entità curva associate (max 2) + local sVal = EgtGetInfo( nOriId, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local AuxId, Aux2Id + if vsAuxId and #vsAuxId >=1 then + AuxId = tonumber( vsAuxId[1]) + end + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if AuxId then AuxId = AuxId + nOriId end + if Aux2Id then Aux2Id = Aux2Id + nOriId end + local nRes = VerifyCurveForChamfer( AuxId) + if nRes == 0 and Aux2Id then + AuxId = Aux2Id + nRes = VerifyCurveForChamfer( AuxId) + end + if nRes == -2 then + return true + end + if nRes == -1 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + if nRes == 0 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true, nil +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSplit.Make( Proc, nPhase, nRawId, nPartId) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- inserimento smussi + local nOriId = EgtGetInfo( Proc.Id, 'ORI', 'i') + if nOriId then + local bOkc, sErrC = MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'TailSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, true, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 50 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- caratteristiche taglio + local bHorizCut = ( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL and b3Raw:getDimZ() < dMaxDepth - BD.CUT_EXTRA) + local dDimYRef = EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, dMaxDepth - BD.CUT_EXTRA, BD.MAX_DIM_HTCUT_HBEAM) + local bDoubleCut = ( not bHorizCut and b3Raw:getDimY() > dDimYRef + 10 * GEO.EPS_SMALL) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- flag di lavorazione faccia + local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_BACK) + -- separazione solo se esiste grezzo successivo con pezzi o scaricabile + local nNextRawId = EgtGetNextRawPart( nRawId) + local bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() >= BD.MinRaw)) + -- determino se più tagli con offset + local nCuts = 1 + local dOffsL = 0 + if not bSplit then + -- cerco grezzo successivo che sia nella fase + if nNextRawId and EgtVerifyRawPartPhase( nNextRawId, nPhase) then + local b3NextRaw = EgtGetRawPartBBox( nNextRawId) + local dLenEndRaw = ptC:getX() - b3NextRaw:getMin():getX() + nCuts = ceil( dLenEndRaw / BD.MAX_LEN_SCRAP) + dOffsL = dLenEndRaw / nCuts + -- aggiorno ingombro del grezzo corrente con quello del successivo + b3Raw:Add( b3NextRaw) + end + end + -- calcolo extra taglio ed accorciamento + local dCutExtra = 0 + local dAccStart = 0 + if b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL or b3Raw:getDimY() < 2 * BD.MAX_DIM_HTCUT_HBEAM + 10 * GEO.EPS_SMALL then + dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN, BD.CUT_EXTRA) + dAccStart = 0 + else + dCutExtra = - ( b3Raw:getDimY() - dMaxDepth - BD.CUT_EXTRA) + local dSawRad = dSawDiam / 2 + local dKL = dSawRad - dMaxDepth + b3Raw:getDimY() / 2 + BD.CUT_EXTRA_MIN + dAccStart = sqrt( dSawRad * dSawRad - dKL * dKL) + end + -- se necessari tagli in doppio, eseguo gli opposti + if bDoubleCut then + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes = EgtIf( bSplit, 'Presplit;', 'Precut;') + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_FRONT, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, sNotes, b3Raw) + if not bOk then return false, true, sErr end + end + end + -- eseguo i tagli necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes + if bSplit then + sNotes = EgtIf( i == 1, 'Split;', 'Presplit;') + else + sNotes = EgtIf( i == 1, 'Cut;', 'Precut;') + end + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, sNotes, b3Raw) + if not bOk then return false, true, sErr end + end + -- ritorno anche flag di passaggio a fase successiva + return true, true +end + +--------------------------------------------------------------------- +return ProcessSplit diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessStepJoint.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessStepJoint.lua new file mode 100644 index 0000000..5eecbd3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessStepJoint.lua @@ -0,0 +1,481 @@ +-- ProcessStepJoint.lua by Egaltech s.r.l. 2021/01/23 +-- Gestione calcolo giunto a gradino per Travi + +-- Tabella per definizione modulo +local ProcessStepJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessStepJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessStepJoint.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 80) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessStepJoint.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- gestisco solo 2 o 3 facce + if nFacetCnt ~= 2 and nFacetCnt ~= 3 then + return false, false + end + -- se due facce, verifico se convesso + local bConvex = false + if nFacetCnt == 2 then + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + bConvex = not bAdj or ( dAng > 0) + end + -- verifico le normali delle facce + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if not bConvex and vtN:getZ() < - 0.72 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione al caso due facce +local function MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- delta negativo affondamento lama per facce concave + local dExtraUp = -0.3 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso (due facce separate sono sicuramente convesse) + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se convesso, lo tratto come due tagli singoli + if bConvex then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- lavoro per prima la faccia più diretta in alto + local vOrd = { 1, 2} + if vtN[2]:getZ() > vtN[1]:getZ() then + vOrd = { 2, 1} + end + -- creo piano di taglio coincidente con la prima faccia e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[1]], vtN[vOrd[1]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + end + -- creo piano di taglio coincidente con la seconda faccia e lo lavoro + AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[2]], vtN[vOrd[2]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + end + -- altrimenti concavo + else + -- calcolo direzione di lavoro + local vtRef = {} + local vtTg = ptP2 - ptP1 ; + vtRef[1] = vtN[1] ^ vtTg + if vtRef[1] * vtN[2] < 0 then vtRef[1] = - vtRef[1] end + vtRef[2] = vtN[2] ^ vtTg + if vtRef[2] * vtN[1] < 0 then vtRef[2] = - vtRef[2] end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- calcolo extra taglio + local dCutExtra = dExtraUp + if dAng < -90.5 and dAng > -179.5 then + dCutExtra = - dSawThick / tan( 180 + dAng) + dExtraUp + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- assegno il modo di tagliare + local vtOrthO = EgtIf( ( i % 2) == 1, vtRef[nSmaInd], vtRef[nBigInd]) + -- lavoro la faccia + for j = 1, #vCuts[i] do + local dLocCutExtra = EgtIf( j == #vCuts[i], dCutExtra - dExtraUp, dCutExtra) + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthO, nil, dLocCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, EgtIf( bHead, 'HeadSide', 'TailSide')) + if not bOk then + return bOk, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione al caso tre facce +local function MakeThreeFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- delta negativo affondamento lama per facce concave + local dExtraUp = -0.3 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- riduco a forma canonica ( concavo tra 0 e 1, faccia 2 oltre convesso) + local bAdj12, _, _, dAng12 = EgtSurfTmFacetsContact( Proc.Id, 1, 2, GDB_ID.ROOT) + local bAdj20, _, _, dAng20 = EgtSurfTmFacetsContact( Proc.Id, 2, 0, GDB_ID.ROOT) + if bAdj12 then + if dAng12 < 0 then + EgtSurfTmSwapFacets( Proc.Id, 0, 2) + end + elseif bAdj20 then + if dAng20 < 0 then + EgtSurfTmSwapFacets( Proc.Id, 1, 2) + end + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + ptC[3], vtN[3] = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- calcolo direzione di lavoro + local vtRef = {} + local vtTg = ptP2 - ptP1 ; + vtRef[1] = vtN[1] ^ vtTg + if vtRef[1] * vtN[2] < 0 then vtRef[1] = - vtRef[1] end + vtRef[2] = vtN[2] ^ vtTg + if vtRef[2] * vtN[1] < 0 then vtRef[2] = - vtRef[2] end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- Taglio la faccia 2 + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio coincidente con la faccia 2 e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[3], vtN[3], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + end + -- Taglio le facce 0 e 1 concave + -- calcolo extra taglio + local dCutExtra = dExtraUp + if dAng < -90.5 and dAng > -179.5 then + dCutExtra = - dSawThick / tan( 180 + dAng) + dExtraUp + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- assegno il modo di tagliare + local vtOrthO = EgtIf( ( i % 2) == 1, vtRef[nSmaInd], vtRef[nBigInd]) + -- lavoro la faccia + for j = 1, #vCuts[i] do + local dLocCutExtra = EgtIf( j == #vCuts[i], dCutExtra - dExtraUp, dCutExtra) + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthO, nil, dLocCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, EgtIf( bHead, 'HeadSide', 'TailSide')) + if not bOk then + return bOk, sErr + end + end + -- Eventuale segnalazione ingombro di testa o coda + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessStepJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- se due facce + if Proc.Fct == 2 then + local bOk, sErr = MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + return bOk, sErr or sErrC + -- se altrimenti tre facce + elseif Proc.Fct == 3 then + local bOk, sErr = MakeThreeFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + return bOk, sErr or sErrC + -- altrimenti errore + else + local sErr = 'Error : face number not allowed' + EgtOutLog( sErr) + return false, sErr + end +end + +--------------------------------------------------------------------- +return ProcessStepJoint diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessStepJointNotch.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessStepJointNotch.lua new file mode 100644 index 0000000..70725fb --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessStepJointNotch.lua @@ -0,0 +1,604 @@ +-- ProcessStepJointNotch.lua by Egaltech s.r.l. 2020/12/01 +-- Gestione calcolo tacca a gradino per Travi + +-- Tabella per definizione modulo +local ProcessStepJointNotch = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessStepJointNotch started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessStepJointNotch.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 80) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessStepJointNotch.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- gestisco solo 2 o 4 facce + if nFacetCnt ~= 2 and nFacetCnt ~= 4 and nFacetCnt ~= 6 and nFacetCnt ~= 8 then + return false, false + end + -- verifico le normali delle facce + local bDown = false + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se faccia limite la salto + if AreSameOrOppositeVectorApprox( vtN, Y_AX()) or AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + -- attualmente non gestita +-- return false, false + -- altrimenti faccia principale + elseif vtN:getZ() < -0.1 then + bDown = true + end + end + return true, bDown +end + +--------------------------------------------------------------------- +local function MachineByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Solid, ptC, vtN, nBigInd, nSmaInd, bOnY, ptPs, b3Raw, dAng) + + -- delta negativo affondamento lama + local dExtraUp = -0.3 + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + local dSawThick = 5 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- calcolo extra taglio + local dCutExtra = dExtraUp + if dAng < -90.5 and dAng > -179.5 then + dCutExtra = - dSawThick / tan( 180 + dAng) + dExtraUp + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local k, l = nBigInd, nSmaInd + if ( i % 2) == 1 then + k, l = l, k + end + local nOrthoOpposite + if bOnY then + local bFront = ( ptC[k]:getY() < ptPs:getY()) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + local bOver = true + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local dLocCutExtra = EgtIf( j == #vCuts[i], dCutExtra - dExtraUp, dCutExtra) + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, nil, dLocCutExtra, BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide') + if not bOk then + return bOk, sErr + end + end + return true +end + +--------------------------------------------------------------------- +local function MakePocket( Proc, nPartId, ptPs, vtN, nFaceRef, nDiffWidth, sMchFind, nUseRoughTool, tBHx) + + -- calcolo il elevazione dal punto medio + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[nFaceRef]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + local dCollSic = 2 * BD.COLL_SIC + local sTuuidMstr + -- calcolo il diametro utensile + local dDiamTool + if nUseRoughTool == 1 then + dDiamTool = max( 80, min( tBHx[nFaceRef][1], tBHx[nFaceRef][2])) + else + -- se non uso truciolatore prendo il valore dalle dimensioni minime delle facce + dDiamTool = min( tBHx[nFaceRef][1], tBHx[nFaceRef][2]) + end + local sPocketing = ML.FindPocketing( sMchFind, dDiamTool, dElev + dCollSic) + if not sPocketing then + local sErr = 'Error : pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile + if EgtMdbSetCurrMachining( sPocketing) then + sTuuidMstr = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidMstr) or '') then + dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dDiamTool + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef - 1) + 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( {{ Proc.Id, (nFaceRef-1)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if vtN[nFaceRef]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- La tasca ha sempre almeno un lato aperto, imposto opportuno attacco + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, '', sTuuidMstr +end + +--------------------------------------------------------------------- +local function MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, ptC, vtN, nBigInd, nSmaInd, ptPs, tBHx, b3Raw, nDiffWidth, nUseRoughTool, dAng) + + local sMchFind = 'Pocket' + -- se feature é larga come trave imposto openpocket + if nDiffWidth == 0 then + sMchFind = 'OpenPocket' + -- altrimenti se non è passante disabilito il truciolatore + else + nUseRoughTool = 0 + end + -- applico la svuotatura + local bOk, sErr, sTuuidMstr = MakePocket( Proc, nPartId, ptPs, vtN, nBigInd, nDiffWidth, sMchFind, nUseRoughTool, tBHx) + if not bOk then + return bOk, sErr + end + -- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto + if dAng > -90.1 then + -- se la normale della faccia corta si discosta dalla trave di più di 40° utilizzo la svuotatura altrimenti la contornatura + if abs( vtN[nSmaInd]:getX()) < 0.766 then + -- applico la svuotatura + local bOk, sErr = MakePocket( Proc, nPartId, ptPs, vtN, nSmaInd, nDiffWidth, sMchFind, nUseRoughTool, tBHx) + if not bOk then + return bOk, sErr + end + -- altrimenti contornatura + else + local bOpenStart = false + local bOpenEnd = false + if nDiffWidth == 0 then + bOpenStart = true + bOpenEnd = true + else + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBigInd-1))[1] + for j = 1, #vAdj2 do + if vAdj2[j] == (nSmaInd-1) then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == (nSmaInd-1) do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == (nSmaInd-1) do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + end + end + local sMilling + if nUseRoughTool > 0 then + sMilling = ML.FindMilling( 'Long2Cut', nil, sTuuidMstr) + else + sMilling = ML.FindMilling( 'LongSmallCut', nil, sTuuidMstr) + end + + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 50 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + end + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( tBHx[nBigInd][3]:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, (nSmaInd-1)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- setto inversione del percorso + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- setto a 0 eventuali offset + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + return true +end + +--------------------------------------------------------------------- +-- Lavorazione di due facce +local function MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local tBHx = {} + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- angolo diedro + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + local bConvex + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local rfFac1, dH1, dV1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1, GDB_ID.ROOT) + local nBigInd = EgtIf( dV1 * dH1 >= dV2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + tBHx[1] = {dH1, dV1, rfFac1} + tBHx[2] = {dH2, dV2, rfFac2} + -- verifico parametro Q per stabilire se deve essere lavorato con truciolatore + -- o se larghezza inferiore del trave, utilizzare una svuotatura + local nUseRoughTool = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 + -- se feature non è larga come trave o è selezionato l'utilizzo del truciolatore utilizzo svuotatura + if nDiffWidth > 0 or nUseRoughTool == 1 then + -- se angolo compreso è >= di 90° applico svuotatura con fresa + if not bConvex and dAng >= -90.1 then + local bOk, sErr = MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, ptC, vtN, nBigInd, nSmaInd, ptPs, tBHx, b3Raw, nDiffWidth, nUseRoughTool, dAng) + if not bOk then + return bOk, sErr + end + else + local sErr = 'Error : internal angle less than square angle' + EgtOutLog( sErr) + return false, sErr + end + -- altrimenti provo a lavorare con la lama + else + local bOk, sErr = MachineByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Solid, ptC, vtN, nBigInd, nSmaInd, bOnY, ptPs, b3Raw, dAng) + if not bOk then + return bOk, sErr + end + end + return true +end + +--------------------------------------------------------------------- +-- Lavorazione di due facce +local function MakeFourFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + -- Prime due facce + local bOk, sErr = MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + -- Seconde due facce + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- copio la superficie e scambio le facce + local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) + if AddId then + EgtSurfTmSwapFacets( AddId, 0, 2) + EgtSurfTmSwapFacets( AddId, 1, 3) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local NewProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = MakeTwoFaces( NewProc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + end + return true +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- prendo il boundig box della feature + local bBoxExtr = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD ) + local nTypePos = 0 + -- determino se sborda da un lato + if abs( vtExtr:getZ()) < 0.1 then -- se orizzontale + -- se altezza percorso inferiore della larghezza trave + if dWidth < b3Raw:getDimY() - 1 then + nTypePos = 1 + -- verifico se sborda verso y+ + if abs( bBoxExtr:getMax():getY() - b3Raw:getMax():getY()) < 0.1 then + nTypePos = 2 + -- se sborda verso y- + elseif abs( bBoxExtr:getMin():getY() - b3Raw:getMin():getY()) < 0.1 then + nTypePos = 3 + end + end + elseif abs( vtExtr:getZ()) > 0.9 then -- se verticale + -- se altezza percorso inferiore della larghezza trave + if dWidth < b3Raw:getDimZ() - 1 then + nTypePos = 1 + -- verifico se sborda verso z+ + if abs( bBoxExtr:getMax():getZ() - b3Raw:getMax():getZ()) < 0.1 then + nTypePos = 4 + -- se sborda verso z- + elseif abs( bBoxExtr:getMin():getZ() - b3Raw:getMin():getZ()) < 0.1 then + nTypePos = 5 + end + end + else -- altrimenti se altra direzione setto per non fare smussi + nTypePos = 6 + end + + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0 + if dDepth < 0.1 then return true, '', nTypePos end + + -- disabilito smusso se feature non sborda dalla trave almeno da un lato + if nTypePos == 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn , nTypePos + end + -- salto lo smusso se sborda dal lato in Z- o una direzione diversa da Y e Z + if nTypePos >= 5 then + local sWarn = 'Warning : skipped chamfer (wrong side to apply)' + EgtOutLog( sWarn) + return true, sWarn, nTypePos + end + local bExeNormal = true + local bExeOpposite = true + -- controllo le lavorazioni quando la feature è orizzontale + if abs( vtExtr:getY()) > 0.99 then + -- se diretta verso Y+ + if vtExtr:getY() > 0 then + -- se sborda verso Y+ abilito solo la lavorazione della parte normale + if nTypePos == 2 then + bExeOpposite = false + -- se sborda verso Y- abilito solo la lavorazione della parte opposta + elseif nTypePos == 3 then + bExeNormal = false + end + -- altrimenti diretta verso Y- + else + -- se sborda verso Y+ abilito solo la lavorazione della parte opposta + if nTypePos == 2 then + bExeNormal = false + -- se sborda verso Y- abilito solo la lavorazione della parte normale + elseif nTypePos == 3 then + bExeOpposite = false + end + end + -- se diretta verso Z + elseif abs( vtExtr:getZ()) > 0.99 then + -- se diretta verso Z+ + if vtExtr:getZ() > 0 then + -- se sborda verso Z+ abilito solo la lavorazione della parte normale + if nTypePos == 4 or nTypePos == 0 then + bExeOpposite = false + else -- altrimenti disabilito entrambe + bExeNormal = false + bExeOpposite = false + end + -- altrimenti diretta verso Z- + else + -- se sborda verso Z+ abilito solo la lavorazione della parte opposta + if nTypePos == 4 or nTypePos == 0 then + bExeNormal = false + else -- altrimenti disabilito entrambe + bExeNormal = false + bExeOpposite = false + end + end + end + + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + if bExeNormal then + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + if bExeOpposite then + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + return true, '', nTypePos +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessStepJointNotch.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- esecuzione eventuale smusso + -- ottengo anche il flag che indica che la feature è larga come la trave + local bOkc, sErrC, nDiffWidth = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- come fatto nella classify, conto solo le facce che non sono dirette in Y o Z + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + local nUsableFaces = 0 + + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se faccia limite la salto + if AreSameOrOppositeVectorApprox( vtN, Y_AX()) or AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + -- altrimenti faccia principale + else + nUsableFaces = nUsableFaces + 1 + end + end + + -- se due facce + if nUsableFaces == 2 then + local bOk, sErr = MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + -- se quattro facce + elseif nUsableFaces == 4 then + local bOk, sErr = MakeFourFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + -- altrimenti errore + else + local sErr = 'Error : face number not allowed' + EgtOutLog( sErr) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessStepJointNotch diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessTenon.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessTenon.lua new file mode 100644 index 0000000..1508029 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessTenon.lua @@ -0,0 +1,328 @@ +-- ProcessTenon.lua by Egaltech s.r.l. 2021/01/20 +-- Gestione calcolo tenone per Travi + +-- Tabella per definizione modulo +local ProcessTenon = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTenon started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + + +--------------------------------------------------------------------- +local function VerifyOrientation( Proc, vtN, b3Raw) + -- se trave molto bassa + if b3Raw:getDimZ() <= 120 then + -- se tenone praticamente in asse, accetto fino a -45 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.7072) + -- altrimenti accetto fino a -30deg + else + return ( vtN:getZ() >= -0.51) + end + -- se trave bassa + elseif b3Raw:getDimZ() <= 200 then + -- se tenone praticamente in asse, accetto fino a -30 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.51) + -- altrimenti accetto fino a -20deg + else + return ( vtN:getZ() >= -0.343) + end + -- se trave media + elseif b3Raw:getDimZ() <= 300 then + -- se tenone praticamente in asse, accetto fino a -20 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.343) + -- altrimenti, accetto fino a -10 deg + else + return ( vtN:getZ() >= -0.174) + end + -- altrimenti + else + -- accetto fino a -5deg + return ( vtN:getZ() >= -0.088) + end +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessTenon.Identify( Proc) + return ( (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 50) or + (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 52)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessTenon.Classify( Proc, b3Raw) + -- recupero i dati della curva di contorno della faccia top + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se il tenone è lavorabile solo da sotto + local bDown = not VerifyOrientation( Proc, vtExtr, b3Raw) + return true, bDown +end + +--------------------------------------------------------------------- +local function ApplyPocket( Proc, sPocketing, nStep, dSurfStep, nIdSurf, vtExtr) + + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. nStep + local nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nIdSurf, -1}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + if dSurfStep > 0 then + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dSurfStep, 2) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessTenon.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') 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 + local bShortPart = ( b3Solid:getDimX() < BD.LEN_SHORT_PART) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + 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 di contorno della faccia top + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + local bClosed = EgtCurveIsClosed( AuxId) + -- verifico che il tenone non sia orientato troppo verso il basso + if not VerifyOrientation( Proc, vtExtr, b3Raw) then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Tenon from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza del tenone + local frTen = Frame3d( ptBC, vtExtr) + local b3Ten = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frTen) + local dTenH = b3Ten:getDimZ() + -- assegno centro e normale della faccia top + local vtN = vtExtr + local ptC = ptBC + vtN * dTenH + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- determino larghezza massima di svuotatura + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frTen) + local dPockX = max( b3Ten:getMax():getX() - b3Aux:getMax():getX(), b3Aux:getMin():getX() - b3Ten:getMin():getX()) + local dPockY = max( b3Ten:getMax():getY() - b3Aux:getMax():getY(), b3Aux:getMin():getY() - b3Ten:getMin():getY()) + local dPockL = sqrt( dPockX * dPockX + dPockY * dPockY) + -- abilitazione lavorazione da sotto + local bMillDown = ( BD.DOWN_HEAD and vtExtr:getZ() < 0.1) + -- porto inizio curva il più possibile sul bordo + BL.PutStartNearestToEdge( AuxId, b3Solid, bMillDown and not bShortPart) + -- se vero tenone inclinato o non esattamente alle estremità, necessario taglio di lama sulla testa + if Proc.Prc ~= 52 and + ( not AreSameOrOppositeVectorApprox( vtN, X_AX()) or + ( Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dOvmHead - 100 * GEO.EPS_SMALL and + Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 100 * GEO.EPS_SMALL)) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla testa del tenone e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC, vtN, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- se pezzo piccolo, in coda, con piano inclinato verso il basso e macchina con testa da sotto applico svuotatura + if bShortPart and vtExtr:getX() < 0 and vtExtr:getZ() < -0.09 and BD.DOWN_HEAD then + local sPockType = EgtIf( bMillDown, 'OpenPocket_H2', 'OpenPocket') + local sPocketing = ML.FindPocketing( sPockType) + local dMaxDepth = 100 + local dStep = 30 + local nSurfStep + -- acquisisco i dati necessari dall'utensile + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dStep + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- acquisisco elevazione + local dElev = BL.GetFaceElevation( AddId, 0, nPartId) + nSurfStep = ceil( dElev / dMaxDepth) + dSurfStep = dElev / nSurfStep + local bOk = true + local sErr + -- copio superfice al passo superfice e ci applico la lavorazione + for i = nSurfStep, 2, -1 do + local nAddIdTmp = EgtSurfTmPlaneInBBox( nAddGrpId, ptC+((dSurfStep*(i-1))*vtN), vtN, b3Solid, GDB_RT.GLOB) + if nAddIdTmp then + EgtSetName( nAddIdTmp, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( nAddIdTmp, 'TASKID', Proc.TaskId) + -- aggiungo lavorazione + bOk, sErr = ApplyPocket( Proc, sPocketing, i, (dSurfStep + 0), nAddIdTmp, vtExtr) + if not bOk then + break + end + end + end + if not bOk then + return false, sErr + end + -- faccio ultima superfice + bOk, sErr = ApplyPocket( Proc, sPocketing, 1, EgtIf( nSurfStep > 1, ( dSurfStep + 0), 0), AddId, vtExtr) + if not bOk then + return false, sErr + end + -- altrimenti applico taglio di lama + else + local b3Cut = EgtGetBBoxGlob( AddId or GDB_ID.NULL, GDB_BB.STANDARD) + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Cut, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bFromBottom = ( bShortPart and vtExtr:getZ() > 0.25) + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom) + if not bOk then return bOk, sErr end + end + end + end + -- recupero la lavorazione + local sMillType = EgtIf( bMillDown, 'Tenon_H2', 'Tenon') + local sMilling = ML.FindMilling( sMillType, dTenH) or ML.FindMilling( sMillType) + 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 dMillDiam = 20 + local dMaxDepth = 0 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + local dDepth = 0 + if dTenH > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in tenon : elevation (' .. EgtNumToString( dTenH, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth - dTenH + dTenH = dMaxDepth + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + -- determino il numero di passate concentriche (max 6) + local MAX_PASS = 6 + local nPass = min( ceil( dPockL / ( 0.7 * dMillDiam)), MAX_PASS) + local dStep = min( dPockL, 0.7 * dMillDiam * MAX_PASS) / nPass + for i = nPass, 1, -1 do + -- inserisco la passata finale della lavorazione + local sNameF = 'TenF_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo i parametri + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dTenH - 100 * GEO.EPS_SMALL, 1) .. ';') + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + local dOffset = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- se contorno aperto, cambio parametri di attacco/uscita + if not bClosed then + EgtSetMachiningParam( MCH_MP.LITANG, 0.7 * dMillDiam) + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, 0.7 * dMillDiam) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = MCH_SCC.ADIR_YM + if abs( vtExtr:getY()) > 0.088 then + nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if abs( vtN:getY()) > 0.1 or ( b3Raw:getDimZ() - Proc.Box:getDimZ()) < BD.MIN_HEIGHT then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = 0.5 * dOffs + end + if bShortPart and b3Raw:getDimZ() < BD.VICE_MINH and abs( vtN:getZ()) > 0.575 then + local b3Base = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) + dOffs = dOffs - 0.825 * b3Base:getDimX() + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = 0.5 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessTenon diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessText.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessText.lua new file mode 100644 index 0000000..eac4f34 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessText.lua @@ -0,0 +1,86 @@ +-- ProcessText.lua by Egaltech s.r.l. 2018/04/17 +-- Gestione calcolo testi per Travi + +-- Tabella per definizione modulo +local ProcessText = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessText started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessText.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 61) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessText.Classify( Proc) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + return false + end + -- verifico se il testo è lavorabile solo da sotto + local bDown = (( vtN:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessText.Make( Proc, nPhase, nRawId, nPartId) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Text with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che il testo non sia orientato verso il basso (-5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Text from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Text') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Text_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -1}}) + -- imposto posizione braccio porta testa + if vtN:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessText diff --git a/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessTyroleanDovetail.lua b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessTyroleanDovetail.lua new file mode 100644 index 0000000..1ecdf26 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/LuaLibs/ProcessTyroleanDovetail.lua @@ -0,0 +1,711 @@ +-- ProcessTyroleanDovetail.lua by Egaltech s.r.l. 2020/10/14 +-- Gestione calcolo giunzione tirolese + +-- Tabella per definizione modulo +local ProcessTyroleanDovetail = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTyroleanDovetail started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sDepthChamferMill = '' -- d + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessTyroleanDovetail.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 136) +end + +--------------------------------------------------------------------- +local function AssignQValues( Proc) + + -- reset delle variabili assegnazione parametri Q + sDepthChamferMill = '' + + if Proc.Prc == 136 then + sDepthChamferMill = 'Q01' -- d + end +end + +--------------------------------------------------------------------- +local function TestElleShape3( Proc) + -- valida solo nel caso di tre facce + if Proc.Fct ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessTyroleanDovetail.Classify( Proc, b3Raw) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + local nFlatFaceNeg + local bDown = false + -- individuo se c'è faccia rastremata verso Z- + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < -1 + GEO.EPS_SMALL then + nFlatFaceNeg = i-1 + break + end + end + -- se trovata faccia rastremata rivolta verso Z- + -- verifico se lunghezza faccia piatta è compatibile con il taglio di lama + if nFlatFaceNeg then + -- se ho 3 facce sicuramente è gruppo 3 o 4, setto il ribaltamento senza ulteriori controlli + if nFacetCnt == 3 then + bDown = true + -- altrimenti faccio controllo di lavorabilità da sotto e setto eventuale ribaltamento + -- ( può essere gruppi 1 o 2, oppure gruppo 3 o 4 ma spostati verso le teste) + else + -- prendo le dimensioni della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFlatFaceNeg, GDB_ID.ROOT) + local nOtherFace = EgtIf( nFlatFaceNeg == 0, nFlatFaceNeg + 1, nFlatFaceNeg - 1) + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT) + local dDist = dist( ptP1, ptP2) + local dLargeface + local dDelta = 100000 + local dDeltadH = abs( dDist - dH) + local dDeltadV = abs( dDist - dV) + -- prendo la dimensione diversa dalla lunghezza di adiacenza + if dDeltadH < dDeltadV then + dLargeface = dV + else + dLargeface = dH + end + -- se lunghezza faccia maggiore di taglio lama da sotto setto il ribaltamento + if dLargeface > BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then + bDown = true + end + -- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama setto il ribaltamento + if dAng < 0 and dAng > -90 + 5 * GEO.EPS_SMALL then + bDown = true + end + end + -- altrimenti controllo la componente in Z delle facce + else + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- altrimenti se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + -- considerazioni: al momento non è possibile sapere se ci sono due rastremature o una quindi se è rivolta verso il basso + -- viene dato errore, altrimenti si potrebbe imporre la rotazione di 180 (ovviamente con una sola rastrematura rivolta verso il basso) + if abs(vtN:getZ()) > abs(vtN:getX()) and abs(vtN:getZ()) > abs(vtN:getY()) and vtN:getZ() < -0.5 then + return false + end + end + end + return true, bDown +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc, sDephtCham) + local nChamfer = 0 + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + + return nChamfer, dDepth +end + +--------------------------------------------------------------------- +local function MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- recupero la geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- ordino le facce (1=faccia ausiliaria, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + local dMinZedFace = 1 + for i = 1, nFacetCnt do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinZedFace then + dMinZedFace = dXVal + vFaceOrd[3] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + if AuxId then + local vtNx = EgtSurfTmFacetNormVersor( AuxId, 0, GDB_ID.ROOT) + bHead = ( vtNx:getX() > 0) + end + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato + local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), 'b') + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + else + dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + end + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < (#vCuts-1) or (i == #vCuts) then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head and AuxId then + local dHCI = 00 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + -- altrimenti di fianco + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail and AuxId then + local dTCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + -- altrimenti di fianco + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +local function MakeMillCut( Proc, i, j, k, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep) + local sWarn = '' + -- inserisco la lavorazione di fresatura + -- per evitare nomi lavorazioni coincidenti, concateno anche il Proc.Id se il nome (del Proc.Id) è presente + local s2ndName = EgtGetName( Proc.Id) or '' + local sName = 'MillTCone_' .. ( EgtIf( #s2ndName > 0, s2ndName, tostring( Proc.Id))) .. ( EgtIf( #s2ndName > 0, '_' .. tostring( Proc.Id), '')) .. '_' .. tostring(i) .. '_' .. tostring(j) + local kStep = k or 0 + if kStep > 0 then + sName = sName .. '_' .. tostring(k) + end + 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( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( TabNAD[j][1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + if kStep % 2 == 1 then + -- imposto lato destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, 2) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + -- imposto lato sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + -- tolgo inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + -- imposto affondamento in base al passo del ciclo + EgtSetMachiningParam( MCH_MP.DEPTH, dOffs) + --imposto passo 0 + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto offset radiale in base all'angolo tra le due facce e alla posizione in Z + il passo laterale + dOffrRad = dOffrRad + dAddOffsRad + -- per le passate intermedie aggiungo un delta sull'offset radiale perchè c'è già il taglio di lama precedente + EgtSetMachiningParam( MCH_MP.OFFSR, dOffrRad + EgtIf( ( i < nStep) and ( kStep < 1), 0.5, 0)) + -- imposto offset longotudinale a 0 + EgtSetMachiningParam( MCH_MP.OFFSL, 0) + -- imposto gli attacchi + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( dToolDiam * 0.75)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( dToolDiam * 0.75)) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill solo in ultima passata in Z locale + local sUserNotes + if i < nStep then + sUserNotes = 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + else + sUserNotes = 'VMRS=0;' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + _, sWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + + local sWarn = '' + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- recupero l'angolo di spoglia dell'utensile a tronco di cono + -- recupero la lavorazione + local sMchFind = 'ProfTCone' + local sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on TyroleanDovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 100 + local dMaxMat = 50 + local dSideAngle = 0 + local dStepmach = 0 + local bUCutMax + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + -- ottengo il passo della lavorazione + dStepmach = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) + end + end + if dStepmach <= 0.1 then + dStepmach = dMaxMat * 0.5 + end + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, sin(dSideAngle)) + if not nFacInd or nFacInd < 0 then + -- provo eliminando i sottosquadra + nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, -2) + if not nFacInd or nFacInd < 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MakeMachByMill could not find reference face' + EgtOutLog( sErr) + return false, sErr + else + bUCutMax = true + end + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham = EvaluateQParam( Proc, sDepthChamferMill) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se U + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) + -- verifico se due facce o L con una o due facce di terminazione + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc)) + -- faccio tagli di lama come antischeggia sulle altre 2 facce + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN:getY(), vtN:getZ()) + vtRef:normalize() + local TabNAD = {} + -- ciclo inserimento tagli antischeggia sulle facce + for i = 1, nFacetCnt do + if (i-1) ~= nFacInd then + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, (i-1), GDB_ID.ROOT) + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) + if dAng then + TabNAD[i] = { vtN2, dAng, dist( ptP1, ptP2)} + end + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + else + dTrim = ((dToolThick* vtN) * vtN2 * vtN2):len() + end + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, (i-1), sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + 1), BD.CUT_SIC, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- creo percorsi di lavorazione +-- local nCountSkipStep = 0 +-- local nMaxSkippedStep = 0 + local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dStepmach) + local dStep = dFacElev / nStep + local dLargeVal + local nLenSideMax + for i = 1, nStep do + local dOffs = ( i * dStep) - dFacElev + if i == nStep then dOffs = 0 end + local dOffsSide = 0 + local dDelta = 100000 + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + local dParzElev = dOffs + -- calcolo la larghezza (solo 1 volta) + if i == 1 then + -- se ho un sottosquadra maggiore dell'angolo di spoglia utensile + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dParzElev = dFacElev + end + local dDeltadH = abs( TabNAD[j][3] - dH) + local dDeltadV = abs( TabNAD[j][3] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta + 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + nLenSideMax = j + end + else + if dDeltadV < dDelta + 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + nLenSideMax = j + end + end + end + -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) + dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) + end + end + -- se la larghezza è più grande dell'utensile allora posso lavorare il passo + if ( dLargeVal - dOffsSide) >= dToolDiam then + -- resetto il contatore skip +-- nCountSkipStep = 0 + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + -- calcolo l'offset radiale in base all'affondamento + local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dOffrRad = -( tan( 90 + TabNAD[j][2]) * dFacElev) + end + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, 0, nStep, dToolDiam, dStep) + if not bOk then + return false, sErr + else + sWarn = sErr + end + -- se lato lavorato è il più lungo e la larghezza cava consente passi interni + if j == nLenSideMax and ( dLargeVal - dOffsSide) > 2*dToolDiam then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) + local dStepSide = ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) / nStepSide + for k = 1, nStepSide do + local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep) + if not bOk then + return false, sErr + else + sWarn = sErr + end + end + end + end + end + -- altrimenti passo saltato esco con errore + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' + EgtOutLog( sErr) + return false, sErr + end + end + + -- se ho saltato più di un passo invalido le lavorazioni +-- if nMaxSkippedStep >= 2 or ( nStep >= nMaxSkippedStep and nMaxSkippedStep >= 1) then +-- local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' +-- EgtOutLog( sErr) +-- return false, sErr +-- end + + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessTyroleanDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- se ho due facce allora è di testa + if nFacetCnt == 2 then + local bOk, sErr = MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + if not bOk then return bOk, sErr end + else + local bOk, sErr = MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + if not bOk then return bOk, sErr end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dTCI) + end + + return true +end + +--------------------------------------------------------------------- +return ProcessTyroleanDovetail diff --git a/ProgramData/EgtCAM5/Beam.old/Process.lua b/ProgramData/EgtCAM5/Beam.old/Process.lua new file mode 100644 index 0000000..e5eacca --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/Process.lua @@ -0,0 +1,257 @@ +-- Process.lua by Egaltech s.r.l. 2020/10/25 +-- Gestione calcolo disposizione e lavorazioni per Travi +-- Si opera sulla macchina corrente +-- 2020/01/08 Aggiunta seconda sezione limite (BD.MAX_WIDTH2 x BD.MAX_HEIGHT2). +-- 2020/10/25 Se assegno lunghezza barra nulla prende il minimo calcolato. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not sMachDir then + EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Travi', 'ERROR') + return +end +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + EgtOutBox( 'La macchina corrente non è configurata per lavorare travi', 'Lavora Travi', 'ERROR') + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Segnalazione avvio +EgtOutLog( '*** Beam Process Start ***', 1) + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Variabili di modulo +local vBeam = {} +local dRawW +local dRawH + +------------------------------------------------------------------------------------------------------------- +-- *** Recupero le travi selezionate *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessInputData() + + -- Recupero le travi selezionate + local nId = EgtGetFirstSelectedObj() + while nId do + local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) + if nPartId then + local bFound = false + for i = 1, #vBeam do + if vBeam[i].Id == nPartId then + bFound = true + break + end + end + if not bFound then + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + end + nId = EgtGetNextSelectedObj() + end + if #vBeam == 0 then + EgtOutBox( 'Non sono state selezionate travi', 'Lavora Travi', 'ERROR') + return false + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi selezionate : ' .. sOut, 1) + end + + -- Ne recupero e verifico le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + EgtOutBox( 'Box non definito per la trave ' .. vBeam[i].Name, 'Lavora Travi', 'ERROR') + return false + else + vBeam[i].Box = b3Solid + end + end + dRawW = vBeam[1].Box:getDimY() + dRawH = vBeam[1].Box:getDimZ() + local vBeamErr = {} + for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end + end + if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + EgtDeselectPartObjs( vBeam[vBeamErr[i]].Id) + table.remove( vBeam, vBeamErr[i]) + end + EgtOutLog( sOut, 1) + EgtOutBox( sOut, 'Lavora Travi', 'INFO') + EgtDraw() + return false + end + EgtDeselectAll() + + -- Le ordino in senso di lunghezza crescente + table.sort( vBeam, function( B1, B2) return B1.Box:getDimX() < B2.Box:getDimX() end) + do + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi ordinate : ' .. sOut, 1) + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle travi nel grezzo *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessBeams() + + -- Determinazione minimo grezzo scaricabile + BE.CalcMinUnloadableRaw( dRawW, dRawH) + + -- Lunghezza totale delle travi + local dTotLen = 0 + for i = 1, #vBeam - 1 do + dTotLen = dTotLen + vBeam[i].Box:getDimX() + end + dTotLen = dTotLen + max( vBeam[#vBeam].Box:getDimX(), BD.MinRaw) + local dAddLen = BD.OVM_HEAD + ( #vBeam - 1) * BD.OVM_MID + EgtOutLog( 'Ltot : ' .. EgtNumToString( dTotLen, 1) .. ' Lagg : '.. EgtNumToString( dAddLen, 1), 1) + + -- Richiedo lunghezza del grezzo e sovramateriale di testa + local vsVal = EgtDialogBox( 'Lavora Travi' .. ' (Ltot='.. EgtNumToString( dTotLen + dAddLen + 0.5, 0) .. ', Lmax=' .. EgtNumToString( BD.MAX_RAW, 0) .. ')', + {'Lunghezza grezzo', EgtNumToString( BD.STD_RAW, 0)}, + {'Sovramateriale di testa', EgtNumToString( BD.OVM_HEAD, 0)}, + {'Forza sezione verticale', ' CB:true,*false'}) + if not vsVal then + EgtDraw() + return + end + local dRawL = EgtEvalNumExpr( vsVal[1]) + if not dRawL then + local sOut = 'Lunghezza grezzo errata : ' .. vsVal[1] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + if dRawL < GEO.EPS_SMALL then dRawL = dTotLen + dAddLen + 0.5 end + dRawL = min( dRawL, BD.MAX_RAW) + local dOvmHead = EgtEvalNumExpr( vsVal[2]) + if not dOvmHead then + local sOut = 'Sovramateriale di testa errato : ' .. vsVal[2] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo sezione barra con travi + local bVert = ( vsVal[3] == 'true') + if bVert then + if dRawW > dRawH then dRawW, dRawH = dRawH, dRawW end + end + EgtOutLog( 'Lraw : ' .. EgtNumToString( dRawL, 1) .. ' Lovm : '.. EgtNumToString( dOvmHead, 1), 1) + + -- Verifico sezione barra non troppo grande + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) and + ( dRawW > BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' .. + 'e (' .. EgtNumToString( BD.MAX_WIDTH2, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT2, 2) .. ')' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Verifico sezione barra non troppo piccola + if dRawW < BD.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < BD.MIN_HEIGHT - 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'sotto i limiti della macchina (' .. EgtNumToString( BD.MIN_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MIN_HEIGHT, 2) .. ')' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo le travi nel grezzo + local bOk, sErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) + if not bOk then + EgtOutLog( sErr) + EgtOutBox( sErr, 'Lavora Travi', 'ERROR') + return false + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessFeatures() + + local bOk, Stats = BE.ProcessFeatures() + local nErrCnt = 0 + local nWarnCnt = 0 + local sOutput = '' + for i = 1, #Stats do + if Stats[i].Err > 0 then + nErrCnt = nErrCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + elseif Stats[i].Err < 0 then + nWarnCnt = nWarnCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + end + end + if #sOutput > 0 then EgtOutLog( sOutput) end + if nErrCnt > 0 then + EgtOutBox( sOutput, 'Lavora Travi', 'ERRORS') + return false + elseif nWarnCnt > 0 then + EgtOutBox( sOutput, 'Lavora Travi', 'WARNINGS') + return true + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Esecuzione *** +------------------------------------------------------------------------------------------------------------- +if not MyProcessInputData() then return end + +if not MyProcessBeams() then return end + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +if not MyProcessFeatures() then return end diff --git a/ProgramData/EgtCAM5/Beam.old/Rotate.lua b/ProgramData/EgtCAM5/Beam.old/Rotate.lua new file mode 100644 index 0000000..c7a6c9b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/Rotate.lua @@ -0,0 +1,32 @@ +-- Rotate.lua by Egaltech s.r.l. 2017/11/04 +-- Gestione rotazione di una Trave + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Rotate Trave', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la trave ' .. sName, 'Rotate Trave', 'ERROR') + return +end + +-- eseguo rotazione di 90 gradi attorno asse X +local ptRot = b3Solid:getMin() + Vector3d( 0, b3Solid:getDimZ() / 2, b3Solid:getDimZ() / 2) +EgtRotate( nPartId, ptRot, X_AX(), 90, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam.old/Stato_lavori.xlsx b/ProgramData/EgtCAM5/Beam.old/Stato_lavori.xlsx new file mode 100644 index 0000000..b5b8067 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam.old/Stato_lavori.xlsx differ diff --git a/ProgramData/EgtCAM5/Beam.old/Swap.lua b/ProgramData/EgtCAM5/Beam.old/Swap.lua new file mode 100644 index 0000000..c5d74a3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam.old/Swap.lua @@ -0,0 +1,31 @@ +-- Swap.lua by Egaltech s.r.l. 2017/11/02 +-- Gestione scambio testa coda di una Trave + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Swap Trave', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la trave ' .. sName, 'Swap Trave', 'ERROR') + return +end + +-- eseguo rotazione di 180 gradi attorno asse Z +EgtRotate( nPartId, b3Solid:getCenter(), Z_AX(), 180, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam/.gitlab-ci.yml b/ProgramData/EgtCAM5/Beam/.gitlab-ci.yml new file mode 100644 index 0000000..ab52ea9 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/.gitlab-ci.yml @@ -0,0 +1,111 @@ +variables: + VERS_MAIN: '1.0' + APP_NAME: 'Beam' + NEW_REL: '' + NET_SHARE_R: '\\10.74.82.50\EgtTech' + NET_USER: '10.74.82.50\Server' + NET_SHARE_Z: '\\10.74.82.201\Artifacts' + +#Note compilazione LUA: +# lua53 -o 32\$FileName -s $FileName: -o = output, -s = NON include i debug symbols + +# helper compilazione LUA a 32 bit +.LuaCompile32: &LuaCompile32 + - | + Set-Alias lua53 C:\Tools\Lua32\luac53 + echo "Copia file *.ini" + $FileList = Get-ChildItem("*.ini") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + Copy-Item -Path $FileName -Destination 32\$FileName + echo "Copy-Item -Path $FileName -Destination 32\$FileName" + } + echo "Copia file *.lua" + $FileList = Get-ChildItem("*.lua") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + Copy-Item -Path $FileName -Destination 32\$FileName + echo "Copy-Item -Path $FileName -Destination 32\$FileName" + } + $FileList = Get-ChildItem("LuaLibs\*.lua") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + lua53 -o 32\LuaLibs\$FileName LuaLibs\$FileName + echo "lua53 -o 32\LuaLibs\$FileName LuaLibs\$FileName" + } + +# helper compilazione LUA a 64 bit +.LuaCompile64: &LuaCompile64 + - | + Set-Alias lua53 C:\Tools\Lua64\luac53 + echo "Copia file *.ini" + $FileList = Get-ChildItem("*.ini") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + Copy-Item -Path $FileName -Destination 64\$FileName + echo "Copy-Item -Path $FileName -Destination 64\$FileName" + } + echo "Copia file *.lua" + $FileList = Get-ChildItem("*.lua") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + Copy-Item -Path $FileName -Destination 64\$FileName + echo "Copy-Item -Path $FileName -Destination 64\$FileName" + } + $FileList = Get-ChildItem("LuaLibs\*.lua") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + lua53 -o 64\LuaLibs\$FileName LuaLibs\$FileName + echo "lua53 -o 64\LuaLibs\$FileName LuaLibs\$FileName" + } + +# helper copia SORGENTI verso cartella di rete R:\ dei SORGENTI +.CodeReplicaR: &CodeReplicaR + - | + net use R: /delete + net use R: $env:NET_SHARE_R /u:$env:NET_USER $RDRIVE_PASSWD + ROBOCOPY . R:\EgtData\$env:APP_NAME /MIR /XF .git* /XD .git + SLEEP 2 + net use R: /delete + +# helper copia script verso cartella di rete R:\ delle cartelle 32 e 64 +.ReplicaR: &ReplicaR + - | + net use R: /delete + net use R: $env:NET_SHARE_R /u:$env:NET_USER $RDRIVE_PASSWD + ROBOCOPY /MIR 32 R:\EgtData\$env:APP_NAME\32 + ROBOCOPY /MIR 64 R:\EgtData\$env:APP_NAME\64 + ROBOCOPY /MIR Images R:\EgtData\$env:APP_NAME\32\Images + ROBOCOPY /MIR Images R:\EgtData\$env:APP_NAME\64\Images + SLEEP 2 + net use R: /delete + +# helper copia script verso cartella di rete R:\ delle cartelle 32 e 64 +.ReplicaZ: &ReplicaZ + - | + net use Z: /delete + net use Z: $env:NET_SHARE_Z + ROBOCOPY /MIR 32 Z:\EgtData\$env:APP_NAME\32 + ROBOCOPY /MIR 64 Z:\EgtData\$env:APP_NAME\64 + ROBOCOPY /MIR Images Z:\EgtData\$env:APP_NAME\32\Images + ROBOCOPY /MIR Images Z:\EgtData\$env:APP_NAME\64\Images + SLEEP 2 + net use Z: /delete + +stages: + - build + +LuaCompile:build: + stage: build + only: + - main + - master + tags: + - win + script: + - *LuaCompile32 + - *LuaCompile64 + - *CodeReplicaR + - *ReplicaR + - *ReplicaZ + \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam/32/Images/.placeholder b/ProgramData/EgtCAM5/Beam/32/Images/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/ProgramData/EgtCAM5/Beam/32/LuaLibs/.placeholder b/ProgramData/EgtCAM5/Beam/32/LuaLibs/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/ProgramData/EgtCAM5/Beam/64/Images/.placeholder b/ProgramData/EgtCAM5/Beam/64/Images/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/ProgramData/EgtCAM5/Beam/64/LuaLibs/.placeholder b/ProgramData/EgtCAM5/Beam/64/LuaLibs/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/ProgramData/EgtCAM5/Beam/BatchProcess.lua b/ProgramData/EgtCAM5/Beam/BatchProcess.lua new file mode 100644 index 0000000..d125472 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/BatchProcess.lua @@ -0,0 +1,569 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2021/08/04 +-- Gestione calcolo batch disposizione e lavorazioni per Travi +-- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. +-- 2019/07/16 Aggiunta gestione modalità oltre 10 per impostazione macchina e uscita. +-- 2019/07/19 Aggiunta gestione collisioni. +-- 2019/07/24 Aggiunta gestione extra-corse. +-- 2019/08/29 Aggiunta possibilità di processare file NGE. +-- 2019/10/04 Migliorato log dei parametri ricevuti. +-- 2019/10/07 Aggiunta gestione Flag 4 = Check+Generate. +-- 2019/10/09 In ImportBtl aggiunto flag per usare UserAttr. +-- 2019/12/09 Gestione conservazione modifiche su barre. +-- 2019/12/20 Gestione LOAD90 tramite file ausiliario (btm). +-- 2019/12/28 Tolta uscita in caso di errore su features. +-- 2020/01/08 Aggiunta seconda sezione limite (BD.MAX_WIDTH2 x BD.MAX_HEIGHT2). +-- 2020/01/14 Si carica ultimo gruppo di lavoro. Corretto problema con nome non definito in segnalazione errore in generazione o stima. +-- 2020/01/30 File Diff con nome del btl. +-- 2020/02/12 Migliorie nella gestione degli errori. +-- 2020/06/12 Si esegue sempre Processing se parametri macchina TS3 successivi al btl. +-- 2021/02/04 Se necessario ricalcolo allora si aggiorna anche l'attrezzaggio. +-- 2021/02/14 Modifica per macchine senza BD.MAX_WIDTH2 e BD.MAX_HEIGHT2. +-- 2021/02/22 Aggiunto anche controllo su file macchina mlde per aggiornare calcoli. +-- 2021/02/25 Aggiunta gestione tipo scarico (standard, lav. incomplete, a caduta). +-- 2021/06/16 Se disponibile si aggiunge la versione dell'eseguibile alle info del programma CN. +-- 2021/08/04 Direzione vista simulazione da BD.SIMUL_VIEW_DIR se esiste. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--BEAM = {} +--BEAM.FILE = 'c:\\EgtData\\Varie\\TestEssetreFast\\TestFilippo\\BTL\\Bar_20_1.btl' +--BEAM.MACHINE = 'FAST' +--BEAM.FLAG = 3 + +-- Log dati in input +local sFlag = '' +if BEAM.FLAG == 0 then + sFlag = 'GENERATE' +elseif BEAM.FLAG == 1 then + sFlag = 'MODIFY' +elseif BEAM.FLAG == 2 then + sFlag = 'SIMULATE' +elseif BEAM.FLAG == 3 then + sFlag = 'CHECK' +elseif BEAM.FLAG == 4 then + sFlag = 'CHECK+GENERATE' +elseif BEAM.FLAG == 11 then + sFlag = 'TOOLS' +elseif BEAM.FLAG == 12 then + sFlag = 'JOBS' +else + sFlag = 'FLAG='..tostring( BEAM.FLAG) +end +local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. BEAM.MACHINE .. ', ' .. sFlag +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( BEAM.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 WriteFallToLogFile( nErr, sMsg, nCutId, nFall) + local hFile = io.open( sLogFile, 'a') + hFile:write( 'ERR=' .. tostring( nErr) .. '\n') + hFile:write( sMsg .. '\n') + hFile:write( 'CUTID=' .. tostring( nCutId or 0) .. '\n') + hFile:write( 'FALL=' .. tostring( nFall 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 ( BEAM.FLAG == 1 or BEAM.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 ( BEAM.FLAG == 1 or BEAM.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-' .. BEAM.MACHINE +if not EgtSetCurrMachine( sMachine) then + BEAM.ERR = 11 + BEAM.MSG = 'Error selecting machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + BEAM.ERR = 12 + BEAM.MSG = 'Error not configured for beams machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Se modalità visualizzazione finestre per DB esco +if BEAM.FLAG > 10 then + BEAM.ERR = 0 + return +end + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Dati del file +local sDir, sTitle, sExt = EgtSplitPath( BEAM.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( BEAM.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 or + EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\' .. sMachine ..'.mlde') == -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( BEAM.FILE, EIB_FL.TS3_POS + EIB_FL.USEUATTR) then + BEAM.ERR = 13 + BEAM.MSG = 'Error importing BTL file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + -- faccio copia del file btl originale + EgtCopyFile( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + -- altrimenti Nge, lo apro + else + if not EgtOpenFile( BEAM.FILE) then + BEAM.ERR = 13 + BEAM.MSG = 'Error opening NGE file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + -- faccio copia del file originale + EgtCopyFile( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + end + + -- Aggiorno eventuali dati ausiliari + UpdateAuxData( sBtmFile) + + -- Recupero l'elenco ordinato delle travi + local vBeam = {} + local nPartId = EgtGetFirstPart() + while nPartId do + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + nPartId = EgtGetNextPart( nPartId) + end + if #vBeam == 0 then + BEAM.ERR = 14 + BEAM.MSG = 'Error no beams in the file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) + end + + -- Ne recupero le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + BEAM.ERR = 15 + BEAM.MSG = 'Box undefined for beam ' .. vBeam[i].Name + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + vBeam[i].Box = b3Solid + end + end + + -- Ne recupero la posizione + for i = 1, #vBeam do + local PosX = EgtGetInfo( vBeam[i].Id, 'POSX', 'd') + vBeam[i].PosX = PosX + end + + -- Eseguo eventuali rotazioni e inversioni testa-coda + for i = 1, #vBeam do + local b3Solid = vBeam[i].Box + -- rotazione + local dRotAng = EgtGetInfo( vBeam[i].Id, 'ROTATED', 'd') + if dRotAng and abs( dRotAng) > GEO.EPS_ANG_SMALL then + local ptRotCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptRotCen, X_AX(), dRotAng, GDB_RT.GLOB) + b3Solid:rotate( ptRotCen, X_AX(), dRotAng) + end + -- inversione + local dInvAng = 180 - ( EgtGetInfo( vBeam[i].Id, 'INVERTED', 'd') or 0) + if abs( dInvAng) > GEO.EPS_ANG_SMALL then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptInvCen, Z_AX(), dInvAng, GDB_RT.GLOB) + end + end + + -- Ne verifico le dimensioni + local dRawW = vBeam[1].Box:getDimY() + local dRawH = vBeam[1].Box:getDimZ() + local vBeamErr = {} + for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end + end + if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + table.remove( vBeam, vBeamErr[i]) + end + BEAM.ERR = 16 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Verifico sezione barra non troppo grande + if not BD.MAX_WIDTH2 or not BD.MAX_HEIGHT2 then + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + else + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) and + ( dRawW > BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' .. + 'e (' .. EgtNumToString( BD.MAX_WIDTH2, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT2, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + end + + -- Verifico sezione barra non troppo piccola + if dRawW < BD.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < BD.MIN_HEIGHT - 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'sotto i limiti della macchina (' .. EgtNumToString( BD.MIN_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MIN_HEIGHT, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Lunghezza della barra + local dRawL = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'BARLEN', 'd') or 12000) + 0.1 + -- Sovramateriale di testa + local dOvmHead = vBeam[1].PosX or 0 + + -- Sistemo le travi nel grezzo + local bPbOk, sPbErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) + if not bPbOk then + BEAM.ERR = 18 + BEAM.MSG = sPbErr + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Imposto Nome file CN + local _, sName, _ = EgtSplitPath( BEAM.FILE) + EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + + -- Abilito Vmill + EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + + -- Lavoro le features + local bPfOk, Stats = BE.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 + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = 19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + elseif Stats[i].Err < 0 then + -- se segnalazione scarico pezzo standard, incompleto o a caduta + if Stats[i].Err == -100 or Stats[i].Err == -101 or Stats[i].Err == -102 then + BEAM.ERR = 0 + BEAM.MSG = sMsg + BEAM.CUTID = Stats[i].CutId + BEAM.FALL = abs( Stats[i].Err + 100) + WriteFallToLogFile( BEAM.ERR, BEAM.MSG, BEAM.CUTID, BEAM.FALL) + -- altri avvertimenti + else + nWarnCnt = nWarnCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, sMsg) + BEAM.ERR = -19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + end + 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 + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = 0 + BEAM.CUTID = nCutId + BEAM.TASKID = nTaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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 setup corrente e ricalcolo delle lavorazioni + if bToRecalc then + EgtOutLog( ' +++ Recalculating all dispositions and machinings >>>') + EgtImportSetup() + EgtApplyAllMachinings() + -- copia del file btl originale (per dichiarare progetto ricalcolato) + EgtCopyFile( BEAM.FILE, sDir..sTitle..'.ori'..sExt) + end + -- Salvo il progetto + EgtSaveFile( sNgeFile) +end + +-- *** Eseguo simulazione con verifica collisione in cieco *** +if ( BEAM.FLAG == 0 and ( bToProcess or bToRecalc)) or BEAM.FLAG == 3 or BEAM.FLAG == 4 then + EgtOutLog( ' +++ Simulating with collision check >>>') + -- verifico setup + local bSetUpOk, SetUpErrors = EgtVerifyCurrSetup() + if not bSetUpOk then + local sToolsList = "" + for ToolIndex = 1, #SetUpErrors do + sToolsList = sToolsList .. SetUpErrors[ToolIndex] + if ToolIndex ~= #SetUpErrors then + sToolsList = sToolsList .. ", " + end + end + WriteErrToLogFile( 19, 'Error in setup: tool/s ' .. sToolsList .. ' not found', 0, 0, 0) + return + end + -- lancio simulazione + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.INIT then + BEAM.ERR = 19 + BEAM.MSG = 'Error starting simulation' + elseif nErr == MCH_SHE.COLLISION then + BEAM.ERR = 22 + BEAM.MSG = 'Head-part collision' + elseif nErr == MCH_SHE.OUTSTROKE then + BEAM.ERR = 23 + BEAM.MSG = 'Axis outstroke ' .. sErr + elseif nErr == MCH_SHE.SPECIAL then + BEAM.ERR = 24 + BEAM.MSG = 'Clamp move error ' .. sErr + else + BEAM.ERR = 25 + BEAM.MSG = 'General failure (contact supplier)' + end + BEAM.ROT = 0 + BEAM.CUTID = 0 + BEAM.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 + BEAM.CUTID = EgtGetVal( vItem[i], 'CUTID', 'i') or 0 + elseif string.find( vItem[i], 'TASKID', 1, true) then + BEAM.TASKID = EgtGetVal( vItem[i], 'TASKID', 'i') or 0 + end + end + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + return + end +end + +-- *** Genero programma CN *** ( se richiesto) +if BEAM.FLAG == 0 or BEAM.FLAG == 4 then + EgtOutLog( ' +++ Generating NC part program >>>') + local sInfo = 'EgtCAM5 - ' + if EgtGetExeVersion then + sInfo = 'EgtCAM5 ver.' .. EgtGetExeVersion() .. ' - ' + end + if not EgtGenerate( '', sInfo .. sNgeFile) then + BEAM.ERR = 20 + local _, sName, _ = EgtSplitPath( BEAM.FILE) + BEAM.MSG = 'Error generating NC part program : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end +end + +-- *** Eseguo stima tempi *** +EgtOutLog( ' +++ Estimating T&L >>>') +if not EgtEstimate( '', 'EgtCAM5 - ' .. sNgeFile) then + BEAM.ERR = 21 + local _, sName, _ = EgtSplitPath( BEAM.FILE) + BEAM.MSG = 'Error estimating production time : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.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 BEAM.FLAG == 1 or BEAM.FLAG == 2 then + local vView = { SCE_VD.ISO_NW, SCE_VD.ISO_SW, SCE_VD.ISO_NE, SCE_VD.ISO_SE} + local nV = min( max( BD.SIMUL_VIEW_DIR or 2, 1), 4) + EgtSetView( vView[nV], false) +end + +-- Completamento senza errori e avvisi +if nWarnCnt == 0 then + BEAM.ERR = 0 + BEAM.MSG = '---' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) +end + +-- Scrittura tempo totale stimato di lavorazione +WriteTimeToLogFile( Ttot) + +EgtOutLog( ' +++ BatchProcess completed') diff --git a/ProgramData/EgtCAM5/Beam/BatchProcessNew.lua b/ProgramData/EgtCAM5/Beam/BatchProcessNew.lua new file mode 100644 index 0000000..89da840 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/BatchProcessNew.lua @@ -0,0 +1,669 @@ +-- BatchProcessNew.lua by Egaltech s.r.l. 2022/02/09 +-- Gestione calcolo batch disposizione e lavorazioni per Travi +-- 2021/01/07 Per nuova interfaccia Egt. +-- 2021/01/15 CREATE_BAR ora FLAG = 6 (prima 5). +-- 2021/02/04 Se necessario ricalcolo allora si aggiorna anche l'attrezzaggio. +-- 2021/02/14 Modifica per macchine senza BD.MAX_WIDTH2 e BD.MAX_HEIGHT2. +-- 2021/02/25 Aggiunta gestione tipo scarico (standard, lav. incomplete, a caduta). +-- 2021/06/16 Se disponibile si aggiunge la versione dell'eseguibile alle info del programma CN. +-- 2021/08/04 Direzione vista simulazione da BD.SIMUL_VIEW_DIR se esiste. +-- 2022/01/07 Per CUTID/TASKID senza ToProcess si verificano anche eventuali Duplo. +-- 2022/02/09 Aggiornato come Wall per gestione errori e verifica attrezzaggio utensili. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--BEAM = {} +--BEAM.FILE = 'c:\\EgtData\\Varie\\TestEssetreFast\\TestFilippo\\BTL\\Bar_20_1.btl' +--BEAM.MACHINE = 'Essetre-FAST' +--BEAM.FLAG = 3 + +-- Log dati in input +local sFlag = '' +if BEAM.FLAG == 0 then + sFlag = 'GENERATE' +elseif BEAM.FLAG == 1 then + sFlag = 'MODIFY' +elseif BEAM.FLAG == 2 then + sFlag = 'SIMULATE' +elseif BEAM.FLAG == 3 then + sFlag = 'CHECK' +elseif BEAM.FLAG == 4 then + sFlag = 'CHECK+GENERATE' +elseif BEAM.FLAG == 6 then + sFlag = 'CREATE_BAR' +else + sFlag = 'FLAG='..tostring( BEAM.FLAG) +end +local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. BEAM.MACHINE .. ', ' .. sFlag +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( BEAM.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 WriteFallToLogFile( nErr, sMsg, nCutId, nFall) + local hFile = io.open( sLogFile, 'a') + hFile:write( 'ERR=' .. tostring( nErr) .. '\n') + hFile:write( sMsg .. '\n') + hFile:write( 'CUTID=' .. tostring( nCutId or 0) .. '\n') + hFile:write( 'FALL=' .. tostring( nFall 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 ( BEAM.FLAG == 1 or BEAM.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 ( BEAM.FLAG == 1 or BEAM.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 + +-- Funzione di reset gruppo di lavoro in caso di impossibilità di inserire i pezzi +local function ResetMachGroup( vBeam) + for i = 1, #vBeam do + EgtErase( vBeam[i].Id) + end + EgtRemoveMachGroup( EgtGetCurrMachGroup() or GDB_ID.NULL) +end + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Se necessario, impostazione della macchina corrente +local sMachine = BEAM.MACHINE +if BEAM.FLAG ~= 6 then + EgtResetCurrMachGroup() + if not EgtSetCurrMachine( sMachine) then + BEAM.ERR = 11 + BEAM.MSG = 'Error selecting machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + BEAM.ERR = 12 + BEAM.MSG = 'Error not configured for beams machine : ' .. sMachine + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Dati del file +local sDir, sTitle, sExt = EgtSplitPath( BEAM.FILE) +local sOriFile = sDir..sTitle..'.ori.bwe' +local sNgeFile = sDir..sTitle..'.bwe' +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 EgtExistsFile( sOriFile) then + bToProcess = false + EgtCopyFile( sOriFile, sNgeFile) + -- se cambiata configurazione macchina da ultima elaborazione, devo aggiornare + if EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\Beam\\TS3Data.lua') == -1 or + EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\Tools\\Tools.data') == -1 or + EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\' .. sMachine ..'.mlde') == -1 then + bToRecalc = true + end +end + +-- Inizializzo contatori errori e avvisi +local nErrCnt = 0 +local nWarnCnt = 0 + +-- Se da elaborare +if bToProcess then + EgtOutLog( ' +++ Processing Parts >>>') + + -- Flag di barra da creare + local bCreateBar + -- Lunghezza della barra ed elenco travi + local dBarLen + local vBeam = {} + + -- Se necessario, apro il file Bwe + if BEAM.FLAG ~= 6 then + if not EgtOpenFile( BEAM.FILE) then + BEAM.ERR = 13 + BEAM.MSG = 'Error opening BWE file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + -- Faccio copia del file originale + EgtCopyFile( BEAM.FILE, sOriFile) + + -- Aggiorno eventuali dati ausiliari + --UpdateAuxData( sBtmFile) + + -- Se già presente un gruppo di lavoro + if EgtGetFirstMachGroup() then + -- Barra già presente + bCreateBar = false + -- Rendo corrente il gruppo di lavoro + EgtSetCurrMachGroup() + -- Area tavola + local b3Tab = EgtGetTableArea() + -- Calcolo posizione estremo TR o BR della tavola rispetto a sua origine in BL + BD.OriXR = Point3d( b3Tab:getDimX(), EgtIf( BD.RIGHT_LOAD, 0, b3Tab:getDimY()), 0) + BD.PosXR = EgtIf( BD.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR) + -- Calcolo minimo grezzo scaricabile + local nRawId = EgtGetFirstRawPart() + if not nRawId then + BEAM.ERR = 14 + BEAM.MSG = 'Error no Raw Parts in the file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + local b3Raw = EgtGetRawPartBBox( nRawId) + BE.CalcMinUnloadableRaw( b3Raw:getDimY(), b3Raw:getDimZ()) + -- altrimenti devo recuperare i pezzi per creare la barra + else + -- Barra da creare + bCreateBar = true + -- Recupero l'elenco ordinato delle travi + local nPartId = EgtGetFirstPart() + while nPartId do + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + nPartId = EgtGetNextPart( nPartId) + end + if #vBeam == 0 then + BEAM.ERR = 14 + BEAM.MSG = 'Error no beams in the file : ' .. BEAM.FILE + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) + end + -- Ne recupero le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + BEAM.ERR = 15 + BEAM.MSG = 'Box undefined for beam ' .. vBeam[i].Name + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + vBeam[i].Box = b3Solid + end + end + -- Assegno lunghezza della barra + dBarLen = vBeam[1].Box:getDimX() + 10 + if dBarLen < 2200 then + dBarLen = dBarLen + 1800 + end + -- Assegno posizione prima ed unica trave + vBeam[1].PosX = 10 + end + + -- Altrimenti, opero sul progetto corrente + else + -- Recupero l'identificativo del gruppo di lavoro corrente + local nMGrpId = EgtGetCurrMachGroup() + -- Barra da creare + bCreateBar = true + -- Lunghezza della barra + dBarLen = EgtGetInfo( nMGrpId, 'BARLEN', 'd') + -- Recupero l'elenco ordinato delle travi da inserire nella barra + for i = 1, 100 do + local sKey = 'PART'..tostring( i) + local sVal = EgtGetInfo( nMGrpId, sKey) + local vVal = EgtSplitString( sVal or '') + if not vVal or #vVal < 2 then break end + local nPartId = tonumber( vVal[1]) + local dPosX = tonumber( vVal[2]) + table.insert( vBeam, { Id = nPartId, PosX = dPosX, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + if #vBeam == 0 then + BEAM.ERR = 14 + BEAM.MSG = 'Error : no beams in the project' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + return + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) + end + -- Ne recupero le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + BEAM.ERR = 15 + BEAM.MSG = 'Box undefined for beam ' .. vBeam[i].Name + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + return + else + vBeam[i].Box = b3Solid + end + end + end + + -- Se devo creare la barra + if bCreateBar then + local dRawW + local dRawH + if #vBeam == 0 then + -- Recupero l'identificativo del gruppo di lavoro corrente + local nMGrpId = EgtGetCurrMachGroup() + -- Recupero le dimensioni della barra + dRawW = EgtGetInfo(nMGrpId, 'BARWIDTH', 'd') + dRawH = EgtGetInfo(nMGrpId, 'BARHEIGHT', 'd') + else + -- Ne verifico le dimensioni + dRawW = vBeam[1].Box:getDimY() + dRawH = vBeam[1].Box:getDimZ() + end + local vBeamErr = {} + for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end + end + if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + table.remove( vBeam, vBeamErr[i]) + end + ResetMachGroup( vBeam) + BEAM.ERR = 16 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Verifico sezione barra non troppo grande + if not BD.MAX_WIDTH2 or not BD.MAX_HEIGHT2 then + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) then + ResetMachGroup( vBeam) + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + else + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) and + ( dRawW > BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) then + ResetMachGroup( vBeam) + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' .. + 'e (' .. EgtNumToString( BD.MAX_WIDTH2, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT2, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + end + + -- Verifico sezione barra non troppo piccola + if dRawW < BD.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < BD.MIN_HEIGHT - 10 * GEO.EPS_SMALL then + ResetMachGroup( vBeam) + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'sotto i limiti della macchina (' .. EgtNumToString( BD.MIN_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MIN_HEIGHT, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end + + -- Lunghezza della barra + local dRawL = dBarLen + 0.1 + -- Sovramateriale di testa + local dOvmHead = 0 + if #vBeam > 0 then + dOvmHead = vBeam[1].PosX or 0 + end + + -- Sistemo le travi nel grezzo + local bPbOk, sPbErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam, BEAM.FLAG == 6) + if not bPbOk then + BEAM.ERR = 18 + BEAM.MSG = sPbErr + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + else + -- Scrivo altezza e larghezza barra nel gruppo di lavoro corrente + local nMGrpId = EgtGetCurrMachGroup() + EgtSetInfo(nMGrpId, 'BARHEIGHT', dRawH) + EgtSetInfo(nMGrpId, 'BARWIDTH', dRawW) + end + -- sistemazioni per pezzi nella barra + else + -- ciclo sui grezzi + local nRawId = EgtGetFirstRawPart() + while nRawId do + -- massimo un pezzo per grezzo + local nPartId = EgtGetFirstPartInRawPart( nRawId) + -- box del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + -- se nel grezzo c'è un pezzo + if nPartId then + -- creo o pulisco gruppo geometrie aggiuntive + BL.CreateOrEmptyAddGroup( nPartId) + -- aggiungo faccia per taglio iniziale al pezzo + BL.AddPartStartFace( nPartId, b3Solid) + -- aggiungo faccia per taglio finale al pezzo + BL.AddPartEndFace( nPartId, b3Solid) + end + -- passo al successivo grezzo + nRawId = EgtGetNextRawPart( nRawId) + end + end + + -- Se richiesta solo barra, esco + if BEAM.FLAG == 6 then + -- Completamento senza errori e avvisi + if nWarnCnt == 0 then + BEAM.ERR = 0 + BEAM.MSG = '---' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + end + EgtOutLog( ' +++ BatchProcess completed') + return + end + + -- Imposto Nome file CN + local _, sName, _ = EgtSplitPath( BEAM.FILE) + EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + + -- Abilito Vmill + EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + + -- Aggiorno Setup utensili + EgtImportSetup() + + -- Lavoro le features + local bPfOk, Stats = BE.ProcessFeatures() + local sOutput = '' + for i = 1, #Stats do + local sMsg = Stats[i].Msg + sMsg = string.gsub( sMsg or '', '\n', ' ', 10) + sMsg = string.gsub( sMsg or '', '\r', ' ', 10) + if Stats[i].Err == 0 then + BEAM.ERR = 0 + BEAM.MSG = '---' + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.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) + BEAM.ERR = 19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + elseif Stats[i].Err < 0 then + -- se segnalazione scarico pezzo standard, incompleto o a caduta + if Stats[i].Err == -100 or Stats[i].Err == -101 or Stats[i].Err == -102 then + BEAM.ERR = 0 + BEAM.MSG = sMsg + BEAM.CUTID = Stats[i].CutId + BEAM.FALL = abs( Stats[i].Err + 100) + WriteFallToLogFile( BEAM.ERR, BEAM.MSG, BEAM.CUTID, BEAM.FALL) + -- altri avvertimenti + else + nWarnCnt = nWarnCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, sMsg) + BEAM.ERR = -19 + BEAM.MSG = sMsg + BEAM.ROT = Stats[i].Rot or 0 + BEAM.CUTID = Stats[i].CutId + BEAM.TASKID = Stats[i].TaskId + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + end + end + end + + -- Salvo il progetto + EgtSaveFile( sNgeFile) + -- copio come originale (per dichiarare progetto ricalcolato) + EgtCopyFile( sNgeFile, sOriFile) + + -- 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 vDup = EgtDuploList( nPartId) + -- if not vDup or #vDup == 0 then + -- vDup = { nPartId} + -- end + -- for i = 1, #vDup do + -- local nCutId = EgtGetInfo( vDup[i], 'CUTID', 'i') + -- if nCutId then + -- local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( vDup[i], 'Processings') or GDB_ID.NULL) + -- while nProcId do + -- local bIsFea = EgtExistsInfo( nProcId, 'GRP') and EgtExistsInfo( nProcId, 'PRC') + -- local nTaskId = EgtGetInfo( nProcId, 'TASKID', 'i') + -- if bIsFea and nTaskId then + -- BEAM.ERR = 0 + -- BEAM.MSG = '---' + -- BEAM.ROT = 0 + -- BEAM.CUTID = nCutId + -- BEAM.TASKID = nTaskId + -- WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + -- end + -- nProcId = EgtGetNext( nProcId) + -- end + -- end + -- end + -- nPartId = EgtGetNextPart( nPartId) + --end + -- Aggiorno eventuali dati ausiliari + --UpdateAuxData( sBtmFile) + -- Passo in modalità lavora + EgtSetCurrMachGroup( EgtGetLastMachGroup()) + -- Se necessario eseguo aggiornamento con setup corrente e ricalcolo delle lavorazioni + if bToRecalc then + EgtOutLog( ' +++ Recalculating all dispositions and machinings >>>') + EgtImportSetup() + EgtApplyAllMachinings() + -- Salvo il progetto + EgtSaveFile( sNgeFile) + -- copio come originale (per dichiarare progetto ricalcolato) + EgtCopyFile( sNgeFile, sOriFile) + end +end + +-- *** Eseguo simulazione con verifica collisione in cieco *** +if ( BEAM.FLAG == 0 and ( bToProcess or bToRecalc)) or BEAM.FLAG == 3 or BEAM.FLAG == 4 then + EgtOutLog( ' +++ Simulating with collision check >>>') + -- verifico setup + local bSetUpOk, SetUpErrors = EgtVerifyCurrSetup() + if not bSetUpOk then + local sToolsList = "" + for ToolIndex = 1, #SetUpErrors do + sToolsList = sToolsList .. SetUpErrors[ToolIndex] + if ToolIndex ~= #SetUpErrors then + sToolsList = sToolsList .. ", " + end + end + WriteErrToLogFile( 19, 'Error in setup: tool/s ' .. sToolsList .. ' not found', 0, 0, 0) + return + end + -- lancio simulazione + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.INIT then + BEAM.ERR = 19 + BEAM.MSG = 'Error starting simulation' + elseif nErr == MCH_SHE.COLLISION then + BEAM.ERR = 22 + BEAM.MSG = 'Head-part collision' + elseif nErr == MCH_SHE.OUTSTROKE then + BEAM.ERR = 23 + BEAM.MSG = 'Axis outstroke ' .. sErr + elseif nErr == MCH_SHE.SPECIAL then + BEAM.ERR = 24 + BEAM.MSG = 'Clamp move error ' .. sErr + else + BEAM.ERR = 25 + BEAM.MSG = 'General failure (contact supplier)' + end + BEAM.ROT = 0 + BEAM.CUTID = 0 + BEAM.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 + BEAM.CUTID = EgtGetVal( vItem[i], 'CUTID', 'i') or 0 + elseif string.find( vItem[i], 'TASKID', 1, true) then + BEAM.TASKID = EgtGetVal( vItem[i], 'TASKID', 'i') or 0 + end + end + WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) + return + end +end + +-- *** Genero programma CN *** ( se richiesto) +if BEAM.FLAG == 0 or BEAM.FLAG == 4 then + EgtOutLog( ' +++ Generating NC part program >>>') + local sInfo = 'EgtCAM5 - ' + if EgtGetExeVersion then + sInfo = 'EgtCAM5 ver.' .. EgtGetExeVersion() .. ' - ' + end + if not EgtGenerate( '', sInfo .. sNgeFile) then + BEAM.ERR = 20 + local _, sName, _ = EgtSplitPath( BEAM.FILE) + BEAM.MSG = 'Error generating NC part program : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return + end +end + +-- *** Eseguo stima tempi *** +EgtOutLog( ' +++ Estimating T&L >>>') +if not EgtEstimate( '', 'EgtCAM5 - ' .. sNgeFile) then + BEAM.ERR = 21 + local _, sName, _ = EgtSplitPath( BEAM.FILE) + BEAM.MSG = 'Error estimating production time : ' .. sName + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) + PostErrView( BEAM.ERR, BEAM.MSG) + return +end +local Ttot = EgtGetInfo( EgtGetCurrMachGroup(), 'Ttot', 'd') +local sTime = 'Total Time = ' .. EgtNumToString( Ttot, 1) +EgtOutLog( sTime) + +-- Se modifica o simula, imposto la vista ISO 3d opportuna +if BEAM.FLAG == 1 or BEAM.FLAG == 2 then + local vView = { SCE_VD.ISO_NW, SCE_VD.ISO_SW, SCE_VD.ISO_NE, SCE_VD.ISO_SE} + local nV = min( max( BD.SIMUL_VIEW_DIR or 2, 1), 4) + EgtSetView( vView[nV], false) +end + +-- Completamento senza errori e avvisi +if nWarnCnt == 0 then + BEAM.ERR = 0 + BEAM.MSG = '---' + WriteErrToLogFile( BEAM.ERR, BEAM.MSG) +end + +-- Scrittura tempo totale stimato di lavorazione +WriteTimeToLogFile( Ttot) + +EgtOutLog( ' +++ BatchProcess completed') diff --git a/ProgramData/EgtCAM5/Beam/Beam.ini b/ProgramData/EgtCAM5/Beam/Beam.ini new file mode 100644 index 0000000..bc2ede0 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/Beam.ini @@ -0,0 +1,8 @@ +[Beam] +BtlEnable=1 +BaseDir=C:\EgtData\Beam +BtlExec=BatchProcess.lua +Button1=Process.lua,Images\Process.png,Lavora Travi +Button2=Swap.lua,Images\Swap.png,Scambia estremi trave +Button3=Rotate.lua,Images\Rotate.png,Ruota trave +Button4=BeamMachinings,Images\BeamMachinings.png,Lista lavorazioni diff --git a/ProgramData/EgtCAM5/Beam/Images/BeamMachinings.png b/ProgramData/EgtCAM5/Beam/Images/BeamMachinings.png new file mode 100644 index 0000000..5ab6b0c Binary files /dev/null and b/ProgramData/EgtCAM5/Beam/Images/BeamMachinings.png differ diff --git a/ProgramData/EgtCAM5/Beam/Images/Process.png b/ProgramData/EgtCAM5/Beam/Images/Process.png new file mode 100644 index 0000000..13070d5 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam/Images/Process.png differ diff --git a/ProgramData/EgtCAM5/Beam/Images/Rotate.png b/ProgramData/EgtCAM5/Beam/Images/Rotate.png new file mode 100644 index 0000000..bd1532e Binary files /dev/null and b/ProgramData/EgtCAM5/Beam/Images/Rotate.png differ diff --git a/ProgramData/EgtCAM5/Beam/Images/Swap.png b/ProgramData/EgtCAM5/Beam/Images/Swap.png new file mode 100644 index 0000000..04fa8f8 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam/Images/Swap.png differ diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/BeamExec.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/BeamExec.lua new file mode 100644 index 0000000..62905a9 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/BeamExec.lua @@ -0,0 +1,1425 @@ +-- BeamExec.lua by Egaltech s.r.l. 2021/12/20 +-- Libreria esecuzione lavorazioni per Travi +-- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. +-- 2019/09/04 Corretto controllo feature di testa e coda con sovramateriale di testa elevato. +-- 2019/09/25 Aggiunta gestione StepJoint e StepJointNotch. +-- 2020/01/21 Aggiunta gestione ScarfJoint. +-- 2020/02/10 Aggiunta gestione FrenchRidgeLap. +-- 2020/02/11 Aggiunta gestione BlockHausFront. +-- 2020/04/02 Fori di testa dal basso non danno errore e fanno ribaltare la trave. +-- 2020/04/07 Aggiunta gestione TyroleanDovetail. +-- 2020/04/14 Aggiunta gestione Dovetail. +-- 2020/05/16 Migliorie ordinamento fori. +-- 2020/05/16 Gestione rotazione di 90deg. +-- 2020/05/21 Correzione rotazione di 90deg (caso DY > DZ). +-- 2020/05/25 Correzione rotazione di 90deg dopo scarico su carico. +-- 2020/06/02 Per dati foro si chiama funzione GetData di ProcessDrill (per gestire variazioni di diametro da UserParams). +-- 2020/07/25 Ricalcolati flag head e tail della prima parte del foro dopo lo split. +-- 2020/07/27 Modifica a ordinamento fori. +-- 2020/10/07 Aggiunta distanza libera dietro il pezzo (BDST) scritta nel suo grezzo. +-- 2020/10/15 Per foro sdoppiato ricalcolo anche flag Head oltre a Tail . +-- 2020/10/23 Corretto spostamento foro per tenone quando tenone nullo. +-- 2020/12/29 Aggiunta gestione fori in doppio. +-- 2021/02/25 Aggiunta gestione eventuale ricalcolo per macchine tipo PF. +-- 2021/07/13 Aggiunta gestione posizionamento pezzo TR/BR per macchine con carico a destra e scarico a sinistra. +-- 2021/11/27 House mortise sempre prima di (dt)mortise, house tenon sempre dopo (dt)tenon. +-- 2021/12/15 Corretta CompareFeature (risultato deve essere simmetrico scambiando le feature). +-- 2021/12/20 Ulteriore correzione a CompareFeature (caso con entrambe senza geometria). + +-- Tabella per definizione modulo +local BeamExec = {} + +-- Include +require( 'EgtBase') + +-- Carico i dati globali e libero tutti gli altri +_G.package.loaded.BeamData = nil +_G.package.loaded.CutData = nil +_G.package.loaded.MillingData = nil +_G.package.loaded.PocketingData = nil +_G.package.loaded.DrillData = nil +_G.package.loaded.SawingData = nil +local BD = require( 'BeamData') + +-- Carico le librerie +_G.package.loaded.MachiningLib = nil +_G.package.loaded.BeamLib = nil +_G.package.loaded.DiceCut = nil +_G.package.loaded.FacesBySaw = nil +_G.package.loaded.ProcessHeadCut = nil +_G.package.loaded.ProcessSplit = nil +_G.package.loaded.ProcessCut = nil +_G.package.loaded.ProcessDoubleCut = nil +_G.package.loaded.ProcessLongCut = nil +_G.package.loaded.ProcessLongDoubleCut = nil +_G.package.loaded.ProcessSawCut = nil +_G.package.loaded.ProcessRidgeLap = nil +_G.package.loaded.ProcessLapJoint = nil +_G.package.loaded.ProcessChamfer = nil +_G.package.loaded.ProcessDrill = nil +_G.package.loaded.ProcessFrenchRidgeLap = nil +_G.package.loaded.ProcessBlockHausFront = nil +_G.package.loaded.ProcessTenon = nil +_G.package.loaded.ProcessMortise = nil +_G.package.loaded.ProcessDtTenon = nil +_G.package.loaded.ProcessDtMortise = nil +_G.package.loaded.ProcessMark = nil +_G.package.loaded.ProcessText = nil +_G.package.loaded.ProcessScarfJoint = nil +_G.package.loaded.ProcessSimpleScarf = nil +_G.package.loaded.ProcessStepJoint = nil +_G.package.loaded.ProcessStepJointNotch = nil +_G.package.loaded.ProcessProfFront = nil +_G.package.loaded.ProcessProfConcave = nil +_G.package.loaded.ProcessProfConvex = nil +_G.package.loaded.ProcessProfCamb = nil +_G.package.loaded.ProcessProfHead = nil +_G.package.loaded.ProcessRoundArch = nil +_G.package.loaded.ProcessTyroleanDovetail = nil +_G.package.loaded.ProcessDovetail = nil +_G.package.loaded.ProcessFreeContour = nil +_G.package.loaded.ProcessDecor = nil +local BM = require( 'MachiningLib') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Fbs = require( 'FacesBySaw') +local Hcut= require( 'ProcessHeadCut') +local Split = require( 'ProcessSplit') +local Cut = require( 'ProcessCut') +local DoubleCut = require( 'ProcessDoubleCut') +local LongCut = require( 'ProcessLongCut') +local Long2Cut = require( 'ProcessLongDoubleCut') +local SawCut = require( 'ProcessSawCut') +local RidgeLap = require( 'ProcessRidgeLap') +local LapJoint = require( 'ProcessLapJoint') +local Chamfer = require( 'ProcessChamfer') +local Drill = require( 'ProcessDrill') +local FrenchRidgeLap = require( 'ProcessFrenchRidgeLap') +local BlockHausFront = require( 'ProcessBlockHausFront') +local Tenon = require( 'ProcessTenon') +local Mortise = require( 'ProcessMortise') +local DtTenon = require( 'ProcessDtTenon') +local DtMortise = require( 'ProcessDtMortise') +local Mark = require( 'ProcessMark') +local Text = require( 'ProcessText') +local ScarfJoint = require( 'ProcessScarfJoint') +local Scarf = require( 'ProcessSimpleScarf') +local StepJoint = require( 'ProcessStepJoint') +local StJoNotch = require( 'ProcessStepJointNotch') +local ProfFront = require( 'ProcessProfFront') +local ProfConcave = require( 'ProcessProfConcave') +local ProfConvex = require( 'ProcessProfConvex') +local ProfCamb = require( 'ProcessProfCamb') +local ProfHead = require( 'ProcessProfHead') +local RoundArch = require( 'ProcessRoundArch') +local TyroleanDovetail = require( 'ProcessTyroleanDovetail') +local Dovetail = require( 'ProcessDovetail') +local FreeContour = require( 'ProcessFreeContour') +local Decor = require( 'ProcessDecor') + +EgtOutLog( ' BeamExec started', 1) +EgtMdbSetGeneralParam( MCH_GP.MAXDEPTHSAFE, BD.COLL_SIC) +EgtMdbSave() + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle travi nel grezzo *** +------------------------------------------------------------------------------------------------------------- +function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam, bMachGroupOk) + + -- Determinazione minimo grezzo scaricabile + BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) + + -- Creazione nuovo gruppo di lavoro + if not bMachGroupOk then + local sMgName = EgtGetMachGroupNewName( 'Mach_1') + local NewMgId = EgtAddMachGroup( sMgName) + if not NewMgId then + local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName + return false, sOut + end + end + + -- Impostazione della tavola + EgtSetTable( 'Tab') + + -- Area tavola + local b3Tab = EgtGetTableArea() + -- Calcolo posizione estremo TR/BR della tavola rispetto a sua origine in BL + BD.OriXR = Point3d( b3Tab:getDimX(), EgtIf( BD.RIGHT_LOAD, 0, b3Tab:getDimY()), 0) + BD.PosXR = EgtIf( BD.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR) + + -- Impostazione dell'attrezzaggio di default + EgtImportSetup() + + -- Inserimento dei pezzi con il loro grezzo + local Cnt = 0 + local Len = dRawL + local nPrevRaw, dPrevDelta + local DeltaS = dOvmHead + local DeltaE = BD.OVM_MID + for i = 1, #vBeam do + -- assegno identificativo pezzo + local Pz = vBeam[i].Id + -- dati del pezzo + local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT) + local b3Solid = vBeam[i].Box + if b3Part:isEmpty() or b3Solid:isEmpty() then break end + EgtOutLog( 'PartSez=' .. EgtNumToString( b3Part:getDimY(), 1) .. 'x' .. EgtNumToString( b3Part:getDimZ(), 1), 3) + -- se sezione compatibile e lunghezza disponibile sufficiente + local PartLen = b3Solid:getDimX() + local PartWidth = b3Solid:getDimY() + local PartHeight = b3Solid:getDimZ() + local NextLen = Len - DeltaS - PartLen - DeltaE + if (( abs( PartWidth - dRawW) < 10 * GEO.EPS_SMALL and abs( PartHeight - dRawH) < 10 * GEO.EPS_SMALL) or + ( abs( PartHeight - dRawW) < 10 * GEO.EPS_SMALL and abs( PartWidth - dRawH) < 10 * GEO.EPS_SMALL)) and + NextLen + DeltaE >= 0 then + -- eventuale sovramateriale di testa + if vBeam[i].PosX then + DeltaS = max( vBeam[i].PosX - ( dRawL - Len), 0) + end + -- dimensioni del grezzo + local CrawLen = min( PartLen + DeltaS + DeltaE, Len) + local Delta = CrawLen - PartLen - DeltaS + -- creo e posiziono il grezzo + local nRaw = EgtAddRawPart( Point3d(0,0,0), CrawLen, dRawW, dRawH, BD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, BD.OriXR, BD.PosXR) + EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) + -- assegno ordine in lavorazione + Cnt = Cnt + 1 + EgtSetInfo( nRaw, 'ORD', Cnt) + -- creo o pulisco gruppo geometrie aggiuntive + if not BL.CreateOrEmptyAddGroup( Pz) then + local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz) + return false, sOut + end + -- aggiungo faccia per taglio iniziale al pezzo + BL.AddPartStartFace( Pz, b3Solid) + -- se sovramateriale di testa, lo notifico + if DeltaS > 0.09 then + EgtSetInfo( nRaw, 'HOVM', DeltaS) + if nPrevRaw then + EgtSetInfo( nPrevRaw, 'BDST', DeltaS + dPrevDelta) + end + end + -- aggiungo faccia per taglio finale al pezzo + BL.AddPartEndFace( Pz, b3Solid) + -- inserisco il pezzo nel grezzo + EgtDeselectPartObjs( Pz) + local ptPos = b3Part:getMin() - b3Solid:getMin() + Vector3d( Delta, ( dRawW - PartWidth) / 2, ( dRawH - PartHeight) / 2) + EgtAddPartToRawPart( Pz, ptPos, nRaw) + if abs( PartWidth - dRawW) > 10 * GEO.EPS_SMALL then + -- rotazione attorno a centro geometria complessiva del pezzo + EgtRotatePartInRawPart( Pz, X_AX(), 90) + -- correggo per eccentricità solido rispetto a geometria complessiva del pezzo + local vtEccOri = b3Solid:getCenter() - b3Part:getCenter() + local vtEccRot = Vector3d( vtEccOri) + vtEccRot:rotate( X_AX(), 90) + EgtMovePartInRawPart( Pz, ( vtEccOri - vtEccRot)) + end + -- aggiorno la lunghezza residua della barra + Len = Len - CrawLen + -- aggiorno grezzo precedente + nPrevRaw = nRaw + dPrevDelta = Delta + else + local sOut = 'Error: part L(' .. EgtNumToString( PartLen, 1) .. ') too big for raw part L(' .. EgtNumToString( Len - 0.1, 1) .. ')' + return false, sOut + end + -- se rimasto troppo poco grezzo, esco + --if Len < BD.MinRaw then break end + DeltaS = 0 + end + if nPrevRaw then + EgtSetInfo( nPrevRaw, 'BDST', 10000) + end + + -- Se rimasto materiale aggiungo grezzo dell'avanzo + if Len > 10 then + local nRaw = EgtAddRawPart( Point3d(0,0,0), Len, dRawW, dRawH, BD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, BD.OriXR, BD.PosXR) + EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) + -- assegno ordine in lavorazione + Cnt = Cnt + 1 + EgtSetInfo( nRaw, 'ORD', Cnt) + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) + if BD.GetMinUnloadableRaw then + BD.MinRaw = BD.GetMinUnloadableRaw( dRawW, dRawH) + else + local H_S = 200 + local H_L = 400 + -- Determinazione minimo grezzo scaricabile + if dRawH <= H_S then + BD.MinRaw = BD.MINRAW_S + elseif dRawH <= H_L then + local Coeff = ( dRawH - H_S) / ( H_L - H_S) + BD.MinRaw = ( 1 - Coeff) * BD.MINRAW_S + Coeff * BD.MINRAW_L + else + BD.MinRaw = BD.MINRAW_L + end + end +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function Verify90DegRotation( nRawId) + if not nRawId then return false end + -- dimensioni sezione trave in posizione normale (rotazione 0°) + local dRawW = EgtGetRawPartBBox( nRawId):getDimY() + local dRawH = EgtGetRawPartBBox( nRawId):getDimZ() + -- verifica dell'altezza rispetto alla massima larghezza + return ( dRawH < BD.MAX_WIDTH + 10 * GEO.EPS_SMALL and dRawW < BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) or + ( dRawH < BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL and dRawW < BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) +end + +------------------------------------------------------------------------------------------------------------- +local function IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- feature sempre di testa o coda per il gruppo + if Proc.Grp == 1 or Proc.Grp == 2 then + return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- feature sempre di testa o coda nonostante il gruppo + if ( Proc.Grp == 3 or Proc.Grp == 4) and + ( Proc.Prc == 38 or Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then + return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- gestioni speciali + if LapJoint.Identify( Proc) then + return LapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if Drill.Identify( Proc) then + return Drill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if RoundArch.Identify( Proc) then + return RoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if Dovetail.Identify( Proc) then + return Dovetail.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if FreeContour.Identify( Proc) then + return FreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + -- non è di testa + return false +end + +------------------------------------------------------------------------------------------------------------- +local function IsTailFeature( Proc, b3Raw, dCurrOvmH) + -- feature sempre di testa o coda per il gruppo (se non troppo lunga) + if Proc.Grp == 1 or Proc.Grp == 2 then + -- se abilitato avanzamento lavorazione feature di coda e pezzo corto (quindi a caduta) e feature in coda + if BD.ADVANCE_TAIL_CUT and b3Raw:getDimX() < BD.LEN_SHORT_PART and Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH then + -- se taglio, lo avanzo + if Proc.Prc == 10 then + return false, true + end + end + -- standard + return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH and Proc.Box:getDimX() < BD.MAX_LEN_HTFEA) + end + -- feature sempre di testa o coda nonostante il gruppo + if ( Proc.Grp == 3 or Proc.Grp == 4) and + ( Proc.Prc == 38 or Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then + -- se abilitato avanzamento lavorazione feature di coda e pezzo corto (quindi a caduta) e feature in coda + if BD.ADVANCE_TAIL_CUT and b3Raw:getDimX() < BD.LEN_SHORT_PART and Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH then + -- se profilo front solo con smusso, lo avanzo + if Proc.Prc == 100 and ProfFront.OnlyChamfer( Proc) then + return false, true + end + -- se profilo concavo solo con smusso, lo avanzo + if Proc.Prc == 101 and ProfConcave.OnlyChamfer( Proc) then + return false, true + end + -- se profilo convesso solo con smusso, lo avanzo + if Proc.Prc == 102 and ProfConvex.OnlyChamfer( Proc) then + return false, true + end + -- se profilo caudato solo con smusso, lo avanzo + if Proc.Prc == 103 and ProfCamb.OnlyChamfer( Proc) then + return false, true + end + -- se profilo head solo con smusso, lo avanzo + if Proc.Prc == 106 and ProfHead.OnlyChamfer( Proc) then + return false, true + end + end + -- standard + return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) + end + -- gestioni speciali + if LapJoint.Identify( Proc) then + return LapJoint.IsTailFeature( Proc, b3Raw) + end + if Drill.Identify( Proc) then + return Drill.IsTailFeature( Proc, b3Raw) + end + if DtMortise.Identify( Proc) then + return DtMortise.IsTailFeature( Proc, b3Raw) + end + if RoundArch.Identify( Proc) then + return RoundArch.IsTailFeature( Proc, b3Raw) + end + if Dovetail.Identify( Proc) then + return Dovetail.IsTailFeature( Proc, b3Raw) + end + if FreeContour.Identify( Proc) then + return FreeContour.IsTailFeature( Proc, b3Raw) + end + -- non è di coda + return false +end + +------------------------------------------------------------------------------------------------------------- +local function PrintFeatures( vProc, b3Raw) + EgtOutLog( ' RawBox=' .. tostring( b3Raw)) + for i = 1, #vProc do + local Proc = vProc[i] + local sOut = string.format( ' Id=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s', + Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId, + Proc.Flg, EgtIf( Proc.Down, 'T', 'F'), EgtIf( Proc.Side, 'T', 'F'), + EgtIf( Proc.Head, 'T', 'F'), EgtIf( Proc.Tail, 'T', EgtIf( Proc.AdvTail, 'A', 'F')), + Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, tostring( Proc.Box)) + -- info speciali per Block Haus Half Lap + if Proc.Prc == 37 then + local sSpec = string.format( ' N=%s Hd=%s', tostring( Proc.vtN or V_NULL()), EgtIf( Proc.HeadDir, 'T', 'F')) + sOut = sOut .. sSpec + end + EgtOutLog( sOut) + end +end + +------------------------------------------------------------------------------------------------------------- +local function CollectFeatures( PartId, b3Raw, dCurrOvmH) + -- recupero le feature + local vProc = {} + local LayerId = {} + LayerId[1] = BL.GetAddGroup( PartId) + LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings') + for nInd = 1, 2 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.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 + Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH) + Proc.Tail, Proc.AdvTail = IsTailFeature( Proc, b3Raw, dCurrOvmH) + table.insert( vProc, Proc) + -- se foro + if Drill.Identify( Proc) then + -- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento) + Proc.Diam, Proc.Fcs, Proc.Fce = Drill.GetData( Proc, b3Raw) + -- verifico se necessaria seconda lavorazione da parte opposta per foro più lungo della punta + if Drill.Split( Proc, b3Raw) then + -- aggiorno flags prima parte foro (dati tabelle sempre per riferimento) + Proc.Flg = 2 + Proc.Head = Drill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + Proc.Tail = Drill.IsTailFeature( Proc, b3Raw, dCurrOvmH) + -- definisco dati seconda parte + local Proc2 = {} + Proc2.Id = ProcId + Proc2.Grp = nGrp + Proc2.Prc = nPrc + Proc2.Flg = -2 + Proc2.Box = BBox3d( Proc.Box) + Proc2.Fct = Proc.Fct + Proc2.Diam = Proc.Diam + Proc2.Head = Drill.IsHeadFeature( Proc2, b3Raw, dCurrOvmH) + Proc2.Tail = Drill.IsTailFeature( Proc2, b3Raw, dCurrOvmH) + Proc2.Fcs = Proc.Fce + Proc2.Fce = Proc.Fcs + Proc2.CutId = Proc.CutId + Proc2.TaskId = Proc.TaskId + table.insert( vProc, Proc2) + end + -- se BlockHaus HalfLap + elseif Proc.Prc == 37 then + local nFacInd = BL.GetFaceWithMostAdj( Proc.Id, PartId) + if nFacInd then + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN then + Proc.vtN = Vector3d( vtN) + end + end + end + else + Proc.Head = false + Proc.Tail = false + Proc.Flg = 0 + table.insert( vProc, Proc) + EgtOutLog( ' Feature ' .. tostring( Proc.Id) .. ' is empty (no geometry)') + end + end + end + ProcId = EgtGetNext( ProcId) + end + end + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function OrderFeatures( vProc, b3Raw) + + local dDrillPenalty = EgtIf( BD.PRESS_ROLLER, 200, 100) + local dSmallDrillRange = EgtIf( b3Raw:getDimX() < BD.LEN_SHORT_PART, 200, 600) + + -- funzione di confronto + -- secondo centro box in X (taglio di intestazione prima di altri tagli di testa e taglio di separazione però prima di altri tagli di coda) + local function CompareFeatures( B1, B2) + -- se primo disabilitato e secondo no va dopo + if B1.Flg == 0 and B2.Flg ~= 0 then + return false + end + -- se secondo disabilitato e primo no va lasciato dopo + if B2.Flg == 0 and B1.Flg ~= 0 then + return true + end + -- se entrambi disabilitati seguo l'Id + if B1.Flg == 0 and B2.Flg == 0 then + return ( B1.Id < B2.Id) + end + -- se primo è intestazione va sempre prima + if Hcut.Identify( B1) then + return true + end + -- se l'altro è intestazione va sempre prima + if Hcut.Identify( B2) then + return false + end + -- se uno di testa e non l'altro, privilegio quello di testa + if B1.Head ~= B2.Head then + return B1.Head + end + -- se entrambi tenoni e si intersecano, metto prima tenone vero e poi base tenone + if ( Tenon.Identify( B1) or DtTenon.Identify( B1)) and ( Tenon.Identify( B2) or DtTenon.Identify( B2)) and + B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then + return ( ( B1.Prc == 50 or B1.Prc == 55) and B2.Prc == 52) + end + -- se primo house mortise, secondo mortise e si intersecano, metto prima house mortise + if Mortise.Identify( B1) and B1.Prc == 53 and ( Mortise.Identify( B2) or DtMortise.Identify( B2)) and B2.Prc ~= 53 and + B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then + return true + end + -- se primo mortise, secondo house mortise e si intersecano, metto prima house mortise + if ( Mortise.Identify( B1) or DtMortise.Identify( B1)) and B1.Prc ~= 53 and Mortise.Identify( B2) and B2.Prc == 53 and + B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then + return false + end + -- se entrambi di testa e primo è scasso o mortasa e secondo no va messo dopo + if B1.Head and B2.Head and ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1)) and + not ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2)) then + return false + end + -- se entrambi di testa e secondo è scasso o mortasa e primo no va lasciato dopo + if B1.Head and B2.Head and ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2)) and + not ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1)) then + return true + end + -- se primo è feature di coda e l'altro è separazione o non è feature di coda + if B1.Tail and ( Split.Identify( B2) or not B2.Tail) then + return false + end + -- se secondo è feature di coda e l'altro è separazione o non è feature di coda + if B2.Tail and ( Split.Identify( B1) or not B1.Tail) then + return true + end + -- se primo è feature di coda anticipata e l'altro non è feature di coda + if B1.AdvTail and ( not Split.Identify( B2) or not B2.Tail) then + return false + end + -- se secondo è feature di coda anticipata e l'altro non è feature di coda + if B2.AdvTail and ( not Split.Identify( B1) or not B1.Tail) then + return true + end + -- se primo è scasso o mortasa di coda e secondo no, sempre dopo + if B1.Tail and ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1)) and + not ( B2.Tail and ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2))) then + return false + end + -- se secondo è scasso o mortasa di coda e primo no, va lasciato dopo + if B2.Tail and ( LapJoint.Identify( B2) or Mortise.Identify( B2) or DtMortise.Identify( B2)) and + not ( B1.Tail and ( LapJoint.Identify( B1) or Mortise.Identify( B1) or DtMortise.Identify( B1))) then + return true + end + -- se primo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda + if abs( B1.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + -- se anche l'altra è lunga, faccio prima quello piccolo in YZ + if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + if abs( B1.Box:getDimY() * B1.Box:getDimZ() - B2.Box:getDimY() * B2.Box:getDimZ()) < 10 then + return B1.Id < B2.Id + else + return B1.Box:getDimY() * B1.Box:getDimZ() < B2.Box:getDimY() * B2.Box:getDimZ() + end + else + return B2.Tail or B1.Box:getMin():getX() + 20 > B2.Box:getCenter():getX() + end + end + -- se secondo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda + if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then + return not ( B1.Tail or B2.Box:getMin():getX() + 20 > B1.Box:getCenter():getX()) + end + -- se primo è foro e l'altro no, lo penalizzo + if B1.Prc == 40 and B2.Prc ~= 40 then + return ( B1.Box:getCenter():getX() > B2.Box:getMax():getX() + dDrillPenalty) + end + -- se primo è altro e secondo è foro, lo premio + if B1.Prc ~= 40 and B2.Prc == 40 then + return ( B1.Box:getMax():getX() + dDrillPenalty > B2.Box:getCenter():getX()) + end + -- se entrambi fori con posizione praticamente uguale ordino secondo diametro e faccia di inizio (Fcs) + if B1.Prc == 40 and B2.Prc == 40 and abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) < dSmallDrillRange then + if abs( B1.Diam - B2.Diam) < 1.0 then + if B1.Fcs == B2.Fcs then + if abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) < 1.0 then + if abs( B1.Box:getCenter():getY() - B2.Box:getCenter():getY()) < 1.0 then + if abs( B1.Box:getCenter():getZ() - B2.Box:getCenter():getZ()) < 1.0 then + return ( B1.Id < B2.Id) + else + return ( B1.Box:getCenter():getZ() > B2.Box:getCenter():getZ()) + end + else + return ( B1.Box:getCenter():getY() > B2.Box:getCenter():getY()) + end + else + return ( B1.Box:getCenter():getX() > B2.Box:getCenter():getX()) + end + else + return ( B1.Fcs > B2.Fcs) + end + else + return ( B1.Diam > B2.Diam) + end + end + -- confronto standard + if abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) > 0.4 * ( B1.Box:getDimX() + B2.Box:getDimX()) then + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + elseif abs( B1.Box:getCenter():getY() - B2.Box:getCenter():getY()) > 0.2 * ( B1.Box:getDimY() + B2.Box:getDimY()) then + return B1.Box:getCenter():getY() > B2.Box:getCenter():getY() + elseif abs( B1.Box:getCenter():getZ() - B2.Box:getCenter():getZ()) > 0.1 * ( B1.Box:getDimZ() + B2.Box:getDimZ()) then + return B1.Box:getCenter():getZ() > B2.Box:getCenter():getZ() + else + return ( B1.Id < B2.Id) + end + end + + -- test della funzione di ordinamento + if EgtGetDebugLevel() >= 3 then + EgtOutLog( ' CompareFeatures Test ') + local bCompTest = true + for i = 1, #vProc do + for j = i + 1, #vProc do + local bComp1 = CompareFeatures( vProc[i], vProc[j]) + local bComp2 = CompareFeatures( vProc[j], vProc[i]) + if bComp1 == bComp2 then + bCompTest = false + EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', vProc[i].Id, vProc[j].Id)) + end + end + end + if bCompTest then + EgtOutLog( ' ALL OK') + end + end + + -- eseguo ordinamento + table.sort( vProc, CompareFeatures) + + -- riunisco fori con lo stesso diametro e non troppo lontani + local dDrillRange = dSmallDrillRange + if BD.GO_FAST == 2 then + dDrillRange = 6000 + elseif BD.PRESS_ROLLER then + dDrillRange = 2000 + end + for i = 1, #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 40 then + for j = i + 1, #vProc do + local ProcJ = vProc[j] + if ProcJ.Prc == 40 and ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and + abs( ProcJ.Diam - ProcI.Diam) < 1.0 and abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < dDrillRange then + if j > i + 1 then + local ProcK = vProc[i+1] + if ProcK.Prc ~= 40 or abs( ProcK.Diam - ProcJ.Diam) > 1.0 then + table.insert( vProc, i + 1, table.remove( vProc, j)) + end + end + end + end + end + end + -- riunisco fori da fare in doppio + local i = 1 + while i < #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 40 then + local DouId = EgtGetInfo( ProcI.Id, 'DOU', 'i') + if DouId then + for j = i + 1, #vProc do + if vProc[j].Id == DouId then + table.insert( vProc, i, table.remove( vProc, j)) + i = i + 1 + break + end + end + end + end + i = i + 1 + end + -- riunisco marcature, testi e decori non troppo lontani + local dMarkRange = 300 + for i = 1, #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 60 or ProcI.Prc == 61 or ProcI.Prc == 959 then + for j = i + 1, #vProc do + local ProcJ = vProc[j] + if ( ProcJ.Prc == 60 or ProcJ.Prc == 61 or ProcJ.Prc == 959) and + ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and + abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < dMarkRange then + if j > i + 1 then + table.insert( vProc, i + 1, table.remove( vProc, j)) + end + break + end + end + end + end + -- ordino BlockHaus HalfLap vicini (davanti, sotto, dietro, sopra) + local dBHHLRange = 100 + for i = 1, #vProc do + local ProcI = vProc[i] + if ProcI.Prc == 37 then + for j = i + 1, #vProc do + local ProcJ = vProc[j] + if ProcJ.Prc == 37 and abs( ProcI.Box:getCenter():getX() - ProcJ.Box:getCenter():getX()) < dBHHLRange then + if ProcI.HeadDir then + if ProcJ.vtN:getY() < -0.5 then + table.insert( vProc, i, table.remove( vProc, j)) + break + elseif ProcJ.vtN:getZ() < -0.5 and ProcI.vtN:getY() > -0.5 then + table.insert( vProc, i, table.remove( vProc, j)) + ProcI = vProc[i] + elseif ProcJ.vtN:getY() > 0.5 and ProcI.vtN:getY() > -0.5 and ProcI.vtN:getZ() > -0.5 then + table.insert( vProc, i, table.remove( vProc, j)) + ProcI = vProc[i] + end + else + if ProcJ.vtN:getY() > 0.5 then + table.insert( vProc, i, table.remove( vProc, j)) + break + elseif ProcJ.vtN:getZ() < -0.5 and ProcI.vtN:getY() < 0.5 then + table.insert( vProc, i, table.remove( vProc, j)) + ProcI = vProc[i] + elseif ProcJ.vtN:getY() < -0.5 and ProcI.vtN:getY() < 0.5 and ProcI.vtN:getZ() > -0.5 then + table.insert( vProc, i, table.remove( vProc, j)) + ProcI = vProc[i] + end + end + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +local function ClassifyFeatures( vProc, b3Raw, Stats) + local bAllOk = true + local bSomeDown = false + local bSomeSide = false + local bSplitRot = false + local nHeading + local nSplitting + for i = 1, #vProc do + local Proc = vProc[i] + local bOk = true + local bDown = false + local bSide = false + local bDownSideOnHeadOk = false + -- se senza geometria (già disabilitato + if Proc.Flg == 0 then + bOk = false + -- se intestatura + elseif Hcut.Identify( Proc) then + nHeading = i + -- se separazione + elseif Split.Identify( Proc) then + nSplitting = i + -- se taglio + elseif Cut.Identify( Proc) then + bOk, bDown = Cut.Classify( Proc, b3Raw) + -- se doppio taglio + elseif DoubleCut.Identify( Proc) then + bOk, bDown = DoubleCut.Classify( Proc, b3Raw) + -- se taglio longitudinale + elseif LongCut.Identify( Proc) then + bOk, bDown = LongCut.Classify( Proc) + -- se doppio taglio longitudinale + elseif Long2Cut.Identify( Proc) then + -- se due facce longitudinali, classifico doppio taglio longitudinale + if Long2Cut.GetLongFacesCount( Proc) == 2 then + bOk, bDown = Long2Cut.Classify( Proc) + -- altrimenti eseguo singolo taglio longitudinale + else + bOk, bDown = LongCut.Classify( Proc) + end + -- se taglio con lama + elseif SawCut.Identify( Proc) then + bOk, bDown = SawCut.Classify( Proc) + -- se mezzo-legno di testa + elseif RidgeLap.Identify( Proc) then + bOk, bDown = RidgeLap.Classify( Proc, b3Raw) + -- se scanalatura, scanalatura frontale, tacca, tacca cantonale, mezzo-legno, scanalatura-battuta, + -- mezzolegno tipo chalet-tavola di chiusura, rivestimento, mezzolegno chalet, tasca, taglio triangolato + elseif LapJoint.Identify( Proc) then + bOk, bDown = LapJoint.Classify( Proc, b3Raw) + -- se foratura + elseif Drill.Identify( Proc) then + bOk, bDown, bSide = Drill.Classify( Proc, b3Raw) + bDownSideOnHeadOk = true + -- se tenone + elseif Tenon.Identify( Proc) then + bOk, bDown = Tenon.Classify( Proc, b3Raw) + -- se giunzione francese + elseif FrenchRidgeLap.Identify( Proc) then + bOk, bDown = FrenchRidgeLap.Classify( Proc) + -- se block house front + elseif BlockHausFront.Identify( Proc) then + bOk, bDown = BlockHausFront.Classify( Proc) + -- se mortasa (anche frontale) + elseif Mortise.Identify( Proc) then + bOk, bDown = Mortise.Classify( Proc) + -- se tenone a coda di rondine + elseif DtTenon.Identify( Proc) then + bOk, bDown = DtTenon.Classify( Proc, b3Raw) + -- se mortasa a coda di rondine (anche frontale) + elseif DtMortise.Identify( Proc) then + bOk, bDown = DtMortise.Classify( Proc) + -- se marcatura + elseif Mark.Identify( Proc) then + bOk, bDown = Mark.Classify( Proc) + -- se testo + elseif Text.Identify( Proc) then + bOk, bDown = Text.Classify( Proc) + -- se giunto Gerber + elseif ScarfJoint.Identify( Proc) then + bOk, bDown = ScarfJoint.Classify( Proc) + -- se giunto Gerber + elseif Scarf.Identify( Proc) then + bOk, bDown = Scarf.Classify( Proc) + -- se giunto a gradino + elseif StepJoint.Identify( Proc) then + bOk, bDown = StepJoint.Classify( Proc) + -- se tacca a gradino + elseif StJoNotch.Identify( Proc) then + bOk, bDown = StJoNotch.Classify( Proc) + -- se arco + elseif RoundArch.Identify( Proc) then + bOk, bDown = RoundArch.Classify( Proc) + -- se incastro tirolo + elseif TyroleanDovetail.Identify( Proc) then + bOk, bDown = TyroleanDovetail.Classify( Proc, b3Raw) + -- se giunto coda di rondine + elseif Dovetail.Identify( Proc) then + bOk, bDown = Dovetail.Classify( Proc, b3Raw) + -- se profilo front + elseif ProfFront.Identify( Proc) then + bOk, bDown, bSide = ProfFront.Classify( Proc, b3Raw) + -- se profilo concavo + elseif ProfConcave.Identify( Proc) then + bOk, bDown, bSide = ProfConcave.Classify( Proc, b3Raw) + -- se profilo convesso + elseif ProfConvex.Identify( Proc) then + bOk, bDown, bSide = ProfConvex.Classify( Proc, b3Raw) + -- se profilo caudato + elseif ProfCamb.Identify( Proc) then + bOk, bDown, bSide = ProfCamb.Classify( Proc, b3Raw) + -- se profilo head + elseif ProfHead.Identify( Proc) then + bOk, bDown, bSide = ProfHead.Classify( Proc, b3Raw) + -- se contorno libero + elseif FreeContour.Identify( Proc) then + bOk, bDown, bSide = FreeContour.Classify( Proc, b3Raw) + -- se decorazione + elseif Decor.Identify( Proc) then + bOk, bDown = Decor.Classify( Proc) + end + -- assegno risultato + if bOk then + -- non ammessa feature di testa da lavorare ribaltata o ruotata + if Proc.Head and ( bDown or bSide) and not bDownSideOnHeadOk then + Proc.Flg = 0 + Proc.Down = true + bAllOk = false + table.insert( Stats, {Err = 1, Msg='Error : impossible to machine by orientation', CutId=Proc.CutId, TaskId=Proc.TaskId}) + -- gestione feature di coda da lavorare ribaltata + elseif Proc.Tail and bDown then + Proc.Down = true + bSomeDown = true + bSplitRot = true + -- gestione feature di coda da lavorare ruotata + elseif Proc.Tail and bSide then + Proc.Side = true + bSomeSide = true + bSplitRot = true + -- caso normale + else + Proc.Down = bDown + Proc.Side = bSide + if bDown then bSomeDown = true end + if bSide then bSomeSide = true end + end + elseif Proc.Flg == 0 then + bAllOk = false + Proc.ErrMsg = 'Error : out of the part' + table.insert( Stats, {Err = 1, Msg=Proc.ErrMsg, CutId=Proc.CutId, TaskId=Proc.TaskId}) + else + Proc.Flg = 0 + bAllOk = false + if not Proc.ErrMsg then Proc.ErrMsg = 'Error : impossible to machine' end + table.insert( Stats, {Err = 1, Msg=Proc.ErrMsg, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + end + -- se necessario ribaltamento, assegno intestatura alla fase ribaltata + if bSomeDown and nHeading then + vProc[nHeading].Down = true + -- se altrimenti necessaria rotazione (senza ribaltamento), assegno intestatura alla fase ribaltata (creata ad hoc) + elseif bSomeSide and nHeading then + vProc[nHeading].Down = true + bSomeDown = true + end + -- se necessaria separazione del ribaltato o ruotato, la assegno sempre alla fase ribaltata + if bSplitRot and nSplitting then + vProc[nSplitting].Down = true + bSomeDown = true + end + return bAllOk, bSomeDown, bSomeSide, bSplitRot +end + +------------------------------------------------------------------------------------------------------------- +local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut, b3Raw) + local bOk = true + local sErr = '' + local bNewPhase = false + EgtOutLog( ' * Process ' .. tostring( Proc.Id) .. ' *', 1) + -- se intestatura ( 1-340-X ) + if Hcut.Identify( Proc) then + -- esecuzione taglio di testa + bOk, sErr = Hcut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut) + -- se separazione ( 2-350-X ) + elseif Split.Identify( Proc) then + -- esecuzione separazione o eliminazione grezzo residuo + bOk, sErr = Split.Make( Proc, nPhase, nRawId, nPartId) + -- richiedo il passaggio alla seconda fase di lavorazione di questa trave + bNewPhase = true + -- se taglio ( 1/2-010-X) + elseif Cut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se doppio taglio ( 1/2-011-X) + elseif DoubleCut.Identify( Proc) then + -- esecuzione doppio taglio + bOk, sErr = DoubleCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se taglio longitudinale ( 0/3/4-010-X) + elseif LongCut.Identify( Proc) then + -- esecuzione taglio longitudinale + bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) + -- se doppio taglio longitudinale ( 0-012-X) + elseif Long2Cut.Identify( Proc) then + -- se due facce longitudinali, eseguo doppio taglio longitudinale + if Long2Cut.GetLongFacesCount( Proc) == 2 then + bOk, sErr = Long2Cut.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti eseguo singolo taglio longitudinale + else + bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) + end + -- se taglio con lama ( 0/3/4-013-X) + elseif SawCut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = SawCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mezzo-legno di testa ( 1/2-030-X) + elseif RidgeLap.Identify( Proc) then + -- esecuzione mezzo-legno di testa + bOk, sErr = RidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se fessura ( 3/4-016-X) o se fessura frontale ( 3/4-017-X) o se tacca ( 3/4-020-X) o se tacca cantonale ( 3/4-025-X) + -- o se mezzo-legno ( 3/4-030-X) o se scanalatura/battuta ( 3/4-032-X) o se mezzo legno tipo chalet/tavola di chiusura ( 3/4-033-X) + -- o se rivestimento ( 3/4-034-X) o se mezzolegno chalet ( 4-037-X) o se tasca ( 4-039-X) o se taglio triangolato ( 4-120-X) + elseif LapJoint.Identify( Proc) then + -- esecuzione mezzo-legno o scanalatura + bOk, sErr = LapJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se smusso ( 3/4-036-X) + elseif Chamfer.Identify( Proc) then + -- esecuzione smusso + bOk, sErr = Chamfer.Make( Proc, nPhase, nRawId, nPartId) + -- se foratura ( 3/4-040-X) + elseif Drill.Identify( Proc) then + -- esecuzione foratura + bOk, sErr = Drill.Make( Proc, nPhase, nRawId, nPartId) + -- se giunzione francese ( 1/2-035-X) + elseif FrenchRidgeLap.Identify( Proc) then + -- esecuzione giunzione francese + bOk, sErr = FrenchRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se block house front ( 3/4-038-X) + elseif BlockHausFront.Identify( Proc) then + -- esecuzione giunzione francese + bOk, sErr = BlockHausFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se tenone ( 1/2-050-X) + elseif Tenon.Identify( Proc) then + -- esecuzione tenone + bOk, sErr = Tenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mortasa ( 3/4-050-X) anche frontale ( 3/4-051-X) + elseif Mortise.Identify( Proc) then + -- esecuzione mortasa + bOk, sErr = Mortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se tenone a coda di rondine ( 1/2-055-X) + elseif DtTenon.Identify( Proc) then + -- esecuzione tenone + bOk, sErr = DtTenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mortasa a coda di rondine ( 3/4-055-X) anche frontale ( 3/4-056-X) + elseif DtMortise.Identify( Proc) then + -- esecuzione mortasa + bOk, sErr = DtMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se marcatura ( 3/4-060-X) + elseif Mark.Identify( Proc) then + -- esecuzione marcatura + bOk, sErr = Mark.Make( Proc, nPhase, nRawId, nPartId) + -- se testo ( 4-061-X) + elseif Text.Identify( Proc) then + -- esecuzione testo + bOk, sErr = Text.Make( Proc, nPhase, nRawId, nPartId) + -- se giunto Gerber ( 1/2-071-X) + elseif ScarfJoint.Identify( Proc) then + -- esecuzione giunto Gerber + bOk, sErr = ScarfJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se giunto Gerber ( 1/2-070-X) + elseif Scarf.Identify( Proc) then + -- esecuzione giunto Gerber + bOk, sErr = Scarf.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se giunto a gradino ( 1/2-080-X) + elseif StepJoint.Identify( Proc) then + -- esecuzione giunto a gradino + bOk, sErr = StepJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se tacca a gradino ( 3/4-080-X) + elseif StJoNotch.Identify( Proc) then + -- esecuzione tacca a gradino + bOk, sErr = StJoNotch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo Front ( 3/4-100-X) + elseif ProfFront.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo concavo ( 3/4-101-X) + elseif ProfConcave.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo convesso ( 3/4-102-X) + elseif ProfConvex.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo caudato ( 3/4-103-X) + elseif ProfCamb.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se arco ( 4-104-X) + elseif RoundArch.Identify( Proc) then + -- esecuzione arco + bOk, sErr = RoundArch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo Head ( 3/4-106-X) + elseif ProfHead.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se incastro tirolo ( 1/2/3/4-136-X) + elseif TyroleanDovetail.Identify( Proc) then + bOk, sErr = TyroleanDovetail.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se giunto coda di rondine ( 1/2/3/4-138-X) + elseif Dovetail.Identify( Proc) then + bOk, sErr = Dovetail.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se contorno libero ( 0/3/4-250-X) + elseif FreeContour.Identify( Proc) then + -- esecuzione contorno + bOk, sErr = FreeContour.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se decorazione ( 0/3/4-959-X) + elseif Decor.Identify( Proc) then + -- esecuzione decorazione + bOk, sErr = Decor.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti feature sconosciuta + else + sErr = 'Error on process ' .. tostring( Proc.Id) .. ' unknown type (' .. tonumber( Proc.Grp) .. '-' .. tonumber( Proc.Prc) .. ')' + EgtOutLog( sErr) + bOk = false + end + return bOk, sErr, bNewPhase +end + +------------------------------------------------------------------------------------------------------------- +local function VerifyNeedForHeadCut( vProc, bSomeDown, bSomeSide) + -- verifico se necessaria la rotazione di 90 gradi + if not bSomeSide then + return false + end + -- verifico se viene dopo un pezzo diviso quando ruotato (quindi con rimanenza scaricata sul carico) + local nPrevPhase = EgtGetCurrPhase() - 1 + local nPrevDispId = EgtGetPhaseDisposition( nPrevPhase) or GDB_ID.NULL + local nPrevType = EgtGetInfo( nPrevDispId, 'TYPE') + if nPrevType ~= 'MID2' and nPrevType ~= 'END2' then + return false + end + -- verifico se c'è una sola lavorazione ribaltata (quindi è il taglio di testa) + local nDownCnt = 0 + for i = 1, #vProc do + if vProc[i].Down then + nDownCnt = nDownCnt + 1 + end + end + return ( nDownCnt == 1) +end + +------------------------------------------------------------------------------------------------------------- +local function SetCutsOnFrontMortises( vProc) + -- ciclo sulle feature + for i = 1, #vProc do + if vProc[i].Fct > 0 and Cut.Identify( vProc[i]) then + for j = 1, #vProc do + if vProc[j].Fct > 0 and Mortise.FrontIdentify( vProc[j]) then + -- se esiste intersezione tra le due features + if vProc[i].Box:getMin():getX() < vProc[j].Box:getMax():getX() + 100 * GEO.EPS_SMALL and + vProc[j].Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL then + -- recupero il piano del taglio + local ptC1, vtN1 = Cut.GetCutPlane( vProc[i]) + -- recupero il piano frontale della mortasa + local ptC2, vtN2 = Mortise.GetCutPlane( vProc[j]) + -- verifico se i piani coincidono + local bSamePlane = ( ptC1 and vtN1 and ptC2 and vtN2 and AreSameVectorApprox( vtN1, vtN2) and ( ptC2 - ptC1) * vtN1 < 1.0) + if bSamePlane then + vProc[i].CutFront = vProc[j].Id + end + -- log + local sMsg = string.format( 'Cut %d meet Mortise %d', vProc[i].Id, vProc[j].Id) .. EgtIf( bSamePlane, ' with same plane', '') + EgtOutLog( sMsg, 3) + end + elseif vProc[j].Fct > 0 and DtMortise.FrontIdentify( vProc[j]) then + -- se esiste intersezione tra le due features + if vProc[i].Box:getMin():getX() < vProc[j].Box:getMax():getX() + 100 * GEO.EPS_SMALL and + vProc[j].Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL then + -- recupero il piano del taglio + local ptC1, vtN1 = Cut.GetCutPlane( vProc[i]) + -- recupero il piano frontale della mortasa + local ptC2, vtN2 = DtMortise.GetCutPlane( vProc[j]) + -- verifico se i piani coincidono + local bSamePlane = ( ptC1 and vtN1 and ptC2 and vtN2 and AreSameVectorApprox( vtN1, vtN2) and ( ptC2 - ptC1) * vtN1 < 1.0) + if bSamePlane then + vProc[i].CutFront = vProc[j].Id + end + -- log + local sMsg = string.format( 'Cut %d meet DtMortise %d', vProc[i].Id, vProc[j].Id) .. EgtIf( bSamePlane, ' with same plane', '') + EgtOutLog( sMsg, 3) + end + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +local function MoveDrillsOnTenon( vProc) + -- se non richiesto spostamento fori su tenone, esco + if not BD.OFFSET_DRILL_TENON or abs( BD.OFFSET_DRILL_TENON) < 0.1 then return end + -- ciclo sulle feature + for i = 1, #vProc do + if vProc[i].Flg ~= 0 and Tenon.Identify( vProc[i]) then + for j = 1, #vProc do + if Drill.Identify( vProc[j]) then + -- se esiste intersezione tra tenone e foro + if vProc[i].Box:getMin():getX() < vProc[j].Box:getMax():getX() + 100 * GEO.EPS_SMALL and + vProc[j].Box:getMin():getX() < vProc[i].Box:getMax():getX() + 100 * GEO.EPS_SMALL then + -- verifico se foro già spostato + if not EgtExistsInfo( vProc[j].Id, 'MOV') then + -- recupero curva ausiliaria del foro + local AuxDriId = EgtGetInfo( vProc[j].Id, 'AUXID', 'i') + AuxDriId = EgtIf( AuxDriId, AuxDriId + vProc[j].Id, nil) + -- recupero versore normale del tenone + local AuxTenId = EgtGetInfo( vProc[i].Id, 'AUXID', 'i') + AuxTenId = EgtIf( AuxTenId, AuxTenId + vProc[i].Id, GDB_ID.NULL) + local vtExtr = EgtCurveExtrusion( AuxTenId, GDB_RT.GLOB) + -- se tutto ok, eseguo spostamento + if AuxDriId and vtExtr then + local vtMove = -vtExtr * BD.OFFSET_DRILL_TENON + EgtMove( AuxDriId, vtMove, GDB_RT.GLOB) + EgtSetInfo( vProc[j].Id, 'MOV', vtMove) + end + end + end + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamExec.ProcessFeatures() + -- verifica se possibile rotazione di 90 gradi + BD.ROT90 = BD.ROT90 and Verify90DegRotation( EgtGetFirstRawPart()) + -- ciclo sui pezzi + local nTotErr = 0 + local Stats = {} + local nOrd = 1 + local nRawId = EgtGetFirstRawPart() + while nRawId do + -- verifico che il grezzo contenga pezzi oppure sia abbastanza lungo da essere scaricato coi carrelli + local nPartId = EgtGetFirstPartInRawPart( nRawId) + if not nPartId and EgtGetRawPartBBox( nRawId):getDimX() < BD.MinRaw then break end + -- aggiungo la fase, se non è la prima + if nOrd == 1 then + EgtSetCurrPhase( 1) + else + BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, 0) + end + local nPhase = EgtGetCurrPhase() + local nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', EgtIf( nPartId, 'START', 'REST')) + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( nRawId) .. ' Part=' .. tostring( nPartId) .. ' ***', 1) + -- ingombro del grezzo e sovramateriale di testa + local b3Raw = EgtGetRawPartBBox( nRawId) + local dCurrOvmH = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 + -- recupero le feature di lavorazione della trave + local vProc = CollectFeatures( nPartId, b3Raw, dCurrOvmH) + -- le ordino lungo X + OrderFeatures( vProc, b3Raw) + -- le classifico + local bAllOk, bSomeDown, bSomeSide, bSplitRot = ClassifyFeatures( vProc, b3Raw, Stats) + if not bAllOk then + nTotErr = nTotErr + 1 + end + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc, b3Raw) + end + EgtOutLog( ' *** AddMachinings ***', 1) + -- verifico se comunque necessario taglio di testa + local bNeedHCut = VerifyNeedForHeadCut( vProc, bSomeDown, bSomeSide) + -- inserisco corrispondenze di tagli coincidenti con mortase normali o a coda di rondine di testa + SetCutsOnFrontMortises( vProc) + -- eventuale spostamento fori sui tenoni + MoveDrillsOnTenon( vProc) + -- se richiesto ribaltamento (oppure rotazione) + if ( bSomeDown or bSomeSide) and not BD.DOWN_HEAD then + -- ribalto le travi della fase corrente + local nRId = nRawId + while nRId do + EgtRotateRawPart( nRId, X_AX(), 180) + nRId = EgtGetNextRawPart( nRId) + end + EgtSetInfo( nDispId, 'ROT', -2) + -- inserisco le lavorazioni da lavorare ribaltate + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and Proc.Down then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, bNeedHCut, b3Raw) + if not bOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + elseif sMsg and #sMsg > 0 then + table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + else + table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET) + EgtRotateRawPart( nRawId, X_AX(), 180) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'MID2') + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtSetInfo( nDispId, 'ROT', -2) + end + end + end + -- se separazione non ancora effettuata, aggiungo nuova fase con le travi in posizione standard + if not bSplitRot then + BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, 0) + -- altrimenti + else + -- aggiungo nuova fase con le travi in posizione standard + BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + local nType = 'MID' + if bSplitRot then nType = EgtIf( bSomeSide, 'MID2', 'END2') end + EgtSetInfo( nDispId, 'TYPE', nType) + EgtSetInfo( nDispId, 'ORD', nOrd) + end + -- se richiesta rotazione + if bSomeSide and not BD.DOWN_HEAD then + -- vettore movimento grezzi per rotazione di 90deg + local dDeltaYZ = EgtGetRawPartBBox( nRawId):getDimY() - EgtGetRawPartBBox( nRawId):getDimZ() + local vtMove = Vector3d( 0, dDeltaYZ / 2, dDeltaYZ / 2) + local bPreMove = ( dDeltaYZ < 0) + -- ruoto le travi della fase corrente + local nRId = nRawId + while nRId do + if bPreMove then EgtMoveRawPart( nRId, vtMove) end + EgtRotateRawPart( nRId, X_AX(), EgtIf( BD.RIGHT_LOAD, -90, 90)) + if not bPreMove then EgtMoveRawPart( nRId, vtMove) end + nRId = EgtGetNextRawPart( nRId) + end + EgtSetInfo( nDispId, 'ROT', -1) + -- inserisco le lavorazioni da lavorare ruotate + local nSideMchOk = 0 + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and Proc.Side then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, false, b3Raw) + if not bOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + elseif sMsg and #sMsg > 0 then + table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + else + table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + if bOk then nSideMchOk = nSideMchOk + 1 end + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET) + if bPreMove then EgtMoveRawPart( nRawId, vtMove) end + EgtRotateRawPart( nRawId, X_AX(), EgtIf( BD.RIGHT_LOAD, -90, 90)) + if not bPreMove then EgtMoveRawPart( nRawId, vtMove) end + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'MID2') + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtSetInfo( nDispId, 'ROT', -1) + end + end + end + -- se non sono state inserite lavorazioni di fianco, elimino la fase perchè inutile e dannosa + if nSideMchOk == 0 then + EgtRemoveLastPhase() + end + -- se separazione non ancora effettuata, aggiungo nuova fase con le travi in posizione standard + if not bSplitRot then + BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, 0) + -- altrimenti + else + BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', EgtIf( not bSplitRot, 'MID', 'END2')) + EgtSetInfo( nDispId, 'ORD', nOrd) + end + -- inserisco le lavorazioni non ribaltate della trave + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.Flg ~= 0 and ( not ( Proc.Down or Proc.Side) or BD.DOWN_HEAD) then + local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, false, 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 + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'END') + EgtSetInfo( nDispId, 'ORD', nOrd) + end + end + end + EgtOutLog( ' *** End AddMachinings ***', 1) + -- passo al grezzo successivo + nOrd = nOrd + 1 + nRawId = EgtGetNextRawPart( nRawId) + end + + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings() + -- eventuale ricalcolo per macchine tipo PF (ma tengo warning del primo calcolo) + if EgtExistsInfo( EgtGetCurrMachGroup(), 'RECALC') then + EgtOutLog( ' **** RECALC ****') + bApplOk, sApplErrors, _ = EgtApplyAllMachinings() + EgtRemoveInfo( EgtGetCurrMachGroup(), 'RECALC') + end + if not bApplOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err = 1, Msg=sApplErrors, Rot=0, CutId=0, TaskId=0}) + elseif sApplWarns and #sApplWarns > 0 then + local vLine = EgtSplitString( sApplWarns, '\r\n') + for i = 1, #vLine do + local nPos = vLine[i]:find( '(WRN', 1, true) + if nPos then + local sData = vLine[i]:sub( nPos + 1, -2) + local vVal = EgtSplitString( sData, ',') + local nWarn = EgtGetVal( vVal[1] or '', 'WRN', 'i') + local nCutId = EgtGetVal( vVal[2] or '', 'CUTID', 'i') + if nWarn and nCutId then + table.insert( Stats, { Err=-nWarn, Msg=vLine[i], Rot=0, CutId=nCutId, TaskId=0}) + end + end + end + end + + return ( nTotErr == 0), Stats +end + +------------------------------------------------------------------------------------------------------------- +return BeamExec diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/BeamLib.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/BeamLib.lua new file mode 100644 index 0000000..ebc34a1 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/BeamLib.lua @@ -0,0 +1,727 @@ +-- BeamLib.lua by Egaltech s.r.l. 2022/04/05 +-- Libreria globale per Travi +-- 2020/07/28 Corretto calcolo attacchi e uscite di lame per non uscire dalla faccia sotto. +-- 2020/08/18 Aggiunto a GetNearestParalOpposite e GetNearestOrthoOpposite parametro opzionale vtNorm. +-- 2020/11/03 Aggiunta funzione IsEndOrEnd2Phase. +-- 2020/11/18 Correzioni a GetParallelOpposite e a GetFaceElevation. +-- 2021/06/27 Aggiunta funzione GetOtherFaceElevation. +-- 2021/07/01 In GetNearestOrthoOpposite premio direzioni destra/sinistra. +-- 2021/07/15 Aggiunta GetFaceElevationFromPointDir. +-- 2021/09/12 Aggiustamenti in GetNearestParalOpposite e GetNearestOrthoOpposite. +-- 2022/01/11 In GetNearest*Opposite ridotto vantaggio XY rispetto a Z da 1 -> 0.9 a 1 -> 0.99. +-- 2022/04/05 Modifiche a GetNzLimDownUp per FAST. + +-- Tabella per definizione modulo +local BeamLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' BeamLib started', 1) + +-- Dati +local BD = require( 'BeamData') + +------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetAddGroup( PartId) + -- recupero il nome del gruppo di lavoro corrente + local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL) + if not sMchGrp then return nil, nil end + -- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco + local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp) + -- restituisco Id e Nome + return AddGrpId, sMchGrp +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.CreateOrEmptyAddGroup( PartId) + -- recupero i dati del gruppo aggiuntivo + local AddGrpId, sMchGrp = BeamLib.GetAddGroup( PartId) + if not sMchGrp then return false end + -- se esiste, aggiorno riferimento al gruppo di lavoro e lo svuoto + if AddGrpId then + EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup()) + return EgtEmptyGroup( AddGrpId) + end + -- altrimenti lo creo + AddGrpId = EgtGroup( PartId or GDB_ID.NULL) + if not AddGrpId then return false end + -- assegno nome, flag di layer per gruppo di lavoro e colore + EgtSetName( AddGrpId, sMchGrp) + EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup()) + EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 50)) + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPartStartFace( PartId, b3Solid) + -- recupero gruppo per geometria aggiuntiva + local AddGrpId = BeamLib.GetAddGroup( PartId) + if not AddGrpId then + local sErr = 'Error on process StartFace impossible to find AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo nuovo taglio iniziale + local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMax(), X_AX(), b3Solid, GDB_RT.GLOB) + if not nStmId then + local sErr = 'Error on process StartFace impossible to create Face' + EgtOutLog( sErr) + return false, sErr + end + -- applico gli opportuni attributi di feature + EgtSetName( nStmId, 'StartCut') + EgtSetInfo( nStmId, 'GRP', 1) + EgtSetInfo( nStmId, 'PRC', 340) + -- verifico se sostituisce un taglio di testa già presente + local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PartId, 'Processings') or GDB_ID.NULL) + while nProcId do + local nGrp = EgtGetInfo( nProcId, 'GRP', 'i') or 0 + local nProc = EgtGetInfo( nProcId, 'PRC', 'i') or 0 + if ( nGrp == 1 or nGrp == 2) and nProc == 10 then + local ptC, vtN = EgtSurfTmFacetCenter( nProcId, 0, GDB_ID.ROOT) + if ptC and vtN and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL then + EgtSetInfo( nStmId, 'ORI', nProcId) + end + end + nProcId = EgtGetNext( nProcId) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPartEndFace( PartId, b3Solid) + -- recupero gruppo per geometria aggiuntiva + local AddGrpId = BeamLib.GetAddGroup( PartId) + if not AddGrpId then + local sErr = 'Error on process EndFace impossible to find AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo nuovo taglio finale + local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMin(), -X_AX(), b3Solid, GDB_RT.GLOB) + if not nStmId then + local sErr = 'Error on process EndFace impossible to create Face' + EgtOutLog( sErr) + return false, sErr + end + -- applico gli opportuni attributi di feature + EgtSetName( nStmId, 'EndCut') + EgtSetInfo( nStmId, 'GRP', 2) + EgtSetInfo( nStmId, 'PRC', 350) + -- verifico se sostituisce un taglio di coda già presente + local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PartId, 'Processings') or GDB_ID.NULL) + while nProcId do + local nGrp = EgtGetInfo( nProcId, 'GRP', 'i') or 0 + local nProc = EgtGetInfo( nProcId, 'PRC', 'i') or 0 + if ( nGrp == 1 or nGrp == 2) and nProc == 10 then + local ptC, vtN = EgtSurfTmFacetCenter( nProcId, 0, GDB_ID.ROOT) + if ptC and vtN and AreSameVectorApprox( vtN, -X_AX()) and abs( ptC:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL then + EgtSetInfo( nStmId, 'ORI', nProcId) + end + end + nProcId = EgtGetNext( nProcId) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPhaseWithRawParts( nFirstRawId, OriXR, PosXR, dDeltaSucc) + EgtAddPhase() + local nRawId = nFirstRawId + local dRawMove = 0 + while nRawId do + EgtKeepRawPart( nRawId) + EgtMoveToCornerRawPart( nRawId, OriXR, PosXR) + EgtMoveRawPart( nRawId, Vector3d( - dRawMove, 0, 0)) + if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end + dRawMove = dRawMove + EgtGetRawPartBBox( nRawId):getDimX() + nRawId = EgtGetNextRawPart( nRawId) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartOnTop( nCrvId) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- cerco l'estremo più alto e lo imposto come inizio + local dUmax = 0 + local dZmax = - GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf, 0.5 do + local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) + if ptP and ptP:getZ() > dZmax + GEO.EPS_SMALL then + dZmax = ptP:getZ() + dUmax = dU + end + end + if abs( dUmax - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUmax) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartOnLonger( nCrvId) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- cerco l'entità più lunga e la imposto come inizio + local dUmax = 0 + local dLmax = - GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf - 1 do + local ptP1 = EgtUP( nCrvId, dU, GDB_ID.ROOT) + local ptP2 = EgtUP( nCrvId, dU + 0.5, GDB_ID.ROOT) + local ptP3 = EgtUP( nCrvId, dU + 1.0, GDB_ID.ROOT) + local dL = dist( ptP1, ptP2) + dist( ptP2, ptP3) + if dL > dLmax + GEO.EPS_SMALL then + dLmax = dL + dUmax = dU + end + end + if abs( dUmax - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUmax) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw, bDown) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- recupero il versore normale al piano di lavoro o estrusione + local vtN = EgtCurveExtrusion( nCrvId, GDB_ID.ROOT) + -- coefficienti per riportare la distanza nel piano di lavoro + local dCoeffX = 1 / ( sqrt( 1 - vtN:getX() * vtN:getX())) + local dCoeffY = 1 / ( sqrt( 1 - vtN:getY() * vtN:getY())) + local dCoeffZ = 1 / ( sqrt( 1 - vtN:getZ() * vtN:getZ())) + -- cerco l'estremo più vicino al box e lo imposto come inizio (se da sotto escludo Zmax e viceversa) + local dUopt = 0 + local dDopt = GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf, 0.5 do + local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) + if ptP then + local vtMin = ptP - b3Raw:getMin() + local vtMax = ptP - b3Raw:getMax() + local dD = abs( vtMin:getX()) * dCoeffX + dD = min( abs( vtMax:getX()) * dCoeffX, dD) + dD = min( abs( vtMin:getY()) * dCoeffY, dD) + dD = min( abs( vtMax:getY()) * dCoeffY, dD) + if bDown then + dD = min( abs( vtMin:getZ()) * dCoeffZ, dD) + else + dD = min( abs( vtMax:getZ()) * dCoeffZ, dD) + end + if dD < dDopt + GEO.EPS_SMALL then + dDopt = dD + dUopt = dU + end + end + end + if abs( dUopt - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUopt) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetPointDirDepth( nPartId, ptP, vtDir) + -- recupero il solido del grezzo + local nSolId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, 'Box') + if not nSolId then return end + -- interseco con la retta + local bOk, vType, vPar = EgtLineSurfTmInters( ptP, vtDir, nSolId, GDB_RT.GLOB) + if not bOk then return end + if not vPar or #vPar == 0 then return -2 end + local dLenIn, dLenOut + for i = 1, #vPar do + if vPar[i] < 0 then + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = -1 + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN then + dLenIn = -2 + end + else + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = vPar[i] + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN or vType[i] == GDB_SLT.TOUCH then + dLenOut = vPar[i] + end + end + end + return dLenIn, dLenOut +end + +--------------------------------------------------------------------- +function BeamLib.GetNearestParalOpposite( vtRef, vtNorm) + -- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa + local vtMyRef = Vector3d( vtRef) + if vtNorm then + vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm + vtMyRef:normalize() + end + -- se prevalente una componente orizzontale (con piccolissimo vantaggio) + if abs( vtMyRef:getX()) > 0.99 * abs( vtMyRef:getZ()) or abs( vtMyRef:getY()) > 0.99 * abs( vtMyRef:getZ()) then + if abs( vtMyRef:getX()) > abs( vtMyRef:getY()) - GEO.EPS_SMALL then + if vtMyRef:getX() > -GEO.EPS_SMALL then + return MCH_MILL_FU.PARAL_LEFT + else + return MCH_MILL_FU.PARAL_RIGHT + end + else + if vtMyRef:getY() > -GEO.EPS_SMALL then + return MCH_MILL_FU.PARAL_FRONT + else + return MCH_MILL_FU.PARAL_BACK + end + end + -- altrimenti prevale la verticale + else + if vtMyRef:getZ() > -GEO.EPS_SMALL then + return MCH_MILL_FU.PARAL_DOWN + else + return MCH_MILL_FU.PARAL_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetNearestOrthoOpposite( vtRef, vtNorm) + -- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa + local vtMyRef = Vector3d( vtRef) + if vtNorm then + vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm + vtMyRef:normalize() + end + -- se prevalente una componente orizzontale (con piccolissimo vantaggio) + if abs( vtMyRef:getX()) > 0.99 * abs( vtMyRef:getZ()) or abs( vtMyRef:getY()) > 0.99 * abs( vtMyRef:getZ()) then + -- se prevale la componente destra/sinistra (con piccolo vantaggio) + if abs( vtMyRef:getX()) > 0.9 * abs( vtMyRef:getY()) then + if vtMyRef:getX() > -GEO.EPS_SMALL then + return MCH_MILL_FU.ORTHO_LEFT + else + return MCH_MILL_FU.ORTHO_RIGHT + end + else + if vtMyRef:getY() > -GEO.EPS_SMALL then + return MCH_MILL_FU.ORTHO_FRONT + else + return MCH_MILL_FU.ORTHO_BACK + end + end + -- altrimenti prevale la verticale + else + if vtMyRef:getZ() > -GEO.EPS_SMALL then + return MCH_MILL_FU.ORTHO_DOWN + else + return MCH_MILL_FU.ORTHO_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetOrtupOpposite( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return MCH_MILL_FU.ORTUP_LEFT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return MCH_MILL_FU.ORTUP_RIGHT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return MCH_MILL_FU.ORTUP_FRONT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return MCH_MILL_FU.ORTUP_BACK + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return MCH_MILL_FU.ORTUP_DOWN + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return MCH_MILL_FU.ORTUP_TOP + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetParallelOpposite( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return MCH_MILL_FU.PARAL_LEFT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return MCH_MILL_FU.PARAL_RIGHT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return MCH_MILL_FU.PARAL_FRONT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return MCH_MILL_FU.PARAL_BACK + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return MCH_MILL_FU.PARAL_DOWN + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return MCH_MILL_FU.PARAL_TOP + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetVersRef( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return X_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return -X_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return Y_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return -Y_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return Z_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return -Z_AX() + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetBoxFaceNorm( b3Box, ptP, vtV) + local vtNx = V_NULL() + if abs( ptP:getX() - b3Box:getMin():getX()) < 10 * GEO.EPS_SMALL then + vtNx = -X_AX() + elseif abs( ptP:getX() - b3Box:getMax():getX()) < 10 * GEO.EPS_SMALL then + vtNx = X_AX() + end + local vtNy = V_NULL() + if abs( ptP:getY() - b3Box:getMin():getY()) < 10 * GEO.EPS_SMALL then + vtNy = -Y_AX() + elseif abs( ptP:getY() - b3Box:getMax():getY()) < 10 * GEO.EPS_SMALL then + vtNy = Y_AX() + end + local vtNz = V_NULL() + if abs( ptP:getZ() - b3Box:getMin():getZ()) < 10 * GEO.EPS_SMALL then + vtNz = -Z_AX() + elseif abs( ptP:getZ() - b3Box:getMax():getZ()) < 10 * GEO.EPS_SMALL then + vtNz = Z_AX() + end + local dNxDotV = vtNx * vtV + local dNyDotV = vtNy * vtV + local dNzDotV = vtNz * vtV + if dNxDotV > dNyDotV and dNxDotV > dNzDotV then + return vtNx + elseif dNyDotV > dNzDotV then + return vtNy + else + return vtNz + end +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceElevation( nSurfId, nFac, nPartId) + -- centro e normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFac, GDB_ID.ROOT) + if not ptC or not vtN then return 0 end + -- riferimento OCS della faccia per ricavare elevazione rispetto alla faccia della superficie + local frOCS = Frame3d( ptC, vtN) + local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS) + local dElev = b3Box:getMax():getZ() + -- se definito identificativo di pezzo + if nPartId then + -- se superficie con più facce + if EgtSurfTmFacetCount( nSurfId) > 1 then + -- determino elevazione del centro faccia rispetto al box del pezzo + local _, dCenElev = BeamLib.GetPointDirDepth( nPartId, ptC, vtN) + if dCenElev and dCenElev > dElev then + dElev = dCenElev + end + -- altrimenti superficie ad una sola faccia + else + -- determino elevazione box del pezzo rispetto alla faccia + local b3Solid = EgtGetBBoxRef( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD, frOCS) + local dSolidElev = b3Solid:getMax():getZ() + if b3Solid and dSolidElev > dElev then + dElev = dSolidElev + end + end + end + return dElev +end + +--------------------------------------------------------------------- +function BeamLib.GetOtherFaceElevation( nSurfId, nOtherSurfId, nOtherFac, nPartId) + -- centro e normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nOtherSurfId, nOtherFac, GDB_ID.ROOT) + if not ptC or not vtN then return 0 end + -- riferimento OCS della faccia per ricavare elevazione rispetto alla faccia della superficie + local frOCS = Frame3d( ptC, vtN) + local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS) + local dElev = b3Box:getMax():getZ() + -- se definito identificativo di pezzo + if nPartId then + -- determino elevazione del centro faccia rispetto al box del pezzo + local _, dCenElev = BeamLib.GetPointDirDepth( nPartId, ptC, vtN) + if dCenElev and dCenElev > dElev then + dElev = dCenElev + end + end + return dElev +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceElevationFromPointDir( nSurfId, nPartId, ptC, vtN, nIdGeomMaster) + if not ptC or not vtN then return 0 end + -- riferimento OCS della faccia per ricavare elevazione rispetto alla faccia della superficie + local frOCS = Frame3d( ptC, vtN) + local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS) + local dElev = b3Box:getMax():getZ() + -- se definito identificativo di pezzo + if nPartId then + -- se superficie con più facce + if EgtSurfTmFacetCount( nSurfId) > 1 then + _, dElev = BeamLib.GetPointDirDepth( nPartId, ptC, vtN) + else + local b3Solid = EgtGetBBoxRef( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD, frOCS) + if b3Solid and b3Solid:getMax():getZ() > dElev then + dElev = b3Solid:getMax():getZ() + end + end + end + return dElev +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc, dCosSideAng) + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nSurfId) + if not dCosSideAng then + dCosSideAng = -0.09 + end + -- recupero le normali delle facce + local vvtN = {} + for i = 1, nFacCnt do + local vtN = EgtSurfTmFacetNormVersor( nSurfId, i - 1, GDB_ID.ROOT) + vvtN[i] = vtN ; + end + -- adiacenze e sottosquadra delle facce + local vAdj = {} + local vUcut = {} + local vOrtho = {} + for i = 1, nFacCnt do + -- recupero le adiacenze del loop esterno + local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + vAdj[i] = nCount + -- ne determino eventuale sottosquadra ( dal valore passato o - 3deg) e ortogonalità + local bUcut = false + local bOrtho = true + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + local vtN = vvtN[i] + local vtN2 = vvtN[vFacAdj[j]+1] + local dResV = vtN * vtN2 + if dResV < dCosSideAng - GEO.EPS_SMALL then + bUcut = true + end + if abs( dResV) > 2 * GEO.EPS_SMALL then + bOrtho = false + end + end + end + vUcut[i] = bUcut + vOrtho[i] = bOrtho + end + -- se 4 facce tutte con adiacenza 2, allora è un tunnel + if nFacCnt == 4 then + if vAdj[1] == 2 and vAdj[2] == 2 and vAdj[3] == 2 and vAdj[4] == 2 then + -- se tutte le facce sono ortogonali tra loro esco con un flag che ne indica questa propietà + if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true and vOrtho[4] == true then + return -1, GEO.INFINITO, true + else + return -1, GEO.INFINITO + end + end + end + -- se 3 facce con una che ha 2 adiacenze e le altre hanno 1 adiacenza, allora è una semi-fessura + if bCompare3Fc and nFacCnt == 3 then + local nCount2Adc = 0 + local nCount1Adc = 0 + -- ottengo il numero di facce con due adiacenze e il numero di facce con una adiacenza + for i = 1, #vAdj do + if vAdj[i] == 2 then + nCount2Adc = nCount2Adc + 1 + elseif vAdj[i] == 1 then + nCount1Adc = nCount1Adc + 1 + end + end + -- se il numero di adiacenze corrisponde + if nCount2Adc == 1 and nCount1Adc == 2 then + if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true then + return -1, GEO.INFINITO, true + else + return -1, GEO.INFINITO + end + end + end + -- recupero le facce non in sottosquadra e con il maggior numero di adiacenze + local nFacInd = {} + local nMaxAdj = -1 + local nSupAdj = -1 + for i = 1, nFacCnt do + if not vUcut[i] then + if vAdj[i] > nMaxAdj then + nFacInd = {} + nFacInd[1] = i - 1 + nMaxAdj = vAdj[i] + elseif vAdj[i] == nMaxAdj and nMaxAdj > 0 then + table.insert( nFacInd, i - 1) + end + end + if vAdj[i] > nSupAdj then + nSupAdj = vAdj[i] + end + end + -- verifico non ci sia una faccia in sottosquadra con adiacenza superiore + if nSupAdj > nMaxAdj then + return -2, GEO.INFINITO + end + -- premio la faccia con minore elevazione + local nFacOpt, nFacOpt2 + local dMinElev, dMinElev2 = GEO.INFINITO, GEO.INFINITO + local dtElev = {} + for i = 1, #nFacInd do + local dElev = BeamLib.GetFaceElevation( nSurfId, nFacInd[i], nPartId) + table.insert( dtElev, dElev) + if dElev < dMinElev then + if dMinElev < dMinElev2 then + nFacOpt2 = nFacOpt + dMinElev2 = dMinElev + end + nFacOpt = nFacInd[i] + dMinElev = dElev + elseif dElev < dMinElev2 then + nFacOpt2 = nFacInd[i] + dMinElev2 = dElev + end + end + -- faccio una ulteriore verifica + -- se le elevazioni di max 3 facce sono in un range minimo o al di sotto dell'elevazione ritenuta fattibile, + -- premio quella che non è sottosquadra e che ha la X minore + local bDiffSmall = true + for i = 1, #dtElev do + if dtElev[i] > dMinElev + 5 or dtElev[i] > 80 then + bDiffSmall = false + end + end + -- se tutte sono nel range minimo posso prendere la faccia che ha la componente Z magiore, e se sono uguali, prendo quella con componente X minore + local dMaxZ, dMaxZ2 = -1.1, -1.1 + if bDiffSmall and #nFacInd <= 3 then + for i = 1, #nFacInd do + if vvtN[nFacInd[i]+1]:getZ() > dMaxZ then + if dMaxZ > dMaxZ2 then + nFacOpt2 = nFacOpt + dMinElev2 = dMinElev + dMaxZ2 = dMaxZ + end + nFacOpt = nFacInd[i] + dMinElev = dtElev[i] + dMaxZ = vvtN[nFacInd[i]+1]:getZ() + elseif vvtN[nFacInd[i]+1]:getZ() > dMaxZ2 then + nFacOpt2 = nFacInd[i] + dMinElev2 = dtElev[i] + dMaxZ2 = vvtN[nFacInd[i]+1]:getZ() + end + end + -- se hanno uguale Z premio quella con la componente X minore + if abs( dMaxZ - dMaxZ2) < 10*GEO.EPS_SMALL then + if abs(vvtN[nFacOpt+1]:getX()) > abs(vvtN[nFacOpt2+1]:getX()) then + nFacOpt, nFacOpt2 = nFacOpt2, nFacOpt + dMinElev, dMinElev2 = dMinElev2, dMinElev + end + end + end + + return nFacOpt, dMinElev, nFacOpt2, dMinElev2 +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceHvRefDim( nSurfId, nFacet) + -- recupero centro e normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + if not ptC or not vtN then return end + -- riferimento tipo OCS della faccia (X orizz, Y max pendenza, Z normale) + local frHV = Frame3d( ptC, vtN) + if frHV:getVersY():getZ() < 0 then + frHV:rotate( ptC, vtN, 180) + end + -- determino l'ingombro in questo riferimento + local b3HV = EgtSurfTmGetFacetBBoxRef( nSurfId, nFacet, GDB_BB.STANDARD, frHV) + -- restituisco i valori calcolati + return frHV, b3HV:getDimX(), b3HV:getDimY() +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.UpdateHCING( nRawId, dHCI, dDist) + local dOldHCI = EgtGetInfo( nRawId, 'HCING', 'd') or 0 + if dDist and dDist > dOldHCI + 0.1 then + return + end + if dHCI > dOldHCI then + EgtSetInfo( nRawId, 'HCING', dHCI) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.UpdateTCING( nRawId, dTCI) + local dOldTCI = EgtGetInfo( nRawId, 'TCING', 'd') or 0 + if dTCI > dOldTCI then + EgtSetInfo( nRawId, 'TCING', dTCI) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetNzLimDownUp( b3Raw, vtN, vtOrtho) + if not BD.C_SIMM then + if vtOrtho and vtOrtho:getZ() > 0.5 then + if vtN and ( abs( vtN:getY()) < 0.1 or abs( vtN:getY()) > 0.49) then + return -0.708 + else + return EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM, -0.609, -0.383) + end + else + if vtN and ( abs( vtN:getY()) > 0.866) then + return -0.708 + else + if b3Raw:getDimZ() < 200 then + return -0.5 + elseif b3Raw:getDimZ() < BD.MIN_DIM_HBEAM then + return -0.258 + else + return -0.174 + end + end + end + else + return -0.484 + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.IsSplittedPartPhase( nPhase) + local sVal = BeamLib.GetPhaseType( nPhase) + return ( sVal == 'END' or sVal == 'MID2' or sVal == 'END2') +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.IsPartFinalPhase( nPhase) + local sVal = BeamLib.GetPhaseType( nPhase) + return ( sVal == 'END' or sVal == 'END2') +end + +--------------------------------------------------------------------- +function BeamLib.GetPhaseType( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '') +end + +------------------------------------------------------------------------------------------------------------- +return BeamLib diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/DiceCut.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/DiceCut.lua new file mode 100644 index 0000000..255a1d1 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/DiceCut.lua @@ -0,0 +1,641 @@ +-- DiceCut.lua by Egaltech s.r.l. 2022/02/18 +-- Gestione dei piano paralleli nei tagli lunghi: equidistanziamento dei piani paralleli + +-- Tabella per definizione modulo +local DiceCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' DiceCut started', 1) + +-- Dati +local BD = require( 'BeamData') + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- creo i piani paralleli +-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptC: il punto centrale del piano della feature +-- vtN: il versore normale del piano della feature +-- nCopyPlane: 0 => genera una copia del piano passato, 1=> non genera una copia del piano passato +-- dOffset: offset dei piani paralleli +-- nStep: numero massimo di step +-- Color: colre del fascio di piani +-- dTolerance*: distanza tra i piani paralleli e i piani di taglio (se non esistono altre superfici può essere omesso) +-- bNoTolOnFirstCut*: elimina la tolleranza per il primo piano del fascio (se non esistono altre superfici può essere omesso) +-- ptCCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +local function GetParallelPlanes( nParent, BBoxRawPart, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) + local ptMyCCut + local AreaMin = 5*5 + if ptCCut and vtNCut then + if dTolerance then + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + ptMyCCut = Point3d( ptCCut) + end + local ptMyCCut1 + if ptCCut1 and vtNCut1 then + ptMyCCut1 = Point3d( ptCCut1 + 0 * vtNCut1) + end + local TabellaTmSurfParallel = {} + local i = nCopyPlane + while i < nStep do + local SurfId = EgtSurfTmPlaneInBBox( nParent, ptC + ( i * dOffset) * vtN, vtN, BBoxRawPart, GDB_RT.GLOB) + local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL) + if nFacet == 0 then + -- se sono al primo taglio do una possibilità in più di girare + if i > nCopyPlane then + break + end + end + if nFacet > 0 and vtNCut and ptMyCCut and EgtSurfArea(SurfId) > AreaMin then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut, -vtNCut, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut, -vtNCut, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and vtNCut1 and ptMyCCut1 and EgtSurfArea(SurfId) > AreaMin then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut1, -vtNCut1, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut1, -vtNCut1, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and EgtSurfArea(SurfId) > AreaMin then + table.insert( TabellaTmSurfParallel, SurfId) + EgtSetColor( SurfId, Color) + else + EgtErase( SurfId) + end + if dOffset == 0 then + break + end + i = i + 1 + end + return TabellaTmSurfParallel +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrderedCutTable: +-- nParent: il layer +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function GetOrderedCutTable( nParent, TabParallelPlanes, TabOrtoPlanes) + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + local TabellaOrderParallelCut1 = {} + + for IndexTmP=1, StepParallel do + TabellaOrderParallelCut1[IndexTmP] = {} + for IndexOrto=1, StepOrto do + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT) + local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + if Copy1Id and ptOrtoN then + EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB) + EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + local nFacet1 = EgtSurfTmFacetCount( Copy1Id) + local nFacet2 = EgtSurfTmFacetCount( Copy2Id) + if nFacet1 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + elseif nFacet2 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + break + else + table.insert( TabellaOrderParallelCut1[IndexTmP], Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + end + end + end + table.insert(TabellaOrderParallelCut1[IndexTmP], TabParallelPlanes[IndexTmP]) + end + return TabellaOrderParallelCut1 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrtoCutCenter: +-- idFacet: l'id della faccia +-- ptC: il punto centrale della faccia +-- vtN: il versore normale della faccia +-- vtO: il versore dei piani ortogonali +-- dOffsetEff: offset della distanza dal punto centrale +-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset +local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff, dNzLimDwnUp) + local FrameLocal = Frame3d( EgtSurfTmFacetCenter( FacetId, 0, GDB_ID.ROOT)) + EgtSetGridFrame(FrameLocal) + local IdAuxLocal = EgtGroup(EgtGetParent( FacetId), FrameLocal) + EgtSetName( IdAuxLocal, "AuxLocal") + local BoxLocal = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, FrameLocal) + local ptS = EgtGP( EgtSurfTmBBox( IdAuxLocal, BoxLocal, GDB_RT.GRID), GDB_ID.ROOT) + EgtErase( IdAuxLocal) + EgtSetGridFrame(Frame3d()) + -- riferimento intrinseco + local asseX = vtO + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + -- ingombro della faccia secondo questo riferimento + local Box = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, Frame) + local dLen = Box:getDimX() + local dWidth = Box:getDimY() + + -- se faccia non troppo lunga, con un lato piccolo e non diretta troppo verso il basso, non servono dice + local dMaxLen = BD.MAX_LEN_DICE or 600 + if dLen < dMaxLen and dWidth < dMaxLen and + ( dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0) and vtN:getZ() > dNzLimDwnUp then + return nil, nil, nil + end + + local N = ceil( dLen / dOffsetEff) + local dOffsetRel = dLen / N + local dCopyPlane + local dCenOffs = ( Box:getMax():getX() + Box:getMin():getX()) / 2 + + if dLen <= dOffsetRel then + --dOffsetRel = 0 + dCopyPlane = 1 + elseif dLen <= 2 * dOffsetRel then + dOffsetRel = dOffsetEff + dCopyPlane = 0 + else + if N % 2 == 0 then + dCopyPlane = 0 + elseif N % 2 == 1 then + dCopyPlane = 0.5 + end + end + + + return dOffsetRel, dCopyPlane, dCenOffs, ptS +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- TableMesh: +-- TableOrto: tabella delle superfici dei piani ortogonali +-- TableParallel: tabella delle superfici dei piani paralleli +-- Forma una tabella unica delle superfici di taglio inserendo strati di tagli ortogonali alternati da strati di taglio parallelo +local function TableMesh( TableOrto, TableParallel) + local TableUnited = {} + for i=1, #TableOrto do + table.insert( TableUnited, TableOrto[i]) + table.insert( TableUnited, TableParallel[i]) + end + return TableUnited +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- FindValue: +-- tab: tabella da scansionare +-- val: valore da cercare +-- Verifica se tab contiene val, a supporto della funzione SortOrtoCutsByNormalMethod +local function FindValue( tab, val) + for index, value in ipairs( tab) do + if value == val then + return true + end + end + return false +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- SortOrtoCutsByNormalMethod: +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio sfruttando il prodotto dei versori normali (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function SortOrtoCutsByNormalMethod( TabParallelPlanes, TabOrtoPlanes) + -- tabella dei tagli ordinati + local TabOrderOrtoCut = {} + -- tabella ausiliaria dei dati inseriti nell'ordine + local TabAux = {} + -- ciclo di ordinamento + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + for IndexTmP=1, StepParallel do + TabOrderOrtoCut[IndexTmP] = {} + local ptParalN, vtNParalN = EgtSurfTmFacetCenter( TabParallelPlanes[IndexTmP][1], 0, GDB_ID.ROOT) + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- controlla che l'elemento da valutare non sia gia' stato inserito nella tabella + if not FindValue( TabAux, OrtoPlaneId) then + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( OrtoPlaneId, 0, GDB_ID.ROOT) + local scalarProduct = ( ptOrtoN - ptParalN) * vtNParalN + if scalarProduct > 0 then + table.insert( TabOrderOrtoCut[IndexTmP], OrtoPlaneId) + table.insert( TabAux, OrtoPlaneId) + end + end + end + end + end + -- cancello dal DB geometrico i tagli non inseriti + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- ricerco il taglio tra gli inseriti + if not FindValue( TabAux, OrtoPlaneId) then + EgtErase( OrtoPlaneId) + end + end + end + return TabOrderOrtoCut +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- VerifyFirstOrthoCut : +-- CutTable: tabella dei tagli +-- OffsetP: offset della distanza dal punto centrale +-- BBoxRawPart: il grezzo della barra +-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia O è superflua +local function VerifyFirstOrthoCut( CutTable, OffsetP, BBoxRawPart, dNzLimDwnUp) + + if not CutTable[1] or not CutTable[2] then return end + + local CutOId = CutTable[1][1] + local Cut1Id = CutTable[2][1] + local Cut2Id = CutTable[2][2] + + if CutOId and Cut1Id and Cut2Id then + -- centri e normali delle due semifacce + local ptC1, vtN1 = EgtSurfTmFacetCenter( Cut1Id, 0, GDB_ID.ROOT) + local ptC2, vtN2 = EgtSurfTmFacetCenter( Cut2Id, 0, GDB_ID.ROOT) + -- normale alla faccia ortogonale + local _, vtO = EgtSurfTmFacetCenter( CutOId, 0, GDB_ID.ROOT) + vtO = vtO - vtO * vtN1 * vtN1 ; vtO:normalize() + -- calcolo lunghezza prima semi-faccia + local asseX1 = vtO + local asseY1 = vtN1 ^ asseX1 + local Frame1 = Frame3d( ptC1, ptC1+asseX1, ptC1+asseY1) + local Box1 = EgtGetBBoxRef( Cut1Id, GDB_BB.STANDARD, Frame1) + local x1 = Box1:getDimX() + -- calcolo lunghezza seconda semi-faccia + local asseX2 = vtO + local asseY2 = vtN2 ^ asseX2 + local Frame2 = Frame3d( ptC2, ptC2+asseX2, ptC2+asseY2) + local Box2 = EgtGetBBoxRef( Cut2Id, GDB_BB.STANDARD, Frame2) + local x2 = Box2:getDimX() + -- lunghezza totale faccia + local dLongSize = x1 + x2 + -- se faccia piccola e non orientata verso il basso, elimino ortogonale e unisco le due parti + if dLongSize <= OffsetP + 1.0 and vtN1:getZ() > dNzLimDwnUp then + local nParent = EgtGetParent( Cut1Id) + local SurfId = EgtSurfTmBySewing( nParent, { Cut1Id, Cut2Id}) + EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) + EgtErase( CutOId) + table.remove( CutTable[1], 1) + table.remove( CutTable[2], 1) + table.remove( CutTable[2], 1) + table.insert( CutTable[2], 1, SurfId) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- ricavo i vertici del box +local function CalcolaPuntiEstremiBox( BBoxRawPart) + local ptMin = BBoxRawPart:getMin() + local ptMax = BBoxRawPart:getMax() + local TBoxPoint = {} + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMin:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMin:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMax:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMax:getY(), ptMin:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMin:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMin:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMin:getX(), ptMax:getY(), ptMax:getZ()), On = true}) + table.insert( TBoxPoint, { P = Point3d( ptMax:getX(), ptMax:getY(), ptMax:getZ()), On = true}) + return TBoxPoint +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- restituisce i punti che devono essere presi in considerazione per la costruzione del BoundingBox +local function VerificaEstremiGrezzo( ptC, vtN, TPoint) + for i = 1, #TPoint do + if ( TPoint[i].P - ptC) * vtN < 0 then + TPoint[i].On = false + end + end + return TPoint +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- ricavo l'altezza del BoundingBox assegnati gli estremi del grezzo e la feature +-- le funzioni commentate permettono di vedere la creazione di BoundingBox +local function DistanzaMassima( nParent, ptC1, vtN1, ptC2, vtN2, BBoxRawPart, TPoint) + -- calcolo il riferimento nel piano 1 + local Frame1 = Frame3d( ptC1, vtN1) + -- determino l'ingombro in questo riferimento della parte di trave compresa nel o nei piani + local BB1 = BBox3d() + -- punti di vertice della trave compresi + for i = 1, #TPoint do + if TPoint[i].On then + local ptP = Point3d( TPoint[i].P) + ptP:toLoc( Frame1) + BB1:Add( ptP) + end + end + -- eventuale altra faccia + if ptC2 and vtN2 then + local IdAux = EgtGroup( nParent) + local IdSurf2 = EgtSurfTmPlaneInBBox( IdAux, ptC2, vtN2, BBoxRawPart, GDB_RT.GLOB) + EgtCutSurfTmPlane( IdSurf2, ptC1, -vtN1, false, GDB_RT.GLOB) + if IdSurf2 then + local BB2 = EgtGetBBoxRef( IdSurf2, GDB_BB.STANDARD, Frame1) + BB1:Add( BB2) + end + EgtErase( IdAux) + end + if not BB1:isEmpty() then + return ( BB1:getMax():getZ() + 0.1) + end + + return 0 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- DiceCut.GetDice : +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptCPlanes: il punto centrale del piano della feature +-- vtNPlanes: il versore normale del piano della feature +-- bGetOrtoPlanes*: se voglio calcolare i piani ortogonali al piano passato (se non esistono altre superfici può essere omesso) +-- ptCBond*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNBond*: il versore normale della superfice limitante (se non esistono altre superfici può essere omesso) +-- dOrthoMaxDim : massima profondità taglio se faccia singola perpendicolare facce laterali trave +-- dCustMaxDimDice: dimensione massima customizzata, sostituisce il parametro BD.MAX_DIM_DICE +-- bDownHead : taglio con testa da sotto +---------------------------------------------------------------------------------------------------------------------------------------------------- +function DiceCut.GetDice( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, bGetOrtoPlanes, ptCBond, vtNBond, dOrthoMaxDim, dCustMaxDimDice, bDownHead) + + local dMaxDimDice = EgtIf( dCustMaxDimDice and dCustMaxDimDice < BD.MAX_DIM_DICE, dCustMaxDimDice, BD.MAX_DIM_DICE) + local dTolerance = 0 -- distanza di sicurezza per i tagli ortogonali + local OffsetP = dMaxDimDice -- distanza tra i piani paralleli + local StepP = 100 -- numero massimo di piani paralleli da generare + local OffsetO = dMaxDimDice -- distanza tra i piani ortogonali + local StepO = 100 -- numero massimo di piani ortogonali da generare + + --Ricavo le altezze dei BoundingBox contenente feature e estremi del grezzo + local TBoxPoint = CalcolaPuntiEstremiBox( BBoxRawPart) + TBoxPoint = VerificaEstremiGrezzo( ptCPlanes, vtNPlanes, TBoxPoint) + if ptCBond and vtNBond then + TBoxPoint = VerificaEstremiGrezzo( ptCBond, vtNBond, TBoxPoint) + end + local dElevP = DistanzaMassima( nParent, ptCPlanes, vtNPlanes, ptCBond, vtNBond, BBoxRawPart, TBoxPoint) + local dElevO + if ptCBond and vtNBond then + dElevO = DistanzaMassima( nParent, ptCBond, vtNBond, ptCPlanes, vtNPlanes, BBoxRawPart, TBoxPoint) + end + + -- inclinazione limite per taglio da sotto + local dNzLimDwnUp = BL.GetNzLimDownUp( BBoxRawPart) + + -- se non c'è testa da sotto e normali senza componenti in Y con faccia quasi verticale e trave non alta, uso per offset i limiti dei tagli di testa e coda + if not BD.DOWN_HEAD and abs( vtNPlanes:getY()) < 0.1 and vtNPlanes:getZ() < 0.7071 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) and BBoxRawPart:getDimZ() < BD.MIN_DIM_HBEAM then + OffsetO = dOrthoMaxDim or BD.MAX_DIM_HTCUT + end + + -- aggiungo piccolo extra agli offset + OffsetP = OffsetP + 10 * GEO.EPS_SMALL + OffsetO = OffsetO + 10 * GEO.EPS_SMALL + + -- se seconda faccia non definita, forzo calcolo piani ortogonali + if not ptCBond or not vtNBond then + bGetOrtoPlanes = true + end + + -- se piani non ortogonali, diminuisco la distanza di offset opportunamente + local originalOffsetP = OffsetP + if not bGetOrtoPlanes then + local dCoeff = ( vtNPlanes ^ vtNBond):len() + OffsetP = OffsetP * dCoeff + OffsetO = OffsetO * dCoeff + end + + local n = ceil( dElevP / OffsetP) + OffsetP = dElevP / n + if dElevO then + local m = ceil( dElevO / OffsetO) + OffsetO = dElevO / m + end + + -- elenco di tutte le superfici generate dai tagli + local TabFUCHSIA = {} + local TabGREEN = {} + + -- PIANI PARALLELI alla faccia di taglio + local TabellaTmSurfP = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, 0, OffsetP, StepP, Color3d( FUCHSIA(), 60), dTolerance, true, ptCBond, vtNBond) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfP, TabFromIn[i]) + end + + -- PIANI ORTOGONALI alla faccia di taglio + -- orientamento definito da seconda faccia + if not bGetOrtoPlanes then + local TabellaTmSurfOrto = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCBond, vtNBond, 0, OffsetO, StepO, Color3d( GREEN(), 60), dTolerance, false, ptCPlanes, vtNPlanes) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfOrto, TabFromIn[i]) + end + local TabellaOrderParallelCut = GetOrderedCutTable( nParent, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati + local TabellaOrderOrtoCut = GetOrderedCutTable( nParent, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato + + TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato + TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati + + -- orientamento da definire + else + for PlnInd = 1, #TabellaTmSurfP do + -- piano interno + local ptCInner, vtNInner = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd], 0, GDB_ID.ROOT) + -- eventuale piano esterno + local ptCOuter, vtNOuter = nil, nil + if PlnInd > 1 then + ptCOuter, vtNOuter = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd-1], 0, GDB_ID.ROOT) + vtNOuter = -vtNOuter + end + -- calcolo la direzione dei piani ortogonali + local vtO = VectorFromUprightOrtho( vtNInner) + if vtNInner:getZ() > -0.0175 or vtNInner:getZ() < dNzLimDwnUp or abs( vtNInner:getY()) > 0.8 then + vtO:rotate( vtNInner, 90) + -- se diretto troppo ortogonalmente all'asse trave e taglio non da sotto, lo ruoto ulteriormente + if ( abs( vtO:getY()) > 3 * abs( vtO:getX()) or BBoxRawPart:getDimZ() > 620) and vtNInner:getZ() > dNzLimDwnUp then + vtO:rotate( vtNInner, 90) + -- se faccia principale verso il basso (almeno -3deg), lo inverto per iniziare da sopra + if vtNInner:getZ() < -0.05 then + vtO = -vtO + end + else + if vtNInner:getX() > -0.017 then + if vtO:getX() < 0 then vtO = - vtO end + else + if vtO:getX() > 0 then vtO = - vtO end + end + end + end + -- se quasi verticale (fino a 20 gradi di distanza) su faccia inclinata in Y, ruoto di 90 gradi + if vtO:getZ() > 0.939 and abs( vtNInner:getY()) > 0.5 then + vtO:rotate( vtNInner, 90) + end + -- se taglio con testa da sotto + if bDownHead and vtO:getZ() > 0.05 then + vtO = -vtO + end + -- calcolo le dimensioni dell'offset e dove posizionare la prima faccia: + -- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato + -- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato + -- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero + local OffsetRel, CopyPlane, dCenOffs, ptCStart = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, OffsetO, dNzLimDwnUp) + + if OffsetRel and CopyPlane and dCenOffs then + ptCInner = ptCInner + dCenOffs * vtO + local TabRight = GetParallelPlanes( nParent, BBoxRawPart, ptCStart, vtO, CopyPlane, -OffsetRel, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + if CopyPlane == 0 then + CopyPlane = 1 + end + local TabLeft = GetParallelPlanes( nParent, BBoxRawPart, ptCStart, vtO, CopyPlane, OffsetRel, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + -- carico la tabella con gli indici riordinati + local TempOrtoTab = {} + for i = #TabLeft, 1, -1 do + table.insert( TempOrtoTab, TabLeft[i]) + end + for i = 1, #TabRight do + table.insert( TempOrtoTab, TabRight[i]) + end + -- creo una tabella per ogni piano per generare i tagli sulla Inner + local TempParTab = GetOrderedCutTable( nParent, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) + for i = 1, #TempParTab do + table.insert( TabFUCHSIA, TempParTab[i]) + end + table.insert( TabGREEN, TempOrtoTab) + else + table.insert( TabFUCHSIA, {TabellaTmSurfP[PlnInd]}) + table.insert( TabGREEN, {}) + end + end + end + + -- Se sono state costruite non più di una faccia parallela e una faccia perpendicolare, allora non servono e tengo le originali + if #TabGREEN == 1 and #TabGREEN[1] <= 1 and #TabFUCHSIA == 1 and #TabFUCHSIA[1] <= 1 then + if #TabGREEN[1] == 1 then + EgtErase( TabGREEN[1][1]) + end + TabGREEN = {} + if #TabFUCHSIA[1] == 1 then + EgtErase( TabFUCHSIA[1][1]) + end + TabFUCHSIA = {} + end + + -- Si uniscono le tabelle dei tagli ortogonali e paralleli in una sola tabella + local UltimateTable = TableMesh( TabGREEN, TabFUCHSIA) + + -- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato + if not bGetOrtoPlanes then + VerifyFirstOrthoCut( UltimateTable, originalOffsetP, BBoxRawPart, dNzLimDwnUp) + end + + return UltimateTable +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- PrintOrderCut: +-- TabellaOrderCut: tabella delle superfici di taglio +-- stampo l'ordine dei piani di taglio ricevendo una tabella con gli strati parallelo/ortogonali già ordinati +function DiceCut.PrintOrderCut( TabellaOrderCut) + local Step = #TabellaOrderCut + if Step > 0 then + EgtOutLog( " L'ordine delle superfici da tagliare è il seguente:") + else + EgtOutLog( ' Non sono necessarie superfici aggiuntive di taglio.') + end + for i = 1, Step do + if i % 2 == 1 then + EgtOutLog( ' *** Strato di taglio ' .. EgtNumToString( ( i + 1) / 2, 0)) + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli ortogonali: ') + else + EgtOutLog( ' Tagli ortogonali assenti') + end + else + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli paralleli: ') + else + EgtOutLog( ' Tagli paralleli assenti') + end + end + for j=1, #TabellaOrderCut[i] do + EgtOutLog( ' Indice faccia ' .. (TabellaOrderCut[i][j] or 0)) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +local function DiceCutTest() + + -- salvo l'indice del layer Trimesh selezionato + local SelectedIndex = EgtGetFirstSelectedObj() + -- verifico che sia selezionato un elemento + if not SelectedIndex then return end + + -- salvo l'indice del layer Processing + local nParent = EgtGetParent( SelectedIndex) + -- salvo l'indice del layer Part + local nRawPart = EgtGetParent( nParent) + local nBox = EgtGetFirstNameInGroup( nRawPart, 'Box') + -- carico il bounding box della trave + -- local BBoxRawPart = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD ) + local BBoxRawPart = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD ) + -- seleziono il Part e il Layer di destinazione + EgtSetCurrPartLayer( nRawPart, nParent) + + -- conto il numero di facce da processare + local nFacet = EgtSurfTmFacetCount( SelectedIndex) + EgtOutLog( ' Numero facce ' .. nFacet, 1) + + -- salvo + local TabPlanesFeatures = {} + for i = 1, nFacet do + local ptC, vtN = EgtSurfTmFacetCenter( SelectedIndex, i - 1, GDB_ID.ROOT) + table.insert( TabPlanesFeatures, { ptC = ptC, vtN = vtN}) + end + local ptC1 = Point3d( TabPlanesFeatures[1].ptC) + local vtN1 = Vector3d( TabPlanesFeatures[1].vtN) + + local CutTable = {} + if nFacet == 1 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, true) + elseif nFacet == 2 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN) + end + + if EgtGetDebugLevel() >= 3 then + DiceCut.PrintOrderCut( CutTable) + end + + EgtDeselectAll() + + EgtDraw() +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +--DiceCutTest() + +return DiceCut diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/FacesBySaw.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/FacesBySaw.lua new file mode 100644 index 0000000..68d93fe --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/FacesBySaw.lua @@ -0,0 +1,617 @@ +-- FacesBySaw.lua by Egaltech s.r.l. 2022/04/12 +-- Gestione taglio con lama di feature con una o due facce +-- 2021/01/06 Cambiato limite per attacco Tg con lama e CalcLeadInOutGeom rinominata in CalcLeadInOutPerpGeom. +-- 2021/02/03 In taglio lama si accettano anche due lati con deviazione minore di 20deg. +-- 2021/02/09 In taglio lama con PF si preferisce testa in Y- quindi SCC di conseguenza. +-- 2021/02/26 In taglio lama consento attacco anche da sotto (grazie a migliorie in MachKernel). +-- 2021/03/22 Attacchi e uscite di tagli longitudinali da sotto con lama solo ortogonali. +-- 2021/04/27 Migliorati controlli per attacchi e uscite Tg con lama. +-- 2021/07/08 Modifiche in MakeOneFaceBySaw per gestione taglio con due segmenti. +-- 2021/08/03 In MakeOneFaceBySaw mgliorata gestione tagli con normale verso il basso e da sopra. +-- 2021/08/31 DS Aggiunta gestione nessun limite direzione da sotto per testa da sotto. +-- 2021/11/26 DS Spostate qui MakeOneFaceBySaw (ora MakeOne), CalcLeadInOutPerpGeom e CalcLeadInOutTangGeom. +-- 2022/04/12 DS Aggiunta gestione speciale cubetti con fresa da sotto. + +-- Tabella per definizione modulo +local FacesBySaw = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' FacesBySaw started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +function FacesBySaw.MakeOne( nSurfId, nFacet, sCutting, dSawDiam, Par5, dVzLimDwnUp, dCutExtra, dCutSic, dCutOffset, dAccStart, dAccEnd, sNotes, b3Raw) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + -- risolvo parametro ambiguo + local nOrthoOpposite + local vtOrthO + if isVector3d( Par5) then + nOrthoOpposite = BL.GetNearestOrthoOpposite( Par5, vtN) + vtOrthO = Vector3d( Par5) + else + nOrthoOpposite = Par5 + vtOrthO = BL.GetVersRef( Par5) + end + -- verifico se testa da sotto + local bDownHead = ( dVzLimDwnUp and dVzLimDwnUp < - 1.5) + -- linea o bilinea di lavorazione (qui uso nOrthoOpposite per ripetere esattamente il calcolo del Mach) + local ptP1, ptPm, ptP2, vtV1, vtV2, dLen, dWidth = EgtSurfTmFacetOppositeSide( nSurfId, nFacet, BL.GetVersRef( nOrthoOpposite), GDB_ID.ROOT) + if not dLen or dLen < 1.1 or not dWidth or dWidth < 1.1 then + local sWarn = 'Face ' .. string.format( '%d,%d', nSurfId, nFacet) .. ' skipped : too small' + EgtOutLog( sWarn, 1) + return true, '' + end + vtV1 = - vtV1 + local bInvert = ( ptP2:getZ() < ptP1:getZ() - 100 * GEO.EPS_SMALL) + if bInvert then + ptP1, ptP2 = ptP2, ptP1 + vtV1, vtV2 = vtV2, vtV1 + end + local vtTg = ptP2 - ptP1 ; vtTg:normalize() + local dAllStart = 0 + local dAllEnd = 0 + -- se bilinea, scarto la parte più allineata con la direzione ortogonale (se deviazione angolare oltre 20 deg o lunghezza minore di dSawDiam/2 * cos( 20/2)) ma maggiore di un minimo + if ( ( ptPm - ptP1) - ( ptPm - ptP1) * vtTg * vtTg):len() > 100 * GEO.EPS_SMALL then + local vtTg1 = ptPm - ptP1 ; vtTg1:normalize() + local vtTg2 = ptP2 - ptPm ; vtTg2:normalize() + local dDist1 = dist( ptP1, ptPm) + local dDist2 = dist( ptP2, ptPm) + local dCosMax = 0.951 -- cos( 18°) + local dLenMin = 30 + local dLenMax = max( 0.5 * dSawDiam * 0.17365 + 1, 2 * dLenMin) + --if vtTg1 * vtTg2 < dCosMax or ( dDist1 < dLenMax and dDist1 > dLenMin) or ( dDist2 < dLenMax and dDist2 > dLenMin) then + if vtTg1 * vtTg2 < dCosMax then + local dOrtho1 = abs( vtTg1 * vtOrthO) + local dOrtho2 = abs( vtTg2 * vtOrthO) + if dOrtho1 < dOrtho2 or ( abs( dOrtho1 - dOrtho2) < 0.1 and dDist1 > 4 * dDist2) then + if dDist1 > dLenMin or dDist1 > 0.5 * dDist2 then + ptP2 = Point3d( ptPm) + dAllEnd = - dDist2 - 10 * GEO.EPS_SMALL + end + else + if dDist2 > dLenMin or dDist2 > 0.5 * dDist1 then + ptP1 = Point3d( ptPm) + dAllStart = - dDist1 - 10 * GEO.EPS_SMALL + end + end + vtTg = ptP2 - ptP1 ; vtTg:normalize() + end + end + -- verifico se lavorazione con lama sotto e testa sopra + if not dVzLimDwnUp then dVzLimDwnUp = BL.GetNzLimDownUp( b3Raw, vtN, vtOrthO) end + local bDownUp = ( vtN:getZ() < dVzLimDwnUp) + local nFaceUse = nOrthoOpposite + if bDownUp then nFaceUse = BL.GetOrtupOpposite( nOrthoOpposite) end + local bWsRight = ( bInvert ~= bDownUp) + local nWorkSide = EgtIf( bWsRight, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) + -- Versore di riferimento + local vtRef = Vector3d( vtTg) + vtRef:rotate( vtN, EgtIf( bInvert, -90, 90)) + -- Versore esterno + local vtOut = vtRef - vtRef * vtTg * vtTg ; vtOut:normalize() + -- Versore ausiliario (direzione braccio) + local vtAux = Vector3d( vtN:getX(), vtN:getY(), 0) ; vtAux:normalize() + vtAux:rotate( Z_AX(), EgtIf( bWsRight, 90, -90)) + if vtAux:isSmall() then + vtAux = Vector3d( vtOut:getX(), vtOut:getY(), 0) ; vtAux:normalize() + else + if abs( vtAux * vtOut) < GEO.EPS_SMALL then + if abs( vtTg:getZ()) > 0.5 then + if vtAux * vtRef < 0 then + vtAux = - vtAux + end + elseif vtAux * vtTg > 0 then + vtAux = - vtAux + end + elseif vtAux * vtOut < 0 then + vtAux = - vtAux + end + end + -- parametri di attacco/uscita + local b3Box = BBox3d( b3Raw) + b3Box:expand( dCutSic) + local ptP1act = ptP1 + vtN * dCutOffset + local ptP2act = ptP2 + vtN * dCutOffset + -- attacco perpendicolare + local dLiTang, dLiPerp, dLoTang, dLoPerp = FacesBySaw.CalcLeadInOutPerpGeom( ptP1act, ptP2act, vtV1, vtV2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + local dLenLi = sqrt( dLiTang * dLiTang + dLiPerp * dLiPerp) + local dLenLo = sqrt( dLoTang * dLoTang + dLoPerp * dLoPerp) + -- attacco tangente + local dLi2Tang, dLi2Perp, dLo2Tang, dLo2Perp = FacesBySaw.CalcLeadInOutTangGeom( ptP1act, ptP2act, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + local dLenLi2 = abs( dLi2Tang) + local dLenLo2 = abs( dLo2Tang) + -- scelgo l'attacco più conveniente (se non taglio praticamente longitudinale) + local Ktp = 1.1 + if BD.KIOTP then Ktp = BD.KIOTP end + if ( not bDownUp or abs( vtTg:getY()) > 0.5) and + ( not bDownHead or abs( vtTg:getZ()) < 0.51) and + abs( vtTg:getX()) < 0.9848 and + ( ( abs( vtTg:getZ()) < 0.17 and ( vtV1:getZ() < -0.5 or vtV2:getZ() < -0.5)) or + ( abs( vtTg:getZ()) < 0.51 and b3Box:getDimZ() > 300 and BD.C_SIMM and BD.MAX_HEIGHT > 450) or + ( Ktp * dLenLi2 < dLenLi and Ktp * dLenLo2 < dLenLo) or Ktp * ( dLenLi2 + dLenLo2) < ( dLenLi + dLenLo)) then + dLiTang, dLiPerp, dLoTang, dLoPerp = dLi2Tang, dLi2Perp, dLo2Tang, dLo2Perp + end + -- posizione braccio + EgtOutLog( 'vtN=' .. tostring( vtN) .. ' vtRef=' .. tostring( vtRef) .. ' vtOut=' .. tostring( vtOut) .. ' vtAux=' .. tostring( vtAux), 3) + local nSCC = MCH_SCC.NONE + if not BD.TURN then + if abs( vtAux:getX()) > abs( vtAux:getY()) - GEO.EPS_SMALL then + nSCC = EgtIf( ( vtAux:getX() > -GEO.EPS_SMALL), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + else + nSCC = EgtIf( ( vtAux:getY() > -GEO.EPS_SMALL), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + else + nSCC = MCH_SCC.ADIR_ZP + end + -- inserisco la lavorazione di taglio + local sName = 'Cut_' .. ( EgtGetName( nSurfId) or tostring( nSurfId)) .. '_' .. tostring( nFacet + 1) + local nMchFId = EgtAddMachining( sName, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + sName = EgtGetOperationName( nMchFId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nSurfId, nFacet}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, bInvert) + EgtSetMachiningParam( MCH_MP.WORKSIDE, nWorkSide) + -- affondamento aggiuntivo + EgtSetMachiningParam( MCH_MP.OFFSR, -dCutExtra) + -- offset longitudinale + EgtSetMachiningParam( MCH_MP.OFFSL, EgtIf( bDownUp, -dCutOffset, dCutOffset)) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLiTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLiPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLoTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLoPerp) + -- imposto allungamenti iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAllStart - dAccStart) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAllEnd - dAccEnd) + -- eventuali note + if sNotes and #sNotes > 0 then EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, sName, nMchFId +end + +--------------------------------------------------------------------- +function FacesBySaw.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, sCutType, bUpdateIng, bDownHead) + -- bUpdateIng : parametro opzionale con default true + if bUpdateIng == nil then bUpdateIng = true end + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico il numero di facce + if Proc.Fct < 2 then + local sErr = 'Error : TwoFacesBySaw facet number not supported' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bDownHead and not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error : TwoFacesBySaw from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero dati su giunzione tra facce + local bTouch, ptT1, ptT2, dAngT = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if not bTouch then + local sErr = 'Error : TwoFacesBySaw faces not touching' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo direzione di lavoro + local vtRef = {} + local vtTg = ptT2 - ptT1 ; + vtRef[1] = vtN[1] ^ vtTg + if vtRef[1] * vtN[2] < 0 then vtRef[1] = - vtRef[1] end + vtRef[1]:normalize() + vtRef[2] = vtN[2] ^ vtTg + if vtRef[2] * vtN[1] < 0 then vtRef[2] = - vtRef[2] end + vtRef[2]:normalize() + -- determino quale faccia è più grande + local ptPs = ( ptT1 + ptT2) / 2 + local dSqDim1 = ( ptC[1] - ptPs):sqlen() + local dSqDim2 = ( ptC[2] - ptPs):sqlen() + local nBigInd = EgtIf( dSqDim1 > dSqDim2 - 1., 1, 2) + local nSmaInd = 3 - nBigInd + local nUpInd = EgtIf( vtN[1]:getZ() > vtN[2]:getZ() - GEO.EPS_SMALL, 1, 2) + local nOtInd = 3 - nUpInd + -- metto in relazione la scelta facce con il confronto del versore Z con la scelta in base alla grandezza faccia + -- se la faccia più grande è messa secondaria e il suo versore Z non è negativo + if nOtInd == nBigInd and vtN[nBigInd]:getZ() > -5 * GEO.EPS_SMALL and vtN[nSmaInd]:getZ() < 0.866 then + nOtInd = nSmaInd + nUpInd = nBigInd + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( sCutType) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 5 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- calcolo extra taglio + local dCutExtra = 0 + if dAngT < -91 and dAngT > -179 then + dCutExtra = - dSawThick / tan( 180 + dAngT) + end + -- sistemo direzione limite da sotto (con testa da sotto limite Vz Down Up messo a -2 per non farlo mai intervenire) + local dNzLimDwnUp + if bDownHead then + dNzLimDwnUp = - 2 + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nUpInd], vtN[nUpInd], false, ptC[nOtInd], vtN[nOtInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- con testa da sopra + if not bDownHead then + -- eseguo + for i = 1, #vCuts do + -- assegno il modo di tagliare + local vtOrthO = EgtIf( ( i % 2) == 1, vtRef[nOtInd], vtRef[nUpInd]) + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se FAST, pezzo alto e ultimo taglio verticale -> allungo uscita per consentire eventuale rotazione B sul posto + local dAccEnd = 0 + if not BD.C_SIMM and BD.MAX_HEIGHT_ROT_B_ABOVE and b3Raw:getDimZ() > BD.MAX_HEIGHT_ROT_B_ABOVE and vtOrthO:getZ() > 0.866 and j == #vCuts[i] then + dAccEnd = - ( dSawDiam / 2 + BD.CUT_SIC) + end + local bOk, sErr = FacesBySaw.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthO, dNzLimDwnUp, dCutExtra, BD.CUT_SIC, 0, 0, dAccEnd, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti con testa da sotto + else + -- eseguo (facendo di seguito i due tagli di ogni singolo cubetto) + for i = 1, #vCuts, 2 do + -- determino il modo di tagliare dei perpendicolari + local vtOrthoO_1 = Vector3d( vtN[nUpInd]) + -- determino il modo di tagliare dei paralleli + local vtOrthoO_2 + local bNoPerpCuts_2 = false + local vtO + if #vCuts[i] > 0 then + vtO = EgtSurfTmFacetNormVersor( vCuts[i][1], 0, GDB_ID.ROOT) + elseif vCuts[i+2] and #vCuts[i+2] > 0 then + -- lunghezza faccia nell'eventuale direzione ortogonale + local asseX = EgtSurfTmFacetNormVersor( vCuts[i+2][1], 0, GDB_ID.ROOT) + local asseY = asseX ^ vtN[nUpInd] + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + local b3Fac = EgtGetBBoxRef( vCuts[i+1][1], GDB_BB.STANDARD, Frame) + -- se lunghezza inferiore al limite, accetto la direzione + if b3Fac:getDimX() < dMaxDepth - BD.CUT_EXTRA then + vtO = asseX + else + bNoPerpCuts_2 = true + end + else + bNoPerpCuts_2 = true + end + if vtO then + vtOrthoO_2 = Vector3d( vtO) + else + if bHorizCut then + vtOrthoO_2 = -Z_AX() + elseif vtN:getY() > -0.02 then + if not Proc.Head then + vtOrthoO_2 = -Y_AX() + else + vtOrthoO_2 = Y_AX() + end + else + vtOrthoO_2 = -Y_AX() + end + end + -- lavoro le coppie di facce del singolo cubetto + for j = 1, max( #vCuts[i], #vCuts[i+1]) do + -- extra taglio per perpendicolari + local dExtraCut_1 = -0.1 + -- extra taglio per paralleli + local dExtraCut_2 = -0.1 + -- se non ci sono tagli ortogonali devo affondare + if bNoPerpCuts_2 then + dExtraCut_2 = BD.CUT_EXTRA + end + -- taglio perpendicolare (limite Vz Down Up messo a -2 per non farlo mai intervenire) + if vCuts[i][j] then + local bOk, sErr = FacesBySaw.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO_1, -2, dExtraCut_1, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- taglio parallelo (limite Vz Down Up messo a -2 per non farlo mai intervenire) + if vCuts[i+1][j] then + local bOk, sErr = FacesBySaw.MakeOne( vCuts[i+1][j], 0, sCutting, dSawDiam, vtOrthoO_2, -2, dExtraCut_2, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + end + end + else + nUpInd = EgtIf( vtN[1]:getZ() > vtN[2]:getZ() - GEO.EPS_SMALL, 1, 2) + nOtInd = 3 - nUpInd + -- se prima faccia lavorata è da sotto scambio le facce + if vtN[nOtInd]:getZ() < -0.5 then + nUpInd, nOtInd = nOtInd, nUpInd + end + -- lavoro la prima faccia + local bOk, sErr = FacesBySaw.MakeOne( Proc.Id, nOtInd-1, sCutting, dSawDiam, vtRef[nOtInd], dNzLimDwnUp, dCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + -- lavoro seconda faccia + bOk, sErr = FacesBySaw.MakeOne( Proc.Id, nUpInd-1, sCutting, dSawDiam, vtRef[nUpInd], dNzLimDwnUp, dCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if bUpdateIng and Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng and + not ( abs( vtN[nBigInd]:getX()) < 0.05 and vtN[nBigInd]:getY() < 0 and Proc.Box:getDimX() > 500) then + if Proc.Head then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + elseif Proc.Box:getCenter():getX() > b3Solid:getCenter():getX() then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + local dDist = b3Solid:getMax():getX() - Proc.Box:getMax():getX() + -- se concavo aumento la distanza (rimane una punta...) + if dAngT < 0 then dDist = dDist + 10 end + BL.UpdateHCING( nRawId, dOffs, dDist) + end + end + return true +end + +--------------------------------------------------------------------- +function FacesBySaw.CalcLeadInOutPerpGeom( ptP1, ptP2, vtV1, vtV2, vtN, dRad, vtRef, dCutExtra, b3Box) + -- Mi assicuro che i vettori ingresso/uscita giacciano nel piano + vtV1 = vtV1 - vtV1 * vtN * vtN ; vtV1:normalize() + vtV2 = vtV2 - vtV2 * vtN * vtN ; vtV2:normalize() + -- Versore tangente al taglio + local vtTg = ptP2 - ptP1 ; + vtTg = vtTg - vtTg * vtN * vtN ; vtTg:normalize() + -- Sistema di riferimento intrinseco al taglio + local vtX = vtTg ^ vtN + local frFace = Frame3d( ptP1, vtX, vtTg, vtN) + EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Versori di attacco e uscita + local dCos1 = vtV1 * vtRef + local dCos2 = vtV2 * vtRef + local vtLi, vtLo + if abs( dCos1 - dCos2) < 0.001 then + if abs( vtV1:getZ()) < abs( vtV2:getZ()) then + vtLi = vtV1 + vtLo = vtV1 + else + vtLi = vtV2 + vtLo = vtV2 + end + elseif dCos1 > dCos2 then + vtLi = vtV1 + vtLo = vtV1 + else + vtLi = vtV2 + vtLo = vtV2 + end + local bRight = ( vtX * vtLi > 0) + -- Versori di attacco e uscita nel riferimento intrinseco al taglio + local vtLiL = Vector3d( vtLi) ; vtLiL:toLoc( frFace) + local vtLoL = Vector3d( vtLo) ; vtLoL:toLoc( frFace) + -- Spostamento punti per effetto dell'extra o della deficienza di taglio + ptP1 = ptP1 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) + ptP2 = ptP2 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) + -- Non va considerata l'uscita dalla faccia sotto, pertanto va abbassata + -- 2021/02/26 Abilito anche uscita sotto + local b3MyBox = BBox3d( b3Box) ; --b3MyBox:Add( b3MyBox:getMin() - 1000 * Z_AX()) + -- Attacco + local dLiTang = 10000 + local dLiPerp = 10000 + local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtLi, b3MyBox) + if bLiOk and #vLiPar > 0 then + -- con la prima faccia di uscita + local dLen = vLiPar[#vLiPar] + local ptInt = ptP1 + vtLi * dLen + local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, vtLi) + EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLi * vtFN) + local dLiLen = dLen + dAddLen + EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) + dLiTang = - dLiLen * vtLiL:getY() + dLiPerp = EgtIf( bRight, dLiLen, - dLiLen) * vtLiL:getX() + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtLi, b3Mod) + if bLiOk2 and #vLiPar2 > 0 then + local dLen2 = vLiPar2[#vLiPar2] + local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP1 + vtLi * dLen2, vtLi) + EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLi * vtFN2) + local dLiLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) + local dLiTang2 = - dLiLen2 * vtLiL:getY() + local dLiPerp2 = EgtIf( bRight, dLiLen2, - dLiLen2) * vtLiL:getX() + if dLiLen2 < dLiLen then + dLiTang = dLiTang2 + dLiPerp = dLiPerp2 + end + end + end + -- Lunghezza di uscita + local dLoTang = 10000 + local dLoPerp = 10000 + local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtLo, b3MyBox) + if bLoOk and #vLoPar > 0 then + -- con la prima faccia di uscita + local dLen = vLoPar[#vLoPar] + local ptInt = ptP2 + vtLo * dLen + local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, vtLo) + EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLo * vtFN) + local dLoLen = dLen + dAddLen + EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) + dLoTang = dLoLen * vtLoL:getY() + dLoPerp = EgtIf( bRight, dLoLen, - dLoLen) * vtLoL:getX() + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtLo, b3Mod) + if bLoOk2 and #vLoPar2 > 0 then + local dLen2 = vLoPar2[#vLoPar2] + local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP2 + vtLo * dLen2, vtLo) + EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLo * vtFN2) + local dLoLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) + local dLoTang2 = dLoLen2 * vtLoL:getY() + local dLoPerp2 = EgtIf( bRight, dLoLen2, - dLoLen2) * vtLoL:getX() + if dLoLen2 < dLoLen then + dLoTang = dLoTang2 + dLoPerp = dLoPerp2 + end + end + end + return dLiTang, dLiPerp, dLoTang, dLoPerp +end + +--------------------------------------------------------------------- +function FacesBySaw.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dRad, vtRef, dCutExtra, b3Box) + -- Versore tangente al taglio + local vtTg = ptP2 - ptP1 ; + vtTg = vtTg - vtTg * vtN * vtN ; vtTg:normalize() + -- Sistema di riferimento intrinseco al taglio + local vtX = vtTg ^ vtN + local frFace = Frame3d( ptP1, vtX, vtTg, vtN) + if ( vtX * vtRef < 0) then + vtX = - vtX + end + EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Spostamento punti per effetto dell'extra o della deficienza di taglio + ptP1 = ptP1 - vtX * dCutExtra + ptP2 = ptP2 - vtX * dCutExtra + -- Non va considerata l'uscita dalla faccia sotto, pertanto va abbassata + -- 2021/02/26 Abilito anche uscita sotto + local b3MyBox = BBox3d( b3Box) ; --b3MyBox:Add( b3MyBox:getMin() - 1000 * Z_AX()) + -- Attacco + local dLiTang = 10000 + local dLiPerp = 0 + local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtTg, b3MyBox) + if bLiOk and #vLiPar > 0 then + local dLen = vLiPar[1] + local ptInt = ptP1 + vtTg * dLen + local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, -vtTg) + EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) + local dLiLen = dLen + dAddLen + EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) + dLiTang = - dLiLen + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtTg, b3Mod) + if bLiOk2 and #vLiPar2 > 0 then + local dLen2 = vLiPar2[1] + local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP1 + vtTg * dLen2, -vtTg) + EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) + local dLiLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) + if -dLiLen2 < -dLiLen then + dLiTang = - dLiLen2 + end + end + end + -- Lunghezza di uscita + local dLoTang = 10000 + local dLoPerp = 0 + local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtTg, b3MyBox) + if bLoOk and #vLoPar > 0 then + local dLen = vLoPar[#vLoPar] + local ptInt = ptP2 + vtTg * dLen + local vtFN = BL.GetBoxFaceNorm( b3MyBox, ptInt, vtTg) + EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) + local dLoLen = dLen + dAddLen + EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) + dLoTang = dLoLen + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3MyBox) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtTg, b3Mod) + if bLoOk2 and #vLoPar2 > 0 then + local dLen2 = vLoPar2[#vLoPar2] + local vtFN2 = BL.GetBoxFaceNorm( b3Mod, ptP2 + vtTg * dLen2, vtTg) + EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) + local dLoLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) + if dLoLen2 < dLoLen then + dLoTang = dLoLen2 + end + end + end + return dLiTang, dLiPerp, dLoTang, dLoPerp +end + +return FacesBySaw \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/MachiningLib.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/MachiningLib.lua new file mode 100644 index 0000000..6fcb743 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/MachiningLib.lua @@ -0,0 +1,130 @@ +-- MachiningLib.lua by Egaltech s.r.l. 2021/04/14 +-- Libreria ricerca lavorazioni per Travi + +-- Tabella per definizione modulo +local MachiningLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' MachiningLib started', 1) + +-- Dati +local BD = require( 'BeamData') +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, dMaxDiam, dMaxTotLen) + 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() + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + if ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and + ( not sTuuidMstr or sTuuidMstr == sTuuid) and + ( not dMaxDiam or dTDiam < dMaxDiam + GEO.EPS_SMALL) and + ( not dMaxTotLen or dTTotLen < dMaxTotLen + GEO.EPS_SMALL) then + return Milling.Name, dTMaxDepth, dTDiam + end + end + end +end + +--------------------------------------------------------------------- +function MachiningLib.FindPocketing( sType, dMaxDiam, dDepth, dMaxTotLen) + 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() + local dTTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + if ( not dMaxDiam or dTDiam < dMaxDiam + GEO.EPS_SMALL) and + ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and + ( not dMaxTotLen or dTTotLen < dMaxTotLen + 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, dDepth, bDown) + -- ricerca sulle forature, dal diametro maggiore al minore + local sDrType = 'Drill' .. EgtIf( bDown, '_H2', '') + for i = #Drillings, 1, -1 do + local Drilling = Drillings[i] + if Drilling.On and Drilling.Type == sDrType and SetCurrMachiningAndTool( Drilling.Name) then + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + local dMaxToolLength = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + local dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dDiamTh = EgtTdbGetCurrToolThDiam() + local dLenTh = 72 + if EgtTdbGetCurrToolThLength then dLenTh = EgtTdbGetCurrToolThLength() end + local dFreeLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) - dLenTh - EgtMdbGetGeneralParam( MCH_GP.MAXDEPTHSAFE) + if dTDiam < dDiam + 10 * GEO.EPS_SMALL and dTDiam > dDiam - BD.DRILL_TOL - 10 * GEO.EPS_SMALL then + if not dDepth or dTMaxMat > dDepth - GEO.EPS_SMALL then + return Drilling.Name, Drilling.Type, dTMaxMat, dMaxToolLength, dToolDiam, dDiamTh, dFreeLen + end + end + end + end + -- ricerca sulle svuotature, dal diametro maggiore al minore + local sPkType = 'Pocket' .. EgtIf( bDown, '_H2', '') + for i = #Drillings, 1, -1 do + local Drilling = Drillings[i] + if Drilling.On and Drilling.Type == sPkType and SetCurrMachiningAndTool( Drilling.Name) then + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxDepth = EgtTdbGetCurrToolMaxDepth() + local dMaxToolLength = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + local dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dDiamTh = EgtTdbGetCurrToolThDiam() + local dFreeLen = dTMaxDepth + if dTDiam < dDiam - 10 * GEO.EPS_SMALL then + if not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL then + return Drilling.Name, Drilling.Type, dTMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dFreeLen + end + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +return MachiningLib diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessBlockHausFront.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessBlockHausFront.lua new file mode 100644 index 0000000..9a8b635 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessBlockHausFront.lua @@ -0,0 +1,307 @@ +-- ProcessBlockHausFront.lua by Egaltech s.r.l. 2020/08/03 +-- Gestione calcolo giunzione block house in testa + +-- Tabella per definizione modulo +local ProcessBlockHausFront = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessBlockHausFront started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessBlockHausFront.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 38) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessBlockHausFront.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + -- do errore perchè non è ancora gestita la rotazione di 90° + -- considerazioni: al momento non è possibile sapere se ci sono due rastremature o una quindi se è rivolta verso il basso + -- viene dato errore, altrimenti si potrebbe imporre la rotazione di 180 (ovviamente con una sola rastrematura rivolta verso il basso) + if abs(vtN:getZ()) > abs(vtN:getX()) and abs(vtN:getZ()) > abs(vtN:getY()) and vtN:getZ() < -0.5 then + return false + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessBlockHausFront.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + local dMinZedFace = 1 + for i = 1, nFacetCnt do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinZedFace then + dMinZedFace = dXVal + vFaceOrd[3] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + bHead = ( vtN[vFaceOrd[1]]:getX() > 0) + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- recupero la geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato + local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), 'b') + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + local dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < (#vCuts-1) or (i == #vCuts) then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 00 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + -- altrimenti di fianco + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + -- altrimenti di fianco + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessBlockHausFront diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessChamfer.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessChamfer.lua new file mode 100644 index 0000000..b44c13a --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessChamfer.lua @@ -0,0 +1,193 @@ +-- ProcessChamfer.lua by Egaltech s.r.l. 2020/09/01 +-- Gestione calcolo profilo libero per Travi + +-- Tabella per definizione modulo +local ProcessChamfer = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessChamfer started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessChamfer.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 36) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessChamfer.Make( Proc, nPhase, nRawId, nPartId) + -- verifico se ha geometria ausiliaria (onde) + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Chamfer') + 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 dMillDiam = 10 + local dMaxMat = 20 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + end + + -- se onde + if AuxId then + -- inserisco la lavorazione + local sName = 'Chm_' .. ( 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 + -- impongo lavorazione dall'alto + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- lavoro tenendo l'utensile a sinistra + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto lavorazione a metà tagliente e senza step + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat / 2) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto attacchi e uscite + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, 3) + EgtSetMachiningParam( MCH_MP.LITANG, 6) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- altrimenti smusso standard + else + -- normale ed elevazione della faccia principale + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + local _, dElev = BL.GetPointDirDepth( nPartId, ptC, vtN) + local bFront = ( vtN:getY() < 0) + -- limitazioni su inizio e fine derivanti da altre facce + local bLimXmin = false + local bLimXmax = false + if Proc.Fct >= 3 then + bLimXmin = true + bLimXmax = true + elseif Proc.Fct >= 2 then + local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if vtN1:getX() > 0 then + bLimXmin = true + else + bLimXmax = true + end + end + -- calcolo eventuali accorciamenti per facce limitanti + local dAllExtr + if dElev < dMillDiam / 2 then + dAllExtr = -sqrt( dMillDiam * dElev - dElev * dElev) + else + dAllExtr = -dMillDiam / 2 + end + local dStartAll = 0 + local dEndAll = 0 + if vtN:getY() < 0 then + if bLimXmax then dStartAll = dAllExtr end + if bLimXmin then dEndAll = dAllExtr end + else + if bLimXmax then dEndAll = dAllExtr end + if bLimXmin then dStartAll = dAllExtr end + end + -- determino numero di parti + local dLen = Proc.Box:getDimX() + -- calcolo la differenza tra lunghezza faccia 0 e lunghezza feature + -- per far corrispondere i punti di inizio-fine delle lavorazioni multiple (a passi) + local dAddLen = (( dH - dLen) / EgtIf( bLimXmax and bLimXmin , 2, 1)) + local dStartAccDist = BD.LONGCUT_ENDLEN + local dEndAccDist = BD.LONGCUT_ENDLEN + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + dC = dLen / ( nC + 2) + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + dC = dLen / 2 + else + nC = 1 + dC = 0 + end + end + -- eseguo le diverse parti + for i = 1, nC do + -- inserisco la lavorazione + local sName = 'Chm_' .. ( 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 + -- lavoro tenendo l'utensile a sinistra + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto lavorazione un poco sotto + local sDepth = 'TH+'..EgtNumToString( BD.CUT_EXTRA) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, sDepth) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- imposto attacchi e uscite + local dSal, dEal + if bFront then + dSal = EgtIf( i == 1, dStartAll, -( i - 1) * dC - dAddLen + 0.5) + dEal = EgtIf( i == nC, dEndAll, -( nC - i) * dC - dAddLen + 0.5) + else + dSal = EgtIf( i == nC, dStartAll, -( nC - i) * dC - dAddLen + 0.5) + dEal = EgtIf( i == 1, dEndAll, -( i - 1) * dC - dAddLen + 0.5) + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.LIPERP, dMillDiam / 4) + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + local nSCC = EgtIf( ( BD.C_SIMM or i == 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + + return true +end + +--------------------------------------------------------------------- +return ProcessChamfer diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessCut.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessCut.lua new file mode 100644 index 0000000..7984d3b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessCut.lua @@ -0,0 +1,743 @@ +-- ProcessCut.lua by Egaltech s.r.l. 2022/02/06 +-- Gestione calcolo singoli tagli di lama per Travi +-- 2021/05/18 I due tagli con testa da sotto di un cubetto sono fatti di seguito. +-- 2021/06/06 Correzioni per tagli con testa da sotto. +-- 2021/07/14 Migliorie per tagli con testa da sotto. +-- 2021/09/19 Tagli da sotto non sbiechi favorita posizione da sopra di testa. +-- 2021/10/06 Piccola correzione a tagli di cubetti con testa da sotto. +-- 2022/01/26 Taglio da sotto orizzontale deve avere direzione di riferimento ortogonale -Z. +-- 2022/02/02 Modifiche per tagli di coda spostati prima come lavorazione su pezzi a caduta. +-- 2022/02/06 Correzioni per tagli di coda spostati prima. + +-- Tabella per definizione modulo +local ProcessCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local DC = require( 'DiceCut') +local LongCut = require( 'ProcessLongCut') + +EgtOutLog( ' ProcessCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessCut.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessCut.Classify( Proc, b3Raw) + -- se PF con testa da sotto, ammessa qualunque orientazione + if BD.C_SIMM and BD.DOWN_HEAD then + return true + end + -- recupero i dati del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN:getZ() <= - 0.5 and abs( vtN:getY()) > 0.1 or ( vtN:getZ() <= - 0.174 and abs( vtN:getY()) > 0.866) then + local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0) + if DimH > BD.MAX_DIM_DICE then + return true, true + end + end + -- verifico se c'è un taglio da sotto e se è nei limiti + local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw) + local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) + if bDownCut then + local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0) + -- confronto anche qua la distanza maggiore della faccia con la massima distanza del DiceCut + -- e se il rapporto supera il 2 (implica che genera 3 tagli) dichiaro impossibile la lavorazione + if DimH and BD.MAX_DIM_DICE and abs( BD.MAX_DIM_DICE) > 20 * GEO.EPS_SMALL and abs( DimH / BD.MAX_DIM_DICE) > 2 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Piano di taglio della feature +function ProcessCut.GetCutPlane( Proc) + if ProcessCut.Identify( Proc) then + return EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + else + return nil, nil + end +end + +--------------------------------------------------------------------- +-- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) +local function VerifyCurveForChamfer( AuxId) + if not AuxId then + return -2 + end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + return -1 + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- va bene solo se direzione estrusione orizzontale + if abs( vtExtr:getZ()) > 0.1 then + return 0 + end + return 1 +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico le entità curva associate (max 2) + local sVal = EgtGetInfo( Proc.Id, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local AuxId, Aux2Id + if vsAuxId and #vsAuxId >=1 then + AuxId = tonumber( vsAuxId[1]) + end + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if AuxId then AuxId = AuxId + Proc.Id end + if Aux2Id then Aux2Id = Aux2Id + Proc.Id end + local nRes = VerifyCurveForChamfer( AuxId) + if nRes == 0 and Aux2Id then + AuxId = Aux2Id + nRes = VerifyCurveForChamfer( AuxId) + end + if nRes == -2 then + return true + end + if nRes == -1 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + if nRes == 0 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true, nil +end + +--------------------------------------------------------------------- +-- Aggiornamento ingombro +local function UpdateEncumbrance( Proc, vtN, dOvmHead, nRawId, b3Solid, b3Raw) + -- eventuale segnalazione ingombro di testa o coda (se non chiamata da altre feature) + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if ProcessCut.Identify( Proc) and Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtN:getZ() > 0.5 then + dOffs = dOffs - 0.6 * Proc.Box:getDimX() + elseif vtN:getZ() < -0.5 then + dOffs = dOffs - 0.2 * Proc.Box:getDimX() + elseif ( abs( vtN:getY()) > 0.9 and vtN:getZ() > 0.2) then + dOffs = dOffs - 0.3 * Proc.Box:getDimX() + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtN:getZ() > 0.5 then + dOffs = dOffs - 0.6 * Proc.Box:getDimX() + elseif vtN:getZ() < -0.5 then + dOffs = dOffs - 0.2 * Proc.Box:getDimX() + elseif ( abs( vtN:getY()) > 0.9 and vtN:getZ() > 0.2) then + dOffs = dOffs - 0.3 * Proc.Box:getDimX() + end + BL.UpdateTCING( nRawId, dOffs) + end + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione con testa da sopra +local function MakeFromTop( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- limiti di taglio (se molto di lato e inclinati sono permessi fino a -45deg) + local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw, vtN) + local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) + if bFromBottom == nil then + bFromBottom = ( vtN:getZ() > 0.25 and b3Solid:getDimX() < BD.LEN_SHORT_PART and not Proc.AdvTail and vtN:getX() < 0) + end + -- verifico se da considerare taglio lungo ( non da sotto, inclinato non più di 30deg, largo come la trave e abbastanza lungo) + local bLongCut = ( not bDownCut and vtN:getZ() > 0.865 and + Proc.Box:getDimY() > b3Solid:getDimY() - 10 * GEO.EPS_SMALL and + ( Proc.Box:getDimX() > 0.75 * b3Solid:getDimX() or Proc.Box:getDimX() > 600.000)) + -- se taglio lungo e Q04 = 1 allora lancio il processo dell'L10 + if bLongCut and EgtGetInfo( Proc.Id, 'Q04', 'i') == 1 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, true) + end + -- se pezzo ancora attaccato alla trave, per non rovinare quello successivo + local bFillAreaPiece + local bFillTail + if not BL.IsSplittedPartPhase( nPhase) then + -- se non da sotto + if not bDownCut then + bFillAreaPiece = bCustDiceCut + -- se true il controllo è già stato fatto dal modulo che ha chiamato il ProcessCut + if not bFillAreaPiece then + -- se poco inclinata ( inclinazione inferiore a 21.56 deg) + if vtN:getZ() > 0.93 then + -- si possono far partire i tagli a cubetti dalla testa + bFillAreaPiece = bLongCut + -- se praticamente verticale di fianco ( inclinazione inferiore a 21.56deg) + elseif abs( vtN:getY()) > 0.93 then + -- se la faccia occupa tutta la trave in X e Z o occupa sicuramente la faccia in Z e almeno 3/4 della faccia in X e sborda in X, + if ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) or + ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) and + Proc.Box:getDimX() > 0.75 * b3Solid:getDimX())) and + abs( Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getZ() - b3Solid:getMax():getZ()) < 10*GEO.EPS_SMALL then + local sErr = 'Error : Impossible to machine by orientation (on side)' + EgtOutLog( sErr) + return false, sErr + end + end + end + -- se quasi orizzontale ( inclinazione inferiore a 30) + if vtN:getZ() > 0.866 then + -- se la faccia termina davanti o dietro la trave e arriva in coda e non interessa la faccia inferiore, forzo il taglio a cubetti a partire dal davanti + if ( abs( Proc.Box:getMin():getY() - b3Solid:getMin():getY()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getY() - b3Solid:getMax():getY()) < 10*GEO.EPS_SMALL) and + abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and b3Solid:getMin():getZ() < Proc.Box:getMin():getZ() - 100 * GEO.EPS_SMALL then + bFillTail = true + end + -- se verticale quasi completamente di fianco ( inclinazione inferiore a 30) + elseif abs( vtN:getY()) > 0.866 then + -- se la faccia termina davanti o dietro la trave e arriva in coda e non interessa la faccia inferiore, forzo il taglio a cubetti a partire dal davanti + if ( abs( Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getZ() - b3Solid:getMax():getZ()) < 10*GEO.EPS_SMALL) and + abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL then + local sErr = 'Error : Impossible to machine by orientation (on side)' + EgtOutLog( sErr) + return false, sErr + end + end + end + end + -- se vero taglio, eventuale inserimento smussi + if Proc.Prc == 10 then + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 2 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + local dMaxVertDepth = dMaxDepth - ( BD.DECR_VERT_CUT or 0) + -- determino la direzione di taglio preferenziale + local frFac, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0) + dCutH = min( dCutH, b3Raw:getDimY() / abs( frFac:getVersX():getY())) + local bHorizCut = ( dCutV < dMaxVertDepth - BD.CUT_EXTRA and not bDownCut) + local bVertCutOk = ( dCutH < dMaxDepth - BD.CUT_EXTRA) + -- verifico se necessari tagli supplementari + EgtOutLog( string.format( 'MaxDepth=%.1f MaxVertDepth=%.1f CutH=%.1f CutV=%.1f', dMaxDepth, dMaxVertDepth, dCutH, dCutV), 3) + local vCuts = {} + if not Proc.AdvTail and ( dCutH > dMaxDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC or dCutV > dMaxVertDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC) then + local ptExtra, vtExtra + local bAutoCalcSurf = true + if bFillAreaPiece or bFillTail then + local ptMiddle = ( b3Solid:getMin() + b3Solid:getMax()) / 2 + ptExtra = Point3d( b3Solid:getMin():getX() + 5*GEO.EPS_SMALL, ptMiddle:getY(), ptMiddle:getZ()) + vtExtra = X_AX() + bAutoCalcSurf = false + end + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxVertDepth - BD.CUT_EXTRA) + -- se taglio sborda in coda e non è stato inserito nessun taglio a cubetti, lo rilancio con le dimensioni customizzate + if ( bFillTail or bCustDiceCut) and #vCuts == 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxVertDepth - BD.CUT_EXTRA, Proc.Box:getDimY()) + end + end + -- se il ProcessCut viene lanciato dal ProcessSawCut e non ci sono tagli a cubetti, esco + if bCustDiceCut and #vCuts == 0 then + return false, -1 + end + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + local bOrthInv = false + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + if ( i % 2) == 1 then + local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) + if ( vtN:getY() > 0.707 and vtO:getY() < -0.05) or + ( vtN:getY() < -0.707 and vtO:getY() > 0.05) then + EgtInvertSurf( vCuts[i][j]) + bOrthInv = true + end + end + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local vtOrthoO + local bNoPerpCuts = false + if i % 2 == 1 then + vtOrthoO = Vector3d( vtN) + else + local vtO + if #vCuts[i-1] > 0 then + vtO = EgtSurfTmFacetNormVersor( vCuts[i-1][1], 0, GDB_ID.ROOT) + elseif vCuts[i+1] and #vCuts[i+1] > 0 then + -- lunghezza faccia nell'eventuale direzione ortogonale + local asseX = EgtSurfTmFacetNormVersor( vCuts[i+1][1], 0, GDB_ID.ROOT) + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + local b3Fac = EgtGetBBoxRef( vCuts[i][1], GDB_BB.STANDARD, Frame) + -- se lunghezza inferiore al limite, accetto la direzione + if b3Fac:getDimX() < dMaxDepth - BD.CUT_EXTRA then + vtO = asseX + else + bNoPerpCuts = true + end + else + bNoPerpCuts = true + end + if vtO then + vtOrthoO = Vector3d( vtO) * EgtIf( bOrthInv, -1, 1) + else + if bHorizCut then + vtOrthoO = Z_AX() + elseif vtN:getY() > -0.02 then + if not Proc.Head then + vtOrthoO = -Y_AX() + else + vtOrthoO = Y_AX() + end + else + vtOrthoO = -Y_AX() + end + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se taglio dal basso + if bDownCut then + -- se strato pari composto da 1 o 2 elementi + if ( i % 2) == 0 and #vCuts[i] <= 2 then + -- il primo elemento prende la direzione prevista, il secondo quella opposta + local vtNewOrthoO = Vector3d( vtOrthoO) + local dVzLimDwnUp = dNzLimDwnUp + if j ~= 1 then + vtNewOrthoO = -vtOrthoO + if not BD.C_SIMM and abs( vtN:getY()) > 0.05 then dVzLimDwnUp = -0.707 end + end + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtNewOrthoO, dVzLimDwnUp, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- tutti gli altri casi vengono saltati + -- caso generale + else + -- in generale sta sollevato di pochissimo + local dExtraCut = -0.1 + -- se tagli paralleli + if ( i % 2) == 0 then + -- se non ci sono tagli ortogonali devo affondare + if bNoPerpCuts then + dExtraCut = BD.CUT_EXTRA + -- se altrimenti tagli ortogonali invertiti, devo approfondire dello spessore lama + elseif bOrthInv then + dExtraCut = dSawThick + -- se ultimo taglio, devo affondare + elseif j == #vCuts[i] then + dExtraCut = BD.CUT_EXTRA + end + end + local dVzLimDwnUp = dNzLimDwnUp + if not BD.C_SIMM and vtN:getZ() > 0.707 then dVzLimDwnUp = -0.708 end + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, dVzLimDwnUp, dExtraCut, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + end + -- altrimenti tagli diretti della faccia + else + -- impostazioni + local dVzLimDwnUp = dNzLimDwnUp + local dCutExtra = BD.CUT_EXTRA + if Proc.AdvTail then + if bHorizCut then dVzLimDwnUp = 0 end + dCutExtra = -BD.ADVANCE_TAIL_OFFS + end + -- lavoro la faccia + local vtOrthoO + if bFromBottom and dCutV < dMaxVertDepth - BD.CUT_EXTRA and vtN:getZ() > 0 then + vtOrthoO = -Z_AX() + elseif bHorizCut and ( not bVertCutOk or b3Solid:getDimX() > BD.LEN_SHORT_PART or Proc.AdvTail or vtN:getX() > 0) then + vtOrthoO = Z_AX() + elseif b3Solid:getDimX() < BD.LEN_SHORT_PART and not Proc.AdvTail and abs( vtN:getY()) > 0.259 and + vtN:getZ() > -0.174 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then + if Proc.Head then + vtOrthoO = X_AX() + else + vtOrthoO = -X_AX() + end + elseif vtN:getZ() < dVzLimDwnUp and abs( vtN:getY()) > 0.259 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then + if Proc.Head then + vtOrthoO = X_AX() + else + vtOrthoO = -X_AX() + end + elseif Proc.Head then + vtOrthoO = EgtIf( vtN:getY() > -0.02, -Y_AX(), Y_AX()) + else + vtOrthoO = EgtIf( vtN:getY() > 0.02, Y_AX(), -Y_AX()) + end + -- taglio + local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, dVzLimDwnUp, dCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- Aggiornamento ingombro + UpdateEncumbrance( Proc, vtN, dOvmHead, nRawId, b3Solid, b3Raw) + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione con testa da sotto +local function MakeFromDown( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- se vero taglio, eventuale inserimento smussi + if Proc.Prc == 10 then + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 2 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + local dMaxVertDepth = dMaxDepth + -- determino la direzione di taglio preferenziale + local frFac, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0) + dCutH = min( dCutH, b3Raw:getDimY() / abs( frFac:getVersX():getY())) + local bHorizCut = ( dCutV < dMaxVertDepth - BD.CUT_EXTRA) or Proc.AdvTail + -- verifico se necessari tagli supplementari + EgtOutLog( string.format( 'MaxDepth=%.1f MaxVertDepth=%.1f CutH=%.1f CutV=%.1f', dMaxDepth, dMaxVertDepth, dCutH, dCutV), 3) + local vCuts = {} + if not Proc.AdvTail and ( dCutH > dMaxDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC or dCutV > dMaxVertDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC) then + local ptExtra, vtExtra + local bAutoCalcSurf = true + if bFillAreaPiece or bFillTail then + local ptMiddle = ( b3Solid:getMin() + b3Solid:getMax()) / 2 + ptExtra = Point3d( b3Solid:getMin():getX() + 5 * GEO.EPS_SMALL, ptMiddle:getY(), ptMiddle:getZ()) + vtExtra = X_AX() + bAutoCalcSurf = false + end + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxVertDepth - BD.CUT_EXTRA, nil ,true) + end + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + local bOrthInv = false + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + if ( i % 2) == 1 then + local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) + if ( vtN:getY() > 0.707 and vtO:getY() < -0.05) or + ( vtN:getY() < -0.707 and vtO:getY() > 0.05) then + EgtInvertSurf( vCuts[i][j]) + bOrthInv = true + end + end + end + end + -- eseguo (facendo di seguito i due tagli di ogni singolo cubetto) + for i = 1, #vCuts, 2 do + -- determino il modo di tagliare dei perpendicolari + local vtOrthoO_1 = Vector3d( vtN) + -- determino il modo di tagliare dei paralleli + local vtOrthoO_2 + local bNoPerpCuts_2 = false + local vtO + if #vCuts[i] > 0 then + vtO = EgtSurfTmFacetNormVersor( vCuts[i][1], 0, GDB_ID.ROOT) + elseif vCuts[i+2] and #vCuts[i+2] > 0 then + -- lunghezza faccia nell'eventuale direzione ortogonale + local asseX = EgtSurfTmFacetNormVersor( vCuts[i+2][1], 0, GDB_ID.ROOT) + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + local b3Fac = EgtGetBBoxRef( vCuts[i+1][1], GDB_BB.STANDARD, Frame) + -- se lunghezza inferiore al limite, accetto la direzione + if b3Fac:getDimX() < dMaxDepth - BD.CUT_EXTRA then + vtO = asseX + else + bNoPerpCuts_2 = true + end + else + bNoPerpCuts_2 = true + end + if vtO then + vtOrthoO_2 = Vector3d( vtO) * EgtIf( bOrthInv, -1, 1) + else + if bHorizCut then + vtOrthoO_2 = -Z_AX() + elseif vtN:getY() > -0.02 then + if not Proc.Head then + vtOrthoO_2 = -Y_AX() + else + vtOrthoO_2 = Y_AX() + end + else + vtOrthoO_2 = -Y_AX() + end + end + -- lavoro le coppie di facce del singolo cubetto + for j = 1, max( #vCuts[i], #vCuts[i+1]) do + -- extra taglio per perpendicolari + local dExtraCut_1 = -0.1 + -- extra taglio per paralleli + local dExtraCut_2 = -0.1 + -- se non ci sono tagli ortogonali devo affondare + if bNoPerpCuts_2 then + dExtraCut_2 = BD.CUT_EXTRA + -- se altrimenti tagli ortogonali invertiti, devo approfondire dello spessore lama + elseif bOrthInv then + dExtraCut_2 = dSawThick + -- se ultimo taglio, devo affondare + elseif j == #vCuts[i+1] then + dExtraCut_2 = BD.CUT_EXTRA + end + -- taglio perpendicolare (limite Vz Down Up messo a -2 per non farlo mai intervenire) + if vCuts[i][j] then + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO_1, -2, dExtraCut_1, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- taglio parallelo (limite Vz Down Up messo a -2 per non farlo mai intervenire) + if vCuts[i+1][j] then + local bOk, sErr = Fbs.MakeOne( vCuts[i+1][j], 0, sCutting, dSawDiam, vtOrthoO_2, -2, dExtraCut_2, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + end + -- altrimenti tagli diretti della faccia + else + -- lavoro la faccia + local vtOrthoO + if bHorizCut and ( b3Solid:getDimX() > BD.LEN_SHORT_PART or Proc.AdvTail or vtN:getX() > 0) then + vtOrthoO = -Z_AX() + elseif b3Solid:getDimX() < BD.LEN_SHORT_PART and not Proc.AdvTail and abs( vtN:getY()) > 0.259 and vtN:getZ() > -0.174 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then + if Proc.Head then + vtOrthoO = X_AX() + else + vtOrthoO = -X_AX() + end + elseif abs( vtN:getY()) > 0.259 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then + if Proc.Head then + vtOrthoO = X_AX() + else + vtOrthoO = -X_AX() + end + elseif vtN:getY() > -0.02 then + if Proc.Head then + vtOrthoO = -Y_AX() + else + vtOrthoO = Y_AX() + end + else + if Proc.Head then + vtOrthoO = Y_AX() + else + vtOrthoO = -Y_AX() + end + end + -- taglio (limite Vz Down Up messo a -2 per non farlo mai intervenire) + local dCutExtra = BD.CUT_EXTRA + if Proc.AdvTail then + dCutExtra = min( -BD.ADVANCE_TAIL_OFFS, dMaxVertDepth - dCutV) + end + local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, -2, dCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- Aggiornamento ingombro + UpdateEncumbrance( Proc, vtN, dOvmHead, nRawId, b3Solid, b3Raw) + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- se taglio di testa + if Proc.Head then + -- se coincide con il taglio di separazione precedente, non va fatto + if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- altrimenti taglio di coda + else + -- se coincide con taglio di separazione, non va fatto + if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + end + -- se coincide con un taglio frontale non va fatto + if Proc.CutFront then + return true + end + -- abilitazione lavorazione da sotto (testa da sotto e direzione normale sotto -20deg e sbandato oltre 1deg oppure sezione larga o pezzo corto) + local bDownHead = ( BD.DOWN_HEAD and vtN:getZ() < -0.341 and + ( abs( vtN:getY()) > 0.017 or b3Raw:getDimY() > 2 * ( BD.MAX_DIM_HTCUT - BD.CUT_EXTRA_MIN) or b3Raw:getDimX() < BD.LEN_SHORT_PART)) + local bTopHead = ( BD.DOWN_HEAD and ( vtN:getZ() > -0.342 or not bDownHead)) + -- recupero la lavorazione + local sCutType = EgtIf( Proc.Head, 'HeadSide', 'TailSide') + local sCutting = ML.FindCutting( sCutType .. EgtIf( bDownHead, '_H2', '')) + if not sCutting and bTopHead then + sCutting = ML.FindCutting( sCutType) + bDownHead = false + end + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- se taglio con testa da sopra + if not bDownHead then + return MakeFromTop( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut) + -- altrimenti taglio con testa da sotto + else + return MakeFromDown( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut) + end +end + +--------------------------------------------------------------------- +return ProcessCut diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDecor.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDecor.lua new file mode 100644 index 0000000..4a7ecd8 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDecor.lua @@ -0,0 +1,81 @@ +-- ProcessDecor.lua by Egaltech s.r.l. 2018/04/18 +-- Gestione calcolo decoro per Travi + +-- Tabella per definizione modulo +local ProcessDecor = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDecor started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDecor.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 959) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDecor.Classify( Proc) + -- recupero i dati della decorazione + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico sia una decorazione + if not vtExtr then + return false + end + -- verifico se la decorazione è lavorabile solo da sotto + local bDown = (( vtExtr:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDecor.Make( Proc, nPhase, nRawId, nPartId) + -- recupero i dati della decorazione + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico che la decorazione non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Decor from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sToFind = EgtGetInfo( Proc.Id, 'P15') + local sMilling = ML.FindMilling( sToFind) + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessDecor diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDoubleCut.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDoubleCut.lua new file mode 100644 index 0000000..900fd3d --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDoubleCut.lua @@ -0,0 +1,346 @@ +-- ProcessDoubleCut.lua by Egaltech s.r.l. 2021/11/25 +-- Gestione calcolo doppi tagli di lama per Travi + +-- Tabella per definizione modulo +local ProcessDoubleCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessDoubleCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDoubleCut.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 11) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDoubleCut.Classify( Proc, b3Raw) + --se una faccia, uso la classificazione dei tagli singoli + if Proc.Fct == 1 then return Cut.Classify( Proc, b3Raw) end + -- se PF con testa da sotto, ammessa qualunque orientazione + if BD.C_SIMM and BD.DOWN_HEAD then + return true + end + -- limite per facce da sotto + local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw) + -- verifico se convesso + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = ( not bAdj or ( dAng > 0)) + if bConvex then + -- recupero i dati di ogni singola faccia + for i = 1, 2 do + local nFac = i - 1 + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFac, GDB_ID.ROOT) + if ( vtN:getZ() <= - 0.5 and abs( vtN:getY()) > 0.1) or ( vtN:getZ() <= - 0.174 and abs( vtN:getY()) > 0.866) then + local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, nFac) + if DimH > BD.MAX_DIM_DICE then + return true, true + end + end + local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) + if bDownCut then + local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, nFac) + -- confronto anche qua la distanza maggiore della faccia con la massima distanza del DiceCut + -- e se il rapporto supera il 2 (implica che genera 3 tagli) dichiaro impossibile la lavorazione + if DimH and BD.MAX_DIM_DICE and abs( BD.MAX_DIM_DICE) > 20 * GEO.EPS_SMALL and abs( DimH / BD.MAX_DIM_DICE) > 2 then + return true, true + end + end + end + return true, false + end + -- altrimenti concavo, verifico le normali delle facce per tagli da sotto + for i = 1, 2 do + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + local bDownCut = ( vtN:getZ() <= dNzLimDwnUp) + if bDownCut then + -- dimensione della faccia perpendicolare alla linea di intersezione tra le facce + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, 2-i, GDB_ID.ROOT) + local vtX = vtN2 ^ vtN + local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2) + local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, i-1, GDB_BB.STANDARD, frRef) + if b3Ref:getDimY() > BD.MAX_DIM_DICE then + return true, true + end + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId then return true end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale o anche testa da sotto (non propago la segnalazione a TS3) + local bVert = ( abs( vtExtr:getZ()) > 0.1) + if bVert and not BD.DOWN_HEAD then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if ( not bVert and dWidth < b3Raw:getDimY() - 1) or ( bVert and dWidth < b3Raw:getDimZ() - 1) then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling (Mark) not found in library' + EgtOutLog( sErr) + return false, sErr + end + local sMillingDw = ML.FindMilling( 'Mark_H2') + if bVert and not sMillingDw then + local sErr = 'Error : milling (Mark_H2) not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, EgtIf( not bVert or vtExtr:getZ() > 0.1, sMilling, sMillingDw)) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, EgtIf( not bVert or vtExtr:getZ() < -0.1, sMilling, sMillingDw)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDoubleCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- se singola faccia, passo a quella lavorazione + if Proc.Fct == 1 then return Cut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- se convesso, lo tratto come due tagli singoli + if bConvex then + -- lavoro per prima la faccia più diretta in alto + local vOrd = { 1, 2} + if vtN[2]:getZ() > vtN[1]:getZ() then + vOrd = { 2, 1} + end + -- creo piano di taglio coincidente con la prima faccia e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[1]], vtN[vOrd[1]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + local b3Add = EgtGetBBoxGlob( AddId, GDB_BB.STANDARD) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = 10, Box = b3Add, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + end + -- creo piano di taglio coincidente con la seconda faccia e lo lavoro + AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[2]], vtN[vOrd[2]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + local b3Add = EgtGetBBoxGlob( AddId, GDB_BB.STANDARD) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = 10, Box = b3Add, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + end + -- altrimenti concavo + else + -- abilitazione lavorazione da sotto (testa da sotto e direzione normale sotto -30deg) + local bTopHead = ( BD.DOWN_HEAD and vtNm:getZ() > -0.5) + local bDownHead = ( BD.DOWN_HEAD and vtNm:getZ() < -0.5) + -- recupero la lavorazione + local sCutType = EgtIf( bHead, 'HeadSide', 'TailSide') + local sCutting = ML.FindCutting( sCutType .. EgtIf( bDownHead, '_H2', '')) + if not sCutting and bTopHead then + sCutting = ML.FindCutting( sCutType) + bDownHead = false + end + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- aggiorno nome e info + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local vtOrthOpp = vtN[nBigInd] + local vtNorm = vtN[nSmaInd] + if ( i % 2) ~= 1 then vtOrthOpp, vtNorm = vtNorm, vtOrthOpp end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthOpp, EgtIf( bDownHead, -2, nil), 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, sCutType .. EgtIf( bDownHead, '_H2', ''), false, bDownHead) + if not bOk then + return bOk, sErr + end + end + -- segnalazione ingombro di testa o coda + if Proc.Head then + -- intersezioni con linee a metà altezza appena dentro dal davanti e dal dietro + local ptRef = b3Raw:getCenter() - 0.5 * b3Raw:getDimX() * X_AX() + local ptL1 = ptRef - ( 0.5 * b3Raw:getDimY() - 0.1) * Y_AX() + local ptL2 = ptRef + ( 0.5 * b3Raw:getDimY() - 0.1) * Y_AX() + local bInt1, IntTy1, IntPar1 = EgtLineSurfTmInters( ptL1, X_AX(), Proc.Id, GDB_ID.ROOT) + local bInt2, IntTy2, IntPar2 = EgtLineSurfTmInters( ptL2, X_AX(), Proc.Id, GDB_ID.ROOT) + local dMinPar = b3Raw:getDimX() + if IntPar1 and #IntPar1 > 0 then + dMinPar = min( dMinPar, IntPar1[1]) + end + if IntPar2 and #IntPar2 > 0 then + dMinPar = min( dMinPar, IntPar2[1]) + end + local dOffs = b3Raw:getDimX() - dMinPar + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + -- accetto approssimazione più grezza + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.4 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessDoubleCut diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDovetail.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDovetail.lua new file mode 100644 index 0000000..f5b1dd3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDovetail.lua @@ -0,0 +1,1779 @@ +-- ProcessDovetail.lua by Egaltech s.r.l. 2021/02/04 +-- Gestione calcolo giunzione coda di rondine + +-- Tabella per definizione modulo +local ProcessDovetail = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessDovetail started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sUseRoughTool = '' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDovetail.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 138) +end + +--------------------------------------------------------------------- +local function AssignQValues( Proc) + + -- reset delle variabili assegnazione parametri Q + sUseRoughTool = '' + + if Proc.Prc == 138 then + sUseRoughTool = 'Q02' -- d + end +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc, sUseRoughTool) + + local bForceUseRough = false + -- verifico se devo usare il truciolatore + -- 2020-03-20 forzata disabilitazione uso truciolatore se parametro Q non è presente + if #sUseRoughTool == 0 or EgtGetInfo( Proc.Id, sUseRoughTool, 'i') == 2 then + bForceUseRough = true + end + + return bForceUseRough +end + +--------------------------------------------------------------------- +local function OrderFaces( Proc, vtN) + + local dMinXFace = 0.99 + local dPosXFace = 0 + local dNegXFace = 0 + local vFaceOrd = { 0, 0, 0} + + -- se 2 facce : ordine (1=0, 2=interna, 3=intermedia) + if #vtN <= 2 then + for i = 1, #vtN do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinXFace then + dMinXFace = dXVal + vFaceOrd[3] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, #vtN do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- se 3 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia) + elseif #vtN == 3 then + for i = 1, #vtN do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinXFace then + dMinXFace = dXVal + vFaceOrd[3] = i + end + if dXVal > dPosXFace then + dPosXFace = dXVal + vFaceOrd[2] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + if vFaceOrd[2] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing internal face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, #vtN do + if i ~= vFaceOrd[3] and i ~= vFaceOrd[2] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + vFaceOrd[1] = i + end + end + end + -- se 4 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia, 4=esterna) + else + for i = 1, #vtN do + if vtN[i]:getX() > dPosXFace then + dPosXFace = vtN[i]:getX() + vFaceOrd[2] = i + end + if vtN[i]:getX() < dNegXFace then + dNegXFace = vtN[i]:getX() + vFaceOrd[4] = i + end + end + if vFaceOrd[2] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing internal face' + EgtOutLog( sErr) + return false, sErr + end + if vFaceOrd[4] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing external face' + EgtOutLog( sErr) + return false, sErr + end + local nMidFace = 3 + for i = 1, #vtN do + if i ~= vFaceOrd[2] and i ~= vFaceOrd[4] then + vFaceOrd[nMidFace] = i + nMidFace = 1 + end + end + if vFaceOrd[1] == 0 or vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing middle face' + EgtOutLog( sErr) + return false, sErr + end + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[1] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' wrong angle between middle faces' + EgtOutLog( sErr) + return false, sErr + end + end + return true, '', vFaceOrd +end + +--------------------------------------------------------------------- +local function VerifyIfRoughMill( dLargeFace, vtN, bCalcElev, dAngOnSide) + local bUseRoughMill = false + local sMilling + -- recupero la lavorazione + if dAngOnSide then + if bCalcElev then + local dCollSic = BD.COLL_SIC + -- se direzione tende verso una delle 3 direzioni azzero l'altezza extra + if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end + sMilling = ML.FindMilling( 'ProfTCone', dLargeFace + dCollSic) + else + sMilling = ML.FindMilling( 'ProfTCone') + end + else + if bCalcElev then + local dCollSic = BD.COLL_SIC + -- se direzione tende verso una delle 3 direzioni azzero l'altezza extra + if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end + sMilling = ML.FindMilling( 'Long2Cut', dLargeFace + dCollSic) + else + sMilling = ML.FindMilling( 'Long2Cut') + end + dAngOnSide = 0 + end + if sMilling then + -- recupero i dati dell'utensile + local dToolDiam = 100 + local dToolLength = 0 + local dMaxDepth = 0 + local dMaxMat = 50 + local dSideAngle = 0 + local dMachStep = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + -- ottengo il passo della lavorazione + dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep + end + end + if dMachStep <= 0.1 then + dMachStep = dMaxMat * 0.5 + end + -- se ho già fatto la ricerca lavorazione considerando l'elevazione controllo solo l'angolo + if bCalcElev then + -- se angolo spoglia compatibile + if abs( dSideAngle - dAngOnSide) < GEO.EPS_SMALL then + return true, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep + end + else + -- se altezza taglio utensile maggiore altezza faccia e angolo spoglia compatibile + if ( dMaxDepth > dLargeFace + 10 * GEO.EPS_SMALL) and ( abs( dSideAngle - dAngOnSide) < GEO.EPS_SMALL) then + return true, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep + end + end + end + + return false +end + +--------------------------------------------------------------------- +local function AddFaceToSurf( Proc, nPartId, b3Solid) + + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + -- punto medio sulla faccia + local ptN = Point3d( b3Solid:getMin():getX(), ( b3Solid:getMin():getY() + b3Solid:getMax():getY())/2, ( b3Solid:getMin():getZ() + b3Solid:getMax():getZ())/2) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN, -X_AX(), b3Solid, GDB_ID.ROOT) + -- se esiste la superfice aggiunta, la ritaglio la superficie con le facce + if nSurfInt then + -- inverto la normale + EgtInvertSurf( nSurfInt) + for i = 1, Proc.Fct do + local ptN, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) + end + -- unisco la nuova superfice + if nSurfInt then + local bOk = EgtSurfTmAdd( nNewProc, nSurfInt) + if bOk then + EgtErase( nSurfInt) + Proc.Id = nNewProc + Proc.Fct = EgtSurfTmFacetCount( nNewProc) + end + end + end +end + +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessDovetail.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() > 0.1 then + return true + end + end + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 *b3Raw:getDimX()) then + return false + end + -- se una o due facce ora è sicuramente di testa + if Proc.Fct <= 2 then + return true + end + -- deve avere la normale principale diretta verso la testa + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN:getX() < 0.499 then + return false + elseif Proc.Fct >= 5 then + return true + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDovetail.IsTailFeature( Proc, b3Raw) + -- recupero identificativo del pezzo + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() < -0.1 then + -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione + if b3Solid:getDimX() > BD.LEN_SHORT_PART then + return true + else + -- aggiungo faccia + AddFaceToSurf( Proc, nPartId, b3Solid) + return false + end + end + end + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then + return false + end + -- se due facce e interessa veramente la coda, allora di coda + if Proc.Fct <= 2 then + if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then + -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione + if b3Solid:getDimX() > BD.LEN_SHORT_PART then + return true + else + -- aggiungo faccia + AddFaceToSurf( Proc, nPartId, b3Solid) + return false + end + end + end + -- deve avere la normale principale diretta verso la coda + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + end + if vtN:getX() > -0.499 then + return false + else + -- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione + if b3Solid:getDimX() > BD.LEN_SHORT_PART then + return true + else + -- aggiungo faccia + AddFaceToSurf( Proc, nPartId, b3Solid) + return false + end + end +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDovetail.Classify( Proc, b3Raw) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- verifico se sono presenti i parametri Q per l'uso forzato del truciolatore + local bForceUseRough = EvaluateQParam( Proc, sUseRoughTool) + -- verifico le normali delle facce + local nFlatFaceNeg + local bDown = false + -- individuo se c'è faccia rivolta verso Z- + for i = 1, Proc.Fct do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < -0.99 then + nFlatFaceNeg = i - 1 + break + end + end + -- se trovata faccia rivolta verso Z- + if nFlatFaceNeg then + -- se 3 o più facce sicuramente è in mezzo, setto il ribaltamento senza ulteriori controlli + if Proc.Fct >= 3 then + bDown = true + -- altrimenti è in testa o coda e verifico se lavorabile da sotto + else + -- prendo le dimensioni della faccia + local nOtherFace = 1 - nFlatFaceNeg + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT) + -- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama e non fattibile con truciolatore + if dAng > -89.99 and dAng < 0 then + bDown = true + -- altrimenti, verifico se lunghezza faccia piatta è compatibile con il taglio di lama + else + local dLargeFace = Proc.Box:getDimX() + local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeFace, -Z_AX(), true) + -- se forzato uso truciolatore + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + end + end + -- altrimenti controllo la componente in Z delle facce + else + local vtN = {} + for i = 1, Proc.Fct do + vtN[i] = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT) + end + for i = 1, Proc.Fct do + local nFacet = i - 1 + -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + if abs( vtN[i]:getZ()) > abs( vtN[i]:getX()) and abs( vtN[i]:getZ()) > abs( vtN[i]:getY()) and vtN[i]:getZ() < -0.5 then + -- se ho due facce e feature agli estremi verifico che la lunghezza faccia sia compatibile col taglio di lama + -- o con truciolatore in base al valore del Q + if Proc.Fct == 2 and ( Proc.Head or Proc.Tail) then + -- prendo le dimensioni della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local nOtherFace = EgtIf( nFacet == 0, nFacet + 1, nFacet - 1) + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) + -- se angolo interno acuto + if dAng < 0 and dAng < -90 - 5 * GEO.EPS_SMALL then + -- se forzato truciolatore allora controllo se posso fare con utensile tronco di cono + local dLargeface = Proc.Box:getDimX() + local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true, (90+dAng)) + -- se forzato uso truciolatore + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + -- altrimenti angolo interno a 90 + else + local dDist = dist( ptP1, ptP2) + local dLargeface + local dDeltadH = abs( dDist - dH) + local dDeltadV = abs( dDist - dV) + -- prendo la dimensione diversa dalla lunghezza di adiacenza + if dDeltadH < dDeltadV then + dLargeface = dV + else + dLargeface = dH + end + -- se (anche) la direzione in z dell'altra faccia è negativa verifico se posso farla di fresa (in base alle impostazioni del Q) + if vtN[nOtherFace+1]:getZ() < -0.001 then + -- se forzato uso truciolatore verifico se posso fare di truciolatore + if bForceUseRough then + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) + bDown = not bUseRough + -- altrimenti posso usare lama, ma (anche) la direzione in z dell'altra faccia è negativa, quindi non è lavorabile, setto il ribaltamento + else + bDown = true + end + else + local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) + -- se forzato uso truciolatore + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + end + end + elseif Proc.Fct == 3 and ( Proc.Head or Proc.Tail) then + -- ordino le 3 facce: (1=altra intermedia, 2=interna, 3=intermedia) + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1 end + -- se le due facce intermedie sono compatibili con la lunghezza lama da sotto + -- prendo le dimensioni della facce + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vFaceOrd[3]-1, GDB_ID.ROOT) + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3]-1, vFaceOrd[1]-1, GDB_ID.ROOT) + -- prendo la dimensione uguale dalla lunghezza di adiacenza + local dLargeface = dist( ptP1, ptP2) + local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true) + -- se forzato uso truciolatore e non riesco a farlo + if bForceUseRough then + bDown = not bUseRough + -- altrimenti uso misto tra lama e truciolatore + else + bDown = not bUseBlade and not bUseRough + end + elseif not Proc.Head and not Proc.Tail then + bDown = true + end + end + end + end + return true, bDown +end + +--------------------------------------------------------------------- +local function MakeCutsByDice( Proc, b3Raw, vCuts, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) + + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + vtOrthoO = Vector3d( vtRef2) + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( i == ( #vCuts - 1) or i == #vCuts) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < ( #vCuts - 1) or i == #vCuts then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -( dTrim + dExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + + return true +end + +--------------------------------------------------------------------- +local function MachChainFacesByBlade( Proc, nCFaceSide, nCFaceInt1, nCFaceInt2, sCutting, bHead, vtRef, dTrim, dDepth) + + -- inserisco la lavorazione di taglio per la laterale negativa + local sName = 'Cut_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. EgtIf( nCFaceSide > 0, tostring( nCFaceSide) .. '_', '') .. tostring( nCFaceInt1) .. '-' .. tostring( nCFaceInt2) + local nMchFId = EgtAddMachining( sName, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nCFaceInt1 - 1},{ Proc.Id, nCFaceInt2 - 1}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) + local nSCC = EgtIf( vtRef:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + -- imposto posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- affondamento aggiuntivo + EgtSetMachiningParam( MCH_MP.OFFSR, -dTrim) + -- offset longitudinale + EgtSetMachiningParam( MCH_MP.OFFSL, 0) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto affondamento + if dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + else + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + end + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, 180) + EgtSetMachiningParam( MCH_MP.LOTANG, 0) + EgtSetMachiningParam( MCH_MP.LOPERP, 180) + local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nCFaceInt1 - 1, GDB_ID.ROOT) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nCFaceInt2 - 1, GDB_ID.ROOT) + local dNyMax = EgtIf( abs( vtN1:getY()) > abs( vtN2:getY()), vtN1:getY(), vtN2:getY()) + local dNzMax = EgtIf( abs( vtN1:getZ()) > abs( vtN2:getZ()), vtN1:getZ(), vtN2:getZ()) + if dNzMax < 0 and bHead == ( dNyMax < 0) then + EgtSetMachiningParam( MCH_MP.LITANG, 340) + EgtSetMachiningParam( MCH_MP.LIPERP, -100) + elseif dNzMax < 0 and bHead == ( dNyMax > 0) then + EgtSetMachiningParam( MCH_MP.LOTANG, 340) + EgtSetMachiningParam( MCH_MP.LOPERP, -100) + end + -- imposto allungamenti iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 50) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 50) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + + return true +end + +--------------------------------------------------------------------- +local function MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1, sErr1 end + ---- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + local vtRef2nd + if Proc.Fct > 2 and vFaceOrd[1] ~= 0 then + vtRef2nd = Vector3d( 0, vtN[vFaceOrd[1]]:getY(), vtN[vFaceOrd[1]]:getZ()) + vtRef2nd:normalize() + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + + -- calcolo la distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 and dAng > -89.9 then + dTrim = 0 + else + dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + end + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) + if not bOk then return false, sErr end + end + if vFaceOrd[1] ~= 0 then + bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[1] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 and dAng > -89.9 then + dTrim = 0 + else + dTrim = ((dToolThick* vtN[vFaceOrd[1]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + end + end + + -- se esistono faccia interna ed altra intermedia, verifico se richiedono taglio a cubetti + local vCuts2 = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[1] ~= 0 then + vCuts2 = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[1] ~= 0 then + vCuts2 = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], true) + end + if #vCuts2 > 0 then + local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts2, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim) + if not bOk then return false, sErr end + end + + -- se non ha fatto nessun taglio a cubetti e ho 3 facce + if #vCuts == 0 and #vCuts2 == 0 and Proc.Fct > 2 then + -- lavoro la faccia interna (di fondo) indirettamente lavorando le due facce intermedie + local bOk, sErr = MachChainFacesByBlade( Proc, 0, vFaceOrd[3], vFaceOrd[1], sCutting, bHead, vtRef, ( dTrim + dFinalExtraTrim)) + if not bOk then return false, sErr end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- inserisco la lavorazione + local bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- taglio sulla seconda faccia intermedia + if vFaceOrd[1] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- inserisco la lavorazione + local bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- se altrimenti non ha fatto una parte dei tagli a cubetti + elseif #vCuts == 0 and #vCuts2 == 0 then + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nDirVect = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr + bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nDirVect, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeMillCut( Proc, i, j, k, sMilling, + nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut, bHead, vtRef) + local sWarn = '' + local bUnderCut = bUCut + -- inserisco la lavorazione di fresatura + -- per evitare nomi lavorazioni coincidenti, concateno anche il Proc.Id se il nome (del Proc.Id) è presente + local s2ndName = EgtGetName( Proc.Id) or '' + local sName = EgtIf( bUnderCut, 'MillTCone_', 'Mill_') .. ( EgtIf( #s2ndName > 0, s2ndName, tostring( Proc.Id))) .. ( EgtIf( #s2ndName > 0, '_' .. tostring( Proc.Id), '')) .. '_' .. tostring(i) .. '_' .. tostring(j) + local kStep = k or 0 + if kStep > 0 then + sName = sName .. '_' .. tostring(k) + end + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + local vtDirRef + -- imposto i parametri lavorazione in base alle facce lavorate + if vFaceOrd and #vFaceOrd > 0 then + -- aggiungo geometria e imposto uso faccia + EgtSetMachiningGeometry( {{ Proc.Id, vFaceOrd[3]-1},{ Proc.Id, vFaceOrd[1]-1}}) + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) + -- setto vettore direzione per posizione braccio porta testa + vtDirRef = vtRef + -- imposto lato corezione e inversione percorso + if kStep % 2 == 1 then + -- imposto lato sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + -- imposto lato destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- tolgo inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + -- imposto affondamento + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH' .. EgtIf( dOffs < 0, '', '-') .. EgtNumToString( dOffs, 4)) + else + -- aggiungo geometria e imposto uso faccia + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + local nFaceUse = BL.GetNearestOrthoOpposite( TabNAD[j][1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- setto vettore direzione per posizione braccio porta testa + vtDirRef = rfFac:getVersZ() + -- imposto lato corezione e inversione percorso + if kStep % 2 == 1 then + -- imposto lato destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + -- imposto lato sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- tolgo inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + -- imposto affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dOffs) + end + -- imposto posizione braccio porta testa + local nSCC = EgtIf( vtDirRef:getY() > (100 * GEO.EPS_ZERO), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + --imposto passo 0 + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto offset radiale in base all'angolo tra le due facce e alla posizione in Z + il passo laterale + dOffrRad = dOffrRad + dAddOffsRad + -- per le passate intermedie aggiungo un delta sull'offset radiale perchè c'è già il taglio di lama precedente + EgtSetMachiningParam( MCH_MP.OFFSR, dOffrRad + EgtIf( bPrevByBlade and ( i < nStep) and ( kStep < 1), 0.5, 0)) + -- imposto offset longotudinale a 0 + EgtSetMachiningParam( MCH_MP.OFFSL, 0) + -- imposto gli attacchi + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( 60 + 0.5 * dToolDiam)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( 60 + 0.5 * dToolDiam)) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill solo in ultima passata in Z locale + local sUserNotes + if i < nStep then + sUserNotes = 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + else + sUserNotes = 'VMRS=0;' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + _, sWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough, + bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces, + vFaceOrd, bHead, sMillingMaster, dToolDiamMaster, dMaxMatMaster, + dSideAngleMaster, dMachStepMaster, nMainFace, dElevMain) + local sWarn = '' + local sMilling + local dToolDiam = 100 + local dSideAngle = 0 + local dMaxMat = 50 + local dMaxDepth = 50 + local dMachStep = 0 + local bUCutMax + -- dati della facce + local vtN = {} + local ptC = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + end + -- se non ho passato la lavorazione ( già verificata) + if not sMillingMaster then + -- se il flag del sottosquadra è nil, cerco se tra le facce c'è un angolo sottosquadra + if bUCut == nil then + for i = 1, nFacetCnt do + for j = i + 1, nFacetCnt do + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, (i-1), (j-1), GDB_ID.ROOT) + if bAdj and dAng and dAng < -90.1 then + bUCut = true + break + end + end + end + end + -- recupero l'angolo di spoglia dell'utensile a tronco di cono + -- recupero la lavorazione + local sMchFind = 'Long2Cut' + if bUCut then + sMchFind = 'ProfTCone' + end + sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep + end + end + if dMachStep <= 0.1 then + dMachStep = dMaxMat * 0.5 + end + else + sMilling = sMillingMaster + dToolDiam = dToolDiamMaster + dMaxMat = dMaxMatMaster + dSideAngle = dSideAngleMaster + dMachStep = dMachStepMaster + end + local nFacInd, dFacElev + if nMainFace and dElevMain then + nFacInd = nMainFace + dFacElev = dElevMain + else + -- se devo lavorare facce concatenate + if bJoinFaces then + nFacInd = vFaceOrd[2] - 1 + -- calcolo l'elevazione + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + if dLenIn > 0 then + dFacElev = dLenIn + elseif dLenOut then + dFacElev = dLenOut + end + else + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, sin(dSideAngle)) + if not nFacInd or nFacInd < 0 then + -- provo eliminando i sottosquadra + nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, -2) + if not nFacInd or nFacInd < 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MachSideFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + else + bUCutMax = true + end + end + end + end + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local TabNAD = {} + local bPrevByBlade = false + -- se non ho la forzatura a usare solo truciolatore e tagli lama consentiti + -- inserisco tagli di lama come antischeggia sulle altre facce + if not bForceUseRough and bUseBlade then + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dToolThick + end + end + -- controllo versore faccia di riferimento, è lungo l'asse trave + local vtRef = Vector3d( vtN[nFacInd+1]) + if not AreSameVectorApprox( vtN[nFacInd+1], X_AX()) and not AreSameVectorApprox( vtN[nFacInd+1], -X_AX()) then + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[nFacInd+1]:getY(), vtN[nFacInd+1]:getZ()) + end + vtRef:normalize() + -- ciclo inserimento tagli antischeggia sulle facce + for i = 1, nFacetCnt do + if ( i - 1) == nFacInd then + TabNAD[i] = { vtN[i]} + else + local dExtraZed = EgtIf( bForceMakeMill, 1, 0.1) + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) + if dAng then + TabNAD[i] = { vtN[i], dAng, dist( ptP1, ptP2)} + end + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + dExtraZed = 0.1 + else + dTrim = ((dToolThick* vtN[nFacInd+1]) * vtN[i] * vtN[i]):len() + end + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, ( i - 1), sCutting, dSawDiam, nOrthoOpposite, nil, -( dTrim + dExtraZed), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + bPrevByBlade = true + end + end + -- altrimenti solo taglio truciolatore + else + for i = 1, nFacetCnt do + if ( i - 1) == nFacInd then + TabNAD[i] = { vtN[i]} + else + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) + if dAng then + TabNAD[i] = { vtN[i], dAng, dist( ptP1, ptP2)} + end + end + end + end + local vtRef + -- se devo lavorare facce concatenate + if bJoinFaces then + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + end + -- creo percorsi di lavorazione + local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dMachStep) + local dStep = dFacElev / nStep + local dLargeVal + local nLenSideMax + -- se non devo fare fresature + if not bForceMakeMill then nStep = 0 end + for i = 1, nStep do + local dOffs = ( i * dStep) - dFacElev + if i == nStep then dOffs = 0 end + local dOffsSide = 0 + local dDelta = 100000 + local dElevface + for j = 1, nFacetCnt do + if ( j - 1) ~= nFacInd then + local dParzElev = dOffs + -- calcolo la larghezza (solo 1 volta) + if i == 1 then + -- se ho un sottosquadra maggiore dell'angolo di spoglia utensile + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dParzElev = dFacElev + end + if bJoinFaces then + -- calcolo l'elevazione di ogni singola faccia dal punto medio + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[j], vtN[j]) + if dLenIn > 0 then + dElevface = dLenIn + elseif dLenOut then + dElevface = dLenOut + end + if not dLargeVal or dElevface > dLargeVal then + dLargeVal = dElevface + end + else + local dDeltadH = abs( TabNAD[j][3] - dH) + local dDeltadV = abs( TabNAD[j][3] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + nLenSideMax = j + end + else + if dDeltadV < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + nLenSideMax = j + end + end + end + end + -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) + dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) + end + end + local dRefLarge + -- se ho facce concatenate verifico che la massima larghezza sia comunque superiore al diametro utensile + if bJoinFaces then + dRefLarge = dToolDiam + dLargeVal = EgtIf( dLargeVal > ( dToolDiam + dOffsSide), dLargeVal, dToolDiam + dOffsSide) + else + dRefLarge = EgtIf( nFacetCnt == 2, dToolDiam, ( 2 * dToolDiam)) + end + -- se ho 2 facce o la larghezza è più grande dell'utensile allora posso lavorare il passo + if nFacetCnt == 2 or ( dLargeVal - dOffsSide) >= dToolDiam then + -- se ho facce concatenate + if bJoinFaces then + local dOffrRad = 0 + -- se larghezza faccia consente passi laterali extra + if ( dLargeVal - dOffsSide) > dRefLarge then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) + local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide + for k = nStepSide, 1, -1 do + local dAddOffsRad = ( k * dStepSide) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, 1, k, sMilling, + nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut, bHead, vtRef) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- inserisco la lavorazione di fresatura a contatto con la faccia + local bOk, sErr = MakeMillCut( Proc, i, 1, nil, sMilling, + nFacInd, vFaceOrd, TabNAD, rfFac, dOffs, + dOffrRad, 0, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut, bHead, vtRef) + if not bOk then + return false, sErr + end + sWarn = sErr + else + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + -- calcolo l'offset radiale in base all'affondamento e all'angolo spoglia + local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dOffrRad = -( tan( 90 + TabNAD[j][2]) * dFacElev) + end + -- se lato lavorato è il più lungo e la larghezza cava consente passi laterali extra + if j == nLenSideMax and ( dLargeVal - dOffsSide) > dRefLarge then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / ( dToolDiam * 0.5)) + local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide + for k = nStepSide, 1, -1 do + local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- inserisco la lavorazione di fresatura a contatto con la faccia + local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, 0, nStep, dToolDiam, dStep, + bPrevByBlade, bUCut) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + end + -- altrimenti passo saltato esco con errore + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' + EgtOutLog( sErr) + return false, sErr + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +local function Make2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) + -- verifico le normali delle facce + -- individuo se c'è faccia rivolta verso Z- + local nFlatFaceNeg + local vtN = {} + local ptC = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + if vtN[i]:getZ() < -0.99 then + nFlatFaceNeg = i - 1 + end + end + -- se trovata faccia rivolta verso Z- faccio controllo di lavorabilità da sotto + if nFlatFaceNeg then + -- prendo le dimensioni della faccia + local dLargeFace = Proc.Box:getDimX() + local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUseRough, sMilling = VerifyIfRoughMill( dLargeFace, -Z_AX(), true) + -- se non forzato truciolatore provo la lama + if not bForceUseRough and bUseBlade then + return MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + -- altrimenti provo con il truciolatore + else + -- se non ho la lavorazione esco + if not sMilling then + local sErr = 'Error, machining or tool not found ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- Calcolo uso faccia + local nOtherInd = 2 - nFlatFaceNeg + local nFaceUse = BL.GetNearestParalOpposite( vtN[nOtherInd]) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFlatFaceNeg}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- annullo offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- applico allungamento iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YP + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- altrimenti non ho faccia (antivento) da sotto + else + for i = 1, Proc.Fct do + local nFacet = i - 1 + -- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + if abs( vtN[i]:getZ()) > abs( vtN[i]:getX()) and abs( vtN[i]:getZ()) > abs( vtN[i]:getY()) and vtN[i]:getZ() < -0.5 then + -- lavoro con lama o truciolatore in base al Q + -- prendo le dimensioni della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local nOtherFace = 1 - nFacet + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) + local dLargeFace = Proc.Box:getDimX() + local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bUCut = ( dAng < 0) and ( dAng < -90 - 5 * GEO.EPS_SMALL) + local bOCut = ( dAng < 0) and ( dAng > -90 + 5 * GEO.EPS_SMALL) + local bForceMakeMill = bUCut or bForceUseRough + -- 2020.04.18 da indicazioni di Fabio Sq. : se angolo interno acuto lo lavoro con utensile a tronco di cono + -- e, se consentito uso lama, preceduto anche due tagli antischeggia (solo in caso di 3 facce, con 2 facce disattivo gli antischeggia) + local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, X_AX(), true, EgtIf( bUCut, ( 90 + dAng), nil)) + -- se devo farlo con fresatura + if bForceMakeMill then + -- se non ho lavorazione (se per esempio l'angolo di spoglia utensile non è uguale a quello tra le due facce) do errore + if not sMilling then + local sErr = 'Error, machining or tool not found ' .. sName + EgtOutLog( sErr) + return false, sErr + end + -- genero lavorazioni + local bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + bUseBlade, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, nOtherFace, dLargeFace) + if not bOk then return false, sErr end + elseif bUseBlade then + local bOk, sErr = MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + -- se fallita di lama e di fresa è fattibile, eseguo con la fresa + if not bOk and sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + bUseBlade, true, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, nOtherFace, dLargeFace) + if not bOk then return false, sErr end + else + return false, sErr + end + end + return true + -- altrimenti non in Z negativa + else + -- se nessuna entità ha z negativa + if i == Proc.Fct then + -- verifico angolo tra le facce + local nOtherFace = nFacet - 1 + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT) + local dLargeFace = Proc.Box:getDimX() + -- ordino le facce, se 2 facce: (1=0, 2=interna, 3=intermedia) + local bOk, sErr, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk then return bOk, sErr end + local bUCut = ( dAng < 0) and ( dAng < -90 - 5 * GEO.EPS_SMALL) + local bOCut = ( dAng < 0) and ( dAng > -90 + 5 * GEO.EPS_SMALL) + -- 2021.02.04 FS ha chiesto di fare con lama anche i concavi (vecchio controllo : bUCut or bForceUseRough) + local bForceMakeMill = bForceUseRough + -- 2020.04.28 FS se angolo interno acuto lo lavoro con utensile a tronco di cono + -- e, se consentito uso lama, preceduto anche due tagli antischeggia (solo in caso di 3 facce, con 2 facce disattivo gli antischeggia) + -- se devo farlo con fresatura + if bForceMakeMill then + local bOk, sErr + bOk = false + -- se angolo ( tra le due facce è) ottuso + if bOCut then + local ptPs = ( ptP1 + ptP2) / 2 + -- calcolo l'elevazione di ogni singola faccia dal punto medio della linea di adiacenza + -- prendo l'elevazione sul punto medio della prima faccia + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[vFaceOrd[2]]) + if dLenIn > 0 then + dLargeFace = dLenIn + elseif dLedOut then + dLargeFace = dLedOut + end + -- verifico la possibilità di lavorare con utensile + local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, vtN[vFaceOrd[2]], true) + -- se ho trovato lavorazione applicata a faccia definita + if sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, vFaceOrd[2]-1, dLargeFace) + end + -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima + if not bOk then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false) + end + if not bOk then return false, sErr end + + -- prendo l'elevazione sul punto medio della seconda faccia + dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[vFaceOrd[3]]) + if dLenIn > 0 then + dLargeFace = dLenIn + elseif dLedOut then + dLargeFace = dLedOut + end + -- verifico la possibilità di lavorare con utensile + bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, vtN[vFaceOrd[3]], true) + -- se ho trovato lavorazione applicata a faccia definita + if sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, vFaceOrd[3]-1, dLargeFace) + end + -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima + if not bOk then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false) + end + if not bOk then return false, sErr end + else + -- verifico la possibilità di lavorare con utensile (orizzontale) + local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dMachStep = VerifyIfRoughMill( dLargeFace, X_AX(), true, EgtIf( bUCut, ( 90 + dAng), nil)) + -- se ho trovato lavorazione applicata a faccia definita + if sMilling then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false, + nil, nil, sMilling, dToolDiam, dMaxMat, + dSideAngle, dMachStep, vFaceOrd[2]-1, dLargeFace) + end + -- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima + if not bOk then + -- genero lavorazioni + bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + true, bForceMakeMill, bUCut, bOCut, false) + end + if not bOk then return false, sErr end + end + else + return MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + end + end + end + end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + + -- recupero la geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return true end + AuxId = AuxId + Proc.Id + -- recupero il centro e la normale della faccia ausiliaria + local ptC, vtN = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + if not vtN then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' wrong Normal of AuxSurface' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se di testa o coda + local bHead = ( vtN:getX() > 0) + -- recupero la lavorazione per la geometria ausiliaria + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se già fatto con altro componente della stessa feature + local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring( AuxId), 'b') + if bAuxMachined then return true end + -- verifico se coincide con taglio di testa + if bHead and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- verifico se coincide con taglio di coda + if not bHead and AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + -- inserisco la lavorazione + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + -- imposto la nota nel gruppo aggiuntivo di lavorazione per evitare di tagliare una seconda volta + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + return true +end + +--------------------------------------------------------------------- +local function MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, nSidePosFct, nMiddleFct, nSideNegFct, vtRef, nFacetCnt) + + local sWarn = '' + -- recupero la lavorazione + local sMchFind = 'Long2Cut' + local sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 100 + local dMaxMat = 50 + local dSideAngle = 0 + local dMachStep = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + -- ottengo il passo della lavorazione + dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep + end + end + if dMachStep <= 0.1 then + dMachStep = dMaxMat * 0.5 + end + local nFacInd = nMiddleFct - 1 + local dFacElev + -- calcolo elevazione + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[nMiddleFct], vtN[nMiddleFct]) + if dLenIn > 0 then + dFacElev = dLenIn + elseif dLenOut then + dFacElev = dLenOut + end + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local TabNAD = {} + TabNAD[nMiddleFct] = { vtN[nMiddleFct]} + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, ( nSideNegFct or 0) - 1, GDB_ID.ROOT) + if dAng then + TabNAD[nSideNegFct] = { vtN[nSideNegFct], dAng, dist( ptP1, ptP2)} + end + bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (nSidePosFct-1), GDB_ID.ROOT) + if dAng then + TabNAD[nSidePosFct] = { vtN[nSidePosFct], dAng, dist( ptP1, ptP2)} + end + -- creo percorsi di lavorazione + local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dMachStep) + local dStep = dFacElev / nStep + local dLargeVal + local nLenSideMax + for i = 1, nStep do + local dOffs = ( i * dStep) - dFacElev + if i == nStep then dOffs = 0 end + local dOffsSide = 0 + local dDelta = 100000 + local dElevface + for j = 1, nFacetCnt do + if j == nSideNegFct or j == nSidePosFct then + local dParzElev = dOffs + -- calcolo la larghezza (solo 1 volta) + if i == 1 then + local dDeltadH = abs( TabNAD[j][3] - dH) + local dDeltadV = abs( TabNAD[j][3] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + nLenSideMax = j + end + else + if dDeltadV < dDelta - 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + nLenSideMax = j + end + end + end + -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) + dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) + end + end + local dRefLarge = EgtIf( nSideNegFct, ( 2 * dToolDiam), dToolDiam) + -- se la larghezza è più grande dell'utensile allora posso lavorare il passo + if ( dLargeVal - dOffsSide) >= dToolDiam then + for j = 1, nFacetCnt do + if j == nSideNegFct or j == nSidePosFct then + -- calcolo l'offset radiale in base all'affondamento e all'angolo spoglia + local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) + -- se lato lavorato è il più lungo e la larghezza cava consente passi laterali extra + if j == nLenSideMax and ( dLargeVal - dOffsSide) > dRefLarge then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * EgtIf( nSideNegFct, 0.5, 1)) + local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide + for k = nStepSide, 1, -1 do + local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep, + true, false) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- inserisco la lavorazione di fresatura a contatto con la faccia + local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, + nFacInd, nil, TabNAD, rfFac, dOffs, + dOffrRad, 0, nStep, dToolDiam, dStep, + true, false) + if not bOk then + return false, sErr + end + sWarn = sErr + end + end + -- altrimenti passo saltato esco con errore + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' + EgtOutLog( sErr) + return false, sErr + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bUseBlade) + + local ptC = {} + local vtN = {} + -- dati delle facce e ordinamento facce { } + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le 4 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia, 4=esterna) + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1, sErr1 end + -- vettori di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + local vtRef2nd = Vector3d( 0, vtN[vFaceOrd[1]]:getY(), vtN[vFaceOrd[1]]:getZ()) + vtRef2nd:normalize() + -- se non forzato uso truciolatore e abilitato il taglio di lama faccio le due pareti con antischeggia + -- lavoro le facce laterali indirettamente lavorando le due facce intermedie + if not bForceUseRough and bUseBlade then + -- recupero la lavorazione con lama + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + local dTrim = -0.3 + -- se ho la faccia laterale negativa + if vFaceOrd[4] ~= 0 then + -- inserisco la lavorazione di taglio per la faccia laterale negativa, faccio in modo che la testa rimanga nella stessa posizione per entrambe i tagli + local bOk, sErr = MachChainFacesByBlade( Proc, vFaceOrd[4], vFaceOrd[3], vFaceOrd[1], sCutting, true, vtRef, dTrim, dToolThick) + if not bOk then return false, sErr end + end + -- se ho la faccia laterale positiva + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione di taglio per la faccia laterale positiva + local bOk, sErr = MachChainFacesByBlade( Proc, vFaceOrd[2], vFaceOrd[3], vFaceOrd[1], sCutting, true, vtRef, dTrim) + if not bOk then return false, sErr end + end + end + -- lavoro le facce intermedie + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione di fresatura per la faccia intermedia + local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[2], vFaceOrd[3], vFaceOrd[4], vtRef, Proc.Fct) + if not bOk then return false, sErr end + end + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione di fresatura per la faccia intermedia + local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[2], vFaceOrd[1], vFaceOrd[4], vtRef, Proc.Fct) + if not bOk then return false, sErr end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bInMiddle) + -- flag per lavorazioni sulla testa o coda + local bUseBlade = false + local bForceMakeMill = bForceUseRough + local bUCut = false + local bOCut = false + local bJoinFaces = true + -- modifiche ai flag per lavorazione in mezzo + if bInMiddle then + -- abilito la lama per i tagli antischeggia + bUseBlade = true + -- abilito la fresatura + bForceMakeMill = true + -- disabilito il concatenamento delle facce intermedie + bJoinFaces = false + -- annullo il flag del sottosquadra per forzare la ricerca all'interno della funzione + bUCut = nil + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce, se 3 facce: (1=altra intermedia, 2=interna, 3=intermedia) + local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN) + if not bOk1 then return bOk1, sErr1 end + -- verifica se di testa o coda + local bHead = false + if not bInMiddle then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + end + -- se non in mezzo può essere necessario lavorare come in mezzo + if not bInMiddle then + -- calcolo l'elevazione + local dSideElev = 0 + local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + if dLenIn > 0 then + dSideElev = dLenIn + elseif dLenOut then + dSideElev = dLenOut + end + -- determino il massimo affondamento con l'utensile + local sMchFind = 'Long2Cut' + sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 10 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se l'elevazione supera l'affondamento, lavoro perpendicolare all'asse trave + if dSideElev > dMaxDepth then + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bUseBlade) + end + end + + -- lavoro le restanti facce in modo standard + return MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough, + bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces, + vFaceOrd, bHead) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- verifico se sono presenti i parametri Q per l'uso forzato del truciolatore + local bForceUseRough = EvaluateQParam( Proc, sUseRoughTool) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + if Proc.Fct < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + + -- se ha due facce ( allora è di testa o coda) + if Proc.Fct == 2 then + -- eventuale taglio di testa o coda + local bAuxOk, sAuxErr = MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + if not bAuxOk then return bAuxOk, sAuxErr end + -- lavorazione della feature + local bOk, sErr = Make2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) + if not bOk then return bOk, sErr end + -- se ha 3 facce ed è di testa o coda + elseif Proc.Fct == 3 and ( Proc.Head or Proc.Tail) then + -- eventuale taglio di testa o coda + local bAuxOk, sAuxErr = MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + if not bAuxOk then return bAuxOk, sAuxErr end + -- lavorazione della feature + if bForceUseRough then + local bOk, sErr = MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough) + if not bOk then return bOk, sErr end + else + local bOk, sErr = MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid) + if not bOk then return bOk, sErr end + end + -- se ha 3 facce (e interna) + elseif Proc.Fct == 3 then + local bOk, sErr = MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, true) + if not bOk then return bOk, sErr end + -- altrimenti 4 facce (e interna) + else + local bOk, sErr = MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, true) + if not bOk then return bOk, sErr end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dTCI) + end + + return true +end + +--------------------------------------------------------------------- +return ProcessDovetail diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDrill.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDrill.lua new file mode 100644 index 0000000..5f27f00 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDrill.lua @@ -0,0 +1,461 @@ +-- ProcessDrill.lua by Egaltech s.r.l. 2022/03/29 +-- Gestione calcolo forature per Travi +-- 2021/04/14 DS Corretta gestione Invert con testa da sotto. Migliorato calcolo ingombro portautensile. +-- 2021/05/03 DS Su macchina con testa da sotto aggiunta possibilità di fare fori verticali metà sopra e l'altra sotto. +-- 2021/09/19 DS Si premia il più possibile ricerca punta con adeguato affondamento. +-- 2021/10/29 DS MaxElev anche su fori con svuotatura. +-- 2022/03/26 DS Correzioni per fori testa-fianco nel piano. +-- 2022/03/29 DS Corretta assegnazione fori molto inclinati fianco/coda a coda. + +-- Tabella per definizione modulo +local ProcessDrill = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessDrill started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDrill.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 40) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDrill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + return false + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- se entrata principale + if Proc.Flg > 0 then + local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + return ( ( nFcs == 5 or nFcs == 6) and vtExtr:getX() > 0.5) + -- altrimenti entrata opposta + else + local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + return ( ( nFce == 5 or nFce == 6) and vtExtr:getX() < -0.5) + end + +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDrill.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.OVM_MID + BD.MAX_DIST_HTFEA then + return false + end + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + return false + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- se entrata principale + if ( Proc.Flg == 2 or ( Proc.Flg == 1 and vtExtr:getZ() >= BD.DRILL_VZ_MIN)) and ( nFcs == 5 or nFcs == 6 or abs( vtExtr:getX()) < BD.DRILL_VX_MAX) then + local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + return ( ( nFcs == 5 or nFcs == 6) and vtExtr:getX() < -0.5) + -- altrimenti entrata opposta + else + local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + return ( ( nFce == 5 or nFce == 6) and vtExtr:getX() > 0.5) + end +end + +--------------------------------------------------------------------- +-- Recupero dati foro e adattamento se speciale +function ProcessDrill.GetData( Proc, b3Raw) + -- 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 BD.USER_HOLE_DIAM and BD.USER_HOLE_DIAM > 1 then + EgtModifyArcRadius( AuxId, BD.USER_HOLE_DIAM / 2) + 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 + +--------------------------------------------------------------------- +-- Verifica se da lavorare in due metà +function ProcessDrill.Split( 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 bOpen = ( Proc.Fce ~= 0) + -- recupero flag abilitazione split (0=auto,1=no) + local bTrySplit = ( EgtGetInfo( Proc.Id, 'Q02', 'i') ~= 1) + if not bTrySplit then + return false + end + -- restituisco se va fatto in doppio (solo fori orizzontali) + local bHoriz = ( abs( vtExtr:getZ()) < abs( BD.DRILL_VZ_MIN) and + ( abs( vtExtr:getY()) * b3Raw:getDimZ() > abs( vtExtr:getZ()) * b3Raw:getDimY() or Proc.Fce == 5 or Proc.Fce == 6)) + local bSlant = ( abs( vtExtr:getX()) > BD.DRILL_VX_MAX) + return ( bOpen and ( bHoriz or BD.ROT90 or BD.DOWN_HEAD) and not bSlant) +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) + -- se lavorato in doppio, devo considerare il lato più sfavorevole + if Proc.Flg == -2 or (( BD.ROT90 or BD.DOWN_HEAD) and Proc.Flg == 2) then + if vtExtr:getZ() > 0 then + vtExtr = - vtExtr + ptCen = ptCen + vtExtr * dLen + end + end + -- 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()) > BD.DRILL_VX_MAX then + return false, false, false + end + local bOpen = ( Proc.Fce ~= 0) + local bFaceDown = ( ptCen:getZ() < b3Raw:getMin():getZ() + 2 and (( not Proc.Head and not Proc.Tail) or (( BD.ROT90 or BD.DOWN_HEAD) and ( Proc.Flg == 2 or Proc.Flg == -2)))) + -- verifico se il foro è sotto e quindi va spostato o sopra o sul fianco + if (( vtExtr:getZ() < BD.DRILL_VZ_MIN or bFaceDown) and ( not bOpen or Proc.Flg ~= 1)) then + if not bOpen then + return true, true, false + else + return true, not ( BD.ROT90 or BD.DOWN_HEAD), ( BD.ROT90 or BD.DOWN_HEAD) + end + else + return true, false, false + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- 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 : 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) + if Proc.Flg == -2 then vtExtr = - vtExtr end + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- verifico che il foro non sia fattibile solo da sotto + local bToInvert = ( vtExtr:getZ() < BD.DRILL_VZ_MIN) and not BD.DOWN_HEAD + if bToInvert and ( not bOpen or Proc.Flg ~= 1) then + local sErr = 'Error : drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- se il foro è cieco o troppo inclinato all'inizio, lo inverto + if Proc.Fcs == 0 or ( abs( vtExtr:getX()) > BD.DRILL_VX_MAX and Proc.Fcs ~= 5 and Proc.Fcs ~= 6) then + bToInvert = true + end + if bToInvert then vtExtr = - vtExtr end + -- se foro è splittato ed è la parte opposta, inverto + if Proc.Flg == -2 then bToInvert = true end + -- profondità geometrica del foro + local dDepth = dLen + local dDepth2 = dLen + if Proc.Flg == 2 or Proc.Flg == -2 then + dDepth = dLen / 2 + BD.DRILL_OVERLAP + end + local dCheckDepth = dDepth + local dCheckDepth2 = dDepth2 + local nErrorCode = 0 + -- abilitazione foratura da sotto + local bDrillDown = ( BD.DOWN_HEAD and ( Proc.Down or vtExtr:getZ() < -0.1 or vtExtr:getZ() < 0.259)) + local bDrillUp = ( BD.DOWN_HEAD and vtExtr:getZ() > -0.259) + -- primo gruppo di controlli con lunghezza utensile pari a metà foro se passante + -- recupero la lavorazione + local sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, dCheckDepth, bDrillDown) + if not sDrilling and bDrillUp then + sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, dCheckDepth) + end + if not sDrilling and dCheckDepth then + sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, 0, bDrillDown) + if sDrilling then dCheckDepth = nil end + end + if not sDrilling and bDrillUp and dCheckDepth then + sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, 0) + if sDrilling then dCheckDepth = nil end + end + if not sDrilling then + nErrorCode = 1 + end + -- se trovata la lavorazione e la lunghezza massima utensile supera il valore limite del BeamData e inclinato più di 10 gradi da Z + -- allora ricerco un utensile senza imporre minima capacità di taglio + if nErrorCode == 0 and dMaxToolLength > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then + -- se non ho passato altezza di taglio utensile allora la lunghezza utensile non è idonea per il taglio + if not dCheckDepth then + nErrorCode = 2 + -- rifaccio ricerca lavorazione senza specificare la profondità (dovrebbe trovare l'utensile più corto) + else + sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, 0, bDrillDown) + if not sDrilling and bDrillUp then + sDrilling, sType, dMaxDepth, dMaxToolLength, dToolDiam, dDiamTh, dToolFreeLen = ML.FindDrilling( dDiam, 0) + end + if not sDrilling then + nErrorCode = 1 + elseif dMaxToolLength > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then + nErrorCode = 2 + end + end + end + -- secondo gruppo di controlli con lunghezza richiesta pari all'intero foro + -- recupero la lavorazione + local sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 + if dDepth2 > dDepth + BD.DRILL_OVERLAP then + sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, dCheckDepth2, bDrillDown) + if not sDrilling2 and bDrillUp then + sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, dCheckDepth2) + end + if not sDrilling2 and dCheckDepth2 then + sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, 0, bDrillDown) + if sDrilling2 then dCheckDepth2 = nil end + end + if not sDrilling2 and bDrillUp and dCheckDepth2 then + sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, 0) + if sDrilling2 then dCheckDepth2 = nil end + end + if not sDrilling2 then + nErrorCode = 1 + end + -- se trovata la lavorazione e la lunghezza massima utensile supera il valore limite del BeamData e inclinato più di 10 gradi da Z + -- allora ricerco un utensile senza imporre minima capacità di taglio + if nErrorCode == 0 and dMaxToolLength2 > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then + -- se non ho passato altezza di taglio utensile allora la lunghezza utensile non è idonea per il taglio + if not dCheckDepth2 then + nErrorCode = 2 + -- rifaccio ricerca lavorazione senza specificare la profondità (dovrebbe trovare l'utensile più corto) + else + sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, 0, bDrillDown) + if not sDrilling2 and bDrillUp then + sDrilling2, sType2, dMaxDepth2, dMaxToolLength2, dToolDiam2, dDiamTh2, dToolFreeLen2 = ML.FindDrilling( dDiam, 0) + end + if not sDrilling2 then + nErrorCode = 1 + elseif dMaxToolLength2 > ( BD.MAX_TOOL_LEN_FOR_HOR_MACH or 300) and abs( vtExtr:getZ()) < ( BD.DRILL_VZ_MIN_LONG_TOOL or cos(10)) then + nErrorCode = 2 + end + end + end + end + -- se esiste il parametro massima lunghezza per fori da dietro e il foro è passante e non è ancora stato invertito + -- ed è orizzontale ed è orientato principalmente verso Y+ e non è la parte splittata e l'utensile supera una certa lunghezza + -- lo inverto per premiare l'entrata davanti + local bCommonCompare = BD.MAX_TOOL_LEN_BACK_HOR_MACH and bOpen and abs(vtExtr:getX()) < 0.5 and abs(vtExtr:getZ()) < 0.5 + if nErrorCode == 0 and not bToInvert and bCommonCompare and vtExtr:getY() > 0.866 and Proc.Flg == 1 and dMaxToolLength > BD.MAX_TOOL_LEN_BACK_HOR_MACH then + bToInvert = true + vtExtr = - vtExtr + --------------------------------------------------------------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------------------------------------------------------------- + -- 14/12/2020 richiesta di Fabio Squaratti: con foro orizzontale passante e parametro Q02 = 0 (settato per fare in due parti), + -- se punta più lunga del parametro BD.MAX_TOOL_LEN_BACK_HOR_MACH alloro ignoro la doppia foratura contrapposta e faccio foratura solo dal davanti + -- Questo implica che il valore del parametro Q02 = 0 non è vincolante perchè basta che l'utensile supera il parametro allora la foratura si comporta + -- come se il parametro Q02 sia = 1 + --------------------------------------------------------------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------------------------------------------------------------- + elseif nErrorCode == 0 and not bToInvert and bCommonCompare and abs(vtExtr:getY()) > 0.866 and Proc.Flg == 2 and dMaxToolLength2 > BD.MAX_TOOL_LEN_BACK_HOR_MACH then + sDrilling = sDrilling2 + sType = sType2 + dMaxDepth = dMaxDepth2 + dToolDiam = dToolDiam2 + dDiamTh = dDiamTh2 + dToolFreeLen = dToolFreeLen2 + dDepth = dDepth2 + if vtExtr:getY() > 0 then + bToInvert = true + vtExtr = - vtExtr + end + -- se sono al secondo mezzo foro con utensile che supera la lunghezza di riferimento non lo eseguo + elseif nErrorCode == 0 and bCommonCompare and abs(vtExtr:getY()) > 0.866 and Proc.Flg == -2 and dMaxToolLength2 > BD.MAX_TOOL_LEN_BACK_HOR_MACH then + return true, '' + end + if nErrorCode == 1 then + local sErr = 'Error : drilling not found in library' + EgtOutLog( sErr) + return false, sErr + elseif nErrorCode == 2 then + local sErr = 'Error : tool too long to machine with big angle from vertical' + EgtOutLog( sErr) + return false, sErr + end + -- verifico il massimo affondamento + local dSubL1 = 0 + local dSubL2 = 0 + local dSubL3 = 0 + local dDeltaRad = ( Proc.Diam - dToolDiam) / 2 + -- se foro non su testa o coda e inclinato + local bInMid = false + local bInvertFcse = ( bToInvert and Proc.Flg ~= -2) + if ( not bInvertFcse and Proc.Fcs ~= 5 and Proc.Fcs ~= 6) or ( bInvertFcse and Proc.Fce ~= 5 and Proc.Fce ~= 6) then + bInMid = true + local CosB = abs( vtExtr:getX()) + if CosB < BD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dSubL1 = ( dDiamTh / 2 + dDeltaRad + 2) * TgA + else + dMaxDepth = 0 + end + end + -- se foro davanti o dietro e inclinato + if dMaxDepth > 0 and abs( vtExtr:getY()) > abs( vtExtr:getZ()) then + local CosB = abs( vtExtr:getY()) + if bInMid then + CosB = sqrt( vtExtr:getZ() * vtExtr:getZ() + vtExtr:getX() * vtExtr:getX()) + end + if CosB < BD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dSubL2 = ( dDiamTh / 2 + dDeltaRad + 2) * TgA + else + dMaxDepth = 0 + end + end + -- se foro sopra o sotto e inclinato + if dMaxDepth > 0 and abs( vtExtr:getZ()) > abs( vtExtr:getY()) then + local CosB = abs( vtExtr:getZ()) + if bInMid then + CosB = sqrt( vtExtr:getY() * vtExtr:getY() + vtExtr:getX() * vtExtr:getX()) + end + if CosB < BD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dSubL3 = ( dDiamTh / 2 + dDeltaRad + 2) * TgA + else + dMaxDepth = 0 + end + end + local dSubL = max( dSubL1, dSubL2, dSubL3) + if dMaxDepth > 0 then + dMaxDepth = min( dMaxDepth, dToolFreeLen - dSubL) + 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 sType == 'Drill' or sType == 'Drill_H2' then + EgtSetMachiningParam( MCH_MP.INVERT, bToInvert) + else + EgtSetMachiningParam( MCH_MP.TOOLINVERT, bToInvert) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = MCH_SCC.ADIR_YM + if AreSameVectorApprox( vtExtr, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtExtr:getX()) < 0.1 then + local bNearTail = ( Proc.Box:getCenter():getX() < b3Solid:getCenter():getX() and Proc.Box:getCenter():getX() - b3Solid:getMin():getX() < 1000) + local bVeryShortPart = ( BD.LEN_VERY_SHORT_PART and b3Solid:getDimX() < BD.LEN_VERY_SHORT_PART) + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase) or ( bNearTail and not bVeryShortPart), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtExtr:getY() > 0.1 then + nSCC = MCH_SCC.ADIR_YP + end + else + nSCC = MCH_SCC.NONE + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- aggiusto l'affondamento + local sMyWarn + 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) + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione (coincide con affondamento) + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';' + -- se foro passante, aggiungo questa qualifica alle note + if ( sType == 'Drill' or sType == 'Drill_H2') and bOpen then + sUserNotes = sUserNotes .. 'Open=1;' + end + -- se lavorazione in doppio + if EgtExistsInfo( Proc.Id, 'MAIN') then + sUserNotes = sUserNotes .. 'Double;' + elseif EgtExistsInfo( Proc.Id, 'DOU') then + sUserNotes = sUserNotes .. 'Main;' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + local bOk = EgtApplyMachining( true, false) + if not bOk and BD.DOWN_HEAD then + if sType == 'Drill' or sType == 'Drill_H2' then + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + bOk = EgtApplyMachining( true, false) + end + if not bOk 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/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDtMortise.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDtMortise.lua new file mode 100644 index 0000000..41d793f --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDtMortise.lua @@ -0,0 +1,444 @@ +-- ProcessDtMortise.lua by Egaltech s.r.l. 2022/03/23 +-- Gestione calcolo mortase a coda di rondine per Travi +-- 2021/04/08 Aggiunto controllo massimo materiale lavorabile dalla fresa. +-- 2021/04/08 Miglioria scelta lavorazione in presenza di testa da sotto. +-- 2021/06/28 Aggiunta gestione attacco e uscita con pocket. +-- 2021/07/20 Aggiunta gestione rinvio angolare su FAST. +-- 2021/12/01 Se frontale aggiungo taglio con Grp e Proc di vero taglio (per aggiornare ingombro di testa /coda). + +-- Tabella per definizione modulo +local ProcessDtMortise = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessDtMortise started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- settaggi interni ( poi andrà utilizzato parametro ACTIVE_AS proveniente da parametri utente di TechnoEssetre) +local bMakeAntiSplitPath = true +local bMakeAsByArc = true + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDtMortise.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 55) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 56)) +end + +--------------------------------------------------------------------- +-- Riconoscimento della sola feature frontale +function ProcessDtMortise.FrontIdentify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 56) +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDtMortise.IsTailFeature( Proc, b3Raw) + -- la mortasa di fronte è già stata classificata nel chiamante + -- controllo la mortasa standard + if Proc.Box:getMin():getX() < b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + -- recupero la curva di profilo + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtStart = EgtSV( AuxId, GDB_ID.ROOT) + local vtEnd = EgtEV( AuxId, GDB_ID.ROOT) + local vtDir = -vtStart + vtEnd ; vtDir:normalize() + -- se l'asse della mortasa è inclinato indietro più di 8 deg è considerata di coda + return ( vtDir:getX() < -0.15) + end + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDtMortise.Classify( Proc) + -- recupero i dati della curva di contorno della faccia di fondo + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se la mortasa è lavorabile solo da sotto + local bDown = ( vtExtr:getZ() < -0.1) + -- se da sotto e presente rinvio angolare verifico se c'è opportuna lavorazione + if bDown and BD.ANG_TRASM then + if ML.FindMilling( 'DtMortise_AT') then + bDown = false + end + end + return true, bDown +end + +--------------------------------------------------------------------- +-- Piano di taglio della feature +function ProcessDtMortise.GetCutPlane( Proc) + if ProcessDtMortise.FrontIdentify( Proc) then + return EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + else + return nil, nil + end +end + +--------------------------------------------------------------------- +local function CalcTopPath( nProcId, AuxId, nAddGrpId, dAltMort, dSideAng, b3Solid) + -- copio la curva di base + local NewAuxId = EgtCopyGlob( AuxId, nAddGrpId) + if not NewAuxId then return end + -- ne allungo gli estremi + --EgtExtendCurveStartByLen( NewAuxId, 100) + --EgtExtendCurveEndByLen( NewAuxId, 100) + EgtAddCurveCompoLineTg( NewAuxId, 100, false) + EgtAddCurveCompoLineTg( NewAuxId, 100, true) + EgtMergeCurvesInCurveCompo( NewAuxId) + -- eseguo traslazione e offset per portarla sul top + local vtMove = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) * ( dAltMort - 10 * GEO.EPS_SMALL) + EgtMove( NewAuxId, vtMove, GDB_RT.GLOB) + local dOffset = dAltMort * tan( dSideAng) + if not EgtOffsetCurve( NewAuxId, dOffset) then return end + -- la limito entro la trave + local refBox = Frame3d( b3Solid:getMin()) + local vtBoxDiag = b3Solid:getMax() - b3Solid:getMin() + local nCount + NewAuxId, nCount = EgtTrimFlatCurveWithBox( NewAuxId, refBox, vtBoxDiag, true, true, GDB_RT.GLOB) + -- se divisa in più parti, le unisco congiungendole con segmenti + if nCount > 1 then + if EgtGetType( NewAuxId) ~= GDB_TY.CRV_COMPO then + NewAuxId = EgtCurveCompo( nAddGrpId, NewAuxId) + end + for i = 2, nCount do + local CrvId = NewAuxId + i - 1 + local ptStart = EgtSP( CrvId) + EgtAddCurveCompoLine( NewAuxId, ptStart) + EgtAddCurveCompoCurve( NewAuxId, CrvId) + end + end + return NewAuxId +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDtMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Missing profile geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + -- verifico che la mortasa non sia orientata verso il basso (-5 deg) o che ci sia una testa da sotto o un rinvio angolare + local bFaceDown = ( vtExtr:getZ() < -0.1) + if bFaceDown and not BD.DOWN_HEAD and not BD.ANG_TRASM then + local sErr = 'Machining from bottom impossible : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- determino l'altezza della mortasa (0=faccia di fondo) + local rfDtMrt = Frame3d( ptBC, vtExtr) + local b3DtMrt = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfDtMrt) + local dAltMort = b3DtMrt:getDimZ() + -- verifico se di tipo pocket + local bPocket = ( EgtGetInfo( Proc.Id, 'P05', 'i') == 1) + if bPocket then bMakeAntiSplitPath = false end + -- verifico se frontale + local bFront = ( Proc.Prc == 56) + -- se mortasa di fronte, eseguo il taglio della faccia + if bFront then + -- verifico esista la faccia di taglio + local ptCutC, vtCutN = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if ptCutC and vtCutN and AreSameVectorApprox( vtExtr, vtCutN) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptCutC, vtCutN, b3Solid, GDB_RT.GLOB) + local b3Cut = EgtGetBBoxGlob( AddId or GDB_ID.NULL, GDB_BB.STANDARD) + local CutProc = { Id = AddId, Grp = Proc.Grp - 2, Prc = 10, Box = b3Cut, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getZ() > 0.25) + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH, bFromBottom) + if not bOk then return bOk, sErr end + end + end + -- recupero il raggio minimo della mortasa + local dMinRad = 1000 + local nSt, nEnd = EgtCurveDomain( AuxId) + for i = nSt, nEnd - 1 do + local dRad = EgtCurveCompoRadius( AuxId, i) + if dRad > 0 and dRad < dMinRad then + dMinRad = dRad + end + end + -- abilitazione lavorazione da sotto + local bMillUp = ( BD.DOWN_HEAD and vtExtr:getZ() > -0.259) + local bMillDown = ( BD.DOWN_HEAD and vtExtr:getZ() < 0.174) + if BD.DH_MAX_TOP and Proc.Box:getMax():getZ() - b3Solid:getMin():getZ() > BD.DH_MAX_TOP then + bMillDown = false + end + local bMillAngTrasm = ( BD.ANG_TRASM and vtExtr:getZ() < -0.1) + -- recupero la lavorazione + local sMillType = 'DtMortise' + local sMchExt = '' + if bMillDown then + sMchExt = '_H2' + elseif bMillAngTrasm then + sMchExt = '_AT' + end + -- recupero la lavorazione : prima ricerca per sola tipologia + local sMilling = ML.FindMilling( sMillType..sMchExt) + if not sMilling and bMillUp then + sMilling = ML.FindMilling( sMillType) + end + if not sMilling then + local sErr = 'Milling not found in library : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione : seconda ricerca con tipologia e diametro massimo + sMilling = ML.FindMilling( sMillType..sMchExt, nil, nil, 2 * dMinRad) + if not sMilling and bMillUp then + sMilling = ML.FindMilling( sMillType, nil, nil, 2 * dMinRad) + sMchExt = '' + end + if not sMilling then + local sErr = 'Radius too small : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile e l'angolo di spoglia + local dToolDiam = 100 + local dMaxMat = 30 + local dSideAng = 0 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolDiam = max( dToolDiam, 10) + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- verifico che la profondità non superi il massimo materiale dell'utensile + if dAltMort > dMaxMat + 10 * GEO.EPS_SMALL then + local sErr = 'Error : DtMortise Depth bigger than Tool Cutting edge' + EgtOutLog( sErr) + return false, sErr + end + -- se con tasca, la lavoro + if bPocket then + -- recupero il contorno della tasca (seconda curva ausiliaria) + local sVal = EgtGetInfo( Proc.Id, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local Aux2Id + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if Aux2Id then Aux2Id = Aux2Id + Proc.Id end + if not Aux2Id or ( EgtGetType( Aux2Id) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Missing pocket geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sPocketing + sPocketing = ML.FindPocketing( 'Mortise'..sMchExt, dToolDiam) + if not sPocketing and bMillUp then + sPocketing = ML.FindPocketing( 'Mortise', dToolDiam) + end + if not sPocketing then + sPocketing = ML.FindPocketing( 'Pocket'..sMchExt, dToolDiam) + if not sPocketing and bMillUp then + sPocketing = ML.FindPocketing( 'Pocket', dToolDiam) + end + end + if not sPocketing then + local sErr = 'Error : Mortise or Pocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di svuotatura + local sName = 'DtMtPck_' .. ( 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( {{ Aux2Id, -1}}) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- se parametro interno abilitato e il percorso non è chiuso, aggiungo percorso e lavorazione antischeggia + if bMakeAntiSplitPath and not EgtCurveIsClosed( AuxId) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo il percorso top mortise + local nAuxId1 = CalcTopPath( Proc.Id, AuxId, nAddGrpId, dAltMort, dSideAng, b3Solid) + -- se esiste il percorso + if nAuxId1 then + -- creo percorso sulla parte alta della mortasa + local dToolRadDelta = dAltMort * tan( dSideAng) + local dTopDiam = dToolDiam + 2 * dToolRadDelta + -- recupero punto iniziale e finale del percorso + local ptStart = EgtSP( nAuxId1, GDB_RT.GLOB) + local ptEnd = EgtEP( nAuxId1, GDB_RT.GLOB) + if ptStart and ptEnd then + local nId1 + -- se richiesti due segmenti di linea + if not bMakeAsByArc then + -- determino il punto comune dei due segmenti + local vtDelta = ( ptEnd - ptStart) / 4 + vtDelta:rotate( vtExtr, -90) + local ptMid = ( ptStart + ptEnd) / 2 + vtDelta + -- creo la spezzata formata dai due segmenti + nId1 = EgtCurveCompoFromPoints( nAddGrpId, { ptStart, ptMid, ptEnd}, GDB_RT.GLOB) + -- altrimenti richiesto arco + else + -- direzione del segmento + local vtDir = ptEnd - ptStart ; + local dLen = vtDir:len() + vtDir:normalize() + -- direzioni tangenti iniziale e finale + local vtStart = EgtSV( nAuxId1, GDB_RT.GLOB) + local vtEnd = EgtEV( nAuxId1, GDB_RT.GLOB) + -- angoli + local dAngStart = acos( vtStart * vtDir) + local dAngEnd = acos( vtEnd * vtDir) + local dMaxAng = min( 30, dAngStart, dAngEnd) + if dLen < dTopDiam then + dMaxAng = min( dMaxAng, asin( dLen / dTopDiam)) + end + local vtTg = vtDir ; vtTg:rotate( vtExtr, -dMaxAng) + -- creo l'arco + nId1 = EgtArc2PV( nAddGrpId, ptStart, ptEnd, vtTg, GDB_RT.GLOB) + end + if not nId1 then + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + EgtModifyCurveExtrusion( nId1, vtExtr, GDB_RT.GLOB) + -- inserisco la lavorazione di contornatura anti splint + local sNameF = 'DtMtAS_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nId1, -1}}) + -- setto affondamento pari all'altezza della mortsasa + EgtSetMachiningParam( MCH_MP.DEPTH, dAltMort) + -- setto offset radiale con aggiunto un ulteriore allargamento di 1mm + EgtSetMachiningParam( MCH_MP.OFFSR, dToolRadDelta - 1) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, false, true)) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dAltMort, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + else + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + else + local sErr = 'Wrong geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + end + -- verifico se necessarie più passate (distanza all'imbocco ortogonale all'asse) + local vtDiff = EgtEP( AuxId, GDB_RT.GLOB) - EgtSP( AuxId, GDB_RT.GLOB) + local vtAx = EgtEV( AuxId, GDB_RT.GLOB) - EgtSV( AuxId, GDB_RT.GLOB) + vtAx:normalize() + local vtOrtDiff = vtDiff - vtDiff * vtAx * vtAx + local dDist = vtOrtDiff:len() + -- calcolo le passate + local nPass = ceil( dDist / ( 1.9 * dToolDiam)) + local dStep = ( dDist - 0.95 * dToolDiam) / ( 2 * nPass) + for i = nPass, 1, -1 do + -- inserisco la lavorazione di contornatura + local sNameF = 'DtMt_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nPass) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto offset + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, false, true)) + -- in presenza di pocket imposto dati ingresso e uscita + if bPocket then + EgtSetMachiningParam( MCH_MP.STARTPOS, 5) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 5) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2) + EgtSetMachiningParam( MCH_MP.LIPERP, 5) + EgtSetMachiningParam( MCH_MP.LIELEV, 0) + end + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessDtMortise diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDtTenon.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDtTenon.lua new file mode 100644 index 0000000..986f40b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessDtTenon.lua @@ -0,0 +1,342 @@ +-- ProcessTenon.lua by Egaltech s.r.l. 2022/04/14 +-- Gestione calcolo tenone a coda di rondine per Travi +-- 2021/04/08 Aggiunto controllo massimo materiale lavorabile dalla fresa. +-- 2022/04/14 Aumentati un poco i limiti di orientamento verso il basso per FAST e PF. + +-- Tabella per definizione modulo +local ProcessDtTenon = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTenon started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + + +--------------------------------------------------------------------- +local function VerifyOrientation( Proc, vtN, b3Raw) + -- se PF con testa da sotto, ammessa qualunque orientazione + if BD.C_SIMM and BD.DOWN_HEAD then + return true + end + -- se trave molto bassa + if b3Raw:getDimZ() < 121 then + -- se tenone praticamente in asse, accetto fino a -45 deg + if abs( vtN:getY()) < 0.088 then + return ( vtN:getZ() >= -0.7072) + -- altrimenti accetto fino a -30deg + else + return ( vtN:getZ() >= -0.51) + end + -- se trave bassa + elseif b3Raw:getDimZ() < 201 then + -- se tenone praticamente in asse, accetto fino a -30 deg + if abs( vtN:getY()) < 0.088 then + return ( vtN:getZ() >= -0.51) + -- altrimenti accetto fino a -21deg + else + return ( vtN:getZ() >= -0.359) + end + -- se trave medio-bassa + elseif b3Raw:getDimZ() < 281 then + -- se tenone praticamente in asse, accetto fino a -25 deg + if abs( vtN:getY()) < 0.088 then + return ( vtN:getZ() >= -0.422) + -- altrimenti, accetto fino a -15 deg + else + return ( vtN:getZ() >= -0.259) + end + -- se trave media + elseif b3Raw:getDimZ() < 351 then + -- se tenone praticamente in asse, accetto fino a -22 deg + if abs( vtN:getY()) < 0.088 then + return ( vtN:getZ() >= -0.375) + -- altrimenti, accetto fino a -10 deg + else + return ( vtN:getZ() >= -0.174) + end + -- altrimenti + else + -- accetto fino a -5deg + return ( vtN:getZ() >= -0.088) + end +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDtTenon.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 55) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDtTenon.Classify( Proc, b3Raw) + -- recupero i dati della curva di contorno della faccia top + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se il tenone è lavorabile solo da sotto + local bDown = not VerifyOrientation( Proc, vtExtr, b3Raw) + return true, bDown +end + +--------------------------------------------------------------------- +local function ApplyPocket( Proc, sPocketing, nStep, dSurfStep, nIdSurf, vtExtr) + + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. nStep + local nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nIdSurf, -1}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + if dSurfStep > 0 then + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dSurfStep, 2) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDtTenon.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + -- verifico che il tenone non sia orientato verso il basso + if not VerifyOrientation( Proc, vtExtr, b3Raw) then + local sErr = 'Error : DtTenon from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza del tenone + local frDtTen = Frame3d( ptBC, vtExtr) + local b3DtTen = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frDtTen) + local dDtTenH = b3DtTen:getDimZ() + -- assegno centro e normale della faccia top + local vtN = vtExtr + local ptC = ptBC + vtN * dDtTenH + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- porto inizio curva a Zmax + BL.PutStartOnTop( AuxId) + -- se tenone inclinato o non esattamente alle estremità, necessario taglio di lama sulla testa + if not AreSameOrOppositeVectorApprox( vtN, X_AX()) or + ( Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dOvmHead - 100 * GEO.EPS_SMALL and + Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 100 * GEO.EPS_SMALL) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla testa del tenone e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC, vtN, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- se pezzo piccolo, in coda e piano inclinato attorno a Z applico svuotatura + if b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getX() < 0 and abs( vtExtr:getY()) > 0.173 then + local sPocketing = ML.FindPocketing( 'OpenPocket') + local dMaxDepth = 100 + local dStep = 30 + local nSurfStep + -- acquisisco i dati necessari dall'utensile + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dStep + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- acquisisco elevazione + local dElev = BL.GetFaceElevation( AddId, 0, nPartId) + nSurfStep = ceil( dElev / dMaxDepth) + dSurfStep = dElev / nSurfStep + local bOk = true + local sErr + -- copio superfice al passo superfice e ci applico la lavorazione + for i = nSurfStep, 2, -1 do + local nAddIdTmp = EgtSurfTmPlaneInBBox( nAddGrpId, ptC+((dSurfStep*(i-1))*vtN), vtN, b3Solid, GDB_RT.GLOB) + if nAddIdTmp then + EgtSetName( nAddIdTmp, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( nAddIdTmp, 'TASKID', Proc.TaskId) + -- aggiungo lavorazione + bOk, sErr = ApplyPocket( Proc, sPocketing, i, (dSurfStep + 0), nAddIdTmp, vtExtr) + if not bOk then + break + end + end + end + if not bOk then + return false, sErr + end + -- faccio ultima superfice + bOk, sErr = ApplyPocket( Proc, sPocketing, 1, EgtIf( nSurfStep > 1, ( dSurfStep + 0), 0), AddId, vtExtr) + if not bOk then + return false, sErr + end + -- altrimenti applico taglio di lama + else + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getZ() > 0.25) + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom) + if not bOk then return bOk, sErr end + end + end + end + -- abilitazione lavorazione da sotto + local bMillUp = ( BD.DOWN_HEAD and vtExtr:getZ() > -0.259) + local bMillDown = ( BD.DOWN_HEAD and vtExtr:getZ() < 0.174) + -- recupero la lavorazione + local sMillType = 'DtTenon' + local sMilling = ML.FindMilling( sMillType .. EgtIf( bMillDown, '_H2', '')) + if not sMilling and bMillUp then + sMilling = ML.FindMilling( sMillType) + end + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 50 + local dMaxMat = 30 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- verifico che l'altezza non superi il massimo materiale dell'utensile + if dDtTenH > dMaxMat + 10 * GEO.EPS_SMALL then + local sErr = 'Error : DtTenon Height bigger than Tool Cutting edge' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo distanza massima della curva dal punto più lontano della base tenone Dt (facet 0) + local dMaxDist = 0 + local nLoopId, nLoopCnt = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id)) + if nLoopId then + local dUmin, dUmax = EgtCurveDomain( nLoopId) + for dU = dUmin, dUmax do + local ptP = EgtUP( nLoopId, dU, GDB_ID.ROOT) + local ptNear = EgtNP( AuxId, ptP, GDB_ID.ROOT) + local dDist = dist( ptP, ptNear) + if dDist > dMaxDist then + dMaxDist = dDist + end + end + for i = 1, nLoopCnt do + EgtErase( nLoopId + i - 1) + end + else + local b3DtAux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frDtTen) + dMaxDist = 2 * ( b3DtTen:getRadius() - b3DtAux:getRadius()) + end + EgtOutLog( 'MaxDist=' .. EgtNumToString( dMaxDist, 3), 3) + -- Cicli di lavorazione (max 6) + local MAX_PASS = 6 + local nStep = min( ceil( dMaxDist / ( 0.7 * dTDiam)), MAX_PASS) + local dStep = min( dMaxDist, 0.7 * dTDiam * MAX_PASS) / nStep + for i = nStep, 1, -1 do + -- inserisco la passata di lavorazione + local sNameR = 'DtTn_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchRId = EgtAddMachining( sNameR, sMilling) + if not nMchRId then + local sErr = 'Error adding machining ' .. sNameR .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo i parametri + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dDtTenH, 1) .. ';') + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = MCH_SCC.ADIR_YM + if abs( vtExtr:getY()) > 0.088 then + nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchRId, false) + return false, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if abs( vtN:getY()) > 0.1 or ( b3Raw:getDimZ() - Proc.Box:getDimZ()) < BD.MIN_HEIGHT then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = dOffs / 2 + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessDtTenon diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessFreeContour.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessFreeContour.lua new file mode 100644 index 0000000..d37b68e --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessFreeContour.lua @@ -0,0 +1,706 @@ +-- ProcessFreeContour.lua by Egaltech s.r.l. 2021/10/07 +-- Gestione calcolo profilo libero per Travi + +-- Tabella per definizione modulo +local ProcessFreeContour = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessFreeContour started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local Q_DIM_STRIP = 'Q01' -- d +local Q_DEPTH_CHAMFER = 'Q02' -- d +local Q_OVERMAT_FOR_FINISH = 'Q03' -- d +local Q_ONLY_CHAMFER = 'Q00' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessFreeContour.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 250) +end +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessFreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- se pocket, ne verifico la direzione di lavorazione + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + if bPocket then + 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) + return ( vtN:getX() >= 0.5) + end + -- deve occupare una buona parte dell'area + if Proc.Box:getDimY() * Proc.Box:getDimZ() > 0.45 * b3Raw:getDimY() * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessFreeContour.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- se pocket, ne verifico la direzione di lavorazione + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + if bPocket then + 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) + return ( vtN:getX() <= - 0.5) + end + -- deve occupare una buona parte dell'area + if Proc.Box:getDimY() * Proc.Box:getDimZ() > 0.45 * b3Raw:getDimY() * b3Raw:getDimZ() then + return true + end + -- non è di coda + return false +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 true, bDown, false + -- se altrimenti profilo orizzontale + elseif abs( vtN:getZ()) < 0.5 then + return true, false, false + -- se altrimenti profilo verticale che non interessa tutta la sezione + elseif Proc.Box:getDimZ() < 0.9 * b3Raw:getDimZ() then + local bDown = ( vtN:getZ() < - 0.5) + return true, bDown, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'FreeContour') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +local function VerifyChamfer( Proc, AuxId, nRawId, bMakeVertCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, Q_DEPTH_CHAMFER, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, Q_ONLY_CHAMFER, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error : not horizontal chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : Mark not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + + return nChamfer, dDepth, sMilling +end + +--------------------------------------------------------------------- +local function CalcCollisionSafety( vtDir) + local dCollSic = 10 * BD.COLL_SIC + if abs( vtDir:getX()) > 0.999 or abs( vtDir:getY()) > 0.999 or abs( vtDir:getZ()) > 0.999 then + dCollSic = 0 + elseif abs( vtDir:getX()) > 0.996 or abs( vtDir:getY()) > 0.996 or abs( vtDir:getZ()) > 0.996 then + dCollSic = 1 * BD.COLL_SIC + elseif abs( vtDir:getX()) > 0.89 or abs( vtDir:getY()) > 0.89 or abs( vtDir:getZ()) > 0.89 then + dCollSic = 2.5 * BD.COLL_SIC + elseif abs( vtDir:getX()) > 0.866 or abs( vtDir:getY()) > 0.866 or abs( vtDir:getZ()) > 0.866 then + dCollSic = 4 * BD.COLL_SIC + elseif abs( vtDir:getX()) > 0.707 or abs( vtDir:getY()) > 0.707 or abs( vtDir:getZ()) > 0.707 then + dCollSic = 5.5 * BD.COLL_SIC + end + return dCollSic +end + +--------------------------------------------------------------------- +local function CalcSpecialAdd( nCrv, bStartVsEnd, dToolDiam) + -- recupero il dominio della curva + local nUi, nUf = EgtCurveDomain( nCrv) + if not nUi then return 0 end + -- indici punti da analizzare + local nOut = EgtIf( bStartVsEnd, nUi, nUf) + local nIn = EgtIf( bStartVsEnd, nUi + 1, nUf - 1) + -- tangenti prima e dopo il punto interno + local vtPrev = EgtUV( nCrv, nIn, -1) + local vtNext = EgtUV( nCrv, nIn, 1) + -- se c'è perdita di tangenza (delta angolare oltre i 5 gradi) + if vtPrev * vtNext < 0.996 then + -- lunghezza del tratto + local ptP0 = EgtUP( nCrv, nOut) + local ptP1 = EgtUP( nCrv, nIn) + local dDist = dist( ptP0, ptP1) + -- se corto rispetto al raggio utensile, ritorno allugamento opportuno + if dDist < 0.6 * dToolDiam then + return ( 0.6 * dToolDiam - dDist + 1) + end + end + return 0 +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : 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 : 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) + local bDown = ( b3Aux:getMin():getZ() < b3Raw:getMin():getZ() + 5) + -- verifico se in testa o coda + local bHead = Proc.Head + -- verifico i parametri Q per profondità smusso e per eseguirlo in esclusiva + local nChamfer, dDepthCham, sChamfer = VerifyChamfer( Proc, AuxId, nRawId, true) + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'FreeContour') + if not sMilling then + local sErr = 'Error : FreeContour not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 10 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + local dCollSic = CalcCollisionSafety( vtExtr) + dMaxDepth = dMaxDepth - dCollSic + -- ne verifico la lunghezza per eventuale spezzatura e lavorazione in doppio + local nStep = 1 + local dStep = 0 + local dLenMax = BD.LONGCUT_ENDLEN + if b3Aux:getDimX() > dLenMax then + local dCrvLen = EgtCurveLength( AuxId) + nStep = ceil( dCrvLen / dLenMax) + dStep = dCrvLen / nStep + EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) + end + -- eventuale spezzatura sul tratto più lungo se curva chiusa + BL.PutStartOnLonger( AuxId) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local bCross = false + if abs( vtExtr:getX()) < 0.707 then + if abs( vtExtr:getY()) > abs( vtExtr:getZ()) then + if b3Aux:getDimY() > b3Raw:getDimY() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimY() / abs( vtExtr:getY())) + end + if bDown then + nSide = -1 + else + nSide = 1 + end + else + if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimZ() / abs( vtExtr:getZ())) + end + end + end + local dOriDepth = dDepth + local nDouble = 1 + local bCanDouble = ( abs( vtExtr:getY()) > abs( vtExtr:getZ()) and bCross) + local dDimStrip = BD.DIM_STRIP + if dDimStrip < 0 then + dDimStrip = EgtGetInfo( Proc.Id, Q_DIM_STRIP, 'd') or 0 + end + local bStripOnSide = false + if bCross then + if dDimStrip > 10 * GEO.EPS_SMALL and ( nStep > 1 or ( bDown and b3Aux:getDimX() > 0.5 * b3Raw:getDimX())) then + -- devo lasciare un codolo + dDepth = dDepth - dDimStrip + bStripOnSide = true + else + -- devo affondare un poco oltre + dDepth = dDepth + BD.CUT_EXTRA + end + end + -- se parametro beamdata forza codolo in centro e lavorazione orizzontale e se larghezza trave è sufficientemente larga + if BD.DIM_TO_CENTER_STRIP and BD.DIM_TO_CENTER_STRIP > 10 * GEO.EPS_SMALL and nStep > 1 and + bCanDouble and b3Raw:getDimY() > BD.DIM_TO_CENTER_STRIP - 0.1 then + nDouble = 2 + dDepth = min( ( b3Raw:getDimY() - dDimStrip) * 0.5, dMaxDepth) + else + -- se altezza geometria supera capacità taglio utensile ed è orizzontale setto per eseguire codolo in centro + if dDepth > dMaxDepth then + if bCanDouble then + nDouble = 2 + dDepth = min( 0.5 * dDepth, dMaxDepth) + else + dDepth = dMaxDepth + end + end + end + -- se utensile orizzontale verso Y+, non in doppio e codolo da lasciare, devo invertire per lavorare sempre da Y- + if vtExtr:getY() > 0.707 and nDouble == 1 and bStripOnSide then + bToolInv = true + end + -- verifico se primo e ultimo tratti corti e con angolo + local dStartAddSpec = 0 + if Proc.Grp ~= 0 then dStartAddSpec = CalcSpecialAdd( AuxId, true, dToolDiam) end + local dEndAddSpec = 0 + if Proc.Grp ~= 0 then dEndAddSpec = CalcSpecialAdd( AuxId, false, dToolDiam) end + -- se devo inserire il chamfer + if nChamfer > 0 and Proc.Grp ~= 0 and dOriDepth > dDepthCham then + local bDoubleCham = false + local dExtra = 2 + -- eseguo + for i = 1, nStep do + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + end + if Proc.Grp == 3 then + if not bToolInv then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + end + if Proc.Grp == 4 then + if not bToolInv then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- eventuale accorciamento di testa + if i > 1 then + local dStartAddLen = - ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen + 1) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddSpec + 1) + end + -- eventuale accorciamento di coda + if i < nStep then + local dEndAddLen = - ( nStep - i) * dStep + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen + 1) + else + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddSpec + 1) + end + -- posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if Proc.Head then + nSCC = MCH_SCC.ADIR_XP + elseif Proc.Tail then + nSCC = MCH_SCC.ADIR_XM + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + nSCC = MCH_SCC.ADIR_YP + elseif vtExtr:getY() > -0.01 then + nSCC = MCH_SCC.ADIR_YP + else + nSCC = MCH_SCC.ADIR_YM + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + if Proc.Grp == 3 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + elseif Proc.Grp == 4 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- eventuale accorciamento di testa + if i < nStep then + local dEndAddLen = - ( nStep - i) * dStep + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen + 1) + else + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddSpec + 1) + end + -- eventuale accorciamento di coda + if i > 1 then + local dStartAddLen = - ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen + 1) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddSpec + 1) + end + -- posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if Proc.Head then + nSCC = MCH_SCC.ADIR_XP + elseif Proc.Tail then + nSCC = MCH_SCC.ADIR_XM + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + nSCC = MCH_SCC.ADIR_YP + elseif vtExtr:getY() < 0.01 then + nSCC = MCH_SCC.ADIR_YP + else + nSCC = MCH_SCC.ADIR_YM + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + end + -- verifico se devo fare sgrossatura più finitura + local dOffsetPar = EgtGetInfo( Proc.Id, Q_OVERMAT_FOR_FINISH, 'i') or 0 + -- eseguo + for i = 1, nStep do + for j = 1, nDouble do + local sName + local nMchId + local bEnableCham + -- se ho smusso abilitato e profondità geometria minore della profondità smusso, + -- applico lavorazione smusso + if nChamfer > 0 and dOriDepth <= dDepthCham then + -- inserisco la lavorazione + sName = 'FreeCham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + nMchId = EgtAddMachining( sName, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + dOffsetPar = 0 + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham) + bEnableCham = true + else + -- inserisco la lavorazione + sName = 'Free_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- eventuale accorciamento di testa + if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then + local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( j == 1, dStartAddSpec, dEndAddSpec)) + end + -- eventuale accorciamento di coda + if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then + local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + else + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( j == 1, dEndAddSpec, dStartAddSpec)) + end + -- se estrusione da sotto, inverto direzione fresa + if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- se seconda passata, inverto direzione di lavoro + if j == 2 then + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- 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 + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if Proc.Head then + nSCC = MCH_SCC.ADIR_XP + elseif Proc.Tail then + nSCC = MCH_SCC.ADIR_XM + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + nSCC = MCH_SCC.ADIR_YP + elseif ( j == 1 and vtExtr:getY() > -0.01) or ( j == 2 and vtExtr:getY() < 0.01) then + nSCC = MCH_SCC.ADIR_YP + else + nSCC = MCH_SCC.ADIR_YM + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- acquisisco parametro sovramateriale + local bFinish + local dOriOffset = 0 + -- se parametro sovramateriale è maggiore di 0 abilito la finitura extra + if not bEnableCham and dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + elseif bEnableCham and Proc.Grp ~= 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, dDepthCham) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sNewName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByPocket( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- 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, nPhase, nRawId, nPartId, dOvmHead) + -- recupero la tipologia + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- se svuotatura + if bPocket then + return MakeByPocket( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- altrimenti contornatura + else + return MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead) + end +end + +--------------------------------------------------------------------- +return ProcessFreeContour diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessFrenchRidgeLap.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessFrenchRidgeLap.lua new file mode 100644 index 0000000..553a5fb --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessFrenchRidgeLap.lua @@ -0,0 +1,279 @@ +-- ProcessFrenchRidgeLap.lua by Egaltech s.r.l. 2020/02/11 +-- Gestione calcolo giunzione francese + +-- Tabella per definizione modulo +local ProcessFrenchRidgeLap = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessFrenchRidgeLap started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessFrenchRidgeLap.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 35) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessFrenchRidgeLap.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessFrenchRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getX()) > GEO.EPS_SMALL and abs( vtN[i]:getY()) > GEO.EPS_SMALL and abs( vtN[i]:getZ()) > GEO.EPS_SMALL then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + bHead = ( vtN[vFaceOrd[1]]:getX() > 0) + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + local dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < (#vCuts-1) or (i == #vCuts) then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO = Vector3d( vtRef) + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + else + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO = Vector3d( vtRef) + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + -- altrimenti di fianco + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + -- altrimenti di fianco + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessFrenchRidgeLap diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessHeadCut.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessHeadCut.lua new file mode 100644 index 0000000..9e7bd03 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessHeadCut.lua @@ -0,0 +1,268 @@ +-- ProcessSplit.lua by Egaltech s.r.l. 2022/01/25 +-- Gestione calcolo tagli di testa per Travi + +-- Tabella per definizione modulo +local ProcessHeadCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessHeadCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessHeadCut.Identify( Proc) + return ( Proc.Grp == 1 and Proc.Prc == 340) +end + +--------------------------------------------------------------------- +-- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) +local function VerifyCurveForChamfer( AuxId) + if not AuxId then + return -2 + end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + return -1 + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- va bene solo se direzione estrusione orizzontale + if abs( vtExtr:getZ()) > 0.1 then + return 0 + end + return 1 +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( nOriId, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico le entità curva associate (max 2) + local sVal = EgtGetInfo( nOriId, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local AuxId, Aux2Id + if vsAuxId and #vsAuxId >=1 then + AuxId = tonumber( vsAuxId[1]) + end + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if AuxId then AuxId = AuxId + nOriId end + if Aux2Id then Aux2Id = Aux2Id + nOriId end + local nRes = VerifyCurveForChamfer( AuxId) + if nRes == 0 and Aux2Id then + AuxId = Aux2Id + nRes = VerifyCurveForChamfer( AuxId) + end + if nRes == -2 then + return true + end + if nRes == -1 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + if nRes == 0 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true, nil +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessHeadCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bNeedHCut) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- inserimento smussi + local nOriId = EgtGetInfo( Proc.Id, 'ORI', 'i') + if nOriId then + local bOkc, sErrC = MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 50 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + local dMaxVertDepth = dMaxDepth - ( BD.DECR_VERT_CUT or 0) + -- caratteristiche taglio + local bHorizCut = (( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL or BD.TURN) and b3Raw:getDimZ() < dMaxVertDepth - BD.CUT_EXTRA) + local dDimYRef = EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, dMaxDepth, BD.MAX_DIM_HTCUT_HBEAM) + local bDoubleHorizCut = ( BD.DOWN_HEAD and not bHorizCut and b3Raw:getDimY() > 2 * dDimYRef - BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL) + local bDoubleCut = ( not bHorizCut and not bDoubleHorizCut and b3Raw:getDimY() > dDimYRef - BD.CUT_EXTRA + 10 * GEO.EPS_SMALL) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- se non obbligatorio e coincide con inizio grezzo, non va fatto + if not bNeedHCut and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX()) < 10 * GEO.EPS_SMALL then + return true + end + -- determino se più tagli con offset + local nCuts = max( ceil( dOvmHead / ( BD.MAX_LEN_SCRAP_START or BD.MAX_LEN_SCRAP)), 1) + local dOffsL = dOvmHead / nCuts + -- se tagli standard + if not bDoubleHorizCut then + -- flag di lavorazione faccia + local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_FRONT) + -- calcolo extra taglio ed accorciamento + local dCutExtra = 0 + local dAccStart = 0 + local dAccEnd = 0 + if b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL or b3Raw:getDimY() < 2 * BD.MAX_DIM_HTCUT_HBEAM + 10 * GEO.EPS_SMALL then + dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN, BD.CUT_EXTRA) + else + dCutExtra = - ( b3Raw:getDimY() - dMaxDepth) + local dSawRad = dSawDiam / 2 + local dKL = dSawRad - dMaxDepth + b3Raw:getDimY() / 2 + BD.CUT_EXTRA_MIN + if BD.C_SIMM then + dAccEnd = sqrt( dSawRad * dSawRad - dKL * dKL) + else + dAccStart = sqrt( dSawRad * dSawRad - dKL * dKL) + end + end + -- se necessari tagli in doppio, eseguo gli opposti + if bDoubleCut then + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_BACK, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, dAccEnd, '', b3Raw) + if not bOk then return false, sErr end + end + end + -- eseguo i tagli necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, dAccEnd, '', b3Raw) + if not bOk then return false, sErr end + end + -- altrimenti necessari tagli da sopra e sotto con testa opportuna + else + -- recupero la lavorazione con lama da sotto + local sCutting2 = ML.FindCutting( 'HeadSide_H2') + if not sCutting2 then + local sErr = 'Error : cutting H2 not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della seconda lama + local dSawDiam2 = 400 + local dMaxDepth2 = 50 + if EgtMdbSetCurrMachining( sCutting2) then + local sTuuid2 = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid2) or '') then + dSawDiam2 = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam2 + dMaxDepth2 = EgtTdbGetCurrToolMaxDepth() or dMaxDepth2 + end + end + -- verifico che le due lame riescano a lavorare la sezione + local dDimZ = b3Raw:getDimZ() + local dExtra = dMaxVertDepth + dMaxDepth2 - dDimZ + if dExtra - 2 * BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL < 0 then + local sErr = 'Error : section too big for head cut' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo extra taglio ed accorciamento + local dCutExtra = -dMaxDepth2 + dExtra / 2 + BD.CUT_EXTRA_MIN + local dCutExtra2 = -dMaxVertDepth + dExtra / 2 + BD.CUT_EXTRA_MIN + local dAccStart = 0 + -- eseguo i tagli da sotto necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting2, dSawDiam2, MCH_MILL_FU.ORTHO_TOP, nil, dCutExtra2, BD.CUT_SIC, dCutOffset, dAccStart, 0, '', b3Raw) + if not bOk then return false, sErr end + end + -- eseguo i tagli da sopra necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_DOWN, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, 0, '', b3Raw) + if not bOk then return false, sErr end + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessHeadCut diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLapJoint.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLapJoint.lua new file mode 100644 index 0000000..8aa3aa5 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLapJoint.lua @@ -0,0 +1,5571 @@ +-- ProcessLapJoint.lua by Egaltech s.r.l. 2022/03/29 +-- Gestione calcolo mezzo-legno per Travi +-- 2019/10/08 Agg. gestione OpenPocket. +-- 2021/01/24 Con sega a catena ora sempre impostato asse A. +-- 2021/02/03 Corretto riconoscimento feature di coda. +-- 2021/02/04 Razionalizzata gestione forzatura lama. Corretta gestione diametro minimo utensile per svuotatura. +-- 2021/03/04 Due facce con testa da sotto. +-- 2021/03/20 Piccole correzioni. +-- 2021/03/22 Modificata gestione caso due facce lunghe come la trave con trave corta. +-- 2021/04/13 Modificata gestione fessura U con sega a catena (corta ora ok, lunga ancora da correggere). +-- 2021/04/14 Correzioni ribasso a U con fresa da sotto. +-- 2021/04/15 Aggiunta gestione massima lunghezza fresa da sotto su svuotature. +-- 2021/04/21 Anche feature lunga con due facce con opzione lama ora si taglia con lama. +-- 2021/04/23 Corretto caso con antischeggia non inseriti perchè inutili. +-- 2021/04/27 Antischeggia solo se feature trasversali. +-- 2021/05/12 Semplificata gestione diametro minimo utensile per svuotatura. +-- 2021/06/04 Su U passante con faccia perpendicolare aggiunta si forza Pocket. +-- 2021/06/11 Su U passante e profonda se non bastano due svuotature su faccia ortogonale si fa anche la faccia di fondo per quanto possibile. +-- 2021/06/21 Nel caso precedente si fa la terza svuotatura anche se è possibile fare una sola delle prime due (altra da sotto). +-- 2021/06/21 Gestione ripresa spigoli o contorno con fresa più piccola ( diametro < 3/4 utensile svuotatura) attivata da parametro Q. +-- 2021/07/02 Migliorie e correzioni su svuotature e pulitura spigoli. +-- 2021/07/15 Aggiunti antischeggia con fresa. +-- 2021/09/08 Aggiunta gestione parametro Q04 per i tagli di lama lungo facce lunghe (con o senza facce di chiusura) +-- 2021/09/21 Aggiunta lavorazione/opzione "lamello" con le feature 16, 30, 32, 39, +-- che si attiva abilitando il check al tipo milling: SideMillAsBlade (SideMillAsBlade_2) +-- 2021/09/23 Gestione migliorata lavorazioni BH (blockhaus) su macchina fast BH, +-- migliorata applicazione lavorazioni BH su feature lunghe lavorte a passi +-- 2021/10/06 Ad antischeggia con lama in presenza di testa da sotto aggiunta preferenza a testa da sopra. +-- 2021/10/19 Corretta gestione inversione per Tunnel. OpenPocket anche se spezzato ma 1 o 2 facce. Introdotta lunghezza minima per lamello. +-- 2021/10/21 Migliorato controllo affondamento utensile in U lavorato da 3 parti (anche da sotto). +-- 2021/10/27 Migliorato calcolo asse tunnel o similare. +-- 2021/11/02 In svuotatura con lati aperti diametro fresa non superiore al doppio del lato piccolo. +-- 2021/11/15 Quando si usa sega a catena uso Q10 come massima elevazione. +-- 2021/11/22 Corretta segnalazione warning su foro di L20 e L25. +-- 2022/01/19 Cambiata % lunghezza pezzo per spezzatura. Tolta correzione spessore fresa a disco con superficie da lavorare verso Z-. +-- 2022/01/26 Migliorato controllo uso testa da sotto nel caso due facce con lama. +-- 2022/02/07 Corretto caso con due facce che non è un LongDoubleCut ma che veniva identificato come tale. +-- 2022/02/14 Introdotto uso svuotature ZigZag ottimizzate. +-- 2022/03/18 Corretta lavorazione BH. +-- 2022/03/21 Quando si usa lama uso Q10 come massima elevazione. +-- 2022/03/29 Aggiunta gestione antischeggia con Q06 anche su 3/4-033-X. + +-- Tabella per definizione modulo +local ProcessLapJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local Cut = require( 'ProcessCut') +local DoubleCut = require( 'ProcessDoubleCut') +local LongCut = require( 'ProcessLongCut') +local Long2Cut = require( 'ProcessLongDoubleCut') + +EgtOutLog( ' ProcessLapJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local Q_FORCE_BLADE = '' -- i +local Q_DEPTH_CHAMFER = '' -- d +local Q_ONLY_CHAMFER = '' -- i +local Q_USE_MILL = '' -- i +local Q_USE_ROUGH_TOOL = '' -- i +local Q_BORE_ON_CORNER = '' -- 1 +local Q_CONTOUR_SMALL_TOOL = '' -- i +local Q_ONLY_CONTOUR = '' -- i +local Q_SIDE_ROUGH_TOOL = '' -- i +local Q_ANTISPLINT_TYPE = '' -- i +local Q_BLADE_ON_ALONG_FACE = '' -- i +local Q_MAX_ELEVATION = '' -- d + +-- variabile smussi +local bMadeChamfer + +-- Settaggi interni +local bTrySidePocketAtFirst = true + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLapJoint.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 33) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or + ( Proc.Grp == 4 and Proc.Prc == 37) or + ( Proc.Grp == 4 and Proc.Prc == 39) or + ( Proc.Grp == 4 and Proc.Prc == 120)) +end + +--------------------------------------------------------------------- +local function AssignQIdent( Proc) + + -- reset assegnazione parametri Q + Q_FORCE_BLADE = '' + Q_DEPTH_CHAMFER = '' + Q_ONLY_CHAMFER = '' + Q_USE_MILL = '' + Q_USE_ROUGH_TOOL = '' + Q_BORE_ON_CORNER = '' + Q_CONTOUR_SMALL_TOOL = '' + Q_ONLY_CONTOUR = '' + Q_SIDE_ROUGH_TOOL = '' + Q_ANTISPLINT_TYPE = '' + Q_MAX_ELEVATION = 'Q10' + + if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then + Q_FORCE_BLADE = 'Q01' -- i + Q_DEPTH_CHAMFER = 'Q04' -- d + Q_ONLY_CHAMFER = 'Q05' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then + Q_DEPTH_CHAMFER = 'Q01' -- d + Q_ONLY_CHAMFER = 'Q02' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then + Q_DEPTH_CHAMFER = 'Q01' -- d + Q_USE_MILL = 'Q02' -- i + Q_USE_ROUGH_TOOL = 'Q03' -- i + Q_BORE_ON_CORNER = 'Q06' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25 then + Q_BORE_ON_CORNER = 'Q01' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then + Q_CONTOUR_SMALL_TOOL = 'Q01' -- i + Q_ONLY_CONTOUR = 'Q02' -- i + Q_SIDE_ROUGH_TOOL = 'Q03' -- i + Q_BLADE_ON_ALONG_FACE = 'Q04' -- i + Q_ANTISPLINT_TYPE = 'Q06' -- i + Q_DEPTH_CHAMFER = 'Q07' -- d + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then + Q_SIDE_ROUGH_TOOL = 'Q01' -- i + Q_CONTOUR_SMALL_TOOL = 'Q02' -- i + Q_ANTISPLINT_TYPE = 'Q06' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 33 then + Q_ANTISPLINT_TYPE = 'Q06' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34 then + Q_CONTOUR_SMALL_TOOL = 'Q01' -- i + Q_ANTISPLINT_TYPE = 'Q06' -- i + elseif ( Proc.Grp == 4) and Proc.Prc == 37 then + Q_ANTISPLINT_TYPE = 'Q06' -- i + elseif ( Proc.Grp == 4) and Proc.Prc == 39 then + Q_CONTOUR_SMALL_TOOL = 'Q01' -- i + Q_USE_MILL = 'Q02' -- i + Q_ANTISPLINT_TYPE = 'Q06' -- i + end + -- le altre features gestite non hanno parametri Q +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc) + -- verifico che lo smusso sia richiesto + local nChamfer = 0 + local dDepth = EgtGetInfo( Proc.Id, Q_DEPTH_CHAMFER, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, Q_ONLY_CHAMFER, 'i') == 1 then + if dDepth > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- verifico se devo usare lama invece della sega-catena + -- 2020-03-20 forzata abilitazione uso lama se parametro Q non è presente + -- xxxx-xx-xx tolta la preferenza alla lama in favore della sega-catena per un caso particolare + -- 2021-02-15 re-introdotta la preferenza alla lama se non c'è il parametro Q. Rimane da + -- implementare un ulteriore parametro per poter scegliere di prediligere la sega-catena o no al fine di continuare + -- a cambiare il codice per gestire il caso particolare + local bForceUseBlade = false + if #Q_FORCE_BLADE == 0 or EgtGetInfo( Proc.Id, Q_FORCE_BLADE, 'i') == 1 then + bForceUseBlade = true + end + + return nChamfer, dDepth, sErr, bForceUseBlade +end + +--------------------------------------------------------------------- +local function TestElleShape3( Proc, bNotProc) + -- se non passato il Proc vero e proprio + local nNumFacet + local nProcId + if bNotProc then + nProcId = Proc + nNumFacet = EgtSurfTmFacetCount( nProcId) + else + nProcId = Proc.Id + nNumFacet = Proc.Fct + end + -- valida solo nel caso di tre facce + if nNumFacet ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( nProcId, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +local function TestElleShape4( Proc) + -- valida solo nel caso di quattro facce + if Proc.Fct ~= 4 then return false end + -- determino se L con due facce terminali o O + local nFac3Adj = 0 + local dMinArea3 = GEO.INFINITO * GEO.INFINITO + local dMaxArea2 = 0 + for i = 1, 4 do + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, i - 1, GDB_ID.ROOT) + local dArea = dH * dV + if nCount == 2 then + dMaxArea2 = max( dMaxArea2, dArea) + elseif nCount == 3 then + dMinArea3 = min( dMinArea3, dArea) + nFac3Adj = nFac3Adj + 1 + end + end + if nFac3Adj ~= 2 then return false end + -- verifico se L profonda oppure lunga + if dMinArea3 < 2 * dMaxArea2 then + return 1 + else + return 2 + end +end + +--------------------------------------------------------------------- +local function GetChainSawBlockedAxis( nInd) + if BD.GetChainSawBlockedAxis then + return BD.GetChainSawBlockedAxis( nInd) + else + if nInd == 1 then + return EgtIf( BD.C_SIMM, 'A=90', 'A=90') + else + return EgtIf( BD.C_SIMM, 'A=0', 'A=0') + end + end +end + +--------------------------------------------------------------------- +local function GetChainSawInitAngs( vtN, vtO, nInd) + if BD.GetChainSawInitAngs then + return BD.GetChainSawInitAngs( vtN, vtO, nInd) + else + if BD.C_SIMM then + return EgtIf( vtN:getY() > 0, 'C=180', 'C=-180') + else + if nInd ==1 then + return '' + else + return EgtIf( vtN:getY() > 0, 'C=180', 'C=-180') + end + end + end +end + +--------------------------------------------------------------------- +local function VerifyChainSaw( Proc, dMinDim, dMaxDim) + local bUseChainSaw = false + local sMchFind = 'Sawing' + local sSawing = ML.FindSawing(sMchFind) + local dMaxMat = 0 + local dSawCornerRad = 0 + local dSawThick = 0 + local dMaxDepth = 200 + -- se non trova una lavorazione di sawing esco + if not sSawing then + return bUseChainSaw + else + -- recupero i dati dell'utensile + local dToolLength = 0 + local dSawWidth = 75 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dSawCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) or dSawCornerRad + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + if dSawThick < dMinDim + 10 * GEO.EPS_SMALL and dSawWidth < dMaxDim + 10 * GEO.EPS_SMALL then + bUseChainSaw = true + end + end + end + return bUseChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick, dMaxDepth +end + +--------------------------------------------------------------------- +local function VerifyPocket( Proc, dDiam, dDepth, dMaxTotLen, sMchFindMaster) + -- tipo di svuotatura + local sMchFind = EgtIf( sMchFindMaster and #sMchFindMaster > 0, sMchFindMaster, 'Pocket') + -- ricerca della svuotatura + local sPocketing + if dDepth then + sPocketing = ML.FindPocketing( sMchFind, dDiam, dDepth, dMaxTotLen) or + ML.FindPocketing( sMchFind, dDiam, 0.8 * dDepth, dMaxTotLen) or + ML.FindPocketing( sMchFind, dDiam, 0.6 * dDepth, dMaxTotLen) or + ML.FindPocketing( sMchFind, dDiam, 0.4 * dDepth, dMaxTotLen) or + ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen) + else + sPocketing = ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen) + end + if not sPocketing then + return false + end + -- recupero i dati dell'utensile + local bUsePocketing = false + local dMaxDepth = 0 + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + bUsePocketing = true + end + return bUsePocketing, sPocketing, dMaxDepth, dToolDiam +end + +--------------------------------------------------------------------- +local function VerifyBHSideMill( Proc, bIsU, bIsL, bSinglePart, bPrevBhSideMill) + + -- se non feature BlockHausHalfLap e non abilitato parametro Q per lavorarlo di fianco e non macchina BH esco + local nUseSideTool = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0 + if Proc.Prc ~= 37 and nUseSideTool == 0 and not BD.BH_MACHINE then + return false + end + + -- recupero l'ingombro della trave + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + return false + end + + -- verifico se la funzione è lanciata da IsTailFeature o Classify + if bSinglePart == nil then + -- se lunghezza non richiede spezzatura setto la variabile bSinglePart + if not( ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or + ( Proc.Box:getDimX() > 0.8 * b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN)) then + bSinglePart = true + end + end + + -- determino se U o L(anche con 1 o 2 facce di terminazione) + bIsU = ( bIsU or ( Proc.Fct == 3 and not TestElleShape3( Proc))) + bIsL = ( bIsL or ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2)) + + -- le facce devono contenere X e quelle di chiusura devono essere perpendicolari a X + local bStopY, bStopZ + for i = 1, Proc.Fct do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + if abs( vtN:getX()) > 0.001 and abs( vtN:getX()) < 0.999962 then + return false + end + if abs( vtN:getY()) > 0.866 then bStopY = true end + if abs( vtN:getZ()) > 0.866 then bStopZ = true end + end + if bStopY and bStopZ then + return false + end + + -- se non U o L o singola faccia di multipla, non accettata + if not ( ( bIsU or bIsL or ( Proc.Fct == 1 and not bSinglePart)) and Proc.Box:getDimX() <= BD.LONGCUT_MAXLEN) then + return false + end + + -- se risultato precedente di passo multiplo negativo, riporto il risultato del passo precedente + if bPrevBhSideMill ~= nil and not bPrevBhSideMill then + return false + end + + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'BHSideMill') + if not sMilling then + return false + end + + -- recupero i dati dell'utensile + local dToolLength = 0 + local dToolDiam = 0 + local dMaxDepth = 0 + local dThickTool = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dThickTool = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThickTool + end + end + + -- verifico se abbastanza larga (oppure L) rispetto all'utensile + if Proc.Box:getDimX() < dThickTool - 15 * GEO.EPS_SMALL and not bIsL then + return false + end + + -- limiti longitudinali + local dMinXF = Proc.Box:getMin():getX() + local dMaxXF = Proc.Box:getMax():getX() + local dMinT = b3Solid:getMin():getX() + local dMaxT = b3Solid:getMax():getX() + + -- determino se è più vicino alla testa o alla coda (con offset per evitare problemi a metà) + local bHeadDir = ( dMaxT - dMinXF) < ( dMaxXF - dMinT) + 50 + local bHead = bHeadDir + + -- verifico se raggiungibile con la testa senza collisioni + local bUseBHSideMill = EgtIf( bHead, ( dMaxT - dMinXF), ( dMaxXF - dMinT)) < dMaxDepth + -- se diametro utensile maggiore della testa + if BD.HEAD_DIM_FOR_BH and dToolDiam > BD.HEAD_DIM_FOR_BH then + bHead = true + bUseBHSideMill = true + end + + return bUseBHSideMill, bHead, bHeadDir, sMilling, dThickTool, dToolDiam +end + +--------------------------------------------------------------------- +local function GetTunnelDimension( Proc, nPartId) + -- sono necessarie almeno due facce + if Proc.Fct < 2 then return 0, 0, 0 end + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- recupero centro e normale delle facce + local ptC = {} + local vtN = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + end + -- calcolo l'orientamento del tunnel + local vtOrtho + local bAdj = EgtSurfTmFacetsContact( Proc.Id, 0, 1) + if bAdj then + vtOrtho = vtN[1] ^ vtN[2] + else + if Proc.Fct >= 3 then + vtOrtho = vtN[1] ^ vtN[3] + else + return 0, 0, 0 + end + end + -- ottengo il boundingBox e prendo le dimensioni lungo la direzione (Z locale) che rappresenta la profondità della fessura + local frFc = Frame3d( ptC[1], vtOrtho) ; + local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) + local dDepth = b3BoxLoc:getDimZ() + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + EgtOutLog( 'Error : missing AddGroup') + return 0, 0, 0 + end + -- centro del bounding box locale + local ptCen = b3BoxLoc:getCenter() + ptCen:toGlob( frFc) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptCen, vtOrtho, b3Solid, GDB_ID.ROOT) + if not nSurfInt then return 0, 0, 0 end + -- ritaglio la superficie con le facce della fessura + for i = 1, Proc.Fct do + EgtCutSurfTmPlane( nSurfInt, ptC[i], -vtN[i], false, GDB_ID.ROOT) + end + local frSurfInt, dDimMax, dDimMin = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT) + -- cerco la faccia con larghezza pari a dimensione massima della fessura + local nLongIdFace = 0 + for i = 1, Proc.Fct do + if abs( vtN[i] * frSurfInt:getVersX()) < 0.5 then + nLongIdFace = i - 1 + break + end + end + return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt +end + +--------------------------------------------------------------------- +local function GetFaceAdj( Proc, nFacInd, dH, dV) + + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + return -1, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 4) + -- Riordino le dimensioni per avere dH > dV + if dH < dV then + dH, dV = dV, dH + end + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > 0.5 * dH then + nFacAdj = vAdj[i] + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 4) + break + end + end + end + if not nFacAdj then + local sErr = 'Error : main face without long adjacent face' + return -1, sErr + end + return nFacAdj +end + +--------------------------------------------------------------------- +local function CalcCollisionSafety( vtDir) + local dCollSic = 10 * BD.COLL_SIC + if abs( vtDir:getX()) > 0.999 or abs( vtDir:getY()) > 0.999 or abs( vtDir:getZ()) > 0.999 then + dCollSic = 0 + elseif abs( vtDir:getX()) > 0.996 or abs( vtDir:getY()) > 0.996 or abs( vtDir:getZ()) > 0.996 then + dCollSic = 1 * BD.COLL_SIC + elseif abs( vtDir:getX()) > 0.89 or abs( vtDir:getY()) > 0.89 or abs( vtDir:getZ()) > 0.89 then + dCollSic = 2.5 * BD.COLL_SIC + elseif abs( vtDir:getX()) > 0.866 or abs( vtDir:getY()) > 0.866 or abs( vtDir:getZ()) > 0.866 then + dCollSic = 4 * BD.COLL_SIC + elseif abs( vtDir:getX()) > 0.707 or abs( vtDir:getY()) > 0.707 or abs( vtDir:getZ()) > 0.707 then + dCollSic = 5.5 * BD.COLL_SIC + end + return dCollSic +end + +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() > 0.1 then + return true + end + end + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 *b3Raw:getDimX()) then + return false + end + -- recupero identificativo del pezzo + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + -- se una o due facce e interessa veramente la testa, allora di testa + if Proc.Fct <= 2 then + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if Proc.Box:getMax():getX() > b3Solid:getMax():getX() - 1. then + return true + elseif Proc.Box:getMax():getX() < b3Solid:getMax():getX() - 5. then + return false + end + end + -- deve avere la normale principale diretta verso la testa + local nFacInd, dElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN and vtN:getX() < 0.499 then + return false + elseif Proc.Fct >= 5 then + return true + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessLapJoint.IsTailFeature( Proc, b3Raw) + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() < -0.1 then + return true + end + end + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQIdent( Proc) + -- se può essere fatto con utensile tipo lama + local bUseBHSideMill, bHead, bHeadDir = VerifyBHSideMill( Proc) + if bUseBHSideMill then + Proc.HeadDir = bHeadDir + --return not bHead + end + -- recupero box del pezzo + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- verifico se è in coda + local dEndDist = Proc.Box:getMin():getX() - b3Solid:getMin():getX() + if dEndDist > BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then + return false + end + -- se una o due facce e interessa veramente la coda, allora di coda + if Proc.Fct <= 2 then + if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then + return true + elseif Proc.Box:getMin():getX() > b3Solid:getMin():getX() + 5. then + return false + end + end + -- deve avere la normale principale diretta verso la coda (oppure tunnel) + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN and vtN:getZ() < BD.NZ_MINA and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + dElev, dElev2 = dElev2, dElev + end + if not vtN or vtN:getX() > -0.001 or dEndDist + vtN:getX() * dElev > 0 then + return false + else + return true + end +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLapJoint.Classify( Proc, b3Raw) + -- se 1 faccia + if Proc.Fct == 1 then + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + --local bDown = ( vtN:getZ() < BD.NZ_MINA) + --return true, bDown + return true, false + -- se 2 facce + elseif Proc.Fct == 2 then + -- se può essere fatto con utensile tipo lama + local bUseBHSideMill = VerifyBHSideMill( Proc) + if bUseBHSideMill then + return true, false + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bSmall = ( ( Proc.Head or Proc.Tail) and Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) or + ( not ( Proc.Head or Proc.Tail) and Proc.Box:getDimY() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or + ( vtN[1]:getZ() < BD.NZ_MINA and vtN[2]:getZ() < 0.5 and ( vtN[2]:getZ() < -0.1 or not bSmall)) or + ( vtN[2]:getZ() < BD.NZ_MINA and vtN[1]:getZ() < 0.5 and ( vtN[1]:getZ() < -0.1 or not bSmall)) + bDown = ( bDown and not BD.DOWN_HEAD and not BD.TURN) + return true, bDown + -- se più di 2 facce + else + local bClosedOrthoFaces + local nDeletedFace + -- recupero la faccia con il maggior numero di adiacenze e minor elevazione + local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + else + return false + end + end + -- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche + if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + return false + end + -- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura + for i = 1, Proc.Fct do + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + -- elimino una faccia + nDeletedFace = i - 1 + if EgtSurfTmRemoveFacet( nNewProc, nDeletedFace) then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( nNewProc, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + EgtErase( nNewProc) + break + else + EgtErase( nNewProc) + return false + end + end + -- altrimenti esco + else + EgtErase( nNewProc) + break + end + end + -- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo + if bClosedOrthoFaces then + nFacInd = nDeletedFace + -- rendo nulla la faccia opzionale perchè si tratta di una fessura + nFacInd2 = nil + dElev = BL.GetFaceElevation( Proc.Id, nFacInd) + bClosedOrthoFaces = false -- non lo setto come tunnel + end + end + -- se facce formano un tunnel e sono ortogonali + if bClosedOrthoFaces then + -- ottengo le dimensioni del tunnel + local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId) + EgtErase( nSurfInt) + -- verifico se può essere fatto con svuotatura + if VerifyPocket( Proc, dDimMin) then + return true, false + elseif VerifyChainSaw( Proc, dDimMin, dDimMax) then + return true, false + else + return false + end + else + -- dati della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local nFac2Ind = EgtIf( nFacInd ~= 0, 0, 1) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFac2Ind, GDB_ID.ROOT) + if abs( rfFac:getVersY() * vtN2) < 0.5 then + dH, dV = dV, dH + rfFac:rotate( rfFac:getOrigin(), rfFac:getVersZ(), 90) + end + -- se può essere fatto con utensile tipo lama + local bUseBHSideMill = VerifyBHSideMill( Proc) + if bUseBHSideMill then + return true, false + -- altrimenti controllo se deve essere ruotato con le altre lavorazioni + else + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- cerco se c'è faccia adiacente sul lato più lungo + local nFaceAdj = GetFaceAdj( Proc, nFacInd, dH, dV) or -1 + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2) + -- verifico se è lavorabile solo dal basso + local bDown = ( vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD and not BD.TURN) + -- se verso il basso, verifico se utilizzabile seconda faccia + if bDown then + if nFacInd2 and dElev2 < 2 * dElev then + local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINB) + elseif not nFacInd2 and bIsL and nFaceAdj >= 0 then + local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINB) + end + -- verifico se la faccia principale è sottosquadra, ha forma L ed esiste la faccia adiacente + elseif vtN:getZ() < -0.2589 and bIsL and nFaceAdj >= 0 then + -- box del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- se il numero di facce > 2 o il box della feature supera una certa distanza dalle teste allora controllo la z della faccia ausiiaria + if Proc.Fct > 2 or ( Proc.Box:getMax():getX() < b3Solid:getMin():getX() - 150) or ( Proc.Box:getMin():getX() > b3Solid:getMax():getX() + 150) then + local ptC2, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINB) + end + end + return true, bDown + end + end + end +end + +--------------------------------------------------------------------- +-- Lavorazione con fresa +--------------------------------------------------------------------- +local function MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se orientata verso l'alto + local bUp = ( vtN:getZ() >= BD.NZ_MINA) + -- scelta faccia da lavorare + local nFacInd = 0 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'BirdsMouth') + if not sMilling then + local sErr = 'Error : BirdsMouth not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + if vtN:getX() > 0 then + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_LEFT, MCH_MILL_FU.PARAL_LEFT)) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.PARAL_RIGHT)) + end + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + if not bUp then EgtSetMachiningParam( MCH_MP.INVERT, true) end + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId, bDownHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- recupero il parametro Q per uso fresa + local nUseRM = EgtGetInfo( Proc.Id, Q_USE_MILL, 'i') + -- recupero la lavorazione + local sMilling + if nUseRM and nUseRM == 1 then + sMilling = ML.FindMilling( 'LongSmallCut' .. EgtIf( bDownHead, '_H2', '')) + else + sMilling = ML.FindMilling( 'BirdsMouth' .. EgtIf( bDownHead, '_H2', '')) + end + if not sMilling then + local sErr = 'Error : LongSmallCut & BirdsMouth not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- dati medi + local ptM = ( ptC[1] + ptC[2]) / 2 + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bDownHead and not BD.TURN and not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error : LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- scelta faccia da lavorare + local nFacInd + -- se entrambe possibili + if bFaceOk[1] and bFaceOk[2] then + -- se in testa, scelgo quella orientata verso la testa + if Proc.Head then + if vtN[1]:getX() > vtN[2]:getX() then + nFacInd = 0 + else + nFacInd = 1 + end + -- se altrimenti in coda, scelgo quella orientata verso la coda + elseif Proc.Tail then + if vtN[1]:getX() < vtN[2]:getX() then + nFacInd = 0 + else + nFacInd = 1 + end + -- altrimenti, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+) + else + if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then + if ptM:getX() > b3Raw:getCenter():getX() then + nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1) + else + nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1) + end + else + nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1) + end + end + elseif bFaceOk[1] then + nFacInd = 0 + else + nFacInd = 1 + end + local nOthInd = 1 - nFacInd + local sName + local nMchFId + local nFaceUse + -- se forzato uso fresa controllo se posso fare in una o più passate + if nUseRM and nUseRM == 1 then + -- prendo la larghezza della faccia + local _, pPt1, pPt2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOthInd, GDB_ID.ROOT) + local dDistPoint = dist( pPt1, pPt2) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local dWidth = EgtIf( abs( dDistPoint - dH) < abs( dDistPoint - dV), dV, dH) + -- se larghezza faccia maggiore diametro utensile aggiungo una lavorazione + if dTDiam > 0 and dWidth > dTDiam then + -- inserisco la lavorazione di fresatura + sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_1' + nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- tolgo l'inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- aggiungo offset laterale + EgtSetMachiningParam( MCH_MP.OFFSR , (dTDiam/2)) + -- imposto posizione braccio porta testa + if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + -- inserisco la lavorazione di fresatura + sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + nFaceUse = BL.GetNearestOrthoOpposite( vtN[nOthInd+1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- tolgo l'inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- imposto posizione braccio porta testa + if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dOffs) + elseif Proc.Box:getCenter():getX() > b3Solid:getCenter():getX() then + local dOffs = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + local dDist = b3Solid:getMax():getX() - Proc.Box:getMax():getX() + -- sempre concavo aumento la distanza (rimane una punta...) + dDist = dDist + 10 + BL.UpdateHCING( nRawId, dOffs, dDist) + end + end + return true +end + +--------------------------------------------------------------------- +local function MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, nChamfer) + -- se interessa l'intera sezione della trave, necessaria sgrossatura + if nChamfer < 2 and Proc.Box:getDimY() > 0.9 * b3Raw:getDimY() and Proc.Box:getDimZ() > 0.9 * b3Raw:getDimZ() then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo sgrossatura e la lavoro + local AddId = EgtSurfTmConvexHullInBBox( nAddGrpId, Proc.Id, b3Raw, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local nCutFacet = EgtSurfTmFacetCount( AddId) + if nCutFacet == 1 then + return Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + elseif nCutFacet == 2 then + return DoubleCut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + end + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dElev, dCollSic, bSpecialApp, sMillMaster, nFacInd2, dFacElev2) + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj, sErr = GetFaceAdj( Proc, nFacInd, dH, dV) + if nFacAdj < 0 then + EgtOutLog( sErr) + return false, sErr + end + -- Determino se estremi aperti o chiusi e faccia adiacente da aggiungere alla lavorazione + local bOpenStart = false + local bOpenEnd = false + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) + local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacAdj, GDB_ID.ROOT) + -- Riordino le dimensioni per avere dH > dV + if dH2 < dV2 then + dH2, dV2 = dV2, dH2 + end + local nFacAdj2 + for j = 1, #vAdj2 do + if vAdj2[j] == nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + -- decommentare questa parte per concatenare due facce + --if bSpecialApp and vAdj2[j] >= 0 then + -- local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacAdj, vAdj2[j], GDB_ID.ROOT) + -- local dLen = dist( ptP1, ptP2) + -- if abs( dLen - dV2) < 10 * GEO.EPS_SMALL then + -- nFacAdj2 = vAdj2[j] + -- end + --end + end + -- Recupero la lavorazione di fresa + local sMilling + if bSpecialApp then + sMilling = sMillMaster + else + sMilling = ML.FindMilling( 'LongSmallCut') + if not sMilling then + sErr = 'Error : LongSmallCut not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dTDiam = 50 + local dMaxMat = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + end + end + -- Se massimo materiale utensile è molto inferiore dell'elevazione non faccio la lavorazione e do un warning + if dMaxMat > 0 and dMaxMat + 15 < dElev + dCollSic then + sWarn = 'Warning : skipped milling; elevation bigger than max tool depth' + return true, sWarn, dMaxMat + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + if nFacAdj2 then + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj},{ Proc.Id, nFacAdj2}}) + else + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + end + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- lato di lavoro e direzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- tipo di attacco e uscita + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.LINEAR) + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + if bSpecialApp then + -- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita + if nFacAdj2 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2)) + -- confronto la faccia applicata nella lavorazione(faccia adiacente) con la seconda faccia passata nella funzione + -- se corrispondono allora aggiungo una estensione nei lati chiusi pari all'elevazione della stessa faccia corrispondente + if nFacAdj == nFacInd2 then + if not bOpenStart then + EgtSetMachiningParam( MCH_MP.LOPERP, dFacElev2) + end + if not bOpenEnd then + EgtSetMachiningParam( MCH_MP.LIPERP, dFacElev2) + end + end + end + -- applico elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, 0, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, 0, - dTDiam / 2)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, '', dTDiam +end + +--------------------------------------------------------------------- +local function ChooseCorner( Proc, nFacInd) + -- Recupero le adiacenze della faccia principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + -- Cerco i corner tra le facce adiacenti alla principale + local tFacAdj = {} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + for j = i+1, #vAdj do + if vAdj[j] >= 0 then + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vAdj[i], vAdj[j], GDB_ID.ROOT) + if ptP1 and ptP2 and dAng < 0 then + local dLen = dist( ptP1, ptP2) + table.insert( tFacAdj, { vAdj[i], vAdj[j], dLen, ptP1, ptP2, dAng}) + end + end + end + end + end + -- Tra le linee dei corner determino la più lunga + local dMaxLen = 0 + local nIdLine + for i = 1, #tFacAdj do + if tFacAdj[i][3] > dMaxLen then + nIdLine = i + dMaxLen = tFacAdj[i][3] + end + end + + return dMaxLen, nIdLine, tFacAdj +end + +--------------------------------------------------------------------- +local function ChooseContour( Proc, nFacInd, bVerifyCorner) + -- Recupero le adiacenze della faccia principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + -- Se richiesto, verifico che ci siano facce adiacenti consecutive (sicuramente con angolo) + if bVerifyCorner then + local bCorner = false + for i = 1, #vAdj do + local j = EgtIf( i > 1, i - 1, #vAdj) + if vAdj[i] >= 0 and vAdj[j] >= 0 then + bCorner = true + break + end + end + if not bCorner then return {} end + end + -- Cerco le facce adiacenti con angolo convesso + local tFacAdjMain = {} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + if ptP1 and ptP2 and dAng < 0 then + local dLen = dist( ptP1, ptP2) + table.insert( tFacAdjMain, { vAdj[i], dLen, ptP1, ptP2, dAng}) + end + end + end + + return tFacAdjMain +end + +--------------------------------------------------------------------- +local function CheckToInvert( AuxId, bPositive) + + -- recupero versore estrusione + local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT) + -- faccio una copia del percorso + local sParnt = EgtGetParent( AuxId) + local nNewEntId = EgtCopyGlob( AuxId, sParnt) + -- chiudo il percorso + if EgtCloseCurveCompo( nNewEntId) then + local vtMPlane, dDist, dArea = EgtCurveArea( nNewEntId) + -- cancello percorso copia + EgtErase( nNewEntId) + if dArea and abs(dArea) > 1 then + local frEnt = EgtGetGlobFrame( AuxId) + if vtMPlane then + vtMPlane:toGlob(frEnt) + if dArea and dArea * ( vtMPlane * vtExtr) < 0 then + if bPositive then + return true + end + elseif dArea and dArea * ( vtMPlane * vtExtr) > 0 then + if not bPositive then + return true + end + end + end + end + else + -- cancello percorso copia + EgtErase(nNewEntId) + end + + return false +end + +--------------------------------------------------------------------- +local function SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId, nStartPoint) + + -- fondo tra loro le curve compatibili + EgtMergeCurvesInCurveCompo( nPathInt) + local nStartIdEnt, nNumEnt = EgtCurveDomain( nPathInt) + local pLastPIni, pLastPEnd + + -- faccio una copia della curva e la esplodo + if nStartIdEnt then + -- prendo i punti + for i = 1, nNumEnt do + local pPini = EgtUP( nPathInt, (i-1), GDB_RT.GLOB) + local pPend = EgtUP( nPathInt, EgtIf( i == nNumEnt, 0, i), GDB_RT.GLOB) + -- Se normale lungo la Z considero il box in X e Y + if abs(vtOrtho:getZ()) > 0.999 then + -- se corrisponde a X + if ( abs( pPini:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Y + elseif ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + -- altrimenti se normale lungo la Y considero il box in X e Z + elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.999 then + -- se corrisponde a X + if ( abs( pPini:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL and abs( pPend:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Z + elseif ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + -- caso che non dovrebbe mai capitare ma gestito per completezza + -- altrimenti se normale lungo la X considero il box in Y e Z + elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.999 then + -- se corrisponde a Y + if ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Z + elseif ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + -- se asse Z orizzontale verifico se si avvicina piú a Y + elseif abs(vtOrtho:getZ()) < 0.001 then + if abs(vtOrtho:getY()) > 0.75 then + -- se corrisponde a Z + if ( abs( pPini:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMax():getZ()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL and abs( pPend:getZ() - b3Solid:getMin():getZ()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + end + -- se asse Y a 0 (fresa ne davanti ne dietro) verifico se si avvicina piú a Z+ + elseif abs(vtOrtho:getY()) < 0.001 then + if abs(vtOrtho:getZ()) > 0.75 then + -- se corrisponde a Y + if ( abs( pPini:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMax():getY()) < 10 * GEO.EPS_SMALL) or + ( abs( pPini:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL and abs( pPend:getY() - b3Solid:getMin():getY()) < 10 * GEO.EPS_SMALL) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. (i-1)) + else + EgtSetInfo( nPathInt, 'OPEN', (i-1)) + end + -- prendo i punti per eventuale modifica del punto di inizio percorso + pLastPIni = pPini + pLastPEnd = pPend + end + end + end + end + -- se devo cambiare il punto di partenza + if nStartPoint then + if pLastPIni and pLastPEnd then + -- calcolo il punto medio con gli ultimi punti utilizzati + local ptPs = ( pLastPIni + pLastPEnd) / 2 + EgtChangeClosedCurveStartPoint( nPathInt, ptPs, GDB_RT.GLOB) + -- se devo eliminare la parte open + if nStartPoint == 2 then + EgtRemoveCurveCompoCurve( nPathInt, true) + EgtRemoveCurveCompoCurve( nPathInt, false) + return true + end + end + end + end + + return false +end + +--------------------------------------------------------------------- +local function MakeRoundCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, dDiam, bMillDown, bDoubleSide) + + -- recupero la lavorazione senza considerare l'elevazione + local sMilling = ML.FindMilling( 'SmallToolContour' .. EgtIf( bMillDown and not bDoubleSide, '_H2', '')) + if not sMilling then + local sMyWarn = 'Warning : SmallToolContour not found in library' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + + -- recupero i dati dell'utensile + local dTDiam = 50 + local dTMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + dTMaxDepth = EgtTdbGetCurrToolMaxDepth() or dTMaxDepth + end + + -- se il diametro trovato non è minore dei 3/4 del diametro utilizzato in precedenza, esco + if dTDiam > ( 0.75 * dDiam) then + local sMyWarn = 'Warning : tool diameter not enough small' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + + -- ottengo gli angoli dove applicare il percorso con fresa più piccola + local _, _, tFacAdj = ChooseCorner( Proc, nFacInd) + -- se non trovato nessun angolo interno valido esco + if #tFacAdj == 0 then + return true + end + + -- recupero la normale della faccia di fondo + local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se fresatura da sotto salto la lavorazione + if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then + local sErr = 'Error : milling from bottom ' + EgtOutLog( sErr) + return false, sErr + end + + -- ciclo su tutti gli angoli trovati + local sMyWarn = '' + for i = 1, #tFacAdj do + local pAuxId = {} + -- le 2 facce di contatto devono essere perpendicolari e non sottosquadra rispetto alla faccia di fondo + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][1], GDB_ID.ROOT) + local _, ptP1x, ptP2x, dAngx = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][2], GDB_ID.ROOT) + if dAng >= 0 or dAng < -90 - 10 * GEO.EPS_SMALL or dAngx >= 0 or dAngx < -90 - 10 * GEO.EPS_SMALL then + goto continue + end + -- prendo la lunghezza di adiacenza delle due linee + local dLen1 = dist( ptP1, ptP2) + local dLen2 = dist( ptP1x, ptP2x) + -- cerco il punto tra le 3 facce: nIdEndPoint + local nIdIniPoint + local nIdEndPoint + if ptP1 and ptP2 then + if dist( ptP1, tFacAdj[i][4]) < GEO.EPS_SMALL or dist( ptP2, tFacAdj[i][4]) < GEO.EPS_SMALL then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif dist( ptP1, tFacAdj[i][5]) < GEO.EPS_SMALL or dist( ptP2, tFacAdj[i][5]) < GEO.EPS_SMALL then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- devo avere un punto comune + if not nIdEndPoint then + goto continue + end + -- calcolo lunghezza minima in base all'angolo tra le due pareti + local dMinDist = (( dDiam / 2) / tan( ( 180 + tFacAdj[i][6]) / 2)) + 2 + -- verifico che entrambe le linee siano maggiori delle lunghezza minima + if dLen1 <= dMinDist or dLen2 <= dMinDist then + sMyWarn = 'Warning : impossible make clean corner path' + goto continue + end + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + local ptApPoint = EgtIf( dist( tFacAdj[i][nIdEndPoint], ptP1) < 10 * GEO.EPS_SMALL, ptP2, ptP1) + -- prima linea + local nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[i][nIdEndPoint], GDB_RT.GLOB) + -- calcolo arretramento + local dTrimDist = dLen1 - dMinDist + -- se arretramento valido + if dTrimDist > 100 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dTrimDist, ptApPoint , GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- se il punto finale corrisponde con il punto comune, uso l'altro + ptApPoint = EgtIf( dist( tFacAdj[i][nIdEndPoint], ptP1x) < 10 * GEO.EPS_SMALL, ptP2x, ptP1x) + -- seconda linea + nAuxId = EgtLine( nAddGrpId, tFacAdj[i][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + -- calcolo arretramento + dTrimDist = dLen2 - dMinDist + -- se arretramento valido + if dTrimDist > 100 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dTrimDist, ptApPoint , GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- trasformo in percorso + local AuxId + if #pAuxId > 0 then + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + end + -- deve esserci il percorso + if not AuxId then + sMyWarn = 'Warning : impossible make clean corner path' + goto continue + end + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtN1, GDB_RT.GLOB) + -- inserisco la lavorazione + local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + sMyWarn = 'Warning : impossible add machining ' .. sName .. '-' .. sMilling + goto continue + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto lato di lavoro sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if AreSameOrOppositeVectorApprox( vtN1, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN1:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtN1:getY() < GEO.EPS_SMALL then + nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + else + nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- tipo attacco e uscita + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + -- annullo allungamenti iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + -- setto massimo affondamento possibile + local dDepth = 0 + if tFacAdj[i][3] > dTMaxDepth then + dDepth = dTMaxDepth - tFacAdj[i][3] + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- setto se devo invertire il percorso + local bInvert = CheckToInvert( AuxId, true) + EgtSetMachiningParam( MCH_MP.INVERT, bInvert) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione + local sUserNotes = 'VMRS=0;' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( ( tFacAdj[i][3] + dDepth), 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if EgtApplyMachining( true, false) then + _, sMyWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + -- altrimenti lavorazione non applicata + else + _, sMyWarn = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + end + ::continue:: + end + if #sMyWarn > 0 then + EgtOutLog( sMyWarn) + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function MakeRoundCleanContour( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, dDiam, nFunction, bMillDown, + bDoubleSide, vtOrtho, nPathInt, nSurfInt, b3Solid, + dDepth, bOneShot) + + -- recupero la lavorazione senza considerare l'elevazione perché viene calcolata l'elevazione utile + local sMilling = ML.FindMilling( 'SmallToolContour' .. EgtIf( bMillDown and not bDoubleSide, '_H2', '')) + if not sMilling then + local sMyWarn = 'Warning : SmallToolContour not found in library' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + + -- recupero i dati dell'utensile + local dTDiam = 50 + local dTMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + dTMaxDepth = EgtTdbGetCurrToolMaxDepth() or dTMaxDepth + end + + local sMillingDn = ML.FindMilling( 'SmallToolContour' .. EgtIf( bMillDown and bDoubleSide, '_H2', '')) + if not sMillingDn then + local sMyWarn = 'Warning : Opposite SmallToolContour not found in library' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + -- recupero i dati dell'utensile testa da sotto + local dTDiamDn = 50 + local dTMaxDepthDn = 0 + if EgtMdbSetCurrMachining( sMillingDn) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiamDn = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiamDn + dTMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dTMaxDepthDn + end + + -- se il diametro trovato non è minore dei 3/4 del diametro utilizzato in precedenza, esco + if dTDiam > ( 0.75 * dDiam) then + local sMyWarn = 'Warning : tool diameter not enough small' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + + local vtN1 + local nFirstId, nNumId + local dMaxElev + local dCollSic = 0 + local dExtraDepth = 0 + + -- se non ho la faccia aggiunta + if not nPathInt then + -- cerco gli angoli dove applicare il percorso con fresa piú piccola e i lati in comune + local tFacAdjMain = ChooseContour( Proc, nFacInd, true) + -- se non trovato nessun angolo interno da pulire esco + if #tFacAdjMain == 0 then + return true + end + -- normale alla faccia di fondo + vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se fresatura da sotto salto la lavorazione + if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then + local sErr = 'Error : milling from bottom' + EgtOutLog( sErr) + return false, sErr + end + -- distanza di sicurezza per evitare collisioni + dCollSic = CalcCollisionSafety( vtN1) + -- elevazione massima della faccia + dMaxElev = BL.GetFaceElevation( Proc.Id, nFacInd, nPartId) + -- ciclo tutta la tabella + local tPaths = {} + local ptIniPath + local ptMidDist + local dMaxLen = 0 + for i = 1, #tFacAdjMain do + -- le 2 facce di contatto devono essere perpendicolari o non sottosquadra rispetto alla faccia di fondo + local ptP1, ptP2, dAng + ptP1 = tFacAdjMain[i][3] + ptP2 = tFacAdjMain[i][4] + dAng = tFacAdjMain[i][5] + if ( dAng < 0 and dAng >= -90 - 10 * GEO.EPS_SMALL) then + -- creo la linea da P1 a P2 + local nAuxId = EgtLine( nAddGrpId, ptP1, ptP2, GDB_RT.GLOB) + table.insert( tPaths, nAuxId) + -- prendo la lunghezza massima e il punto medio + if tFacAdjMain[i][2] > dMaxLen then + ptIniPath = ptP1 + dMaxLen = tFacAdjMain[i][2] + ptMidDist = ( ptP1 + ptP2) / 2 + end + end + end + -- costruisco il/i percorso/i + nFirstId, nNumId = EgtCurveCompoByReorder( nAddGrpId, tPaths, ptIniPath, true, GDB_RT.GLOB) + if nFirstId then + -- se un solo percorso e chiuso cambio il punto di inizio nell'entitá piú lunga + if nNumId == 1 and EgtCurveIsClosed( nFirstId) then + EgtChangeClosedCurveStartPoint( nFirstId, ptMidDist, GDB_RT.GLOB) + end + -- modifico versore direzione + for i = 1, nNumId do + EgtModifyCurveExtrusion( nFirstId + i - 1, vtN1, GDB_RT.GLOB) + end + end + + -- alrimenti ho la faccia aggiunta + else + -- assegno il percorso + nFirstId = EgtCopyGlob( nPathInt, nAddGrpId) + nNumId = 1 + -- distanza di sicurezza per evitare collisioni + dCollSic = CalcCollisionSafety( vtOrtho) + -- calcolo elevazione dalla faccia trasversale aggiunta + local dSurfIntElev = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + if bDoubleSide then + dMaxElev = dSurfIntElev + else + dMaxElev = dDepth + -- se la precedente svuotatura è stata fatta completamente in una sola volta + -- valuto di nuovo se devo fare due passate o una sola + if bOneShot then + -- se non è possibile svuotare completamente da una sola parte + if dTMaxDepth <= ( dMaxElev + BD.CUT_EXTRA + dCollSic) then + bDoubleSide = true + dMaxElev = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + else + dExtraDepth = dMaxElev - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + end + -- altrimenti non è stata fatta completamente calcolo la distanza tra faccia aggiunta e profondità superficie + else + dExtraDepth = dMaxElev - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + end + end + -- normale alla faccia aggiunta + vtN1 = Vector3d( vtOrtho) + -- imposto i lati aperti + SetOpenSide( nFirstId, vtOrtho, b3Solid, nAddGrpId, 2) + end + + -- se non trovato il percorso, esco + if not nFirstId then + local sMyWarn = 'Warning : impossible make clean corner path' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + + -- assegno lavorazioni ad ogni percorso + local sMyWarn = '' + for i = 1, nNumId do + local nIdPath = nFirstId + i - 1 + local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + sMyWarn = 'Warning : impossible add machining ' .. sName .. '-' .. sMilling + goto continue + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nIdPath, -1}}) + -- imposto lato di lavoro sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- inversione direzione utensile + local bInvertMach = false + if nPathInt then + -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) + if vtN1:getZ() < BD.NZ_MINA and abs(vtN1:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti + elseif not bDoubleSide and vtN1:getY() > GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + end + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if AreSameOrOppositeVectorApprox( vtN1, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN1:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtN1:getY() < GEO.EPS_SMALL then + nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + else + nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- gestione attacco e uscita + if EgtCurveIsClosed( nIdPath) then + -- attacco e uscita a quarto di cerchio senza allungamenti a inizio e fine + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, 0.5 * dTDiam) + EgtSetMachiningParam( MCH_MP.LIELEV, 0) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + else + -- nessun attacco e uscita, allungo inizio e fine di raggio utensile + 5mm (per evitare controllo collisioni) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2 + 5) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2 + 5) + end + -- setto massimo affondamento possibile + local dMachDepth = 0 + if ( dMaxElev + dCollSic) > dTMaxDepth then + dMachDepth = dTMaxDepth - ( dMaxElev + dCollSic) + end + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth + dExtraDepth) + -- setto se devo invertire il percorso + local bInvert = CheckToInvert( nIdPath, true) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bInvertMach, not bInvert, bInvert)) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione + local sUserNotes = 'VMRS=0;' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if EgtApplyMachining( true, false) then + _, sMyWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + -- altrimenti lavorazione non applicata + else + _, sMyWarn = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + end + -- se devo applicare la contornatura anche sul lato opposto + if bDoubleSide then + if bMillDown then + sMilling = sMillingDn + dTDiam = dTDiamDn + dTMaxDepth = dTMaxDepthDn + end + sName = 'CleanOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + sMyWarn = 'Warning : impossible add machining ' .. sName .. '-' .. sMilling + goto continue + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nIdPath, -1}}) + -- imposto lato di lavoro sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto direzione utensile opposta + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if AreSameVectorApprox( vtN1, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN1:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtN1:getY() < GEO.EPS_SMALL then + nSCC = MCH_SCC.ADIR_YP + else + nSCC = MCH_SCC.ADIR_YM + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- tipo attacco e uscita + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + -- allungo inizio e fine di 3/4 del diametro utensile + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam * 0.75) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam * 0.75) + -- setto massimo affondamento possibile + local dMachDepth = 0 + if ( dMaxElev + dCollSic) > dTMaxDepth then + dMachDepth = dTMaxDepth - ( dMaxElev + dCollSic) + end + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) + -- setto se devo invertire il percorso + local bInvert = CheckToInvert( nIdPath, true) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvert) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione + local sUserNotes = 'VMRS=0;' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if EgtApplyMachining( true, false) then + _, sMyWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + -- altrimenti lavorazione non applicata + else + _, sMyWarn = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + end + end + ::continue:: + end + if #sMyWarn > 0 then + EgtOutLog( sMyWarn) + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function MakeRoundCleanCornerOrContour( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, dDiam, nFunction, bMillDown, + bDoubleSide, vtOrtho, nPathInt, nSurfInt, b3Solid, + dDepth, bOneShot) + + -- se modalitá pulitura spigoli e lavorazione di lato forzo a fare il contorno + if nFunction == 2 and nPathInt then + nFunction = 1 + end + -- se richiesta pulitura del contorno + if nFunction == 1 then + return MakeRoundCleanContour( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, dDiam, nFunction, bMillDown, + bDoubleSide, vtOrtho, nPathInt, nSurfInt, b3Solid, + dDepth, bOneShot) + -- se richiesta pulitura dei soli corner + elseif nFunction == 2 then + return MakeRoundCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, dDiam, bMillDown, bDoubleSide) + -- altri casi non previsti + else + return true + end +end + +--------------------------------------------------------------------- +local function MakeSharpCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam) + + local sMyWarn = '' + local pAuxId = {} + local nAuxId + local AuxId + local ptApPoint + local dLenTrimExt + local sMilling + local dMaxDepth = 0 + + -- cerco l'angolo di riferimento dove applicare il percorso di pulitura, altrimenti esco + local _, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) + if #tFacAdj == 0 then + return true + end + -- prendo il primo versore + local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local vtN3 = EgtSurfTmFacetNormVersor( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local nIdIniPoint + local nIdEndPoint + if ptLocP1 and ptLocP2 then + if dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL or dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL or dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- versore direzione + local vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] + vtExtr:normalize() + -- inserisco le prime tre linee + if nIdIniPoint and nIdEndPoint then + -- se fresatura da sotto salto la lavorazione + if vtExtr:getZ() < BD.DRILL_VZ_MIN then + local sErr = 'Error : clean corner milling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- sommo i tre versori per avre una direzione media + vtExtr = vtN1 + vtN2 + vtN3 + vtExtr:normalize() + -- recupero la lavorazione non calcolando l'elevazione + sMilling = ML.FindMilling( 'CleanCorner', ( 0.5 * dDiam)) + if not sMilling then + local sErr = 'Error : CleanCorner not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile ( temporaneo, per compensare errore nella lavorazione) + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth + end + -- l'altezza di taglio del tagliente corrisponde al raggio del raccordo che si riesce a coprire + -- quindi confronto l'elevazione con il raggio utensile utilizzato per la svuotatura + if dMaxDepth < ( dDiam * 0.5) - 100 * GEO.EPS_SMALL then + sMyWarn = 'Warning : skip clean corner (the cut heigth is smaller to machine the corner radius)' + EgtOutLog( sMyWarn) + return false, sMyWarn + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdIniPoint], tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB) + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- inserisco le ultime tre linee + uscita discostata rispetto all'ingresso + -- trovo il secondo punto sulla superfice di riferimento + _, ptLocP1, ptLocP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][2], GDB_ID.ROOT) + if ptLocP1 and ptLocP2 then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - (( dDiam/2) + 2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint , GDB_RT.GLOB) + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- piccolo scostamento di 2mm dall'angolo + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- ultima linea di risalita + nAuxId = EgtLine( nAddGrpId, tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), tFacAdj[nIdLine][nIdIniPoint] + ( 2 * vtExtr), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- trasformo in percorso + if #pAuxId > 0 then + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + end + -- se non c'é il percorso do errore + if not AuxId then + local sErr = 'Error : impossible make clean corner path' + EgtOutLog( sErr) + return false, sErr + end + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- inserisco la lavorazione + local sName = 'Clean_' .. ( 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}}) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if AreSameVectorApprox( vtN1, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN1:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtN1:getY() < GEO.EPS_SMALL then + nSCC = MCH_SCC.ADIR_YP + else + nSCC = MCH_SCC.ADIR_YM + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- tipo attacco e uscita + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + -- allungo inizio e fine di 10mm + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- setto affondamento 0 + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione + local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';' + 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 + +--------------------------------------------------------------------- +local function MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiam, bSpecialMach) + local sMyWarn = '' + -- ottengo l'angolo dove applicare il foro + local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) + -- se non trovato nessun angolo interno valido esco + if #tFacAdj == 0 then + return true, sMyWarn + end + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local nIdIniPoint + local nIdEndPoint + if ptLocP1 and ptLocP2 then + if ( dist( ptLocP1, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptLocP1, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[nIdLine][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- inserisco foro + if nIdIniPoint and nIdEndPoint then + local vtExtr + if bSpecialMach then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) + vtExtr = vtN0 + vtN1 + vtN2 + else + -- versore direzione + vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] + end + vtExtr:normalize() + -- se foratura da sotto salto la lavorazione + if vtExtr:getZ() < BD.DRILL_VZ_MIN then + local sErr = 'Error : drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sDrilling, nType = ML.FindDrilling( dDiam) + if not sDrilling then + local sErr = 'Error : drilling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 20 + local dDiamTool = 20 + local dDiamTh = 35 + local bIsDrilling + if EgtMdbSetCurrMachining( sDrilling) then + 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 + dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + dDiamTh = EgtTdbGetCurrToolThDiam() + end + end + -- se foro inclinato, limito il massimo affondamento + local CosB = abs( vtExtr:getX()) + if CosB < BD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dMaxDepth = dMaxDepth - dDiamTh / 2 * TgA + else + dMaxDepth = 0 + end + -- setto griglia + if bSpecialMach then + EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdEndPoint], vtExtr)) + else + EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdIniPoint], vtExtr)) + end + -- creo geometria + local AuxId = EgtCircle( nAddGrpId, {0,0,0}, EgtIf( bIsDrilling, dDiamTool/2, ( dDiamTool/2) + 0.1), GDB_RT.GRID) + -- riporto la griglia a globale + EgtSetGridFrame() + -- calcolo spessore + local dDepthBore = dMaxLen + if bSpecialMach then + -- calcolo l'elevazione + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, tFacAdj[nIdLine][nIdEndPoint], vtExtr) + if dLenIn > 0 then + dDepthBore = dLenIn + elseif dLedOut then + dDepthBore = dLedOut + end + EgtModifyCurveThickness( AuxId, dDepthBore) + else + EgtModifyCurveThickness( AuxId, -dMaxLen) + 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}}) + -- 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 dDepth + if bSpecialMach then + dDepth = dDepthBore + else + dDepth = dMaxLen + 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) + end + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione (coincide con affondamento) + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dDepth, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + 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 + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function ExtractExternalPaths( nPathInt, nNumIdAux, vtOrtho, b3Solid, nAddGrpId) + local nAuxId1, nAuxId2 + if nNumIdAux == 1 then + -- fondo tra loro le curve compatibili + EgtMergeCurvesInCurveCompo( nPathInt) + -- esplodo il percorso in modo da avere entià separate per poterle controllare + local nStartId, nNumIds = EgtExplodeCurveCompo( nPathInt) + if nStartId then + local sDeleteByDir + -- Se normale lungo la Z elimino le entità che hanno differenza in Z + if abs(vtOrtho:getZ()) > 0.7 then + sDeleteByDir = 'Z' + -- altrimenti se normale lungo la Y elimino le entità che hanno variazione in Y +-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.7 then + elseif abs(vtOrtho:getY()) > 0.7 then + sDeleteByDir = 'Y' + -- caso che non dovrebbe mai capitare ma gestito per completezza + -- altrimenti se normale lungo la X elimino le entità che hanno variazione in X +-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.7 then + elseif abs(vtOrtho:getX()) > 0.7 then + sDeleteByDir = 'X' + end + if sDeleteByDir then + for i = 1, nNumIds do + local ptP1 = EgtSP( ( nStartId + i - 1), GDB_RT.GLOB) + local ptP2 = EgtEP( ( nStartId + i - 1), GDB_RT.GLOB) + if sDeleteByDir == 'Z' then + -- se hanno variazione in Z cancello l'entità + if abs( ptP1:getZ() - ptP2:getZ()) > 10 * GEO.EPS_SMALL then + EgtErase( nStartId + i - 1) + end + elseif sDeleteByDir == 'Y' then + -- se hanno variazione in Y cancello l'entità + if abs( ptP1:getY() - ptP2:getY()) > 10 * GEO.EPS_SMALL then + EgtErase( nStartId + i - 1) + end + elseif sDeleteByDir == 'X' then + -- se hanno variazione in X cancello l'entità + if abs( ptP1:getX() - ptP2:getX()) > 10 * GEO.EPS_SMALL then + EgtErase( nStartId + i - 1) + end + end + end + -- ricreo i vari percorsi + local dLocalVal + local tPaths = {} + local nNumPaths + local dMaxVal + local dMinVal + for i = 1, nNumIds do + local ptP1 = EgtSP( ( nStartId + i - 1), GDB_RT.GLOB) + if ptP1 then + if sDeleteByDir == 'Z' then + local bInsTab + for j = 1, #tPaths do + local dLocalVal = tPaths[j][2] + if abs( ptP1:getZ() - dLocalVal) < 10 * GEO.EPS_SMALL then + local tLocIds = tPaths[j][1] + table.insert( tLocIds, ( nStartId + i - 1)) + tPaths[j][1] = tLocIds + bInsTab = true + end + end + -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella + if not bInsTab then + table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getZ()}) + dMaxVal = b3Solid:getMax():getZ() + dMinVal = b3Solid:getMin():getZ() + end + elseif sDeleteByDir == 'Y' then + local bInsTab + for j = 1, #tPaths do + local dLocalVal = tPaths[j][2] + if abs( ptP1:getY() - dLocalVal) < 10 * GEO.EPS_SMALL then + local tLocIds = tPaths[j][1] + table.insert( tLocIds, ( nStartId + i - 1)) + tPaths[j][1] = tLocIds + bInsTab = true + end + end + -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella + if not bInsTab then + table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getY()}) + dMaxVal = b3Solid:getMax():getY() + dMinVal = b3Solid:getMin():getY() + end + elseif sDeleteByDir == 'X' then + local bInsTab + for j = 1, #tPaths do + local dLocalVal = tPaths[j][2] + if abs( ptP1:getX() - dLocalVal) < 10 * GEO.EPS_SMALL then + local tLocIds = tPaths[j][1] + table.insert( tLocIds, ( nStartId + i - 1)) + tPaths[j][1] = tLocIds + bInsTab = true + end + end + -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella + if not bInsTab then + table.insert( tPaths, {{( nStartId + i - 1)}, ptP1:getX()}) + dMaxVal = b3Solid:getMax():getX() + dMinVal = b3Solid:getMin():getX() + end + end + end + end + + if tPaths then + local tChamPath = {} + -- elimino quelle che non corrispondono agli estremi + for i = 1, #tPaths do + -- se non corrisponde ai limiti elimino l'elemento + if abs( tPaths[i][2] - dMaxVal) > 10 * GEO.EPS_SMALL and abs( tPaths[i][2] - dMinVal) > 10 * GEO.EPS_SMALL then + tPaths[i] = nil + end + end + + for i = 1, #tPaths do + if tPaths[i] then + local tNoMatch = {} + local tPathLoc = tPaths[i][1] + local pIniLoc = EgtSP( tPathLoc[1], GDB_RT.GLOB) + local pEndLoc = EgtEP( tPathLoc[1], GDB_RT.GLOB) + -- ciclo sui percorsi per trovare i punti non coincidenti (se percorso non chiuso) + for j = 2, #tPathLoc do + -- prendo i punti del percorso successivo + local pAddIni = EgtSP( tPathLoc[j], GDB_RT.GLOB) + local pAddEnd = EgtEP( tPathLoc[j], GDB_RT.GLOB) + -- se consecutivi + if AreSamePointApprox( pEndLoc, pAddIni) then + pEndLoc = pAddEnd + elseif AreSamePointApprox( pIniLoc, pAddEnd) then + pIniLoc = pAddIni + else + table.insert( tNoMatch, tPathLoc[j]) + end + end + -- controllo eventuali percorsi scartati + for j = 1, #tNoMatch do + -- prendo i punti del percorso successivo + local pAddIni = EgtSP( tNoMatch[j], GDB_RT.GLOB) + local pAddEnd = EgtEP( tNoMatch[j], GDB_RT.GLOB) + -- se consecutivi + if AreSamePointApprox( pEndLoc, pAddIni) then + pEndLoc = pAddEnd + elseif AreSamePointApprox( pIniLoc, pAddEnd) then + pIniLoc = pAddIni + end + end + -- creo concatenamento partendo dal punto iniziale + local nIdLoc = EgtCurveCompoByReorder( nAddGrpId, tPathLoc, pIniLoc, true) + if nIdLoc then + table.insert( tChamPath, nIdLoc) + end + end + end + for i = 1, #tChamPath do + local ptP1 = EgtSP( tChamPath[i], GDB_RT.GLOB) + -- modifico estrusione percorso + if sDeleteByDir == 'Z' then + if abs(ptP1:getZ() - dMaxVal) < 10 * GEO.EPS_SMALL then + EgtModifyCurveExtrusion( tChamPath[i], Z_AX(), GDB_RT.GLOB) + else + EgtModifyCurveExtrusion( tChamPath[i], -Z_AX(), GDB_RT.GLOB) + end + elseif sDeleteByDir == 'Y' then + if abs(ptP1:getY() - dMaxVal) < 10 * GEO.EPS_SMALL then + EgtModifyCurveExtrusion( tChamPath[i], Y_AX(), GDB_RT.GLOB) + else + EgtModifyCurveExtrusion( tChamPath[i], -Y_AX(), GDB_RT.GLOB) + end + elseif sDeleteByDir == 'X' then + if abs(ptP1:getX() - dMaxVal) < 10 * GEO.EPS_SMALL then + EgtModifyCurveExtrusion( tChamPath[i], X_AX(), GDB_RT.GLOB) + else + EgtModifyCurveExtrusion( tChamPath[i], -X_AX(), GDB_RT.GLOB) + end + end + end + if #tChamPath == 1 then + return tChamPath[1], 1, nil + elseif #tChamPath == 2 then + return tChamPath[1], 2, tChamPath[2] + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + for i = 1, #tChamPath do + EgtErase( tChamPath[i]) + end + end + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + end + -- altrimenti cancello tutte le emtità e restituisco nil + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + end + end + end + + return nil, 0, nil +end + +--------------------------------------------------------------------- +local function MakeChamfer( Proc, bIs3Faces, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + + -- Se variabile globale indica che lo smusso è gi stato fatto, esco + if bMadeChamfer then + return 0 + end + bMadeChamfer = true + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : Mark not found in library' + EgtOutLog( sErr) + return -1, sErr + end + -- ottengo le curve di contorno libero + local nAuxId1, nAuxId2, nNumIdAux + if bIs3Faces then +-- nAuxId1, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) +-- EgtModifyCurveExtrusion( nAuxId1, vtOrtho, GDB_RT.GLOB) +-- SetOpenSide( nAuxId1, vtOrtho, b3Solid, nAddGrpId, 1) +-- nNumIdAux = 2 + + -- estraggo i percorsi + nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId) + -- se percorso creato estraggo solo i percorsi delle facce interessate, non di testa + if nAuxId1 then + nAuxId1, nNumIdAux, nAuxId2 = ExtractExternalPaths( nAuxId1, nNumIdAux, vtOrtho, b3Solid, nAddGrpId) + end + else + nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId) + if not nNumIdAux then nNumIdAux = 0 end + end + + local dExtra = 2 + for i = 1, nNumIdAux do + local AuxId + local vtExtr + if bIs3Faces then + if i == 1 then + AuxId = nAuxId1 + else + -- faccio la copia del percorso +-- AuxId = EgtCopyGlob( nAuxId1, nAddGrpId) + AuxId = nAuxId2 + end + if AuxId then + vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + end + else + AuxId = nAuxId1 + i - 1 + vtExtr, _, _ = EgtCurveArea( AuxId) + end + if vtExtr then + if not bIs3Faces then + local fFrCurve = EgtGetGlobFrame( AuxId) + vtExtr:toGlob( fFrCurve) + end +-- if bIs3Faces and i == nNumIdAux then +-- vtExtr = -vtExtr +-- end + -- Se normale entro certi limiti +-- if vtExtr:getZ() > -0.707 and ( abs(vtOrtho:getX()) > 0.99 or abs(vtOrtho:getY()) > 0.99 or abs(vtOrtho:getZ()) > 0.99) then + if vtExtr:getZ() > -0.707 and ( abs(vtExtr:getX()) > 0.99 or abs(vtExtr:getY()) > 0.99 or abs(vtExtr:getZ()) > 0.99) then + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchId = EgtAddMachining( sNameCh, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sMilling + EgtOutLog( sErr) + return -1, sErr + end + -- modifico estrusione percorso + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto posizione braccio porta testa + if vtExtr:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- assegno affondamento e offset radiale +-- EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra - EgtIf( bIs3Faces, (dDepth / 2), 0)) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- se opero su 3 facce e sono al secondo e ultimo percorso inverto la lavorazione +-- if bIs3Faces and i == nNumIdAux then +-- EgtSetMachiningParam( MCH_MP.INVERT, true) +-- end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return -1, sErr + end + -- se non perpendicolare emetto un warning + -- else + -- sWarn = 'Warning : chamfer skipped because not perpendicular to face or from bottom' + -- EgtOutLog( sWarn) + end + --emetto un warning + -- else + -- sWarn = 'Warning : chamfer skipped because not perpendicular to face' + -- EgtOutLog( sWarn) + end + end + + return 0 +end + +--------------------------------------------------------------------- +local function MakeByMillAsSaw( Proc, nPhase, nRawId, nPartId, nFacInd, + rfFac, dH, dV, dElev, bForceUseBlade, + nBottomFace, nAddGrpId, b3Solid, dSawMaxDepth, sMillingOnSide, + dSawDiam, dSawThick) + local bOrthoFaces + local sWarn + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ottengo la distanza tra la fine del pezzo e il pezzo successivo + local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or 5. + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd1, dFacElev1, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, true) + if not nFacInd1 or nFacInd1 < 0 then + if nFacInd1 == -1 then + bOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeByMillAsSaw could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + + if bOrthoFaces then + -- ottengo le dimensioni del tunnel + local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId) + end + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Cerco una faccia adiacente alla principale sul lato più lungo + local nFacAdj + local dMaxLen = 0 + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > dMaxLen then + nFacAdj = vAdj[i] + dMaxLen = dLen + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) + end + end + end + if not nFacAdj then + local sErr = 'Error : long adjacent face not found' + EgtOutLog( sErr) + return false, sErr + end + -- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT) + if abs( vtN * rfFac:getVersX()) > abs( vtN * rfFac:getVersY()) then + dH, dV = dV, dH + end + -- Determino se estremi aperti o chiusi + local bOpenStart = false + local bOpenEnd = false + local vtNS, vtNE + -- se non ho la faccia di fondo ( che comporta essere una fessura) verifico se ho lati aperti + if not nBottomFace then + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) + for j = 1, #vAdj2 do + if vAdj2[j] == nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- se è chiusa acquisisco vettore faccia tappo + if not bOpenStart and vAdj2[i] >= 0 then + _, vtNS = EgtSurfTmFacetCenter( Proc.Id, vAdj2[i], GDB_ID.ROOT) + end + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + -- se è chiusa acquisisco vettore faccia tappo + if not bOpenEnd and vAdj2[k] >= 0 then + _, vtNE = EgtSurfTmFacetCenter( Proc.Id, vAdj2[k], GDB_ID.ROOT) + end + end + end + end + -- Se possibile, lavoro con la lama + if bForceUseBlade then + -- Recupero la lavorazione di lama + local sCutting = sMillingOnSide + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ()) + local dStartDist = -1 + local dEndDist = -1 + -- calcolo eventuali arretramenti lama + if not bOpenStart then + local dRadius = dSawDiam / 2 + local dCat1 = dRadius - dElev + dStartDist = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) + end + if not bOpenEnd then + if not bOpenStart then + dEndDist = dStartDist + else + local dRadius = dSawDiam / 2 + local dCat1 = dRadius - dElev + dEndDist = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) + end + end + -- Eseguo i tagli + local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + local dOffs = ( i - 1) * dStep + --if vtN:getZ() < BD.NZ_MINA then dOffs = dOffs + dSawThick end + local bOk, sErr, nMchId = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, dStartDist, dEndDist, nil, b3Raw) + if not bOk then return bOk, sErr end + -- setto l'elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( 0, 1) .. ';' + -- applico elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- tolgo eventuale step + EgtSetMachiningParam( MCH_MP.STEP, 0) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + -- in base all'elevazione calcolo l'impronta della lama + local dUsedBladeLen = sqrt( ((dSawDiam / 2)*(dSawDiam / 2)) - ( ( (dSawDiam / 2) - dElev) * ( (dSawDiam / 2) - dElev))) + -- controllo direzione taglio e se il minimo della feature sborda in coda + if abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then + -- do avviso che la lama può sbordare nel pezzo successivo + sWarn = 'Warning on mill side as blade : Cut machining can damage next piece' + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, + rfFac, dH, dV, dElev, bForceUseBlade, + dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, + bOrthoFacesMaster, nBottomFace, nChamfer, nAddGrpId, b3Solid, + dDepthCham, nSurfInt, bIs3Faces) + local bOrthoFaces + local sWarn + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ottengo la distanza tra la fine del pezzo e il pezzo successivo + local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or 5.4 + if bIs3Faces then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd1, dFacElev1, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, bIs3Faces) + if not nFacInd1 or nFacInd1 < 0 then + if nFacInd1 == -1 then + bOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeByChainOrSaw could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + else + bOrthoFaces = bOrthoFacesMaster + end + -- eventuale massima elevazione imposta dall'utente + local dMaxElev = EgtGetInfo( Proc.Id, Q_MAX_ELEVATION, 'd') + if dMaxElev and dMaxElev < 1 then dMaxElev = nil end + + if bOrthoFaces then + -- ottengo le dimensioni del tunnel + dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId) + -- verifico la direzione + -- se devo inserire il chamfer + if nChamfer > 0 then + local nOk, sErr = MakeChamfer( Proc, bIs3Faces, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return false, sErr end + end + end + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Cerco una faccia adiacente alla principale sul lato più lungo + local nFacAdj + local dMaxLen = 0 + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > dMaxLen then + nFacAdj = vAdj[i] + dMaxLen = dLen + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) + end + end + end + if not nFacAdj then + local sErr = 'Error : long adjacent face not found' + EgtOutLog( sErr) + return false, sErr + end + -- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT) + if abs( vtN * rfFac:getVersX()) > abs( vtN * rfFac:getVersY()) then + dH, dV = dV, dH + end + -- Determino se estremi aperti o chiusi + local bOpenStart = false + local bOpenEnd = false + local vtNS, vtNE + -- se non ho la faccia di fondo ( che comporta essere una fessura) verifico se ho lati aperti + if not nBottomFace then + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) + for j = 1, #vAdj2 do + if vAdj2[j] == nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- se è chiusa acquisisco vettore faccia tappo + if not bOpenStart and vAdj2[i] >= 0 then + _, vtNS = EgtSurfTmFacetCenter( Proc.Id, vAdj2[i], GDB_ID.ROOT) + end + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + -- se è chiusa acquisisco vettore faccia tappo + if not bOpenEnd and vAdj2[k] >= 0 then + _, vtNE = EgtSurfTmFacetCenter( Proc.Id, vAdj2[k], GDB_ID.ROOT) + end + end + end + end + -- verifico se uso lama da sotto + local bCutDown = ( BD.DOWN_HEAD and rfFac:getVersZ():getZ() < - 0.5) + -- Recupero il massimo affondamento possibile con la lama + local dSawMaxDepth = 0 + local sCutting = ML.FindCutting( 'HeadSide'..EgtIf( bCutDown, '_H2', '')) + if sCutting then + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawMaxDepth = EgtTdbGetCurrToolMaxDepth() or dSawMaxDepth + end + end + end + -- se lavorazione sulle teste e altezza trave supera il limite ( che causa collisione con la forcella) e direzione taglio lungo la Z + -- e limite profondità BeamData è maggiore del taglio massimo lama, assegno il massimo affondamento pari al limite profondità del BeamData + if bOpenStart and bOpenEnd and bForceUseBlade and ( Proc.Head or Proc.Tail) and abs(rfFac:getVersY():getY()) > 0.866 and + b3Solid:getDimZ() > BD.MIN_DIM_HBEAM and dSawMaxDepth > BD.MAX_DIM_HTCUT_HBEAM then + dSawMaxDepth = BD.MAX_DIM_HTCUT_HBEAM + end + -- Se entrambi gli estremi sono aperti e possibile, lavoro con la lama + if bOpenStart and bOpenEnd and bForceUseBlade and ( dMaxElev or dElev) < dSawMaxDepth + 10 * GEO.EPS_SMALL then + -- recupero altri dati dell'utensile + local dSawDiam = 400 + local dSawThick = 4 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + if dSawThick > dV + 10 * GEO.EPS_SMALL then + local sErr = 'Error : sawblade too thick' + EgtOutLog( sErr) + return false, sErr + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( rfFac:getVersZ()) + -- Eseguo i tagli + local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + local dOffs = ( i - 1) * dStep + local bOk, sErr = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- in base all'elevazione calcolo l'impronta della lama + local dUsedBladeLen = sqrt( ((dSawDiam / 2)*(dSawDiam / 2)) - ( ( (dSawDiam / 2) - dElev) * ( (dSawDiam / 2) - dElev))) + -- controllo direzione taglio e se il minimo della feature sborda in coda + if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then + -- do avviso che la lama può sbordare nel pezzo successivo + sWarn = 'Warning on saw cut : Cut machining can damage next piece' + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + -- altrimenti con sega a catena + else + -- Recupero la lavorazione + local sSawing = ML.FindSawing( 'Sawing') + if not sSawing then + local sErr = 'Error : Sawing not found in library' + EgtOutLog( sErr) + return false, sErr, 'MNF' + end + -- Recupero i dati dell'utensile + local dSawWidth = 75 + local dSawThick = 8 + local dMaxDepth = 200 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + if dSawThick > dV + 10 * GEO.EPS_SMALL then + local sErr = 'Error : chainsaw too thick' + EgtOutLog( sErr) + return false, sErr + end + local bGoFromHead = true + -- se la lunghezza utensile non riesce ad arrivare sul fondo assegno la possibilità di lavorare di testa o di fianco + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + -- lavora di testa se è un tunnel, lavora di fianco se non è un tunnel + bGoFromHead = not bOrthoFaces + end + -- se continuo a lavorare di testa + if bGoFromHead then + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) + -- Calcolo normale faccia adiacente + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) + -- Verifico se necessarie più passate + local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- Applico la lavorazione con sega a catena a questa faccia + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- controllo direzione taglio e se il minimo della feature sborda in coda + if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL then + -- se ho lato partenza aperto e lato uscita chiuso e direzione lato chiuso è negativa, allora controllo uscita lama + if bOpenStart and not bOpenEnd and vtNE:getX() < -0.99 and dDistToNextPiece < (dSawWidth / 2) then + -- imposto accorciamento iniziale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dDistToNextPiece - 1 - (dSawWidth / 2)) + else + -- imposto accorciamento iniziale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + end + -- se ho lato uscita aperto e lato partenza chiuso e direzione lato partenza è negativa, allora controllo uscita lama + if bOpenEnd and not bOpenStart and vtNS:getX() < -0.99 and dDistToNextPiece < (dSawWidth / 2) then + -- imposto accorciamento finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dDistToNextPiece - 1 - (dSawWidth / 2)) + else + -- imposto accorciamento finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + end + else + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + end + -- imposto angolo 3° asse rot e eventuale angolo suggerito per inizio + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, rfFac:getVersZ(), 1)) + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se necessario, limito l'affondamento + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth - dElev + EgtOutLog( sWarn) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH '..EgtNumToString( dDepth, 1)) + end + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 2) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + if EgtGetOutstrokeInfo() then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- impostazione alternativa angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, rfFac:getVersZ(), 2)) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + if EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + -- altrimenti segacatena di fianco + else + -- verifico se posso farlo con la sega-catena + local bMakeChainSaw, sSawing2, dMaxMat2, dSawCornerRad2, dSawThick2 = VerifyChainSaw( Proc, dDimMin, dDimMax) + if bMakeChainSaw then + -- Calcolo uso faccia + local vtRef = Vector3d( vtOrtho) + if vtRef:getY() > 0.5 or vtRef:getZ() < -0.1 then vtRef = -vtRef end + local nFaceUse = BL.GetNearestParalOpposite( vtRef, vtN) + -- Verifico se necessarie più passate + local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick2) + local dStep = 0 + if nStep > 1 then + dStep = ( dDimMin - dSawThick2) / ( nStep - 1) + end + for i = 1, nStep do + -- inserisco la lavorazione di sawing + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing2) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing2 + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLundIdFace}}) + -- imposto uso del lato faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho, 1)) + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se possibile aumento l'affondamento pari al raggio corner + 1 + if dMaxMat2 > ( dDepth + dSawCornerRad2 + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad2 + 1)) + -- se massimo affondamento supera altezza fessura, uso massimo affondamento + elseif dMaxMat2 > (dDepth + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, (dMaxMat2 - 1)) + -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning + elseif dMaxMat2 < dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat2) + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- considero estremi inizio/fine chiusi + -- recupero massima elevazione da utente + if dMaxElev and dMaxElev > 10 then + local sNotes = 'MaxElev=' .. EgtNumToString( dMaxElev, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + end + -- eseguo + if not EgtApplyMachining( true, false) then + if EgtGetOutstrokeInfo() then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- impostazione alternativa angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho, 2)) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + if EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + end + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw, nFacInd, bReduceDepth, bMillDown) + -- Recupero la lavorazione di lama + local sCutting = ML.FindCutting( 'HeadSide' .. EgtIf( bMillDown, '_H2', '')) + if not sCutting then + local sErr = 'Error : HeadSide (cutting) not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- valuto l'angolo tra le due facce + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT) + local ptPm = (ptP1+ptP2)/2 + -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta l'elevazione della faccia + -- laterale sul punto medio della linea in comune + local frFc = Frame3d( ptPm, vtN) ; + local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) + dDepth = b3BoxLoc:getDimZ() or 0 + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + local dExtraOffs = 0 + -- se profondità superiore al massimo lama modifico elevazione + if dDepth > dMaxDepth then + dExtraOffs = dMaxDepth - dDepth + end + -- se devo ridurre l'affondamento + if bReduceDepth then + local dLimitDepth = 100 + -- se ho ridotto l'affondamento ne riduco ulteriormente l'affondamento (50mm) + if abs(dExtraOffs) > 0 then + if dMaxDepth > dLimitDepth then + dExtraOffs = dLimitDepth - dDepth + end + else + if dDepth > dLimitDepth then + dExtraOffs = dLimitDepth - dDepth + else + dExtraOffs = - (dDepth/2) + end + end + end + -- eseguo il taglio + local bMadeASbyBld, sWarn, nIdMach = Fbs.MakeOne( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, ( -0.5 + dExtraOffs), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if bMadeASbyBld then + sWarn = nil + if abs(dExtraOffs) > 0 then + sWarn = 'Warning : antisplint elevation is bigger than max tool depth' + end + end + return bMadeASbyBld, sWarn, nIdMach, dSawThick, dMaxDepth, bAdj, dAng, dExtraOffs +end + +--------------------------------------------------------------------- +local function MakePocket( Proc, nPartId, ptPs, tvtN, nFaceRef, sMchFind, nUseRoughTool, sMasterPocket, dPrevFaceElev, tDimAndRef, dAng) + + -- calcolo l'elevazione dal punto medio + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, tvtN[2]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + local dCollSic = 2 * BD.COLL_SIC + -- calcolo il diametro utensile + local dFaceDiamTool + if tDimAndRef then + -- prendo il valore dalle dimensioni minime delle facce + dFaceDiamTool = min( tDimAndRef[2][1], tDimAndRef[2][2]) + end + -- se ho lavorazione precedente ricalcolo grossolanamente l'elevazione + if dPrevFaceElev and dPrevFaceElev > 0 and dAng then + dElev = dElev + ( sqrt( ( dElev * dElev) - ( dPrevFaceElev * dPrevFaceElev)) * sin(dAng)) + elseif dPrevFaceElev and dPrevFaceElev > dElev then + dElev = dPrevFaceElev + end + local sPocketing + if sMasterPocket then + sPocketing = sMasterPocket + else + sPocketing = ML.FindPocketing( sMchFind, dFaceDiamTool, dElev + dCollSic) + end + if not sPocketing then + local sErr = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + local sTuuidPk + local dDiamTool = 20 + local dMaxDepth = 0 + local bTipMill = false + if EgtMdbSetCurrMachining( sPocketing) then + sTuuidPk = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidPk) or '') then + dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dDiamTool + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + bTipMill = (( EgtTdbGetCurrToolParam( MCH_TP.TIPFEED) or 0) > 1) + end + end + -- se nome svuotatura non è stato ricalcolato, confronto il diametro utensile utilizzato con il minimo faccia e se non sono compatibili esco + if sMasterPocket and dFaceDiamTool and dDiamTool >= dFaceDiamTool then + return false, '', sTuuidPk, dDiamTool, dElev + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef) + 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( {{ Proc.Id, (nFaceRef)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM and not BD.TURN then + nSCC = MCH_SCC.ADIR_YM + if AreSameVectorApprox( tvtN[2], Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( tvtN[2]:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( EgtGetCurrPhase()), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif tvtN[2]:getY() > 0.1 then + nSCC = MCH_SCC.ADIR_YP + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- se tasca aperta e non lavorata col truciolatore, imposto opportuno attacco + if sMchFind == 'OpenPocket' and nUseRoughTool == 0 then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + if sMchFind == 'OpenPocket' and dDiamTool < 90 then + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFaceRef, GDB_ID.ROOT) + local bL = ( Proc.Fct < 4 or TestElleShape4( Proc) == 2) + if bL and min( dH, dV) < 1.5 * dDiamTool then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.ZIGZAG) + EgtSetMachiningParam( MCH_MP.INVERT, false) + if not bTipMill then + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_POCK_LI.HELIX) + EgtSetMachiningParam( MCH_MP.LITANG, dDiamTool) + EgtSetMachiningParam( MCH_MP.LIELEV, 2) + end + end + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dElev) + dElev = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn, sTuuidPk, dDiamTool +end + +--------------------------------------------------------------------- +local function MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtN, nBaseFace, nSideFace, ptPs, tDimAndRef, + b3Raw, nDiffWidth, nUseRoughTool, dAng, sPocketing, sTuuidPk, dPrevFaceElev) + + local sMchFind = 'Pocket' + local dAngLimit = 40 + + -- se feature é larga come trave imposto openpocket + if nDiffWidth == 0 then + sMchFind = 'OpenPocket' + -- altrimenti non è passante disabilito il truciolatore + else + nUseRoughTool = 0 + end + -- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto + if ( 180 + dAng) > 90.1 then + -- calcolo l'angolo dalla verticale dall'angolo tra le due facce, perchè la feature potrebbe essere ruotata sulla Z locale della + -- faccia principale e quindi la componente X del versore della faccia potrebbe dare un valore non coerente + local dDiffFromSqAng = dAng + 90 + -- se l'angolo dalla verticale si discosta di più dell'angolo limite impostato, utilizzo la svuotatura + if cos( dDiffFromSqAng) < cos( dAngLimit) then + -- applico la svuotatura + local bOk, sWarn, sTuuidPk, dDiamTool, dElev = MakePocket( Proc, nPartId, ptPs, tvtN, nSideFace, sMchFind, nUseRoughTool, sPocketing, dPrevFaceElev, tDimAndRef, dAng) + if not bOk then + -- se ho id utensile e diametro è perchè non ha fatto svuotatura perchè la faccia è più stretta del diametro utensile + -- e provo ad inserire singola passata di testa + if sTuuidPk and dDiamTool then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2Cut', dElev, sTuuidPk) + if not sMilling then + local sErr = 'Error : Long2Cut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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( {{ Proc.Id, nSideFace}}) + -- imposto uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite(tvtN[1]) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + -- imposto posizione braccio porta testa + if tvtN[2]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + else + return false, sWarn + end + else + return bOk, sWarn + end + -- altrimenti contornatura di fianco + else + local bOpenStart = false + local bOpenEnd = false + if nDiffWidth == 0 then + bOpenStart = true + bOpenEnd = true + else + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBaseFace))[1] + for j = 1, #vAdj2 do + if vAdj2[j] == (nSideFace) then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == (nSideFace) do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == (nSideFace) do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + end + end + local sMilling + if nUseRoughTool > 0 then + sMilling = ML.FindMilling( 'Long2Cut', nil, sTuuidPk) + else + sMilling = ML.FindMilling( 'LongSmallCut', nil, sTuuidPk) + end + if not sMilling then + local sErr = 'Error : Long2Cut & LongSmallCut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 50 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + end + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( tDimAndRef[1][3]:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, (nSideFace)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- setto inversione del percorso + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- setto a 0 eventuali offset + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- calcolo elevazione per allungamenti attacchi con fianchi chiusi + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, tvtN[2]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + -- applico gli allungamenti o accorciamenti + if bOpenStart then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dTDiam / 2) + if dElev > 0 then + EgtSetMachiningParam( MCH_MP.LIPERP, dElev) + end + end + if bOpenEnd then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dTDiam / 2) + if dElev > 0 then + EgtSetMachiningParam( MCH_MP.LOPERP, dElev) + end + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + return true +end + +--------------------------------------------------------------------- +local function GetUShapeWidth( Proc, nFacInd) + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + -- se non ho facce adiacenti esco subito + if not vAdj or #vAdj == 0 then return nil end + -- Normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- Cerco le facce adiacenti alla principale con angolo concavo >= 90 + local dWidth = 0 + for i = 1, #vAdj do + if vAdj[i] >= 0 then + -- verifico l'angolo tra le facce ( esco se angolo compreso < 90) + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + if bAdj and dAng < -90 - 20 * GEO.EPS_ANG_SMALL then return nil end + -- larghezza della faccia ortogonalmente alla adiacente + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT) + local vtX = vtN2 ^ vtN + local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2) + local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, nFacInd, GDB_BB.STANDARD, frRef) + if b3Ref then + dWidth = max( dWidth, b3Ref:getDimY()) + end + end + end + return dWidth +end + +--------------------------------------------------------------------- +local function MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMchFindMaster, bIs3Faces, b3Solid, bOrthoFacesMaster, bMillDown) + + local nFirstMachId + local bOrthoFaces + local sWarn + local sMchFind = 'Pocket' + local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt + local bBadMach = false + if sMchFindMaster and #sMchFindMaster > 0 then + sMchFind = sMchFindMaster + end + if bIs3Faces then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId, bIs3Faces) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeByPockets could not find reference face' + EgtOutLog( sErr) + return -1, sErr + end + end + else + bOrthoFaces = bOrthoFacesMaster + end + + -- se è un tunnel verifico se è possibile usare la svuotatura + if bOrthoFaces then + -- ottengo le dimensioni del tunnel + dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = GetTunnelDimension( Proc, nPartId) + local nPathInt + -- se devo inserire il chamfer + if nChamfer > 0 then + local nOk, sErr = MakeChamfer( Proc, bIs3Faces, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return -1, sErr end + end + -- se smusso non è esclusivo + if nChamfer < 2 then + -- ricalcolo se è lavorabile da sotto + bMillDown = ( BD.DOWN_HEAD == true) + -- verifico se può essere fatto con svuotatura + local bMakePocket, sPocketing, dMaxDepth, dDiamTool = VerifyPocket( Proc, dDimMin, dDepth / 2, nil, sMchFind) + local bMakePocketDn, sPocketingDn, dMaxDepthDn, dDiamToolDn + if bMillDown then + bMakePocketDn, sPocketingDn, dMaxDepthDn, dDiamToolDn = VerifyPocket( Proc, dDimMin, dDepth / 2, nil, sMchFind..'_H2') + -- se è negativo inverto il versore e la faccia + if vtOrtho:getZ() < 0 then + vtOrtho = -vtOrtho + EgtInvertSurf( nSurfInt) + end + end + if bMakePocket then + -- gestione svuotatura da un solo lato o anche dal lato opposto (se non verticale) + -- estraggo il contorno dalla superfice per evitare i problemi con la svuotatura + -- e assegno l'estrusione + nPathInt = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) + EgtModifyCurveExtrusion( nPathInt, vtOrtho, GDB_RT.GLOB) + -- se ho 3 facce, ciclo sulle entià del percorso per segnare quelle che sono aperte + if bIs3Faces then + SetOpenSide( nPathInt, vtOrtho, b3Solid, nAddGrpId) + end + -- variabili per parametri lavorazione + local dMachDepth + local dElev = 0 + local bDoubleSide + local bOneShot + local bComplete = true + -- imposto altezza aggiuntiva di elevazione + local dCollSic = CalcCollisionSafety( vtOrtho) + -- se possibile svuotare completamente da una sola parte + if dMaxDepth > ( dDepth + BD.CUT_EXTRA + dCollSic) then + dMachDepth = ( dDepth / 2) + BD.CUT_EXTRA + dElev = dDepth + BD.CUT_EXTRA + bOneShot = true + else + -- se direzione verso la verticale setto max affondamento possibile ed + -- emetto messaggio di warning perché non lavorabile interamente + if abs( vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then + dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic + dElev = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + bComplete = false + -- altrimenti setto il flag per fare la svuotatura da due parti + else + -- se l'altezza utensile riesce a lavorare completamente da due parti + if dMaxDepth > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then + dMachDepth = BD.CUT_EXTRA_MIN + dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN + -- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione + else + dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic + dElev = dMaxDepth + -- se molto inclinato rispetto alla normale della faccia di riferimento, lavorazione non idonea per probabili collisioni + local vtRef = Y_AX() + if abs( vtOrtho:getX()) > abs( vtOrtho:getY()) and abs( vtOrtho:getX()) > abs( vtOrtho:getZ()) then + vtRef = X_AX() + elseif abs( vtOrtho:getZ()) > abs( vtOrtho:getX()) and abs( vtOrtho:getZ()) > abs( vtOrtho:getY()) then + vtRef = Z_AX() + end + if abs( vtOrtho * vtRef) < 0.5 then + bBadMach = true + end + end + bDoubleSide = true + end + end + -- se lavorazione non idonea esco + if bIs3Faces and bBadMach then + local sErr = 'Impossible apply perpendicular pocketing: ' .. sPocketing + return -2, sErr + 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 -1, sErr + end + -- prendo l'id della prima lavorazione inserita + if not nFirstMachId then + nFirstMachId = nMchFId + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nPathInt, -1}}) + -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) + local bInvertMach + if vtOrtho:getZ() < BD.NZ_MINA and abs(vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti + elseif not bDoubleSide and vtOrtho:getY() > GEO.EPS_SMALL and not ( -(vtOrtho:getZ()) < BD.NZ_MINA) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if AreSameOrOppositeVectorApprox( vtOrtho, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtOrtho:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtOrtho:getY() < GEO.EPS_SMALL then + nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + else + nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' or sMchFind == 'OpenPocket_H2' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- inverto il percorso di lavorazione per lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- imposto affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return -1, sErr + end + end + -- se posso applicare la svuotatura sul lato opposto + if bDoubleSide then + -- se ho la lavorazione da sotto ricalcolo in base a questa lavorazione + if bMakePocketDn then + -- sPocketing = sPocketingDn + -- dMaxDepth = dMaxDepthDn + -- dDiamTool = dDiamToolDn + -- se l'altezza utensile riesce a lavorare completamente da due parti + if dMaxDepthDn > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then + dMachDepth = BD.CUT_EXTRA_MIN + dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN + -- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione + else + dMachDepth = dMaxDepthDn - ( dDepth / 2) - dCollSic + dElev = dMaxDepthDn + bComplete = false + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + else + -- se anche lavorando dal lato opposto non riesco a svuotare completamente la fessura + -- setto i parametri affondamento ed emetto warning + if dMaxDepth < ( dDepth / 2) + BD.CUT_EXTRA + dCollSic then + dMachDepth = dMaxDepth - (dDepth / 2) - dCollSic + dElev = dMaxDepth + bComplete = false + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'PockOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, EgtIf( bMakePocketDn, sPocketingDn, sPocketing)) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. EgtIf( bMakePocketDn, sPocketingDn, sPocketing) + EgtOutLog( sErr) + return -1, sErr + end + -- prendo l'id della prima lavorazione inserita + if not nFirstMachId then + nFirstMachId = nMchFId + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nPathInt, -1}}) + -- imposto direzione utensile opposta + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if AreSameVectorApprox( vtOrtho, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtOrtho:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtOrtho:getY() < GEO.EPS_SMALL then + nSCC = MCH_SCC.ADIR_YP + else + nSCC = MCH_SCC.ADIR_YM + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' or sMchFind == 'OpenPocket_H2' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- inverto il percorso di lavorazione per lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- imposo affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return -1, sErr + end + end + end + -- se non completo e U, cerco di lavorare anche la faccia di fondo (con il massimo affondamento possibile) + if not bComplete and bIs3Faces then + -- recupero la faccia da lavorare + local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + local vtN + local bPock3rd = false + if nFacInd then + vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + bPock3rd = ( vtN and ( vtN:getZ() >= BD.NZ_MINA or bMakePocketDn)) + end + if bPock3rd then + -- recupero la distanza di sicurezza aggiuntiva + local dFacCollSic = CalcCollisionSafety( vtN) + -- scelgo se lavorare da sotto + local bFacPocketDn = ( bMakePocketDn and vtN:getZ() < -0.174) + -- inserisco la lavorazione di svuotatura + local sName = EgtIf( bDoubleSide, 'Pock3rd_', 'Pock2nd_') .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, EgtIf( bFacPocketDn, sPocketingDn, sPocketing)) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + EgtOutLog( sErr) + return -1, sErr + end + -- prendo l'id della prima lavorazione inserita + if not nFirstMachId then + nFirstMachId = nMchFId + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtN:getY() < GEO.EPS_SMALL then + nSCC = MCH_SCC.ADIR_YM + else + nSCC = MCH_SCC.ADIR_YP + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' or sMchFind == 'OpenPocket_H2' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- inverto il percorso di lavorazione per lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- imposto affondamento + local dDepth = 0 + local dActMaxDepth = EgtIf( bFacPocketDn, dMaxDepthDn, dMaxDepth) + if dActMaxDepth < dFacElev + dFacCollSic then + dDepth = dActMaxDepth - ( dFacElev + dFacCollSic) + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- dichiaro non si generano sfridi per VMill + local sNotes = 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return -1, sErr + end + end + end + end + return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId + end + end + end + + return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, bOrthoFaces +end + +--------------------------------------------------------------------- +local function ManageAntiSplintBySaw( Proc, b3Raw, bIsU, vtN, nFacInd, sWarn, bMillDown, bReduceDepth) + + local bMadeASbyBld = false + local nNumFac = EgtIf( bIsU, 2, 1) + local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra + -- se a U cerco di ottimizzare il lato di lavoro della lama + if bIsU then + if abs( vtN:getY()) > 0.996 then + nPrefSide = 0 + elseif abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then + -- se X è negativa allora devo tenere il motore a destra + if vtN:getX() < -(10 * GEO.EPS_SMALL) then + nPrefSide = 2 + end + end + end + -- va eseguito sulle facce diverse dalla principale + local nPrevSCC = nil + for nFacet = 0, nNumFac do + if nFacet ~= nFacInd then + -- lavoro + local dSawThick = 0 + local dMaxDepth = 200 + local bAdj, dAng, dExtraOffs, sWarn2, nIdMach + bMadeASbyBld, sWarn2, nIdMach, dSawThick, dMaxDepth, bAdj, dAng, dExtraOffs = MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw, nFacInd, bReduceDepth, bMillDown) + if not bMadeASbyBld then return bMadeASbyBld, false, sWarn2 end + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + -- se antischeggia veramente inserito perchè necessario + if nIdMach then + -- verifico se da invertire + local bInvertMach = false + local dDepth = 0 + if bIsU then + if abs(vtN:getZ()) > 0.63 or abs(vtN:getY()) > 0.63 then +-- if abs(vtN:getZ()) > 0.7 or abs(vtN:getY()) > 0.7 then + -- prendo il vettore normale alla faccia + local _, vtNFc = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + -- se superficie principale parallela al piano XZ + if nPrefSide == 0 then + -- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto) + if vtNFc:getX() * vtNFc:getZ() > 0 then + nPrefSide = 2 + -- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto) + else + nPrefSide = 1 + end + end + -- se faccia verso X+ e mandrino verso sinistra + if vtNFc:getX() > 0 and nPrefSide == 1 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + -- se faccia verso X- e mandrino verso destra + elseif vtNFc:getX() < 0 and nPrefSide == 2 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + end + end + end + -- eseguo inversione + if bInvertMach then + local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT) + local nWS = EgtGetMachiningParam( MCH_MP.WORKSIDE) + local nInvWS = EgtIf( nWS == MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT) + local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE) + local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT) + if not bOrtUp then + -- assegno i parametri invertiti + EgtSetMachiningParam( MCH_MP.WORKSIDE, nInvWS) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert) + -- setto l'offset pari allo spessore lama + EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick) + end + end + -- posizione del braccio : se primo taglio la recupero, altrimenti la imposto + if not nPrevSCC then + nPrevSCC = EgtGetMachiningParam( MCH_MP.SCC) + else + EgtSetMachiningParam( MCH_MP.SCC, nPrevSCC) + end + -- rieseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nIdMach, false) + return false, false, sErr + end + end + end + end + + return bMadeASbyBld, true, sWarn +end + +--------------------------------------------------------------------- +local function MakePathsOnExtremPoints( nAddGrpId, nIdPath, pPaths, dTDiam) + + local dLength = 2 + if not nIdPath then return pPaths end + + -- prendo i punti iniziali e finali del percorso e i versori direzione + local ptIni = EgtSP( nIdPath, GDB_RT.GLOB) + local ptEnd = EgtEP( nIdPath, GDB_RT.GLOB) + + -- se distanza tra i punti è <= del diametro utensile esco + if dist( ptIni, ptEnd) <= dTDiam then return pPaths end + + -- prendo i versori iniziali e finali + local vtIni = EgtSV( nIdPath, GDB_RT.GLOB) + local vtEnd = EgtEV( nIdPath, GDB_RT.GLOB) + + local ptIniP = ptIni + local ptEndP = ptIniP + (vtIni * dLength) + local nAuxId = EgtLine( nAddGrpId, ptIniP, ptEndP, GDB_RT.GLOB) + table.insert( pPaths, { nAuxId, 1, ptIniP}) + + ptIniP = ptEnd + ptEndP = ptEnd - ( vtEnd * dLength) + nAuxId = EgtLine( nAddGrpId, ptIniP, ptEndP, GDB_RT.GLOB) + table.insert( pPaths, { nAuxId, 2, ptIniP}) + + return pPaths +end + +--------------------------------------------------------------------- +local function MakeAntiSplintByMill( Proc, nPartId, pPaths, nPathInt, vtN1, + bDoubleSide, bOppoSide, sMilling, nPhase, sMyWarn, + dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId) + + local sMyWarn2 + + -- assegno lavorazioni ad ogni percorso + for i = 1, #pPaths do + + local nIdPath = pPaths[i][1] + local nSide = pPaths[i][2] + -- modifico versore direzione + EgtModifyCurveExtrusion( nIdPath, vtN1, GDB_RT.GLOB) + local sName + if bOppoSide then + sName = 'AntiSplintOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + else + sName = 'AntiSplint_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + end + local nMchId = EgtAddMachining( sName, sMilling) + if nMchId then + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nIdPath, -1}}) + if ( bOppoSide and nSide == 1) or ( not bOppoSide and nSide == 2) then + -- imposto lato di lavoro destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + else + -- imposto lato di lavoro sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + local nSCC + if bOppoSide then + -- imposto direzione utensile opposta + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- imposto posizione braccio porta testa + nSCC = MCH_SCC.ADIR_YM + if not BD.C_SIMM then + if AreSameVectorApprox( vtN1, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN1:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtN1:getY() < GEO.EPS_SMALL then + nSCC = MCH_SCC.ADIR_YP + else + nSCC = MCH_SCC.ADIR_YM + end + end + else + local bInvertMach = false + if not nPathInt then + -- imposto posizione braccio porta testa + nSCC = MCH_SCC.ADIR_YM + if vtN1:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + else + -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) + if vtN1:getZ() < BD.NZ_MINA and abs(vtN1:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti + elseif not bDoubleSide and vtN1:getY() > GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + end + -- imposto posizione braccio porta testa + nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if AreSameOrOppositeVectorApprox( vtN1, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN1:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtN1:getY() < GEO.EPS_SMALL then + nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + else + nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) + end + end + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- parametri attacco + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 1) + -- allungo inizio + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 2) + EgtSetMachiningParam( MCH_MP.LITANG, 10) + EgtSetMachiningParam( MCH_MP.LIPERP, -5) + -- parametri uscita + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + local dMachDepth = 0 + local dExtraElev = 0 + if bDoubleSide then + dExtraElev = BL.GetFaceElevationFromPointDir( Proc.Id, nPartId, pPaths[i][3], EgtIf( bOppoSide, -vtN1, vtN1)) - dMaxElevMaster + end + local dMaxElev = dMaxElevMaster + dExtraElev + if ( dMaxElev + BD.CUT_EXTRA + dCollSic) > dMaxDepth then + dMachDepth = dMaxDepth - ( dMaxElev + dCollSic) + end + -- setto se devo invertire il percorso + local bInvert = CheckToInvert( nIdPath, true) + if bOppoSide then + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) + EgtSetMachiningParam( MCH_MP.INVERT, bInvert) + else + EgtSetMachiningParam( MCH_MP.DEPTH, (dMachDepth+dExtraDepth)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bInvertMach, not bInvert, bInvert)) + end + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if EgtApplyMachining( true, false) then + _, sMyWarn2 = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + else + -- se ho la lavorazione di svuotatura riloco la lavorazione antischeggia prima di questa + if nFirstMachId then + EgtRelocateGlob( nMchId, nFirstMachId, GDB_IN.BEFORE) + end + end + -- altrimenti lavorazione non applicata + else + _, sMyWarn2 = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + end + -- altrimenti non è stata inserita lavorazione + else + sMyWarn2 = 'warning adding machining ' .. sName .. '-' .. sMilling + end + end + + if sMyWarn2 and #sMyWarn2 > 0 then + sMyWarn = sMyWarn .. '\n' .. sMyWarn2 + end + return sMyWarn +end + + +--------------------------------------------------------------------- +local function ManageAntiSplintByMill( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, bMillDown, dDiam, bDoubleSide, + vtOrtho, nPathInt, nSurfInt, b3Solid, dDepth, + bOneShot, nFirstMachId) + + local sMyWarn = '' + local pPaths = {} + local nAuxId + local sMilling + + -- recupero la lavorazione tenendo conto dell'elevazione + local dCheckDepth + if bDoubleSide then + dCheckDepth = 0.5 * dDepth + else + if not nPathInt then + dCheckDepth = BL.GetFaceElevation( Proc.Id, nFacInd) + else + dCheckDepth = dDepth + end + end + sMilling = ML.FindMilling( 'AntiSplintMillCut' .. EgtIf( bMillDown and not bDoubleSide, '_H2', ''), dCheckDepth) or + ML.FindMilling( 'AntiSplintMillCut' .. EgtIf( bMillDown and not bDoubleSide , '_H2', ''), 2/3 * dCheckDepth) or + ML.FindMilling( 'AntiSplintMillCut' .. EgtIf( bMillDown and not bDoubleSide , '_H2', '')) + + if sMilling then + + local vtN1 + local nFirstId, nNumId + local dMaxElevMaster + local dExtraDepth = 0 + local dCollSic + local ptMidDist + -- recupero i dati dell'utensile + local dTDiam = 50 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + + -- se non ho la faccia aggiunta + if not nPathInt then + -- ottengo i percorsi da cui estrapolare il percorso di antischeggia + local tFacAdjMain = ChooseContour( Proc, nFacInd, false) + local tPaths = {} + -- se non trovato nessun angolo interno valido esco + if #tFacAdjMain == 0 then + return true, sMyWarn + end + -- prendo il primo versore + _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + dCollSic = CalcCollisionSafety( vtN1) or 0 + -- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra + if abs( vtN1:getX()) > 0.7 or abs( vtN1:getY()) > 0.7 or abs( vtN1:getZ()) > 0.7 then dCollSic = 0 end + + -- se fresatura da sotto salto la lavorazione + if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then + local sErr = 'Error : milling from bottom ' + EgtOutLog( sErr) + return false, sErr + end + local ptIniPath + local nMaxLen = 0 + dMaxElevMaster = BL.GetFaceElevation( Proc.Id, nFacInd) + -- ciclo tutta la tabella + for i = 1, #tFacAdjMain do + -- le 2 facce di contatto devono essere perpendicolari o non sottosquadra rispetto alla faccia di fondo + local ptP1, ptP2, dAng + ptP1 = tFacAdjMain[i][3] + ptP2 = tFacAdjMain[i][4] + dAng = tFacAdjMain[i][5] + if ( dAng < 0 and 180 + dAng >= 90 - 10 * GEO.EPS_SMALL) then + -- creo la linea da P1 a P2 + nAuxId = EgtLine( nAddGrpId, ptP1, ptP2, GDB_RT.GLOB) + table.insert( tPaths, nAuxId) + -- prendo la lunghezza massima e il puto medio + if tFacAdjMain[i][2] > nMaxLen then + ptIniPath = ptP1 + nMaxLen = tFacAdjMain[i][2] + ptMidDist = ( ptP1 + ptP2) / 2 + end + end + end + -- cotruisco il/i percorso/i + nFirstId, nNumId = EgtCurveCompoByReorder( nAddGrpId, tPaths, ptIniPath, true, GDB_RT.GLOB) + local bOkPath = true + for i = 1, nNumId do + local nIdPath = nFirstId + i - 1 + if EgtCurveIsClosed( nIdPath) then + bOkPath = false + end + end + -- se ho un percorso chiuso cancello tutto + if not bOkPath then + for i = 1, nNumId do + local nIdPath = nFirstId + i - 1 + EgtErase(nIdPath) + end + else + -- creo percorsi antisplint dagli estremi dei percorsi di contorno trovati + for i = 1, nNumId do + local nIdPath = nFirstId + i - 1 + pPaths = MakePathsOnExtremPoints( nAddGrpId, nIdPath, pPaths, dTDiam) + end + end + -- alrimenti ho la faccia aggiunta + else + + dCollSic = CalcCollisionSafety( vtOrtho) + nFirstId = EgtCopyGlob( nPathInt, nAddGrpId) + nNumId = 1 + -- calcolo elevazione dalla faccia trasversale aggiunta + if bDoubleSide then + dMaxElevMaster = 0.5 * dDepth + else + dMaxElevMaster = dDepth + -- se la precedente svuotatura è stata fatta completamente in una sola volta + -- valuto di nuovo se devo fare due passate o una sola + if bOneShot then + -- se non è possibile svuotare completamente da una sola parte + if dMaxDepth <= ( dMaxElevMaster + BD.CUT_EXTRA + dCollSic) then + bDoubleSide = true + dMaxElevMaster = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + else + dExtraDepth = dMaxElevMaster - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + end + -- altrimenti non è stata fatta completamente calcolo la distanza tra faccia aggiunta e profondità superficie + else + dExtraDepth = dMaxElevMaster - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + end + end + vtN1 = Vector3d(vtOrtho) + local bOkPath = SetOpenSide( nFirstId, vtOrtho, b3Solid, nAddGrpId, 2) + -- se non ho un percorso chiuso estraggo i percorsi + if bOkPath then + -- creo percorsi antisplint dagli estremi dei percorsi di contorno trovati + pPaths = MakePathsOnExtremPoints( nAddGrpId, nFirstId, pPaths, dTDiam) + end + EgtErase(nFirstId) + end + + if #pPaths > 0 then + + sMyWarn = MakeAntiSplintByMill( Proc, nPartId, pPaths, nPathInt, vtN1, + bDoubleSide, false, sMilling, nPhase, sMyWarn, + dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId) + if bDoubleSide then + if bMillDown then + local sMillingDn = ML.FindMilling( 'AntiSplintMillCut_H2', dCheckDepth) or + ML.FindMilling( 'AntiSplintMillCut_H2', 2/3 * dCheckDepth) or + ML.FindMilling( 'AntiSplintMillCut_H2') + sMilling = sMillingDn + -- controllo dati lavorazione + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se lavorazione valida + if sMilling then + sMyWarn = MakeAntiSplintByMill( Proc, nPartId, pPaths, nPathInt, vtN1, + bDoubleSide, true, sMilling, nPhase, sMyWarn, + dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId) + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library' + end + end + -- altrimenti non c'è il percorso + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' + end + -- altrimenti non è stata trovata lavorazione + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library' + end + if #sMyWarn > 0 then + EgtOutLog( sMyWarn) + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, bSinglePart, bPrevBhSideMill) + local sWarn + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + local bClosedOrthoFaces + local nFacInd, dFacElev, nFacInd2, dFacElev2 + local nBottomFace + local sMchFindBackUp + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeMoreFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + -- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche + if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then + -- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura + for i = 1, Proc.Fct do + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + -- elimino una faccia + nBottomFace = i - 1 + if EgtSurfTmRemoveFacet( nNewProc, nBottomFace) then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( nNewProc, nPartId) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bClosedOrthoFaces = nFacInd2 + EgtErase( nNewProc) + break + else + EgtErase( nNewProc) + local sErr = 'Error : MakeMoreFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + -- altrimenti esco + else + EgtErase( nNewProc) + break + end + end + -- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo + if bClosedOrthoFaces then + nFacInd = nBottomFace + -- rendo nulla la faccia opzionale perchè si tratta di una fessura + nFacInd2 = nil + dFacElev = BL.GetFaceElevation( Proc.Id, nFacInd) + bClosedOrthoFaces = false -- non setto come tunnel + end + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham, sErrCham, bForceUseBlade = EvaluateQParam( Proc) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sErrCham + end + -- se è un tunnel provo a vedere se è possibile lavorarlo con la svuotatura o con la sega catena + if bClosedOrthoFaces then + local bTryWithBlades = true + -- lavoro fessura con svuotature (singola o doppia contrapposta) + local sMyMchFind = 'Pocket' + local nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, + nLundIdFace = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMyMchFind, false, b3Solid, bClosedOrthoFaces) + if nOk < 0 then + return false, sErr + elseif nOk > 0 then + bTryWithBlades = false + end + -- Se la svuotatura precedente non è stata fatta e chamfer non è mutuamente esclusivo provo con la sega-catena + if bTryWithBlades and nChamfer < 2 then + -- verifico se posso farlo con la sega-catena + local bMakeChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick = VerifyChainSaw( Proc, dDimMin, dDimMax) + if bMakeChainSaw then + -- Verifico se necessarie più passate + local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dDimMin - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- inserisco la lavorazione di sawing + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLundIdFace}}) + -- imposto uso del lato faccia + -- al momento, dato che la fessura è passante da parte a parte, gestisco solo la lavorazione + -- dall'alto e di fronte (da dietro è disabilitata perchè ho exracorsa con la FAST). + -- Questa feature non è applicata su facce di testa e quindi non controllo l'entrata in X + if abs(vtOrtho:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nLundIdFace, GDB_ID.ROOT) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho, 1)) + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se possibile aumento l'affondamento pari al raggio corner + 1 + if dMaxMat > (dDepth + dSawCornerRad + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad + 1)) + -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning + elseif dMaxMat < dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- eseguo + if not EgtApplyMachining( true, false) then + if EgtGetOutstrokeInfo() then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho, 2)) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + if EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + end + end + -- altrimenti non è una fessura + else + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- larghezza della faccia + local dV = 0 + local dH = 0 + -- se due o più facce (recupero la larghezza della faccia perpendicolarmente alle altre) + if Proc.Fct >= 2 then + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, EgtIf( nFacInd == 0, 1, 0), GDB_ID.ROOT) + local vtX = vtN2 ^ vtN + local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2) + local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, nFacInd, GDB_BB.STANDARD, frRef) + if b3Ref then + dH = b3Ref:getDimX() + dV = b3Ref:getDimY() + end + -- altrimenti una sola faccia + else + _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + if Proc.Box:getDimX() > Proc.Box:getDimY() then + if dH > dV then dH, dV = dV, dH end + else + if dH < dV then dH, dV = dV, dH end + end + end + -- verifico se U + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) + -- verifico se due facce o L con una o due facce di terminazione + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2) + -- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia + local bMakeBySideMill, bHead, bHeadDir, sMilling, dMaxMat, dToolDiam = VerifyBHSideMill( Proc, bIsU, bIsL, bSinglePart, bPrevBhSideMill) + if bPrevBhSideMill == nil then + bPrevBhSideMill = bMakeBySideMill + end + if bMakeBySideMill then + -- se smusso non è esclusivo + if nChamfer < 2 then + -- se lavorazione da sotto e lunga, va divisa in due metà + local bDouble = ( vtN:getZ() < -0.5 and dH > ( BD.MAX_LEN_BH_FROM_BOTTOM or 200)) + -- inserisco la lavorazione di fresatura + local sName = 'BHMill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + sName = EgtGetName( nMchFId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso del lato faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHeadDir, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) + -- calcolo step effettivo ed elevazione + local dVcalc = dV - dMaxMat + if abs( dVcalc) < 0.1 then dVcalc = 0 end + local dStep = min( EgtMdbGetCurrMachiningParam( MCH_MP.STEP), dMaxMat) + local nStep = ceil( dVcalc / dStep) + if nStep > 0 then + dStep = dVcalc / nStep + 0.1 + else + dStep = 0 + end + EgtSetMachiningParam( MCH_MP.STEP, dStep) + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dVcalc + dStep, 2) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- attacchi e uscite + if vtN:getZ() > -0.5 then + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, dFacElev + BD.CUT_SIC) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + else + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + BD.CUT_SIC) + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + if ( nStep % 2) == 1 then + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.LINEAR) + EgtSetMachiningParam( MCH_MP.LOTANG, 0) + else + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.PERP_TG) + EgtSetMachiningParam( MCH_MP.LOTANG, -( dToolDiam / 2 + b3Raw:getDimY() + BD.CUT_SIC)) + end + EgtSetMachiningParam( MCH_MP.LOPERP, dFacElev + BD.COLL_SIC) + if bDouble then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dH / 2) + if ( nStep % 2) == 0 then + EgtSetMachiningParam( MCH_MP.LOTANG, -( dToolDiam / 2 + b3Raw:getDimY() + dH / 2 + BD.CUT_SIC)) + end + end + end + -- tipo passate multiple + local nStepType = EgtIf( ( Proc.HeadDir and vtN:getY() < -0.5) or ( not Proc.HeadDir and vtN:getY() > 0.5), MCH_MILL_ST.ONEWAY, MCH_MILL_ST.ZIGZAG) + EgtSetMachiningParam( MCH_MP.STEPTYPE, nStepType) + -- imposto posizione braccio porta testa + local nSCC = EgtIf( ( vtN:getY() > 0.5 or ( bHeadDir and vtN:getZ() > 0.5 ) or ( not bHeadDir and vtN:getZ() < -0.5)), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- se divisa in due metà + if bDouble then + local nMchFNId = EgtCopyMachining( sName .. '_2', sName) + if not nMchFNId then + local sErr = 'Error copying machining ' .. sName + EgtOutLog( sErr) + return false, sErr + end + -- inverto direzione e lato di lavoro e direzione ausiliaria + local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvert) + local nWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE) + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nWorkSide == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( nSCC == MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFNId, false) + return false, sErr + end + end + end + -- altrimenti lavoro con svuotatura + else + local bSpecial3faces = false + -- verifico se lavorando la faccia principale rimane esclusa molta sezione trasversale complessiva della feature (da box) + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + local bBoxF = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfFac) + if dH * dV < 0.9 * ( bBoxF:getDimX() * bBoxF:getDimY()) then + bSpecial3faces = true + end + -- se riconosciuta gestione 3 facce + -- e limitata per ora alla feature 20 + if bSpecial3faces and Proc.Prc == 20 and nFacInd2 then + -- se smusso non è esclusivo + if nChamfer < 2 then + -- entrambe le facce non devono essere orientate verso il basso + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + -- se orientata verso il basso, verifico l'alternativa + if vtN:getZ() < BD.NZ_MINA and vtN2:getZ() < BD.NZ_MINA then + local sErr = 'Error : special LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd2, GDB_ID.ROOT) + -- eventuali tagli preliminari + do + local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, nChamfer) + if not bOk then return false, sErr end + end + -- Recupero la lavorazione di fresa + local sMilling = ML.FindMilling( 'LongSmallCut') + if not sMilling then + local sErr = 'Error : LongSmallCut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero la lavorazione di svuotatura + local sMchFind = 'Pocket' + -- se forzato uso truciolatore + if EgtGetInfo( Proc.Id, Q_USE_ROUGH_TOOL, 'i') == 1 then + sMchFind = 'OpenPocket' + end + local dDiam = min( dH, dV) + local dDiam2 = min( dH2, dV2) + local dCollSic = 2 * BD.COLL_SIC + local dCollSic2 = 2 * BD.COLL_SIC + if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end + if abs( vtN2:getX()) > 0.7 or abs( vtN2:getY()) > 0.7 or abs( vtN2:getZ()) > 0.7 then dCollSic2 = 0 end + local sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2) + -- se non trova una svuotatura adatta provo ad assegnarla all'altra faccia + if not sPocketing then + dDiam, dDiam2 = dDiam2, dDiam + dCollSic, dCollSic2 = dCollSic2, dCollSic + nFacInd, nFacInd2 = nFacInd2, nFacInd + dH, dH2 = dH2, dH + dV, dV2 = dV2, dV + dFacElev, dFacElev2 = dFacElev2, dFacElev + rfFac, rfFac2 = rfFac2, rfFac + vtN, vtN2 = vtN2, vtN + sPocketing = ML.FindPocketing( sMchFind, dDiam2, dFacElev2 + dCollSic2) + if not sPocketing then + local sErr = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- provo con contornatura + local dDiamTool = 20 + if bIsL then + local bOk, sErr + bOk, sWarn, dDiamTool = MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, dCollSic, true, sMilling, nFacInd2, dFacElev2) + if not bOk then return bOk, sWarn end + else + local sErr = 'Error : Impossible mill special LapJoint' + EgtOutLog( sErr) + return false, sErr + 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( {{ Proc.Id, nFacInd2}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev2, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- se abilitato dal parametro Q inserisco foro sullo spigolo + if EgtGetInfo( Proc.Id, Q_BORE_ON_CORNER, 'i') == 1 then + local bOk + bOk, sWarn = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, 0, nAddGrpId, dDiamTool, true) + if not bOk then return false, sWarn end + -- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura + elseif EgtGetInfo( Proc.Id, Q_BORE_ON_CORNER, 'i') == 2 then + local bOk + bOk, sWarn = MakeSharpCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, 0, nAddGrpId, dDiamTool) + if not bOk then return false, sWarn end + end + end + -- altrimenti lavorazione di svuotatura o contornatura + else + local bUseOtherFace + -- se orientata verso il basso e non c'è testa da sotto, verifico l'alternativa + if vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + dFacElev, dFacElev2 = dFacElev2, dFacElev + bUseOtherFace = true + end + -- verifico non sia orientata verso il basso o ci sia una testa dal basso + local bFaceDown = ( vtN:getZ() < BD.NZ_MINA) + if bFaceDown and not BD.DOWN_HEAD and not BD.TURN then + local sErr = 'Error : LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se forma a L e la componente in X è maggiore di 60° e non in testa allora verifico se posso utilizzare la faccia secondaria + if bIsL and abs( vtN:getX()) > 0.866 and + ( Proc.Box:getMax():getX() < b3Solid:getMax():getX() - 10 or vtN:getX() < 0) and + ( not Proc.Tail or vtN:getX() > 0) then + -- se non ho scambiato la faccia + if not bUseOtherFace then + if nFacInd2 then + nFacInd, nFacInd2 = nFacInd2, nFacInd + dFacElev, dFacElev2 = dFacElev2, dFacElev + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- altrimenti cerco la faccia secondaria per adiacenza alla principale + else + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj, sErr = GetFaceAdj( Proc, nFacInd, dH, dV) + if nFacAdj < 0 then + EgtOutLog( sErr) + return false, sErr + end + nFacInd = nFacAdj + dFacElev = BL.GetFaceElevation( Proc.Id, nFacInd) + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + end + -- altrimenti se ho già cambiato faccia do errore per impossibilità di lavorazione + else + local sErr = 'Error : impossible to machine by side angle too big that cause collision' + EgtOutLog( sErr) + return false, sErr + end + end + -- eventuali tagli preliminari + do + local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, nChamfer) + if not bOk then return false, sErr end + end + -- imposto altezza aggiuntiva di elevazione + local dCollSic = CalcCollisionSafety( vtN) + -- abilitazione lavorazione da sotto + local bMillUp = ( BD.DOWN_HEAD and vtN:getZ() > -0.259) + local bMillDown = ( BD.DOWN_HEAD and vtN:getZ() < 0.342) + -- settaggio voluto da Alessandro/Fabio (per fare angoli con fresa piccola) + sMchFind = 'Pocket' + local dDiam = min( dH, dV) + local bTailOnSide = ( Proc.Box:getMin():getX() - b3Solid:getMin():getX() < 0.1 and not Proc.Tail) + if ( Proc.Fct == 1) or (( Proc.Fct == 2 or Proc.Fct == 3) and bIsL) or ((( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 4 and not bTailOnSide)) and bSinglePart) then + sMchFind = 'OpenPocket' + if bIsU then + dDiam = GetUShapeWidth( Proc, nFacInd) or dDiam + elseif Proc.Fct == 4 then + -- per rifinire gli angoli premio utensile diam 25 o da BD + dDiam = min( dDiam, BD.MAXDIAM_POCK_CORNER or 30) + elseif Proc.Fct == 3 and bIsL then + -- per rifinire gli angoli premio utensile diam 25 o da BD + dDiam = min( 2 * dDiam, BD.MAXDIAM_POCK_CORNER or 30) + else + dDiam = 2 * dDiam + end + end + sMchFindBackUp = sMchFind + local nUseRoughTool = EgtIf( bSinglePart, 0, 1) + local nUseRT + -- 04/08/2020 Se settato parametro uso truciolatore (parametro Q), non si devono prendere altre frese, si da errore (Fabio) + -- Questa opzione si scontra facilmente con altre interpretazioni dello stasso parametro Q (per tornare indietro bNewCheck = false) + local bNewCheck = true + -- se processo 20 e non sto usando il truciolatore + if bNewCheck and Proc.Prc == 20 and nUseRoughTool == 0 then + -- verifico se forzato uso truciolatore + nUseRT = EgtGetInfo( Proc.Id, Q_USE_ROUGH_TOOL, 'i') + if nUseRT and nUseRT ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + end + end + -- 03/12/2020 aggiunto controllo su feature 30 senza uso truciolatore + if bNewCheck and Proc.Prc == 30 and nUseRoughTool == 0 then + -- verifico se forzato uso truciolatore + nUseRT = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') + if nUseRT and nUseRT ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + end + end + -- se processo 20 e non sto usando il truciolatore + if Proc.Prc == 20 and nUseRoughTool == 0 then + if nUseRT and nUseRT ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + end + end + -- se da sotto, imposto massima lunghezza secondo la direzione + local dMaxTotLen + if bMillDown and BD.GetBottomToolMaxTotLen then + dMaxTotLen = BD.GetBottomToolMaxTotLen( vtN) + end + -- ricerca lavorazione + local sPocketing + local _, sMyPocketing, dMyTMaxDepth, dMyTDiam = VerifyPocket( Proc, dDiam, dFacElev + dCollSic, dMaxTotLen, sMchFind .. EgtIf( bMillDown, '_H2', '')) + if not sMyPocketing and bMillUp then + _, sMyPocketing, dMyTMaxDepth, dMyTDiam = VerifyPocket( Proc, dDiam, dFacElev + dCollSic, dMaxTotLen, sMchFind) + bMillDown = false + end + --local sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, dFacElev + dCollSic, dMaxTotLen) + --if not sMyPocketing then + -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, nil, dMaxTotLen) + --end + --if not sMyPocketing and bMillUp then + -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic) + -- if not sMyPocketing then + -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam) + -- end + -- bMillDown = false + --end + if sMyPocketing and + ( dMyTMaxDepth > dFacElev + dCollSic - 10 * GEO.EPS_SMALL or ( dMyTMaxDepth > 0.8 * dFacElev + dCollSic and not bIsU) or ( bIsL and nUseRoughTool == 0)) then + sPocketing = sMyPocketing + end + if bMillDown then + sMchFind = sMchFind ..'_H2' + end + -- 2021.09.16 Richiesta di Fabio Squaratti per lavorazione "Lamello": + -- se ho attiva questo tipo di lavorazione (delle fresature) e una di queste feature: L016, L030, L032, L039 + -- verifico se sono compatibili con questa lavorazione forma a U e larga più dell'altezza tagliente e profondità compatibile con + local bSpecialMillOnSide + local dThickMillOnSide = 0 + local sMillingOnSide + local dToolDiamOnSide = 0 + local dMaxDepthOnSide = 0 + if ( Proc.Prc == 16 or Proc.Prc == 30 or Proc.Prc == 32 or Proc.Prc == 39) then + -- verifico se ho una gola con 3 facce ed eventualmente delle facce terminali: + -- faccio una copia della superfice ed elimino le facce che hanno dimensione X < 1 e le facce risultanti devono essere una U + local nTestId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + if nTestId then + local bNewIsU + local bExit + local nFaces = EgtSurfTmFacetCount( nTestId) + while not bExit and nFaces >= 3 do + local bDeleteFace + nInt = 0 + while not bDeleteFace and nInt < nFaces do + nInt = nInt + 1 + local b3Facet = EgtSurfTmGetFacetBBoxGlob( nTestId, nInt-1, GDB_BB.STANDARD) + local vtN = EgtSurfTmFacetNormVersor( nTestId, nInt-1, GDB_ID.ROOT) + -- se dimensione faccia sulla X + if b3Facet:getDimX() < 1 or abs( vtN:getX()) > 0.1 then + EgtSurfTmRemoveFacet( nTestId, nInt-1) + bDeleteFace = true + end + end + nFaces = EgtSurfTmFacetCount( nTestId) + -- se non ho cancellato una faccia faccio il test per forma ad U + if not bDeleteFace then + -- ottengo il numero di facce rimanenti + bNewIsU = ( nFaces == 3 and not TestElleShape3( nTestId, true)) + bExit = true + end + end + -- verifico che la componente x della faccia o deve essere nulla + local vtN1 = EgtSurfTmFacetNormVersor( nTestId, 0, GDB_ID.ROOT) + if bNewIsU and abs( vtN1:getX()) > 0.01 then + bNewIsU = false + end + -- cancello la copia del percorso + EgtErase( nTestId) + + if bNewIsU and ( not BD.MIN_LEN_LAMELLO or + ( Proc.TotBox and Proc.TotBox:getDimX() > BD.MIN_LEN_LAMELLO) or + ( not Proc.TotBox and Proc.Box:getDimX() > BD.MIN_LEN_LAMELLO)) then + -- recupero la lavorazione + if BD.DOWN_HEAD and vtN:getZ() < BD.NZ_MINA then + sMillingOnSide = ML.FindMilling( 'SideMillAsBlade_H2') + else + sMillingOnSide = ML.FindMilling( 'SideMillAsBlade') + end + + if sMillingOnSide then + -- recupero i dati dell'utensile + local dToolLength = 0 + local sUserNote + if EgtMdbSetCurrMachining( sMillingOnSide) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dToolDiamOnSide = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamOnSide + dThickMillOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dThickMillOnSide + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide + end + end + -- 2021.09.17 Su conferma di Fabio Squaratti, se la gola è più streta dell'utensile o la profondità della gole è maggiore + -- del valore parametro SIDEDEPTH (preso dalle note utente dell'utensile) allora si prosegue come se non fosse abilitata + -- questo tipo di lavorazione SideMillAsBlade + if dDiam > dThickMillOnSide - 10 * GEO.EPS_SMALL and dFacElev < dMaxDepthOnSide + 10 * GEO.EPS_SMALL then + bSpecialMillOnSide = true + -- disabilito eventulae svuotatura + sPocketing = nil + end + end + end + end + end + -- se feature 16 e forzata lama e forma ad U, annulla la svuotatura + if Proc.Prc == 16 and bForceUseBlade and Proc.Fct == 3 and bIsU then + sPocketing = nil + end + -- leggo parametro Q + local nQAntisplintResult = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0 + -- se lavorazione fresa come lama disabilito eveentuale antischegggia + if bSpecialMillOnSide then nQAntisplintResult = 0 end + -- se non trova una svuotatura adatta + if not sPocketing then + -- se forma a L provo con contornatura + if bIsL and not bSpecialMillOnSide then + -- se smusso non è esclusivo + if nChamfer < 2 then + return MakeByMill( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV, dFacElev, dCollSic) + end + -- altrimenti, in base alla forma, provo con svuotature di fianco o con la sega a catena o lama + else + local bTryWithBlades = true + local nOk, bOk, sStat, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, bOrthoFaces, nSurfInt + if bSpecialMillOnSide then + -- eseguo + bOk, sWarn = MakeByMillAsSaw( Proc, nPhase, nRawId, nPartId, nFacInd, + rfFac, dH, dV, dFacElev, bSpecialMillOnSide, + nBottomFace, nAddGrpId, b3Solid, dMaxDepthOnSide, sMillingOnSide, + dToolDiamOnSide, dThickMillOnSide) + if bOk then + return true, sWarn + end + end + -- se feature 16 o 17 e se forzata lama provo prima con questa e poi con la fresa + if ( Proc.Prc == 16 or Proc.Prc == 17) and bForceUseBlade then + -- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame + if bTryWithBlades and nChamfer < 2 then + -- anche su macchine con testa da sotto, la sega a catena è solo da sopra + if vtN:getZ() < BD.NZ_MINA and BD.DOWN_HEAD and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + dFacElev, dFacElev2 = dFacElev2, dFacElev + bUseOtherFace = true + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + end + -- eseguo + bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, + rfFac, dH, dV, dFacElev, bForceUseBlade, + dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, + bOrthoFaces, nBottomFace, nChamfer, nAddGrpId, b3Solid, + dDepthCham, nSurfInt, true) + if not bOk then + -- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e + -- se non è possibile allora provo in seguito con lama o segacatena + -- o passare subito dalla lavorazione con lama/sega catena + if Proc.Fct == 3 and bIsU then + -- lavoro con svuotature (singola o doppia contrapposta) + local sMyMchFind = 'Pocket' + nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, _, _, _, _, _, _, _, + bOrthoFaces = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMyMchFind, true, b3Solid, nil, bMillDown) + -- se lavorazione non idonee ( asse della feature troppo inclinato e impossibile lavorare completamente da due parti) + if nOk == -2 then + if not sMchFind then + sMchFind = sMchFindBackUp + end + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + elseif nOk < 0 then + return false, sErr + elseif nOk == 0 then + if sStat == 'MNF' then + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + else + return bOk, sWarn + end + else + bOk = true + return bOk, sErr + end + else + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + else + return bOk, sWarn + end + else + -- se devo inserire il chamfer + if ( ( Proc.Fct == 3 and bIsU) or (Proc.Fct == 2 and bIsL)) and nChamfer > 0 then + -- ottengo le dimensioni dello pseudotunnel + local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId) + local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return false, sErr end + end + bOk = true + return bOk, sWarn + end + else + -- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo + -- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa + -- 2021.04.27 esegue antischeggia di lama se forma U o L con feature passante in Y o Z + -- 2021.07.16 Per poter eseguire antischeggia di lama su feature che non sono passanti da faccia a faccia + -- ma che sono su un angolo (coinvolgono 2 facce contigue) è stato modificato il confronto in: + -- esegue antischeggia di lama se forma U o L con feature passante in Y o Z, oppure se feature a furma U e con 3 facce oppore a forma a L e con 2 facce + local bMadeASbyBld = false + local bPassThrou = ( Proc.Box:getDimY() > b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > b3Raw:getDimZ() - 1) + local bPassEdge = ((( bIsU and Proc.Fct == 3) or ( bIsL and Proc.Fct == 2)) and bSinglePart and Proc.Box:getDimX() < 0.9 * b3Raw:getDimX()) + if nChamfer < 2 and nQAntisplintResult == 1 and (( bIsU or bIsL) and ( bPassThrou or bPassEdge)) then + local bOk + local bSawDown = ( bMillDown and not bMillUp) + bMadeASbyBld, bOk, sWarn = ManageAntiSplintBySaw( Proc, b3Raw, bIsU, vtN, nFacInd, sWarn, bSawDown, true) + if not bOk then return false, sWarn end + end + -- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e + -- se non è possibile allora provo in seguito con lama o segacatena + -- o passare subito dalla lavorazione con lama/sega catena + if bTrySidePocketAtFirst and Proc.Fct == 3 and bIsU then + -- lavoro con svuotature (singola o doppia contrapposta) + local sMyMchFind = 'Pocket' + local dDiamTool = 100 + local nPathInt, nSurfInt, bOneShot, nFirstMachId + nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, + bOrthoFaces = MakeByPockets( Proc, nPhase, nRawId, nPartId, nChamfer, dDepthCham, nAddGrpId, sMyMchFind, true, b3Solid, nil, bMillDown) + if nOk == -2 then + if not sMchFind then + sMchFind = sMchFindBackUp + end + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr2 = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr2) + return false, sErr2 + end + bTryWithBlades = false + sWarn = sErr + elseif nOk < 0 then + return false, sErr + elseif nOk > 0 then + bTryWithBlades = false + sWarn = sErr + -- se ho antischeggia con fresa le inserisco +-- if nChamfer < 2 and nQAntisplintResult == 2 and ( bIsU or bIsL) then + if nChamfer < 2 and nQAntisplintResult == 2 then + local bOk, sWarn2 = ManageAntiSplintByMill( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, bMillDown, dDiamTool, bDoubleSide, + vtOrtho, nPathInt, nSurfInt, b3Solid, dDepth, + bOneShot, nFirstMachId) + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + end + -- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola + local nContourSmallTool = EgtGetInfo( Proc.Id, Q_CONTOUR_SMALL_TOOL, 'i') or 0 + if nContourSmallTool > 0 then + local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, dDiamTool, nContourSmallTool, bMillDown, + bDoubleSide, vtOrtho, nPathInt, nSurfInt, b3Solid, + dDepth, bOneShotm) + if not bOk then return false, sWarn2 end + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + end + end + bOk = true + end + -- 03/09/2020 da conferma di Fabio Squaratti: Per ora solo sulla feature 016: + -- se ha fallito la fresatura (qua sopra) allora di defalut ( anche se il flag Q della lama è disattivato) prima provo la lama + if Proc.Prc == 16 then + bForceUseBlade = true + end + -- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame + if bTryWithBlades and nChamfer < 2 then + -- anche su macchine con testa da sotto, la sega a catena è solo da sopra + if vtN:getZ() < BD.NZ_MINA and BD.DOWN_HEAD and nFacInd2 then + ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT) + nFacInd, nFacInd2 = nFacInd2, nFacInd + dFacElev, dFacElev2 = dFacElev2, dFacElev + bUseOtherFace = true + rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + end + -- eseguo + bOk, sWarn, sStat = MakeByChainOrSaw( Proc, nPhase, nRawId, nPartId, nFacInd, + rfFac, dH, dV, dFacElev, bForceUseBlade, + dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, + bOrthoFaces, nBottomFace, nChamfer, nAddGrpId, b3Solid, + dDepthCham, nSurfInt) + if not bOk and sStat == 'MNF' then + _, sPocketing = VerifyPocket( Proc, dDiam, dFacElev + dCollSic, nil, sMchFind) + if sPocketing then + sWarn = '' + else + local sErr2 = 'Error : '..sMchFind..' not found in library' + EgtOutLog( sErr2) + return false, sErr2 + end + else + -- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola + local nContourSmallTool = EgtGetInfo( Proc.Id, Q_CONTOUR_SMALL_TOOL, 'i') or 0 + if nContourSmallTool > 0 then + local bOk, sWarn2 + bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, 100, nContourSmallTool, bMillDown) + if not bOk then return false, sWarn2 end + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + end + return bOk, sWarn + end + -- altrimenti verifico se ho già svuotato dal fianco, se si esco + else + -- se non ho annullato la/le svuotatura/e dal fianco + if nOk ~= -2 then + return bOk, sWarn + end + end + end + end + else + -- se devo inserire il chamfer + if ( ( Proc.Fct == 3 and bIsU) or (Proc.Fct == 2 and bIsL)) and nChamfer > 0 then + -- ottengo le dimensioni dello pseudotunnel + local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId) + local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return false, sErr end + end + end + -- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo + -- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa + -- 2021.04.27 esegue antischeggia di lama se forma U o L con feature passante in Y o Z + -- 2021.07.16 Per poter eseguire antischeggia di lama su feature che non sono passanti da faccia a faccia + -- ma che sono su un angolo (coinvolgono 2 facce contigue) è stato modificato il confronto in: + -- esegue antischeggia di lama se forma U o L con feature passante in Y o Z, oppure se feature a furma U e con 3 facce oppore a forma a L e con 2 facce + local bMadeASbyBld = false + local bPassThrou = ( Proc.Box:getDimY() > b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > b3Raw:getDimZ() - 1) + local bPassEdge = ((( bIsU and Proc.Fct == 3) or ( bIsL and Proc.Fct == 2)) and bSinglePart and Proc.Box:getDimX() < 0.9 * b3Raw:getDimX()) + if nChamfer < 2 and nQAntisplintResult == 1 and (( bIsU or bIsL) and ( bPassThrou or bPassEdge)) then + local bOk + local bSawDown = ( bMillDown and not bMillUp) + bMadeASbyBld, bOk, sWarn = ManageAntiSplintBySaw( Proc, b3Raw, bIsU, vtN, nFacInd, sWarn, bSawDown) + if not bOk then return false, sWarn end + end + if nChamfer < 2 and nQAntisplintResult == 2 then + local bOk, sWarn2 + bOk, sWarn2 = ManageAntiSplintByMill( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, bMillDown) + if not bOk then return false, sWarn2 end + end + -- se smusso non esclusivo + if nChamfer < 2 then + -- eseguo la svuotatura della faccia principale, mi restituisce id utensile, il diametro utensile per il foro opzionale + local tvtNx = {} + tvtNx[2] = vtN + local bOk, sWarn2 + bOk, sWarn2, sTuuidPk, dDiamTool = MakePocket( Proc, nPartId, ptC, tvtNx, nFacInd, sMchFind, nUseRoughTool, sPocketing, dFacElev + dCollSic) + if not bOk then return false, sWarn2 end + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + -- se ho più di 3 facce e non di forma ad u oppure ho 3 facce e di forma ad u + -- e non sono stati inseriti antischeggia di lama + -- controllo se c'è una faccia non ortogonale alla principale e la lavoro con una contornatura o svuotatura + if ( ( Proc.Fct > 3 and not bIsU) or ( Proc.Fct == 3 and bIsU)) and not bMadeASbyBld then + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + -- Cerco una faccia adiacente alla principale con angolo > 90 + local nFacAdj + local tDimAndRef = {} + tvtNx = {} + tvtNx[1] = vtN + tDimAndRef[1] = {dH, dV, rfFac} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + if bAdj and dAng < 0 and 180 + dAng > 90.1 then + local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vAdj[i], GDB_ID.ROOT) + _, tvtNx[2] = EgtSurfTmFacetCenter( Proc.Id, vAdj[i], GDB_ID.ROOT) + tDimAndRef[2] = {dH2, dV2, rfFac2} + local ptPs = ( ptP1 + ptP2) / 2 + local bOk, sWarn2 + bOk, sWarn2 = MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, tvtNx, nFacInd, vAdj[i], ptPs, tDimAndRef, + b3Raw, EgtIf( ( Proc.Fct == 3 and bIsU), 0, 2), nUseRoughTool, dAng, sPocketing, sTuuidPk, dFacElev) + if not bOk then return bOk, sWarn2 end + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + end + end + end + end + local nBoreOnCorner = EgtGetInfo( Proc.Id, Q_BORE_ON_CORNER, 'i') or 0 + local nContourSmallTool = EgtGetInfo( Proc.Id, Q_CONTOUR_SMALL_TOOL, 'i') or 0 + -- se abilitato dal parametro Q inserisco foro sullo spigolo + if nBoreOnCorner == 1 then + local bOk, sWarn2 + bOk, sWarn2 = MakeDrillOnCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool) + if not bOk then return false, sWarn2 end + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + -- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura + elseif nBoreOnCorner == 2 then + local bOk, sWarn2 + bOk, sWarn2 = MakeSharpCleanCorner( Proc, nPhase, nRawId, nPartId, b3Raw, nFacInd, nAddGrpId, dDiamTool) + if not bOk then return false, sWarn2 end + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + -- altrimenti se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola + elseif nContourSmallTool > 0 then + local bOk, sWarn2 + bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, nPhase, nRawId, nPartId, b3Raw, + nFacInd, nAddGrpId, dDiamTool, nContourSmallTool, bMillDown) + if not bOk then return false, sWarn2 end + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + end + end + end + end + end + + return true, sWarn, bPrevBhSideMill +end + +--------------------------------------------------------------------- +local function MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- la divido in parti lungo X + local vAddId = {} + local nPart = max( ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN), 2) + local dPartLen = Proc.Box:getDimX() / nPart + local Xmin = Proc.Box:getMin():getX() + for i = 1, nPart do + -- eseguo divisione + local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i)) + if i > 1 then + local ptOn = Point3d( Xmin + ( i - 1) * dPartLen, 0, 0) + EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) + end + if i < nPart then + local ptOn = Point3d( Xmin + i * dPartLen, 0, 0) + EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) + end + -- eseguo inserimento in modo da ordinare da X+ a X- + table.insert( vAddId, 1, AddId) + end + -- applico le lavorazioni sulle diverse parti + local sWarn + local bPrevBhSideMill + for i = 1, #vAddId do + local b3Box = EgtGetBBoxGlob( vAddId[i], GDB_BB.STANDARD) + local nFct = EgtSurfTmFacetCount( vAddId[i]) + local AddProc = { Id = vAddId[i], Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Box, TotBox = Proc.Box, Fct = nFct, Flg = Proc.Flg} + -- lasciare il false nel sesto parametro (perchè internamente viene verificato se diverso da nil) + local bOk, sMyWarn + bOk, sMyWarn, bPrevBhSideMill = MakeMoreFaces( AddProc, nPhase, nRawId, nPartId, dOvmHead, false, bPrevBhSideMill) + if not sWarn then sWarn = sMyWarn end + if not bOk then return bOk, sWarn end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function TestTwoFacesDownHead( Proc) + -- verifico ci siano due facce + if Proc.Fct ~= 2 then return false end + -- verifico se da lavorare con testa da sotto + local bDownHead = false + if BD.DOWN_HEAD then + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + bDownHead = ( vtNm:getZ() < -0.5) + end + return bDownHead +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +--------------------------------------------------------------------- +function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- setto a nil la variabile smussi + bMadeChamfer = nil + -- limiti di fresatura semplice + local MAX_MILL_LIN = 80 + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQIdent( Proc) + -- se non forzate frese, uso la lama + local bUseBlade = EgtGetInfo( Proc.Id, Q_USE_ROUGH_TOOL, 'i') ~= 1 and EgtGetInfo( Proc.Id, Q_USE_MILL, 'i') ~= 1 + local nForceUseBladeOnNotContinueFace + -- se ho attivo la lama e ho la feature 30, verifico i parametri Q propri della feature + if bUseBlade then + if Proc.Prc == 30 then + local nBladeAntisplint = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0 + local nUseRoughToolOnSide = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0 + nForceUseBladeOnNotContinueFace = EgtGetInfo( Proc.Id, Q_BLADE_ON_ALONG_FACE, 'i') or 0 + -- se antischeggia di fresa o abilitato sgrossatore di fianco + if nBladeAntisplint == 2 or nUseRoughToolOnSide == 1 then + bUseBlade = false + end + -- se ho attivo la lama e ho la feature 32, verifico i parametri Q propri della feature + elseif Proc.Prc == 32 then + local nBladeAntisplint = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0 + local nUseRoughToolOnSide = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0 + -- se antischeggia di fresa o abilitato sgrossatore di fianco + if nBladeAntisplint == 2 or nUseRoughToolOnSide == 1 then + bUseBlade = false + end + -- se ho attivo la lama e ho la feature 34, verifico i parametri Q propri della feature + elseif Proc.Prc == 34 then + local nBladeAntisplint = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') or 0 + -- se antischeggia di fresa o abilitato sgrossatore di fianco + if nBladeAntisplint == 2 then + bUseBlade = false + end + end + end + -- se lunghezza richiede spezzatura + if ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or + ( Proc.Box:getDimX() > 0.7 * b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN) then + -- una faccia + if Proc.Fct == 1 then + if bUseBlade then + if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + end + else + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + end + -- due facce + elseif Proc.Fct == 2 then + -- verifico se da lavorare con testa da sotto + local bDownHead = TestTwoFacesDownHead( Proc) + -- determino se due facce lunghe oppure una lunga e l'altra terminale + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) + local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD) + if abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 and abs( b3Fac1:getCenter():getX() - b3Fac2:getCenter():getX()) < 50 then + -- leggo i parametri Q per utilizzare la fresa di fianco e/o lama + local nUseSideTool = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0 + local bUseBlade = EgtGetInfo( Proc.Id, Q_ANTISPLINT_TYPE, 'i') == 1 + return Long2Cut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nUseSideTool) + elseif b3Fac1:getDimX() < 1 then + -- la faccia 0 deve essere quella lunga + EgtSurfTmSwapFacets( Proc.Id, 0, 1) + if bUseBlade then + if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead) + end + else + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + end + elseif b3Fac2:getDimX() < 1 then + if bUseBlade then + if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead) + end + else + return LongCut.Make( Proc, nPhase, nRawId, nPartId) + end + else + if bUseBlade then + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead) + else + return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + end + end + -- tre facce + elseif Proc.Fct == 3 then + -- determino se due facce lunghe oppure una lunga e l'altra terminale + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) + local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD) + local b3Fac3 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 2, GDB_BB.STANDARD) + local bApplyBladeOnLongNotContinueFace + + if b3Fac1:getDimX() < 1 and b3Fac3:getDimX() < 1 then + -- la faccia 0 deve essere quella lunga + EgtSurfTmSwapFacets( Proc.Id, 0, 1) + bApplyBladeOnLongNotContinueFace = true + elseif b3Fac1:getDimX() < 1 and b3Fac2:getDimX() < 1 then + -- la faccia 0 deve essere quella lunga + EgtSurfTmSwapFacets( Proc.Id, 0, 2) + bApplyBladeOnLongNotContinueFace = true + elseif b3Fac2:getDimX() < 1 and b3Fac3:getDimX() < 1 then + bApplyBladeOnLongNotContinueFace = true + end + + if bApplyBladeOnLongNotContinueFace and bUseBlade and nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + end + -- più facce + else + return MakeLongMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + end + -- altrimenti lavorazione unica + else + -- una faccia + if Proc.Fct == 1 then + -- se piccola, con fresa + if not bUseBlade and ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then + return MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) + -- altrimenti, con lama + else + return Cut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + end + -- due facce + elseif Proc.Fct == 2 then + -- se praticamente è lunga come la trave e sono due facce lunghe + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) + local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD) + if Proc.Box:getDimX() > 0.8 * b3Solid:getDimX() and + abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 and abs( b3Fac1:getCenter():getX() - b3Fac2:getCenter():getX()) < 50 then + local nUseSideTool = EgtGetInfo( Proc.Id, Q_SIDE_ROUGH_TOOL, 'i') or 0 + return Long2Cut.Make( Proc, nPhase, nRawId, nPartId, bUseBlade, nUseSideTool) + -- altrimenti + else + -- verifico se da lavorare con testa da sotto + local bDownHead = TestTwoFacesDownHead( Proc) + -- determino l'angolo tra le facce + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + -- se con BH + if VerifyBHSideMill( Proc) then + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, true) + -- se ortogonali e non forzata lama, con fresa + elseif not bUseBlade and bAdj and abs( dAng + 90) < 1 then + -- se piccole + if Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN) then + return MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId, bDownHead) + else + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, true) + end + -- altrimenti, con lama + else + -- verifico se devo fare prima gli smussi + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifiche per smusso + local nChamfer, dDepthCham, sErrCham = EvaluateQParam( Proc) + -- se smusso da fare + if nChamfer > 0 then + local _, _, _, vtOrtho, _, nSurfInt = GetTunnelDimension( Proc, nPartId) + local nOk, sErr = MakeChamfer( Proc, true, nAddGrpId, vtOrtho, b3Solid, nSurfInt, dDepthCham) + if nOk < 0 then return false, sErr end + end + -- se smusso non esclusivo + if nChamfer < 2 then + return Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead) + end + return true + end + end + -- tre o più facce + else + return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, true) + end + end +end + +--------------------------------------------------------------------- +return ProcessLapJoint diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLapJointNew.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLapJointNew.lua new file mode 100644 index 0000000..2eb55f7 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLapJointNew.lua @@ -0,0 +1,5177 @@ +-- ProcessLapJoint.lua by Egaltech s.r.l. 2022/01/28 +-- Gestione calcolo mezzo-legno per Travi +-- 2019/10/08 Agg. gestione OpenPocket. +-- 2021/01/24 Con sega a catena ora sempre impostato asse A. +-- 2021/02/03 Corretto riconoscimento feature di coda. +-- 2021/02/04 Razionalizzata gestione forzatura lama. Corretta gestione diametro minimo utensile per svuotatura. +-- 2021/03/04 Due facce con testa da sotto. +-- 2021/03/20 Piccole correzioni. +-- 2021/03/22 Modificata gestione caso due facce lunghe come la trave con trave corta. +-- 2021/04/13 Modificata gestione fessura U con sega a catena (corta ora ok, lunga ancora da correggere). +-- 2021/04/14 Correzioni ribasso a U con fresa da sotto. +-- 2021/04/15 Aggiunta gestione massima lunghezza fresa da sotto su svuotature. +-- 2021/04/21 Anche feature lunga con due facce con opzione lama ora si taglia con lama. +-- 2021/04/23 Corretto caso con antischeggia non inseriti perchè inutili. +-- 2021/04/27 Antischeggia solo se feature trasversali. +-- 2021/05/12 Semplificata gestione diametro minimo utensile per svuotatura. +-- 2021/06/04 Su U passante con faccia perpendicolare aggiunta si forza Pocket. +-- 2021/06/11 Su U passante e profonda se non bastano due svuotature su faccia ortogonale si fa anche la faccia di fondo per quanto possibile. +-- 2021/06/21 Nel caso precedente si fa la terza svuotatura anche se è possibile fare una sola delle prime due (altra da sotto). +-- 2021/06/21 Gestione ripresa spigoli o contorno con fresa più piccola ( diametro < 3/4 utensile svuotatura) attivata da parametro Q. +-- 2021/07/02 Migliorie e correzioni su svuotature e pulitura spigoli. +-- 2021/07/15 Aggiunti antischeggia con fresa. +-- 2021/09/08 Aggiunta gestione parametro Q04 per i tagli di lama lungo facce lunghe (con o senza facce di chiusura) +-- 2021/09/21 Aggiunta lavorazione/opzione "lamello" con le feature 16, 30, 32, 39, +-- che si attiva abilitando il check al tipo milling: SideMillAsBlade (SideMillAsBlade_2) +-- 2021/09/23 Gestione migliorata lavorazioni BH (blockhaus) su macchina fast BH, +-- migliorata applicazione lavorazioni BH su feature lunghe lavorte a passi +-- 2021/10/06 Ad antischeggia con lama in presenza di testa da sotto aggiunta preferenza a testa da sopra. +-- 2021/10/19 Corretta gestione inversione per Tunnel. OpenPocket anche se spezzato ma 1 o 2 facce. Introdotta lunghezza minima per lamello. +-- 2021/10/21 Migliorato controllo affondamento utensile in U lavorato da 3 parti (anche da sotto). +-- 2021/10/27 Migliorato calcolo asse tunnel o similare. +-- 2021/11/02 In svuotatura con lati aperti diametro fresa non superiore al doppio del lato piccolo. +-- 2021/11/15 Quando si usa sega a catena uso Q10 come massima elevazione. +-- 2021/11/22 Corretta segnalazione warning su foro di L20 e L25. +-- 2021/12/17 Lettura parametri Q una volta sola all'inizio. +-- 2022/01/13 Estrapolazione da MakeMoreFaces() di MakeTwoFaces() e MakeThreeFaces(), e varie ottimizzazioni. +-- 2022/01/19 Cambiata % lunghezza pezzo per spezzatura. Tolta correzione spessore fresa a disco con superficie da lavorare verso Z-. +-- 2022/01/26 Migliorato controllo uso testa da sotto nel caso due facce con lama. +-- 2022/01/28 Aggiunte funzioni DoClean, DoPocketing, DoHeadChainSaw, DoSideChainSaw e DoHeadCut. + +-- Tabella per definizione modulo +local ProcessLapJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local Cut = require( 'ProcessCut') +local DoubleCut = require( 'ProcessDoubleCut') +local LongCut = require( 'ProcessLongCut') +local Long2Cut = require( 'ProcessLongDoubleCut') + +EgtOutLog( ' ProcessLapJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local Q_FORCE_BLADE = nil -- i +local Q_DEPTH_CHAMFER = 0.0 -- d +local Q_MAX_ELEVATION = 0.0 -- d +local Q_ONLY_CHAMFER = 0 -- i +local Q_USE_MILL = 0 -- i +local Q_USE_ROUGH_TOOL = 0 -- i +local Q_USE_ROUGH_TOOL_B90 = 0 -- i +local Q_USE_ROUGH_TOOL_B0 = 0 -- i +local Q_BORE_ON_CORNER = 0 -- i +local Q_CONTOUR_SMALL_TOOL = 0 -- i +local Q_ONLY_CONTOUR = 0 -- i +local Q_SIDE_ROUGH_TOOL = 0 -- i +local Q_ANTISPLINT_TYPE = 0 -- i +local Q_BLADE_ON_ALONG_FACE = 0 -- i + +-- variabile smussi +local _bMadeChamfer +local _nChamfer, _dDepthCham, _sErrCham, _bForceUseBlade + +-- Settaggi interni +local _bTrySidePocketAtFirst = true +local _nPhase, _nRawId, _nPartId, _dOvmHead +local _b3Raw, _b3Solid +local _nAddGrpId + + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLapJoint.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 33) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or + ( Proc.Grp == 4 and Proc.Prc == 37) or + ( Proc.Grp == 4 and Proc.Prc == 39) or + ( Proc.Grp == 4 and Proc.Prc == 120)) +end + +--------------------------------------------------------------------- +local function AssignQValues( Proc) + -- reset assegnazione parametri Q + Q_FORCE_BLADE = nil + Q_BLADE_ON_ALONG_FACE = 0 + Q_DEPTH_CHAMFER = 0.0 + Q_ONLY_CHAMFER = 0 + Q_USE_MILL = 0 + Q_USE_ROUGH_TOOL = 0 + Q_USE_ROUGH_TOOL_B90 = 0 + Q_USE_ROUGH_TOOL_B0 = 0 + Q_BORE_ON_CORNER = 0 + Q_CONTOUR_SMALL_TOOL = 0 + Q_ONLY_CONTOUR = 0 + Q_SIDE_ROUGH_TOOL = 0 + Q_ANTISPLINT_TYPE = 0 + Q_MAX_ELEVATION = EgtGetInfo( Proc.Id, 'Q10', 'd') or 0.0 + + if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then + Q_FORCE_BLADE = EgtGetInfo( Proc.Id, 'Q01', 'i') -- can be nil + Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q04', 'd') or 0.0 + Q_ONLY_CHAMFER = EgtGetInfo( Proc.Id, 'Q05', 'i') or 0 + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then + Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0.0 + Q_ONLY_CHAMFER = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then + Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0.0 + Q_USE_MILL = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 + Q_USE_ROUGH_TOOL = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0 + Q_USE_ROUGH_TOOL_B90 = EgtGetInfo( Proc.Id, 'Q04', 'i') or 0 + Q_USE_ROUGH_TOOL_B0 = EgtGetInfo( Proc.Id, 'Q05', 'i') or 0 + Q_BORE_ON_CORNER = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0 + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25 then + Q_BORE_ON_CORNER = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0 + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then + Q_CONTOUR_SMALL_TOOL = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0 + Q_ONLY_CONTOUR = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 + Q_SIDE_ROUGH_TOOL = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0 + Q_BLADE_ON_ALONG_FACE = EgtGetInfo( Proc.Id, 'Q04', 'i') or 0 + Q_ANTISPLINT_TYPE = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0 + Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q07', 'd') or 0.0 + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then + Q_SIDE_ROUGH_TOOL = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0 + Q_CONTOUR_SMALL_TOOL = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 + Q_ANTISPLINT_TYPE = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0 + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34 then + Q_CONTOUR_SMALL_TOOL = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0 + Q_ANTISPLINT_TYPE = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0 + end +end + +--------------------------------------------------------------------- +local function EvaluateChamfer() + local sErr + -- verifico che lo smusso sia richiesto + local nChamfer = 0 + if Q_DEPTH_CHAMFER > 0 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if Q_ONLY_CHAMFER == 1 then + if Q_DEPTH_CHAMFER > 0 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- verifico se devo usare lama invece della sega-catena + -- 2020-03-20 forzata abilitazione uso lama se parametro Q non è presente + -- xxxx-xx-xx tolta la preferenza alla lama in favore della sega-catena per un caso particolare + -- 2021-02-15 re-introdotta la preferenza alla lama se non c'è il parametro Q. Rimane da + -- implementare un ulteriore parametro per poter scegliere di prediligere la sega-catena o no al fine di continuare + -- a cambiare il codice per gestire il caso particolare + local bForceUseBlade = false + if Q_FORCE_BLADE == nil or Q_FORCE_BLADE == 1 then + bForceUseBlade = true + end + + return nChamfer, dDepth, sErr, bForceUseBlade +end + +--------------------------------------------------------------------- +local function InitGlob( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not Proc then + return false, 'Error : Proc is missing' + end + + -- setto a nil la variabile smussi + _bMadeChamfer = nil + _nPhase = nPhase + _nRawId = nRawId + _nPartId = nPartId + _dOvmHead = dOvmHead + + if _nRawId then + -- recupero l'ingombro del grezzo di appartenenza + _b3Raw = EgtGetRawPartBBox( _nRawId) + end + + if not _nPartId then + _nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL) + end + + if _nPartId then + -- recupero gruppo per geometria addizionale + _nAddGrpId = BL.GetAddGroup( _nPartId) + -- recupero l'ingombro della trave + _b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( _nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + else + local sErr = 'Error : part ID not found' + EgtOutLog( sErr) + return false, sErr + end + + if not _b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + + if not _nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + + -- leggo i valori dei parametri Q + AssignQValues( Proc) + -- verifico se sono presenti i parametri per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + _nChamfer, _dDepthCham, _sErrCham, _bForceUseBlade = EvaluateChamfer() + + return true, '' +end + +--------------------------------------------------------------------- +local function UpdateFacet1Data( nProcId, tFData, nFacInd, dFacElev) + if not tFData then + tFData = {} + end + tFData.nFacInd = nFacInd + if dFacElev then + tFData.dFacElev = dFacElev + end + if tFData.nFacInd and tFData.nFacInd > -1 then + tFData.ptC, tFData.vtN = EgtSurfTmFacetCenter( nProcId, tFData.nFacInd, GDB_ID.ROOT) + tFData.rfFac, tFData.dH, tFData.dV = EgtSurfTmFacetMinAreaRectangle( nProcId, tFData.nFacInd, GDB_ID.ROOT) + end + return tFData +end + +--------------------------------------------------------------------- +local function UpdateFacet2Data( nProcId, tFData, nFacInd2, dFacElev2) + if not tFData then + tFData = {} + end + tFData.nFacInd2 = nFacInd2 + if dFacElev2 then + tFData.dFacElev2 = dFacElev2 + end + if tFData.nFacInd2 and tFData.nFacInd2 ~= true and tFData.nFacInd2 > -1 then + tFData.ptC2, tFData.vtN2 = EgtSurfTmFacetCenter( nProcId, tFData.nFacInd2, GDB_ID.ROOT) + tFData.rfFac2, tFData.dH2, tFData.dV2 = EgtSurfTmFacetMinAreaRectangle( nProcId, tFData.nFacInd2, GDB_ID.ROOT) + end + return tFData +end + +--------------------------------------------------------------------- +local function GetFacetsData( nProcId) + local tFData = {} + local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( nProcId, _nPartId) + if nFacInd then + tFData = UpdateFacet1Data( nProcId, tFData, nFacInd, dFacElev) + tFData = UpdateFacet2Data( nProcId, tFData, nFacInd2, dFacElev2) + if tFData.nFacInd == -1 and tFData.nFacInd2 and tFData.nFacInd2 == true then + tFData.isOrthoFaces = true + end + end + return tFData +end + +--------------------------------------------------------------------- +local function SwapFacetsData( tFData) + if tFData then + tFData.nFacInd, tFData.nFacInd2 = tFData.nFacInd2, tFData.nFacInd + tFData.dFacElev, tFData.dFacElev2 = tFData.dFacElev2, tFData.dFacElev + tFData.ptC, tFData.ptC2 = tFData.ptC2, tFData.ptC + tFData.vtN, tFData.vtN2 = tFData.vtN2, tFData.vtN + tFData.rfFac, tFData.rfFac2 = tFData.rfFac2, tFData.rfFac + tFData.dH, tFData.dH2 = tFData.dH2, tFData.dH + tFData.dV, tFData.dV2 = tFData.dV2, tFData.dV + end + return tFData +end + +--------------------------------------------------------------------- +local function GetToolInfoForMachining( sMachiningName) + if EgtMdbSetCurrMachining( sMachiningName) then + local toolInfo = {} + toolInfo.sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( toolInfo.sTuuid) or '') then + toolInfo.dLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) + toolInfo.dDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + toolInfo.dThDiam = EgtTdbGetCurrToolThDiam() + toolInfo.dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + toolInfo.dMaxDepth = EgtTdbGetCurrToolMaxDepth() + toolInfo.dSideDepth = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') + toolInfo.dCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) + toolInfo.dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) + return toolInfo + end + end + return nil +end + +--------------------------------------------------------------------- +local function FormatWarning( sWarn, sWarn2) + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + return sWarn +end + +--------------------------------------------------------------------- +-- Restituisce solo gli indici delle facce adiacenti esistenti (no -1) +local function GetValidFacetAdjacencies( nSurfId, nFacet) + local vValidAdj + local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, nFacet)[1] + + if vFacAdj then + vValidAdj = {} + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + table.insert( vValidAdj, vFacAdj[j]) + end + end + end + + return vValidAdj +end + +--------------------------------------------------------------------- +local function TestElleShape3( Proc, bNotProc) + local nNumFacet + local nProcId + -- se non passato il Proc vero e proprio + if bNotProc then + nProcId = Proc + nNumFacet = EgtSurfTmFacetCount( nProcId) + else + nProcId = Proc.Id + nNumFacet = Proc.Fct + end + -- valida solo nel caso di tre facce + if nNumFacet ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + -- conto le facce adiacenti (solo quelle valide) + local vFacAdj = GetValidFacetAdjacencies( nProcId, i - 1) + if #vFacAdj == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +local function TestElleShape4( Proc) + -- valida solo nel caso di quattro facce + if Proc.Fct ~= 4 then return false end + -- determino se L con due facce terminali o O + local nFac3Adj = 0 + local dMinArea3 = GEO.INFINITO * GEO.INFINITO + local dMaxArea2 = 0 + for i = 1, 4 do + -- conto le facce adiacenti (solo quelle valide) + local vFacAdj = GetValidFacetAdjacencies( Proc.Id, i - 1) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, i - 1, GDB_ID.ROOT) + local dArea = dH * dV + if #vFacAdj == 2 then + dMaxArea2 = max( dMaxArea2, dArea) + elseif #vFacAdj == 3 then + dMinArea3 = min( dMinArea3, dArea) + nFac3Adj = nFac3Adj + 1 + end + end + if nFac3Adj ~= 2 then return false end + -- verifico se L profonda oppure lunga + if dMinArea3 < 2 * dMaxArea2 then + return 1 + else + return 2 + end +end + +--------------------------------------------------------------------- +--- Test per facce a forma di U o a forma di L +local function TestUL( Proc) + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) + -- verifico se due facce o L con una o due facce di terminazione + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc) or TestElleShape4( Proc) == 2) + + return bIsU, bIsL +end + +--------------------------------------------------------------------- +local function GetIdIniEndPoints( ptP1, ptP2, tFac) + local nIdIniPoint + local nIdEndPoint + if ptP1 and ptP2 then + if dist( ptP1, tFac[4]) < GEO.EPS_SMALL or dist( ptP2, tFac[4]) < GEO.EPS_SMALL then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif dist( ptP1, tFac[5]) < GEO.EPS_SMALL or dist( ptP2, tFac[5]) < GEO.EPS_SMALL then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + return nIdIniPoint, nIdEndPoint +end + +--------------------------------------------------------------------- +local function GetChainSawBlockedAxis( nInd) + if BD.GetChainSawBlockedAxis then + return BD.GetChainSawBlockedAxis( nInd) + else + if nInd == 1 then + return EgtIf( BD.C_SIMM, 'A=90', 'A=0') + else + return EgtIf( BD.C_SIMM, 'A=0', 'A=90') + end + end +end + +--------------------------------------------------------------------- +local function GetChainSawInitAngs( vtN, vtO) + if BD.GetChainSawInitAngs then + return BD.GetChainSawInitAngs( vtN, vtO) + else + if BD.C_SIMM then + if vtN:getY() > 0 then + return 'C=180' + else + return 'C=-180' + end + else + return '' + end + end +end + +--------------------------------------------------------------------- +local function VerifyChainSaw( dMinDim, dMaxDim) + local bUseChainSaw = false + local sMchFind = 'Sawing' + local sSawing = ML.FindSawing( sMchFind) + local dMaxMat = 0 + local dSawCornerRad = 0 + local dSawThick = 0 + local dMaxDepth = 200 + -- se non trova una lavorazione di sawing esco + if not sSawing then + return bUseChainSaw + else + -- recupero i dati dell'utensile + local dToolLength = 0 + local dSawWidth = 75 + local TI = GetToolInfoForMachining( sSawing) + if TI then + dToolLength = TI.dLength or dToolLength + dMaxMat = TI.dMaxMat or dMaxMat + dSawWidth = TI.dDiam or dSawWidth + dSawThick = TI.dThick or dSawThick + dSawCornerRad = TI.dCornerRad or dSawCornerRad + dMaxDepth = TI.dMaxDepth or dMaxDepth + if dSawThick < ( dMinDim + 10 * GEO.EPS_SMALL) and dSawWidth < ( dMaxDim + 10 * GEO.EPS_SMALL) then + bUseChainSaw = true + end + end + end + return bUseChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick, dMaxDepth +end + +--------------------------------------------------------------------- +local function VerifyPocket( dDiam, dDepth, dMaxTotLen, sMchFindMaster) + -- tipo di svuotatura + local sMchFind = EgtIf( sMchFindMaster and #sMchFindMaster > 0, sMchFindMaster, 'Pocket') + -- ricerca della svuotatura + local sPocketing + if dDepth then + sPocketing = ML.FindPocketing( sMchFind, dDiam, dDepth, dMaxTotLen) or + ML.FindPocketing( sMchFind, dDiam, 0.8 * dDepth, dMaxTotLen) or + ML.FindPocketing( sMchFind, dDiam, 0.6 * dDepth, dMaxTotLen) or + ML.FindPocketing( sMchFind, dDiam, 0.4 * dDepth, dMaxTotLen) or + ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen) + else + sPocketing = ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen) + end + if not sPocketing then + return false + end + -- recupero i dati dell'utensile + local bUsePocketing = false + local dMaxDepth = 0 + local dToolDiam = 0 + local TI = GetToolInfoForMachining( sPocketing) + if TI then + dToolDiam = TI.dDiam or dToolDiam + dMaxDepth = TI.dMaxDepth or dMaxDepth + bUsePocketing = true + end + return bUsePocketing, sPocketing, dMaxDepth, dToolDiam +end + +--------------------------------------------------------------------- +local function VerifyBHSideMill( Proc, bSinglePart, bPrevBhSideMill) + + local bUseBHSideMill = false + local bHead = true + local bHeadDir = true + local sMilling + local dThickTool = 0 + local dToolDiam = 0 + -- 22/09/2021 Su richiesta di Alessandro Sola, si toglie la richiesta di presenza del parametro Q per poter applicare + -- la lavorazione su più features (che non hanno questo parametro Q), quindi questa lavorazione viene verificata se è abilitato il parametro utensile + -- che ovviamente tramite la lavorazione è abbinata alla lista lavorazioni con BHSideMill. + -- Al fine di mantenere il funzionamento precedente (purtroppo non sono stati descritti i motivi del confrontare il parametro Q) + -- si elude il controllo del Q solo se la variabile del Beamdata BD.BH_MACHINE segnala che non è una macchina tipo BH (ha la fresa blockhaus al posto della lama) + + -- se non feature BlockHausHalfLap o non abilitato parametro Q per lavorarlo di fianco esco + if Proc.Prc ~= 37 and Q_SIDE_ROUGH_TOOL == 0 and not BD.BH_MACHINE then + return false + end + -- verifico se U o L + local bIsU, bIsL = TestUL( Proc) + -- verifico se la funzione è lanciata da IsTailFeature o Classify + if bSinglePart == nil then + -- se lunghezza non richiede spezzatura setto la variabile bSinglePart per non fare con fresa BH + -- perchè deve avere almeno 2 facce + if not ( ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or + ( Proc.Box:getDimX() > 0.8 * _b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN)) then + bSinglePart = true + end + end + -- ad oggi 22/09/2021 la lavorazione BH non va bene se le facce di chiusura non sono perpendicolari a X, quindi + -- se non sono perpendicolari non si applica la lavorazione BH + if bIsU or bIsL then + local bExit = false + for i = 1, Proc.Fct do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + if abs( vtN:getX()) > 0.001 and abs( vtN:getX()) < 0.999962 then + bExit = true + break + end + end + if bExit then + return false + end + end + + -- se forma a U o L verifico che + -- se U e lunghezza non richiede spezzatura + if ( bIsU or bIsL or ( Proc.Fct == 1 and not bSinglePart)) and Proc.Box:getDimX() <= BD.LONGCUT_MAXLEN then + -- se faccia singola di un passo multiplo e risultato precedente non applicato, riporto il risultato del passo precedente + if ( bIsU or bIsL or ( Proc.Fct == 1 and not bSinglePart)) and bPrevBhSideMill ~= nil and not bPrevBhSideMill then + return false + end + -- recupero la lavorazione + sMilling = ML.FindMilling( 'BHSideMill') + if sMilling then + -- recupero i dati dell'utensile + local dToolLength = 0 + local dMaxDepth = 0 + local TI = GetToolInfoForMachining( sMilling) + if TI then + dToolLength = TI.dLength or dToolLength + dToolDiam = TI.dDiam or dToolDiam + dMaxDepth = TI.dMaxDepth or dMaxDepth + dThickTool = TI.dThick or dThickTool + end + -- verifico se la feature è abbastanza vicino a testa/coda da permettere la lavorazione con questo utensile + if _b3Solid then + local dMinXF = Proc.Box:getMin():getX() + local dMaxXF = Proc.Box:getMax():getX() + local dMinT = _b3Solid:getMin():getX() + local dMaxT = _b3Solid:getMax():getX() + -- determino se è più vicino alla testa o al bordo (con offset per evitare problemi a metà) + bHeadDir = ( dMaxT - dMinXF) < ( dMaxXF - dMinT) + 50 + bHead = bHeadDir + -- determino se è compatibile con il massimo affondamento dell'utensile + -- nota F.M il 22/09/2021: non sarebbe meglio utilizzare lo spessore lama invece della massima lavorazione? + -- questo perchè Alessandro ha settato il parametro Max Material a 80 con spessore lama 42 + -- se invece il Max material viene usato per definire fino a che affondamento (lungo l'asse utensile) + -- può arrivare prima di collidere con la testa allora si può utilizzare il dMaxDepth + bUseBHSideMill = EgtIf( bHead, ( dMaxT - dMinXF), ( dMaxXF - dMinT)) < dMaxDepth + -- se diametro maggiore della testa + if BD.HEAD_DIM_FOR_BH and dToolDiam > BD.HEAD_DIM_FOR_BH then + bHead = true + bUseBHSideMill = true + end + end + end + end + return bUseBHSideMill, bHead, bHeadDir, sMilling, dThickTool, dToolDiam +end + +--------------------------------------------------------------------- +local function GetTunnelDimension( Proc) + -- sono necessarie almeno due facce + if Proc.Fct < 2 then return 0, 0, 0 end + -- recupero centro e normale delle facce + local ptC = {} + local vtN = {} + for i = 1, Proc.Fct do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + end + -- calcolo l'orientamento del tunnel + local vtOrtho + local bAdj = EgtSurfTmFacetsContact( Proc.Id, 0, 1) + if bAdj then + vtOrtho = vtN[1] ^ vtN[2] + else + if Proc.Fct >= 3 then + vtOrtho = vtN[1] ^ vtN[3] + else + return 0, 0, 0 + end + end + -- ottengo il boundingBox e prendo le dimensioni lungo la direzione (Z locale) che rappresenta la profondità della fessura + local frFc = Frame3d( ptC[1], vtOrtho) + local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) + local dDepth = b3BoxLoc:getDimZ() + -- centro del bounding box locale + local ptCen = b3BoxLoc:getCenter() + ptCen:toGlob( frFc) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( _nAddGrpId, ptCen, vtOrtho, _b3Solid, GDB_ID.ROOT) + if not nSurfInt then return 0, 0, 0 end + -- ritaglio la superficie con le facce della fessura + for i = 1, Proc.Fct do + EgtCutSurfTmPlane( nSurfInt, ptC[i], -vtN[i], false, GDB_ID.ROOT) + end + local frSurfInt, dDimMax, dDimMin = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT) + -- cerco la faccia con larghezza pari a dimensione massima della fessura + local nLongFaceId = 0 + for i = 1, Proc.Fct do + if abs( vtN[i] * frSurfInt:getVersX()) < 0.5 then + nLongFaceId = i - 1 + break + end + end + return dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt +end + +--------------------------------------------------------------------- +local function GetFaceAdj( Proc, tFData) + -- Recupero le facce adiacenti alla principale (solo quelle esistenti) + local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd) + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + return -1, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 4) + -- Riordino le dimensioni per avere dH > dV + if tFData.dH < tFData.dV then + tFData.dH, tFData.dV = tFData.dV, tFData.dH + end + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj + for i = 1, #vAdj do + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > 0.5 * tFData.dH then + nFacAdj = vAdj[i] + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, tFData.dH, tFData.dV), 4) + break + end + end + if not nFacAdj then + local sErr = 'Error : main face without long adjacent face' + return -1, sErr + end + return nFacAdj +end + +--------------------------------------------------------------------- +local function CalcCollisionSafety( vtDir) + local dCollSic = 10 * BD.COLL_SIC + if abs( vtDir:getX()) > 0.999 or abs( vtDir:getY()) > 0.999 or abs( vtDir:getZ()) > 0.999 then + dCollSic = 0 + elseif abs( vtDir:getX()) > 0.996 or abs( vtDir:getY()) > 0.996 or abs( vtDir:getZ()) > 0.996 then + dCollSic = 1 * BD.COLL_SIC + elseif abs( vtDir:getX()) > 0.89 or abs( vtDir:getY()) > 0.89 or abs( vtDir:getZ()) > 0.89 then + dCollSic = 2.5 * BD.COLL_SIC + elseif abs( vtDir:getX()) > 0.866 or abs( vtDir:getY()) > 0.866 or abs( vtDir:getZ()) > 0.866 then + dCollSic = 4 * BD.COLL_SIC + elseif abs( vtDir:getX()) > 0.707 or abs( vtDir:getY()) > 0.707 or abs( vtDir:getZ()) > 0.707 then + dCollSic = 5.5 * BD.COLL_SIC + end + return dCollSic +end + +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + if not InitGlob( Proc) then + return false + end + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() > 0.1 then + return true + end + end + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then + return false + end + -- se una o due facce e interessa veramente la testa, allora di testa + if Proc.Fct <= 2 then + if Proc.Box:getMax():getX() > _b3Solid:getMax():getX() - 1. then + return true + elseif Proc.Box:getMax():getX() < _b3Solid:getMax():getX() - 5. then + return false + end + end + local tFData = GetFacetsData( Proc.Id) + -- deve avere la normale principale diretta verso la testa + if tFData.vtN and tFData.vtN:getX() < 0.499 then + return false + elseif Proc.Fct >= 5 then + return true + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessLapJoint.IsTailFeature( Proc, b3Raw) + if not InitGlob( Proc) then + return false + end + -- se una sola faccia + if Proc.Fct == 1 then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN0:getX() < -0.1 then + return true + end + end + -- se può essere fatto con utensile tipo lama + local bUseBHSideMill, bHead, bHeadDir = VerifyBHSideMill( Proc) + if bUseBHSideMill then + Proc.HeadDir = bHeadDir + return not bHead + end + -- verifico se è in coda + local dEndDist = Proc.Box:getMin():getX() - _b3Solid:getMin():getX() + if dEndDist > BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave + if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then + return false + end + -- se una o due facce e interessa veramente la coda, allora di coda + if Proc.Fct <= 2 then + if Proc.Box:getMin():getX() < _b3Solid:getMin():getX() + 1. then + return true + elseif Proc.Box:getMin():getX() > _b3Solid:getMin():getX() + 5. then + return false + end + end + local tFData = GetFacetsData( Proc.Id) + -- deve avere la normale principale diretta verso la coda (oppure tunnel) + if tFData.vtN and tFData.vtN:getZ() < BD.NZ_MINA and tFData.nFacInd2 then + tFData = SwapFacetsData( tFData) + end + if not tFData.vtN or tFData.vtN:getX() > -0.001 or dEndDist + tFData.vtN:getX() * tFData.dFacElev > 0 then + return false + else + return true + end +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLapJoint.Classify( Proc, b3Raw) + if not InitGlob( Proc) then + return false + end + -- se 1 faccia + if Proc.Fct == 1 then + -- dati della faccia + --local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + --local bDown = ( vtN:getZ() < BD.NZ_MINA) + --return true, bDown + return true, false + -- se 2 facce + elseif Proc.Fct == 2 then + -- dati delle facce + local vtN = {} + _, vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + _, vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bSmall = ( ( Proc.Head or Proc.Tail) and Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) or + ( not ( Proc.Head or Proc.Tail) and Proc.Box:getDimY() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) + local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or + ( vtN[1]:getZ() < BD.NZ_MINA and ( vtN[2]:getZ() < -0.1 or not bSmall)) or + ( vtN[2]:getZ() < BD.NZ_MINA and ( vtN[1]:getZ() < -0.1 or not bSmall)) + bDown = ( bDown and not BD.DOWN_HEAD) + return true, bDown + -- se più di 2 facce + else + local bClosedOrthoFaces + local nDeletedFace + local tFData = GetFacetsData( Proc.Id) + if not tFData.nFacInd or tFData.nFacInd < 0 then + if tFData.nFacInd == -1 then + bClosedOrthoFaces = tFData.isOrthoFaces + else + return false + end + end + -- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche + if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then + -- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura + for i = 1, Proc.Fct do + local nNewProc = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL + -- elimino una faccia + nDeletedFace = i - 1 + if EgtSurfTmRemoveFacet( nNewProc, nDeletedFace) then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + tFData = GetFacetsData( nNewProc) + if not tFData.nFacInd or tFData.nFacInd < 0 then + if tFData.nFacInd == -1 then + bClosedOrthoFaces = tFData.isOrthoFaces + EgtErase( nNewProc) + break + else + EgtErase( nNewProc) + return false + end + end + -- altrimenti esco + else + EgtErase( nNewProc) + break + end + end + -- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo + if bClosedOrthoFaces then + tFData = UpdateFacet1Data( Proc.Id, tFData, nDeletedFace) + -- rendo nulla la faccia opzionale perchè si tratta di una fessura + tFData = UpdateFacet2Data( Proc.Id, tFData, nil) + bClosedOrthoFaces = false -- non lo setto come tunnel + end + end + -- se facce formano un tunnel e sono ortogonali + if bClosedOrthoFaces then + -- ottengo le dimensioni del tunnel + local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) + EgtErase( nSurfInt) + -- verifico se può essere fatto con svuotatura + if VerifyPocket( dDimMin) then + return true, false + elseif VerifyChainSaw( dDimMin, dDimMax) then + return true, false + else + return false + end + else + -- se può essere fatto con utensile tipo lama + local bUseBHSideMill, _, _, dMaxMat = VerifyBHSideMill( Proc) +-- if bUseBHSideMill and ( dMaxMat <= tFData.dV + 15 * GEO.EPS_SMALL) then + if bUseBHSideMill and ( dMaxMat <= tFData.dH + 15 * GEO.EPS_SMALL) then + return true, false + -- altrimenti controllo se deve essere ruotato con le altre lavorazioni + else + -- dati della faccia + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, tFData.nFacInd, GDB_ID.ROOT) + -- cerco se c'è faccia adiacente sul lato più lungo + local nFaceAdj = GetFaceAdj( Proc, tFData) or -1 + local _, bIsL = TestUL( Proc) + -- verifico se è lavorabile solo dal basso + local bDown = ( vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD) + -- se verso il basso, verifico se utilizzabile seconda faccia + if bDown then + if tFData.nFacInd2 and tFData.dFacElev2 < 2 * tFData.dFacElev then + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFData.nFacInd2, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINB) + elseif not tFData.nFacInd2 and bIsL and nFaceAdj >= 0 then + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINB) + end + -- verifico se la faccia principale è sottosquadra, ha forma L ed esiste la faccia adiacente + elseif vtN:getZ() < -0.2589 and bIsL and nFaceAdj >= 0 then + -- se il numero di facce > 2 o il box della feature supera una certa distanza dalle teste allora controllo la z della faccia ausiliaria + if Proc.Fct > 2 or ( Proc.Box:getMax():getX() < _b3Solid:getMin():getX() - 150) or ( Proc.Box:getMin():getX() > _b3Solid:getMax():getX() + 150) then + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT) + bDown = ( vtN2:getZ() < BD.NZ_MINB) + end + end + return true, bDown + end + end + end +end + +--------------------------------------------------------------------- +-- Lavorazione con fresa +--------------------------------------------------------------------- +local function MakeOneFaceByMill( Proc) + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- dati della faccia + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se orientata verso l'alto + local bUp = ( vtN:getZ() >= BD.NZ_MINA) + -- scelta faccia da lavorare + local nFacInd = 0 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'BirdsMouth') + if not sMilling then + local sErr = 'Error : BirdsMouth not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + if vtN:getX() > 0 then + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_LEFT, MCH_MILL_FU.PARAL_LEFT)) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.PARAL_RIGHT)) + end + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + if not bUp then EgtSetMachiningParam( MCH_MP.INVERT, true) end + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * _b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < _b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = _b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( _nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - _b3Solid:getMin():getX() + BL.UpdateTCING( _nRawId, dOffs) + end + end + return true +end + +--------------------------------------------------------------------- +local function DoMill( Proc, sName, sMilling, offset, nFacInd, nFac2Ind, vtN) + -- inserisco la lavorazione di fresatura + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + local nFaceUse = BL.GetNearestOrthoOpposite( vtN[nFac2Ind+1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- tolgo l'inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- aggiungo offset laterale + if offset then EgtSetMachiningParam( MCH_MP.OFFSR, offset) end + -- imposto posizione braccio porta testa + if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- dichiaro non si generano sfridi per VMill + EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + + return true +end + +--------------------------------------------------------------------- +local function MakeTwoFacesByMill( Proc, bDownHead) + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- recupero la lavorazione + local sMilling + if Q_USE_MILL and Q_USE_MILL == 1 then + sMilling = ML.FindMilling( 'LongSmallCut' .. EgtIf( bDownHead, '_H2', '')) + else + sMilling = ML.FindMilling( 'BirdsMouth' .. EgtIf( bDownHead, '_H2', '')) + end + if not sMilling then + local sErr = 'Error : LongSmallCut & BirdsMouth not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 0 + local TI = GetToolInfoForMachining( sMilling) + if TI then + dTDiam = TI.dDiam or dTDiam + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- dati medi + local ptM = ( ptC[1] + ptC[2]) / 2 + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bDownHead and not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error : LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- scelta faccia da lavorare + local nFacInd + -- se entrambe possibili + if bFaceOk[1] and bFaceOk[2] then + -- se in testa, scelgo quella orientata verso la testa + if Proc.Head then + if vtN[1]:getX() > vtN[2]:getX() then + nFacInd = 0 + else + nFacInd = 1 + end + -- se altrimenti in coda, scelgo quella orientata verso la coda + elseif Proc.Tail then + if vtN[1]:getX() < vtN[2]:getX() then + nFacInd = 0 + else + nFacInd = 1 + end + -- altrimenti, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+) + else + if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then + if ptM:getX() > _b3Raw:getCenter():getX() then + nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1) + else + nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1) + end + else + nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1) + end + end + elseif bFaceOk[1] then + nFacInd = 0 + else + nFacInd = 1 + end + local nOthInd = 1 - nFacInd + local bOk, sErr, sName + -- se forzato uso fresa controllo se posso fare in una o più passate + if Q_USE_MILL and Q_USE_MILL == 1 then + sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_1' + bOk, sErr = DoMill( Proc, sName, sMilling, dTDiam / 2, nFacInd, nOthInd, vtN) + + if not bOk then return bOk, sErr end + end + sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + bOk, sErr = DoMill( Proc, sName, sMilling, 0, nFacInd, nOthInd, vtN) + if not bOk then return bOk, sErr end + -- eventuale segnalazione ingombro di testa o coda + local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * _b3Raw:getDimZ()) + if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < _b3Raw:getMin():getZ() + dMinHIng then + if Proc.Head then + local dOffs = _b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( _nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - _b3Solid:getMin():getX() + BL.UpdateTCING( _nRawId, dOffs) + elseif Proc.Box:getCenter():getX() > _b3Solid:getCenter():getX() then + local dOffs = _b3Solid:getMax():getX() - Proc.Box:getMin():getX() + local dDist = _b3Solid:getMax():getX() - Proc.Box:getMax():getX() + -- sempre concavo aumento la distanza (rimane una punta...) + dDist = dDist + 10 + BL.UpdateHCING( _nRawId, dOffs, dDist) + end + end + return true +end + +--------------------------------------------------------------------- +local function MakePreCuts( Proc) + -- se interessa l'intera sezione della trave, necessaria sgrossatura + if _nChamfer < 2 and Proc.Box:getDimY() > 0.9 * _b3Raw:getDimY() and Proc.Box:getDimZ() > 0.9 * _b3Raw:getDimZ() then + -- aggiungo sgrossatura e la lavoro + local AddId = EgtSurfTmConvexHullInBBox( _nAddGrpId, Proc.Id, _b3Raw, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local nCutFacet = EgtSurfTmFacetCount( AddId) + if nCutFacet == 1 then + return Cut.Make( CutProc, _nPhase, _nRawId, _nPartId, _dOvmHead) + elseif nCutFacet == 2 then + return DoubleCut.Make( CutProc, _nPhase, _nRawId, _nPartId, _dOvmHead) + end + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, tFData, dCollSic, bSpecialApp, sMillMaster) + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj, sErr = GetFaceAdj( Proc, tFData) + if nFacAdj < 0 then + EgtOutLog( sErr) + return false, sErr + end + -- Determino se estremi aperti o chiusi e faccia adiacente da aggiungere alla lavorazione + local bOpenStart = false + local bOpenEnd = false + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) + local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacAdj, GDB_ID.ROOT) + -- Riordino le dimensioni per avere dH > dV + if dH2 < dV2 then + dH2, dV2 = dV2, dH2 + end + local nFacAdj2 + for j = 1, #vAdj2 do + if vAdj2[j] == tFData.nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == tFData.nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == tFData.nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + -- decommentare questa parte per concatenare due facce + --if bSpecialApp and vAdj2[j] >= 0 then + -- local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacAdj, vAdj2[j], GDB_ID.ROOT) + -- local dLen = dist( ptP1, ptP2) + -- if abs( dLen - dV2) < 10 * GEO.EPS_SMALL then + -- nFacAdj2 = vAdj2[j] + -- end + --end + end + -- Recupero la lavorazione di fresa + local sMilling + if bSpecialApp then + sMilling = sMillMaster + else + sMilling = ML.FindMilling( 'LongSmallCut') + if not sMilling then + sErr = 'Error : LongSmallCut not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dTDiam = 50 + local dMaxMat = 0 + local TI = GetToolInfoForMachining( sMilling) + if TI then + dTDiam = TI.dDiam or dTDiam + dMaxMat = TI.dMaxMat or dMaxMat + end + -- Se massimo materiale utensile è molto inferiore dell'elevazione non faccio la lavorazione e do un warning + if dMaxMat > 0 and dMaxMat + 15 < tFData.dFacElev + dCollSic then + local sWarn = 'Warning : skipped milling; elevation bigger than max tool depth' + return true, sWarn, dMaxMat + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( tFData.rfFac:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + if nFacAdj2 then + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}, { Proc.Id, nFacAdj2}}) + else + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + end + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if tFData.rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- lato di lavoro e direzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- tipo di attacco e uscita + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.LINEAR) + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + if bSpecialApp then + -- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita + if nFacAdj2 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2)) + -- confronto la faccia applicata nella lavorazione (faccia adiacente) con la seconda faccia passata nella funzione + -- se corrispondono allora aggiungo una estensione nei lati chiusi pari all'elevazione della stessa faccia corrispondente + if nFacAdj == tFData.nFacInd2 then + if not bOpenStart then + EgtSetMachiningParam( MCH_MP.LOPERP, tFData.dFacElev2) + EgtSetMachiningParam( MCH_MP.LOTANG, 0) + end + if not bOpenEnd then + EgtSetMachiningParam( MCH_MP.LIPERP, tFData.dFacElev2) + EgtSetMachiningParam( MCH_MP.LITANG, 0) + end + end + end + -- applico elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( tFData.dFacElev, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, 0, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, 0, - dTDiam / 2)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, '', dTDiam +end + +--------------------------------------------------------------------- +local function ChooseCorner( Proc, nFacInd) + -- Recupero le adiacenze della faccia principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + -- Cerco i corner tra le facce adiacenti alla principale + local tFacAdj = {} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + for j = i + 1, #vAdj do + if vAdj[j] >= 0 then + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vAdj[i], vAdj[j], GDB_ID.ROOT) + if ptP1 and ptP2 and dAng < 0 then + local dLen = dist( ptP1, ptP2) + table.insert( tFacAdj, { vAdj[i], vAdj[j], dLen, ptP1, ptP2, dAng}) + end + end + end + end + end + -- Tra le linee dei corner determino la più lunga + local dMaxLen = 0 + local nIdLine + for i = 1, #tFacAdj do + if tFacAdj[i][3] > dMaxLen then + nIdLine = i + dMaxLen = tFacAdj[i][3] + end + end + + return dMaxLen, nIdLine, tFacAdj +end + +--------------------------------------------------------------------- +local function ChooseContour( Proc, nFacInd, bVerifyCorner) + -- Recupero le adiacenze della faccia principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + -- Se richiesto, verifico che ci siano facce adiacenti consecutive (sicuramente con angolo) + if bVerifyCorner then + local bCorner = false + for i = 1, #vAdj do + local j = EgtIf( i > 1, i - 1, #vAdj) + if vAdj[i] >= 0 and vAdj[j] >= 0 then + bCorner = true + break + end + end + if not bCorner then return {} end + end + -- Cerco le facce adiacenti con angolo convesso + local tFacAdjMain = {} + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + if ptP1 and ptP2 and dAng < 0 then + local dLen = dist( ptP1, ptP2) + table.insert( tFacAdjMain, { vAdj[i], dLen, ptP1, ptP2, dAng}) + end + end + end + + return tFacAdjMain +end + +--------------------------------------------------------------------- +local function CheckToInvert( AuxId, bPositive) + -- recupero versore estrusione + local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT) + -- faccio una copia del percorso + local sParnt = EgtGetParent( AuxId) + local nNewEntId = EgtCopyGlob( AuxId, sParnt) + -- chiudo il percorso + if EgtCloseCurveCompo( nNewEntId) then + local vtMPlane, dDist, dArea = EgtCurveArea( nNewEntId) + -- cancello percorso copia + EgtErase( nNewEntId) + if dArea and abs(dArea) > 1 then + local frEnt = EgtGetGlobFrame( AuxId) + if vtMPlane then + vtMPlane:toGlob(frEnt) + if dArea and dArea * ( vtMPlane * vtExtr) < 0 then + if bPositive then + return true + end + elseif dArea and dArea * ( vtMPlane * vtExtr) > 0 then + if not bPositive then + return true + end + end + end + end + else + -- cancello percorso copia + EgtErase(nNewEntId) + end + + return false +end + +--------------------------------------------------------------------- +local function TestPoints( nPathInt, idx, dDiff, pP1, pP2, sAxis) + local pPini = EgtIf( sAxis == 'X', pP1:getX(), EgtIf( sAxis == 'Y', pP1:getY(), pP1:getZ())) + local pPend = EgtIf( sAxis == 'X', pP2:getX(), EgtIf( sAxis == 'Y', pP2:getY(), pP2:getZ())) + local b3SolidMin = EgtIf( sAxis == 'X', _b3Solid:getMin():getX(), EgtIf( sAxis == 'Y', _b3Solid:getMin():getY(), _b3Solid:getMin():getZ())) + local b3SolidMax = EgtIf( sAxis == 'X', _b3Solid:getMax():getX(), EgtIf( sAxis == 'Y', _b3Solid:getMax():getY(), _b3Solid:getMax():getZ())) + if ( abs( pPini - b3SolidMax) < dDiff and abs( pPend - b3SolidMax) < dDiff) or + ( abs( pPini - b3SolidMin) < dDiff and abs( pPend - b3SolidMin) < dDiff) then + -- setto l'entità open + local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or '' + if #sActInfo > 0 then + EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. idx) + else + EgtSetInfo( nPathInt, 'OPEN', idx) + end + return true + else + return false + end +end + +--------------------------------------------------------------------- +local function SetOpenSide( nPathInt, vtOrtho, nStartPoint) + -- fondo tra loro le curve compatibili + EgtMergeCurvesInCurveCompo( nPathInt) + local nStartIdEnt, nNumEnt = EgtCurveDomain( nPathInt) + local pLastPIni, pLastPEnd + + -- faccio una copia della curva e la esplodo + if nStartIdEnt then + -- prendo i punti + for i = 1, nNumEnt do + local pPini = EgtUP( nPathInt, (i - 1), GDB_RT.GLOB) + local pPend = EgtUP( nPathInt, EgtIf( i == nNumEnt, 0, i), GDB_RT.GLOB) + -- Se normale lungo la Z considero il box in X e Y + if abs( vtOrtho:getZ()) > 0.999 then + -- se corrisponde a X prendo i punti per eventuale modifica del punto di inizio percorso + if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'X') then + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Y prendo i punti per eventuale modifica del punto di inizio percorso + elseif TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Y') then + pLastPIni = pPini + pLastPEnd = pPend + end + -- altrimenti se normale lungo la Y considero il box in X e Z + elseif abs( vtOrtho:getZ()) < 0.001 and abs( vtOrtho:getY()) > 0.999 then + -- se corrisponde a X prendo i punti per eventuale modifica del punto di inizio percorso + if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'X') then + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Z prendo i punti per eventuale modifica del punto di inizio percorso + elseif TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Z') then + pLastPIni = pPini + pLastPEnd = pPend + end + -- caso che non dovrebbe mai capitare ma gestito per completezza + -- altrimenti se normale lungo la X considero il box in Y e Z + elseif abs( vtOrtho:getZ()) < 0.001 and abs( vtOrtho:getX()) > 0.999 then + -- se corrisponde a Y prendo i punti per eventuale modifica del punto di inizio percorso + if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Y') then + pLastPIni = pPini + pLastPEnd = pPend + -- altrimenti se corrisponde a Z prendo i punti per eventuale modifica del punto di inizio percorso + elseif TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Z') then + pLastPIni = pPini + pLastPEnd = pPend + end + -- se asse Z orizzontale verifico se si avvicina piú a Y + elseif abs( vtOrtho:getZ()) < 0.001 then + if abs( vtOrtho:getY()) > 0.75 then + -- se corrisponde a Z prendo i punti per eventuale modifica del punto di inizio percorso + if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Z') then + pLastPIni = pPini + pLastPEnd = pPend + end + end + -- se asse Y a 0 (fresa ne davanti ne dietro) verifico se si avvicina piú a Z+ + elseif abs( vtOrtho:getY()) < 0.001 then + if abs( vtOrtho:getZ()) > 0.75 then + -- se corrisponde a Y prendo i punti per eventuale modifica del punto di inizio percorso + if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Y') then + pLastPIni = pPini + pLastPEnd = pPend + end + end + end + end + -- se devo cambiare il punto di partenza + if nStartPoint then + if pLastPIni and pLastPEnd then + -- calcolo il punto medio con gli ultimi punti utilizzati + local ptPs = ( pLastPIni + pLastPEnd) / 2 + EgtChangeClosedCurveStartPoint( nPathInt, ptPs, GDB_RT.GLOB) + -- se devo eliminare la parte open + if nStartPoint == 2 then + EgtRemoveCurveCompoCurve( nPathInt, true) + EgtRemoveCurveCompoCurve( nPathInt, false) + return true + end + end + end + end + + return false +end + +--------------------------------------------------------------------- +local function DoClean( sName, sMilling, nIdPath, vtN, dMaxElev, dMachDepth, dExtraDepth, dNoLeadsAddLen, dLeadInPerp, + bLeftWorkside, bInvertTool, bInvertDir, bCheckToInvertPath, bSCCEvaluateOppositeVector, bEvaluateAddLeads) + local nMchId = EgtAddMachining( sName, sMilling) + local sMyWarn + if not nMchId then + sMyWarn = 'Warning : impossible add machining ' .. sName .. '-' .. sMilling + return false, sMyWarn + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nIdPath, -1}}) + -- imposto lato di lavoro sinistro + if bLeftWorkside then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + -- imposto direzione utensile opposta + if bInvertTool then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if EgtIf( bSCCEvaluateOppositeVector, AreSameOrOppositeVectorApprox( vtN, Z_AX()), AreSameVectorApprox( vtN, Z_AX())) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtN:getY() < GEO.EPS_SMALL then + nSCC = EgtIf( bInvertDir, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + else + nSCC = EgtIf( bInvertDir, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- gestione attacco e uscita + if bEvaluateAddLeads and EgtCurveIsClosed( nIdPath) then + -- attacco e uscita a quarto di cerchio senza allungamenti a inizio e fine + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, dLeadInPerp) + EgtSetMachiningParam( MCH_MP.LIELEV, 0) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + else + -- nessun attacco e uscita, allungo inizio e fine di 3/4 del diametro utensile + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dNoLeadsAddLen) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dNoLeadsAddLen) + end + -- setto massimo affondamento possibile + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth + dExtraDepth) + -- setto se devo invertire il percorso + if bCheckToInvertPath then + local bInvert = CheckToInvert( nIdPath, true) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bInvertDir, not bInvert, bInvert)) + end + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione + local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if EgtApplyMachining( true, false) then + _, sMyWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + -- altrimenti lavorazione non applicata + else + _, sMyWarn = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sMyWarn + end + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function MakeRoundCleanCorner( Proc, nFacInd, dDiam, bMillDown, bDoubleSide) + -- recupero la lavorazione senza considerare l'elevazione + local sMilling = ML.FindMilling( 'SmallToolContour' .. EgtIf( bMillDown and not bDoubleSide, '_H2', '')) + if not sMilling then + local sMyWarn = 'Warning : SmallToolContour not found in library' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + + -- recupero i dati dell'utensile + local dTDiam = 50 + local dTMaxDepth = 0 + local TI = GetToolInfoForMachining( sMilling) + if TI then + dTDiam = TI.dDiam or dTDiam + dTMaxDepth = TI.dMaxDepth or dTMaxDepth + end + + -- se il diametro trovato non è minore dei 3/4 del diametro utilizzato in precedenza, esco + if dTDiam > ( 0.75 * dDiam) then + local sMyWarn = 'Warning : tool diameter not enough small' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + + -- ottengo gli angoli dove applicare il percorso con fresa più piccola + local _, _, tFacAdj = ChooseCorner( Proc, nFacInd) + -- se non trovato nessun angolo interno valido esco + if #tFacAdj == 0 then + return true + end + + -- recupero la normale della faccia di fondo + local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se fresatura da sotto salto la lavorazione + if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then + local sErr = 'Error : milling from bottom ' + EgtOutLog( sErr) + return false, sErr + end + + -- ciclo su tutti gli angoli trovati + local sMyWarn = '' + for i = 1, #tFacAdj do + local pAuxId = {} + -- le 2 facce di contatto devono essere perpendicolari e non sottosquadra rispetto alla faccia di fondo + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][1], GDB_ID.ROOT) + local _, ptP1x, ptP2x, dAngx = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][2], GDB_ID.ROOT) + if dAng >= 0 or dAng < -90 - 10 * GEO.EPS_SMALL or dAngx >= 0 or dAngx < -90 - 10 * GEO.EPS_SMALL then + goto continue + end + -- prendo la lunghezza di adiacenza delle due linee + local dLen1 = dist( ptP1, ptP2) + local dLen2 = dist( ptP1x, ptP2x) + -- cerco il punto tra le 3 facce: nIdEndPoint + local _, nIdEndPoint = GetIdIniEndPoints( ptP1, ptP2, tFacAdj[i]) + -- devo avere un punto comune + if not nIdEndPoint then + goto continue + end + -- calcolo lunghezza minima in base all'angolo tra le due pareti + local dMinDist = ( ( dDiam / 2) / tan( ( 180 + tFacAdj[i][6]) / 2)) + 2 + -- verifico che entrambe le linee siano maggiori delle lunghezza minima + if dLen1 <= dMinDist or dLen2 <= dMinDist then + sMyWarn = 'Warning : impossible make clean corner path' + goto continue + end + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + local ptApPoint = EgtIf( dist( tFacAdj[i][nIdEndPoint], ptP1) < 10 * GEO.EPS_SMALL, ptP2, ptP1) + -- prima linea + local nAuxId = EgtLine( _nAddGrpId, ptApPoint, tFacAdj[i][nIdEndPoint], GDB_RT.GLOB) + -- calcolo arretramento + local dTrimDist = dLen1 - dMinDist + -- se arretramento valido + if dTrimDist > 100 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dTrimDist, ptApPoint, GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- se il punto finale corrisponde con il punto comune, uso l'altro + ptApPoint = EgtIf( dist( tFacAdj[i][nIdEndPoint], ptP1x) < 10 * GEO.EPS_SMALL, ptP2x, ptP1x) + -- seconda linea + nAuxId = EgtLine( _nAddGrpId, tFacAdj[i][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + -- calcolo arretramento + dTrimDist = dLen2 - dMinDist + -- se arretramento valido + if dTrimDist > 100 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dTrimDist, ptApPoint, GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- trasformo in percorso + local AuxId + if #pAuxId > 0 then + AuxId = EgtCurveCompo( _nAddGrpId, pAuxId, true) + end + -- deve esserci il percorso + if not AuxId then + sMyWarn = 'Warning : impossible make clean corner path' + goto continue + end + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtN1, GDB_RT.GLOB) + -- inserisco la lavorazione + local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local dDepth = 0 + if tFacAdj[i][3] > dTMaxDepth then + dDepth = dTMaxDepth - tFacAdj[i][3] + end + _, sMyWarn = DoClean( sName, sMilling, AuxId, vtN1, tFacAdj[i][3], dDepth, 0, 0, 0, true, false, false, true, true, false) + ::continue:: + end + if #sMyWarn > 0 then + EgtOutLog( sMyWarn) + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function MakeRoundCleanContour( Proc, nFacInd, dDiam, bMillDown, + bDoubleSide, vtOrtho, nPathInt, nSurfInt, + dDepth, bOneShot) + + -- recupero la lavorazione senza considerare l'elevazione perché viene calcolata l'elevazione utile + local sMilling = ML.FindMilling( 'SmallToolContour' .. EgtIf( bMillDown and not bDoubleSide, '_H2', '')) + if not sMilling then + local sMyWarn = 'Warning : SmallToolContour not found in library' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + + -- recupero i dati dell'utensile + local dTDiam = 50 + local dTMaxDepth = 0 + local TI = GetToolInfoForMachining( sMilling) + if TI then + dTDiam = TI.dDiam or dTDiam + dTMaxDepth = TI.dMaxDepth or dTMaxDepth + end + + local sMillingDn = ML.FindMilling( 'SmallToolContour' .. EgtIf( bMillDown and bDoubleSide, '_H2', '')) + if not sMillingDn then + local sMyWarn = 'Warning : Opposite SmallToolContour not found in library' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + -- recupero i dati dell'utensile testa da sotto + local dTDiamDn = 50 + local dTMaxDepthDn = 0 + local TI = GetToolInfoForMachining( sMillingDn) + if TI then + dTDiamDn = TI.dDiam or dTDiamDn + dTMaxDepthDn = TI.dMaxDepth or dTMaxDepthDn + end + + -- se il diametro trovato non è minore dei 3/4 del diametro utilizzato in precedenza, esco + if dTDiam > ( 0.75 * dDiam) then + local sMyWarn = 'Warning : tool diameter not enough small' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + + local vtN1 + local nFirstId, nNumId + local dMaxElev + local dCollSic = 0 + local dExtraDepth = 0 + + -- se non ho la faccia aggiunta + if not nPathInt then + -- cerco gli angoli dove applicare il percorso con fresa piú piccola e i lati in comune + local tFacAdjMain = ChooseContour( Proc, nFacInd, true) + -- se non trovato nessun angolo interno da pulire esco + if #tFacAdjMain == 0 then + return true + end + -- normale alla faccia di fondo + vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se fresatura da sotto salto la lavorazione + if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then + local sErr = 'Error : milling from bottom' + EgtOutLog( sErr) + return false, sErr + end + -- distanza di sicurezza per evitare collisioni + dCollSic = CalcCollisionSafety( vtN1) + -- elevazione massima della faccia + dMaxElev = BL.GetFaceElevation( Proc.Id, nFacInd, _nPartId) + -- ciclo tutta la tabella + local tPaths = {} + local ptIniPath + local ptMidDist + local dMaxLen = 0 + for i = 1, #tFacAdjMain do + -- le 2 facce di contatto devono essere perpendicolari o non sottosquadra rispetto alla faccia di fondo + local ptP1, ptP2, dAng + ptP1 = tFacAdjMain[i][3] + ptP2 = tFacAdjMain[i][4] + dAng = tFacAdjMain[i][5] + if ( dAng < 0 and dAng >= -90 - 10 * GEO.EPS_SMALL) then + -- creo la linea da P1 a P2 + local nAuxId = EgtLine( _nAddGrpId, ptP1, ptP2, GDB_RT.GLOB) + table.insert( tPaths, nAuxId) + -- prendo la lunghezza massima e il punto medio + if tFacAdjMain[i][2] > dMaxLen then + ptIniPath = ptP1 + dMaxLen = tFacAdjMain[i][2] + ptMidDist = ( ptP1 + ptP2) / 2 + end + end + end + -- costruisco il/i percorso/i + nFirstId, nNumId = EgtCurveCompoByReorder( _nAddGrpId, tPaths, ptIniPath, true, GDB_RT.GLOB) + if nFirstId then + -- se un solo percorso e chiuso cambio il punto di inizio nell'entitá piú lunga + if nNumId == 1 and EgtCurveIsClosed( nFirstId) then + EgtChangeClosedCurveStartPoint( nFirstId, ptMidDist, GDB_RT.GLOB) + end + -- modifico versore direzione + for i = 1, nNumId do + EgtModifyCurveExtrusion( nFirstId + i - 1, vtN1, GDB_RT.GLOB) + end + end + -- alrimenti ho la faccia aggiunta + else + -- assegno il percorso + nFirstId = EgtCopyGlob( nPathInt, _nAddGrpId) + nNumId = 1 + -- distanza di sicurezza per evitare collisioni + dCollSic = CalcCollisionSafety( vtOrtho) + -- calcolo elevazione dalla faccia trasversale aggiunta + local dSurfIntElev = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + if bDoubleSide then + dMaxElev = dSurfIntElev + else + dMaxElev = dDepth + -- se la precedente svuotatura è stata fatta completamente in una sola volta + -- valuto di nuovo se devo fare due passate o una sola + if bOneShot then + -- se non è possibile svuotare completamente da una sola parte + if dTMaxDepth <= ( dMaxElev + BD.CUT_EXTRA + dCollSic) then + bDoubleSide = true + dMaxElev = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + else + dExtraDepth = dMaxElev - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + end + -- altrimenti non è stata fatta completamente calcolo la distanza tra faccia aggiunta e profondità superficie + else + dExtraDepth = dMaxElev - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + end + end + -- normale alla faccia aggiunta + vtN1 = Vector3d( vtOrtho) + -- imposto i lati aperti + SetOpenSide( nFirstId, vtOrtho, 2) + end + + -- se non trovato il percorso, esco + if not nFirstId then + local sMyWarn = 'Warning : impossible make clean corner path' + EgtOutLog( sMyWarn) + return true, sMyWarn + end + + -- assegno lavorazioni ad ogni percorso + local sMyWarn = '' + local bOk + for i = 1, nNumId do + local nIdPath = nFirstId + i - 1 + local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local bInvertMach + if nPathInt then + -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) + if vtN1:getZ() < BD.NZ_MINA and abs(vtN1:getZ()) >= 0.707 then + bInvertMach = true + -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti + elseif not bDoubleSide and vtN1:getY() > GEO.EPS_SMALL then + bInvertMach = true + end + end + local dMachDepth = 0 + if ( dMaxElev + dCollSic) > dTMaxDepth then + dMachDepth = dTMaxDepth - ( dMaxElev + dCollSic) + end + bOk, sMyWarn = DoClean( sName, sMilling, nIdPath, vtN1, dMaxElev, dMachDepth, dExtraDepth, 0.75 * dTDiam, 0.5 * dTDiam, true, bInvertMach, bInvertMach, true, true, true) + -- se devo applicare la contornatura anche sul lato opposto + if bOk and bDoubleSide then + if bMillDown then + sMilling = sMillingDn + dTDiam = dTDiamDn + dTMaxDepth = dTMaxDepthDn + end + sName = 'CleanOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + bOk, sMyWarn = DoClean( sName, sMilling, nIdPath, vtN1, dMaxElev, dMachDepth, 0, 0.75 * dTDiam, 0, true, true, true, true, false, false) + end + end + if #sMyWarn > 0 then + EgtOutLog( sMyWarn) + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function MakeRoundCleanCornerOrContour( Proc, nFacInd, dDiam, bMillDown, bDoubleSide, + vtOrtho, nPathInt, nSurfInt, dDepth, bOneShot) + local nFunction = Q_CONTOUR_SMALL_TOOL + -- se modalitá pulitura spigoli e lavorazione di lato forzo a fare il contorno + if nFunction == 2 and nPathInt then + nFunction = 1 + end + -- se richiesta pulitura del contorno + if nFunction == 1 then + return MakeRoundCleanContour( Proc, nFacInd, dDiam, bMillDown, bDoubleSide, + vtOrtho, nPathInt, nSurfInt, dDepth, bOneShot) + -- se richiesta pulitura dei soli corner + elseif nFunction == 2 then + return MakeRoundCleanCorner( Proc, nFacInd, dDiam, bMillDown, bDoubleSide) + -- altri casi non previsti + else + return true + end +end + +--------------------------------------------------------------------- +local function MakeSharpCleanCorner( Proc, nFacInd, dDiam) + local sMyWarn = '' + local pAuxId = {} + local nAuxId + local AuxId + local ptApPoint + local dLenTrimExt + local sMilling + local dMaxDepth = 0 + + -- cerco l'angolo di riferimento dove applicare il percorso di pulitura, altrimenti esco + local _, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) + if #tFacAdj == 0 then + return true + end + -- prendo i versori + local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local vtN3 = EgtSurfTmFacetNormVersor( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local nIdIniPoint, nIdEndPoint = GetIdIniEndPoints( ptLocP1, ptLocP2, tFacAdj[nIdLine]) + -- versore direzione + local vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] + vtExtr:normalize() + -- inserisco le prime tre linee + if nIdIniPoint and nIdEndPoint then + -- se fresatura da sotto salto la lavorazione + if vtExtr:getZ() < BD.DRILL_VZ_MIN then + local sErr = 'Error : clean corner milling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- sommo i tre versori per avre una direzione media + vtExtr = vtN1 + vtN2 + vtN3 + vtExtr:normalize() + -- recupero la lavorazione non calcolando l'elevazione + sMilling = ML.FindMilling( 'CleanCorner', ( 0.5 * dDiam)) + if not sMilling then + local sErr = 'Error : CleanCorner not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile (temporaneo, per compensare errore nella lavorazione) + local TI = GetToolInfoForMachining( sMilling) + if TI then + dMaxDepth = TI.dMaxMat or dMaxDepth + end + -- l'altezza di taglio del tagliente corrisponde al raggio del raccordo che si riesce a coprire + -- quindi confronto l'elevazione con il raggio utensile utilizzato per la svuotatura + if dMaxDepth < ( dDiam * 0.5) - 100 * GEO.EPS_SMALL then + sMyWarn = 'Warning : skip clean corner (the cut heigth is too small to machine the corner radius)' + EgtOutLog( sMyWarn) + return false, sMyWarn + end + nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdIniPoint], tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - ( ( dDiam / 2) + 2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId, -dLenTrimExt, ptApPoint, GDB_RT.GLOB) + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( _nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- inserisco le ultime tre linee + uscita discostata rispetto all'ingresso + -- trovo il secondo punto sulla superfice di riferimento + _, ptLocP1, ptLocP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][2], GDB_ID.ROOT) + if ptLocP1 and ptLocP2 then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB) + dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - ( ( dDiam / 2) + 2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId, -dLenTrimExt, ptApPoint, GDB_RT.GLOB) + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( _nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- piccolo scostamento di 2mm dall'angolo + nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- ultima linea di risalita + nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), tFacAdj[nIdLine][nIdIniPoint] + ( 2 * vtExtr), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- trasformo in percorso + if #pAuxId > 0 then + AuxId = EgtCurveCompo( _nAddGrpId, pAuxId, true) + end + -- se non c'é il percorso do errore + if not AuxId then + local sErr = 'Error : impossible make clean corner path' + EgtOutLog( sErr) + return false, sErr + end + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- inserisco la lavorazione + local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local bOk + bOk, sMyWarn = DoClean( sName, sMilling, AuxId, vtN1, dMaxDepth, 0, 0, 10, 0, false, false, true, false, false, false) + if not bOk then + return false, sMyWarn + end + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function MakeDrillOnCorner( Proc, nFacInd, dDiam, bSpecialMach) + local sMyWarn = '' + -- ottengo l'angolo dove applicare il foro + local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd) + -- se non trovato nessun angolo interno valido esco + if #tFacAdj == 0 then + return true, sMyWarn + end + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local nIdIniPoint, nIdEndPoint = GetIdIniEndPoints(ptLocP1, ptLocP2, tFacAdj[nIdLine]) + -- inserisco foro + if nIdIniPoint and nIdEndPoint then + local vtExtr + if bSpecialMach then + local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT) + vtExtr = vtN0 + vtN1 + vtN2 + else + -- versore direzione + vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint] + end + vtExtr:normalize() + -- se foratura da sotto salto la lavorazione + if vtExtr:getZ() < BD.DRILL_VZ_MIN then + local sErr = 'Error : drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sDrilling, nType = ML.FindDrilling( dDiam) + if not sDrilling then + local sErr = 'Error : drilling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 20 + local dDiamTool = 20 + local dDiamTh = 35 + local bIsDrilling + local TI = GetToolInfoForMachining( sDrilling) + if TI then + bIsDrilling = ( EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) == MCH_MY.DRILLING) + if bIsDrilling then + dMaxDepth = TI.dMaxMat or dMaxDepth + else + dMaxDepth = TI.dMaxDepth or dMaxDepth + end + dDiamTool = TI.dDiam or dDiamTool + dDiamTh = TI.dThDiam or dDiamTh + end + -- se foro inclinato, limito il massimo affondamento + local CosB = abs( vtExtr:getX()) + if CosB < BD.DRILL_VX_MAX then + local TgA = CosB / sqrt( 1 - CosB * CosB) + dMaxDepth = dMaxDepth - dDiamTh / 2 * TgA + else + dMaxDepth = 0 + end + -- setto griglia + if bSpecialMach then + EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdEndPoint], vtExtr)) + else + EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdIniPoint], vtExtr)) + end + -- creo geometria + local AuxId = EgtCircle( _nAddGrpId, {0, 0, 0}, EgtIf( bIsDrilling, dDiamTool / 2, ( dDiamTool / 2) + 0.1), GDB_RT.GRID) + -- riporto la griglia a globale + EgtSetGridFrame() + -- calcolo spessore + local dDepthBore = dMaxLen + if bSpecialMach then + -- calcolo l'elevazione + local dLenIn, dLedOut = BL.GetPointDirDepth( _nPartId, tFacAdj[nIdLine][nIdEndPoint], vtExtr) + if dLenIn > 0 then + dDepthBore = dLenIn + elseif dLedOut then + dDepthBore = dLedOut + end + EgtModifyCurveThickness( AuxId, dDepthBore) + else + EgtModifyCurveThickness( AuxId, -dMaxLen) + 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}}) + -- 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 dDepth + if bSpecialMach then + dDepth = dDepthBore + else + dDepth = dMaxLen + 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) + end + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione (coincide con affondamento) + local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( dDepth, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + 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 + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function ErasePathIfNecessary( nPathId, sDeleteByDir, dDiff) + local ptP1 = EgtSP( nPathId, GDB_RT.GLOB) + local ptP2 = EgtEP( nPathId, GDB_RT.GLOB) + if abs( EgtIf( sDeleteByDir == 'X', ( ptP1:getX() - ptP2:getX()), EgtIf( sDeleteByDir == 'Y', ( ptP1:getY() - ptP2:getY()), ( ptP1:getZ() - ptP2:getZ())))) > dDiff then + EgtErase( nPathId) + end +end + +--------------------------------------------------------------------- +local function TestPaths( sDeleteByDir, nStartId, nNumIds, dDiff) + local tPaths = {} + local dMaxVal, dMinVal + for i = 1, nNumIds do + local bInsTab + local nIdx = nStartId + i - 1 + local ptP1 = EgtSP( nIdx, GDB_RT.GLOB) + if ptP1 then + for j = 1, #tPaths do + local dLocalVal = tPaths[j][2] + if abs( EgtIf( sDeleteByDir == 'X', ptP1:getX() - dLocalVal, EgtIf( sDeleteByDir == 'Y', ptP1:getY() - dLocalVal, ptP1:getZ() - dLocalVal))) < dDiff then + local tLocIds = tPaths[j][1] + table.insert( tLocIds, ( nIdx)) + tPaths[j][1] = tLocIds + bInsTab = true + end + end + -- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella + if not bInsTab then + table.insert( tPaths, {{ nIdx}, ptP1:getX()}) + dMaxVal = EgtIf( sDeleteByDir == 'X', _b3Solid:getMax():getX(), EgtIf( sDeleteByDir == 'Y', _b3Solid:getMax():getY(), _b3Solid:getMax():getZ())) + dMinVal = EgtIf( sDeleteByDir == 'X', _b3Solid:getMin():getX(), EgtIf( sDeleteByDir == 'Y', _b3Solid:getMin():getY(), _b3Solid:getMin():getZ())) + end + end + end + + return tPaths, dMaxVal, dMinVal +end + +--------------------------------------------------------------------- +local function ModifyPathExtrusion(tPath, sDeleteByDir, dMaxVal, dDiff) + local ptP1 = EgtSP( tPath, GDB_RT.GLOB) + if abs( EgtIf( sDeleteByDir == 'X', ptP1:getX(), EgtIf( sDeleteByDir == 'Y', ptP1:getY(), ptP1:getZ())) - dMaxVal) < dDiff then + EgtModifyCurveExtrusion( tPath, EgtIf( sDeleteByDir == 'X', X_AX(), EgtIf( sDeleteByDir == 'Y', Y_AX(), Z_AX())), GDB_RT.GLOB) + else + EgtModifyCurveExtrusion( tPath, EgtIf( sDeleteByDir == 'X', -X_AX(), EgtIf( sDeleteByDir == 'Y', -Y_AX(), -Z_AX())), GDB_RT.GLOB) + end +end + +--------------------------------------------------------------------- +local function ExtractExternalPaths( nPathInt, nNumIdAux, vtOrtho) + if nNumIdAux == 1 then + -- fondo tra loro le curve compatibili + EgtMergeCurvesInCurveCompo( nPathInt) + -- esplodo il percorso in modo da avere entià separate per poterle controllare + local nStartId, nNumIds = EgtExplodeCurveCompo( nPathInt) + if nStartId then + local sDeleteByDir + -- Se normale lungo la Z elimino le entità che hanno differenza in Z + if abs(vtOrtho:getZ()) > 0.7 then + sDeleteByDir = 'Z' + -- altrimenti se normale lungo la Y elimino le entità che hanno variazione in Y +-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.7 then + elseif abs(vtOrtho:getY()) > 0.7 then + sDeleteByDir = 'Y' + -- caso che non dovrebbe mai capitare ma gestito per completezza + -- altrimenti se normale lungo la X elimino le entità che hanno variazione in X +-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.7 then + elseif abs(vtOrtho:getX()) > 0.7 then + sDeleteByDir = 'X' + end + if sDeleteByDir then + for i = 1, nNumIds do + ErasePathIfNecessary( nStartId + i - 1, sDeleteByDir, 10 * GEO.EPS_SMALL) + end + -- ricreo i vari percorsi + local tPaths, dMaxVal, dMinVal = TestPaths( sDeleteByDir, nStartId, nNumIds, 10 * GEO.EPS_SMALL) + + if tPaths then + local tChamPath = {} + -- elimino quelle che non corrispondono agli estremi + for i = 1, #tPaths do + -- se non corrisponde ai limiti elimino l'elemento + if abs( tPaths[i][2] - dMaxVal) > 10 * GEO.EPS_SMALL and abs( tPaths[i][2] - dMinVal) > 10 * GEO.EPS_SMALL then + tPaths[i] = nil + else + local tNoMatch = {} + local tPathLoc = tPaths[i][1] + local pIniLoc = EgtSP( tPathLoc[1], GDB_RT.GLOB) + local pEndLoc = EgtEP( tPathLoc[1], GDB_RT.GLOB) + -- ciclo sui percorsi per trovare i punti non coincidenti (se percorso non chiuso) + for j = 2, #tPathLoc do + -- prendo i punti del percorso successivo + local pAddIni = EgtSP( tPathLoc[j], GDB_RT.GLOB) + local pAddEnd = EgtEP( tPathLoc[j], GDB_RT.GLOB) + -- se consecutivi + if AreSamePointApprox( pEndLoc, pAddIni) then + pEndLoc = pAddEnd + elseif AreSamePointApprox( pIniLoc, pAddEnd) then + pIniLoc = pAddIni + else + table.insert( tNoMatch, tPathLoc[j]) + end + end + -- controllo eventuali percorsi scartati + for j = 1, #tNoMatch do + -- prendo i punti del percorso successivo + local pAddIni = EgtSP( tNoMatch[j], GDB_RT.GLOB) + local pAddEnd = EgtEP( tNoMatch[j], GDB_RT.GLOB) + -- se consecutivi + if AreSamePointApprox( pEndLoc, pAddIni) then + pEndLoc = pAddEnd + elseif AreSamePointApprox( pIniLoc, pAddEnd) then + pIniLoc = pAddIni + end + end + -- creo concatenamento partendo dal punto iniziale + local nIdLoc = EgtCurveCompoByReorder( _nAddGrpId, tPathLoc, pIniLoc, true) + if nIdLoc then + table.insert( tChamPath, nIdLoc) + end + end + end + for i = 1, #tChamPath do + -- modifico estrusione percorso + ModifyPathExtrusion( tChamPath[i], sDeleteByDir, dMaxVal, 10 * GEO.EPS_SMALL) + end + if #tChamPath == 1 then + return tChamPath[1], 1, nil + elseif #tChamPath == 2 then + return tChamPath[1], 2, tChamPath[2] + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + for i = 1, #tChamPath do + EgtErase( tChamPath[i]) + end + end + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + end + -- altrimenti cancello tutte le emtità e restituisco nil + else + for i = 1, nNumIds do + EgtErase( nStartId + i - 1) + end + end + end + end + + return nil, 0, nil +end + +--------------------------------------------------------------------- +local function MakeChamfer( Proc, vtOrtho, nSurfInt) + -- Se variabile globale indica che lo smusso è già stato fatto, esco + if _bMadeChamfer then + return 0 + end + _bMadeChamfer = true + local bIs3Faces = Proc.Fct == 3 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : Mark not found in library' + EgtOutLog( sErr) + return -1, sErr + end + -- ottengo le curve di contorno libero + local nAuxId1, nAuxId2, nNumIdAux + if bIs3Faces then +-- nAuxId1, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) +-- EgtModifyCurveExtrusion( nAuxId1, vtOrtho, GDB_RT.GLOB) +-- SetOpenSide( nAuxId1, vtOrtho, b3Solid, nAddGrpId, 1) +-- nNumIdAux = 2 + + -- estraggo i percorsi + nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, _nAddGrpId) + -- se percorso creato estraggo solo i percorsi delle facce interessate, non di testa + if nAuxId1 then + nAuxId1, nNumIdAux, nAuxId2 = ExtractExternalPaths( nAuxId1, nNumIdAux, vtOrtho) + end + else + nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, _nAddGrpId) + if not nNumIdAux then nNumIdAux = 0 end + end + + local dExtra = 2 + for i = 1, nNumIdAux do + local AuxId + local vtExtr + if bIs3Faces then + if i == 1 then + AuxId = nAuxId1 + else + -- faccio la copia del percorso +-- AuxId = EgtCopyGlob( nAuxId1, nAddGrpId) + AuxId = nAuxId2 + end + if AuxId then + vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + end + else + AuxId = nAuxId1 + i - 1 + vtExtr, _, _ = EgtCurveArea( AuxId) + end + if vtExtr then + if not bIs3Faces then + local fFrCurve = EgtGetGlobFrame( AuxId) + vtExtr:toGlob( fFrCurve) + end +-- if bIs3Faces and i == nNumIdAux then +-- vtExtr = -vtExtr +-- end + -- Se normale entro certi limiti +-- if vtExtr:getZ() > -0.707 and ( abs(vtOrtho:getX()) > 0.99 or abs(vtOrtho:getY()) > 0.99 or abs(vtOrtho:getZ()) > 0.99) then + if vtExtr:getZ() > -0.707 and ( abs(vtExtr:getX()) > 0.99 or abs(vtExtr:getY()) > 0.99 or abs(vtExtr:getZ()) > 0.99) then + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchId = EgtAddMachining( sNameCh, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sMilling + EgtOutLog( sErr) + return -1, sErr + end + -- modifico estrusione percorso + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto posizione braccio porta testa + if vtExtr:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- assegno affondamento e offset radiale +-- EgtSetMachiningParam( MCH_MP.DEPTH, _dDepthCham + dExtra - EgtIf( bIs3Faces, (dDepth / 2), 0)) + EgtSetMachiningParam( MCH_MP.DEPTH, _dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- se opero su 3 facce e sono al secondo e ultimo percorso inverto la lavorazione +-- if bIs3Faces and i == nNumIdAux then +-- EgtSetMachiningParam( MCH_MP.INVERT, true) +-- end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return -1, sErr + end + -- se non perpendicolare emetto un warning + -- else + -- sWarn = 'Warning : chamfer skipped because not perpendicular to face or from bottom' + -- EgtOutLog( sWarn) + end + --emetto un warning + -- else + -- sWarn = 'Warning : chamfer skipped because not perpendicular to face' + -- EgtOutLog( sWarn) + end + end + + return 0 +end + +--------------------------------------------------------------------- +local function MakeByMillAsSaw( Proc, tFData, nBottomFace, sMillingOnSide, dSawDiam, dSawThick) + local sWarn + -- ottengo la distanza tra la fine del pezzo e il pezzo successivo + local dDistToNextPiece = EgtGetInfo( _nRawId, 'BDST', 'd') or 5. + -- Recupero le facce adiacenti alla principale (solo quelle esistenti) + local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd) + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Cerco una faccia adiacente alla principale sul lato più lungo + local nFacAdj + local dMaxLen = 0 + for i = 1, #vAdj do + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > dMaxLen then + nFacAdj = vAdj[i] + dMaxLen = dLen + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, tFData.dH, tFData.dV), 3) + end + end + if not nFacAdj then + local sErr = 'Error : long adjacent face not found' + EgtOutLog( sErr) + return false, sErr + end + -- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT) + if abs( vtN * tFData.rfFac:getVersX()) > abs( vtN * tFData.rfFac:getVersY()) then + tFData.dH, tFData.dV = tFData.dV, tFData.dH + end + -- Determino se estremi aperti o chiusi + local bOpenStart = false + local bOpenEnd = false + -- se non ho la faccia di fondo (che comporta essere una fessura) verifico se ho lati aperti + if not nBottomFace then + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) + for j = 1, #vAdj2 do + if vAdj2[j] == tFData.nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == tFData.nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == tFData.nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + end + end + -- Se possibile, lavoro con la lama + if _bForceUseBlade then + -- Recupero la lavorazione di lama + local sCutting = sMillingOnSide + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( tFData.rfFac:getVersZ()) + local dStartDist = -1 + local dEndDist = -1 + -- calcolo eventuali arretramenti lama + if not bOpenStart then + local dRadius = dSawDiam / 2 + local dCat1 = dRadius - tFData.dFacElev + dStartDist = sqrt( ( dRadius * dRadius) - ( dCat1 * dCat1)) + end + if not bOpenEnd then + if not bOpenStart then + dEndDist = dStartDist + else + local dRadius = dSawDiam / 2 + local dCat1 = dRadius - tFData.dFacElev + dEndDist = sqrt( ( dRadius * dRadius) - ( dCat1 * dCat1)) + end + end + -- Eseguo i tagli + local nStep = ceil( ( tFData.dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( tFData.dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + local dOffs = ( i - 1) * dStep + --if vtN:getZ() < BD.NZ_MINA then dOffs = dOffs + dSawThick end + local bOk, sErr, nMchId = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, dStartDist, dEndDist, nil, _b3Raw) + if not bOk then return bOk, sErr end + -- setto l'elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( 0, 1) .. ';' + -- applico elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- tolgo eventuale step + EgtSetMachiningParam( MCH_MP.STEP, 0) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + -- in base all'elevazione calcolo l'impronta della lama + local dUsedBladeLen = sqrt( ( ( dSawDiam / 2) * ( dSawDiam / 2)) - ( ( ( dSawDiam / 2) - tFData.dFacElev) * ( ( dSawDiam / 2) - tFData.dFacElev))) + -- controllo direzione taglio e se il minimo della feature sborda in coda + if abs( vtN:getX()) < GEO.EPS_SMALL and abs( _b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then + -- do avviso che la lama può sbordare nel pezzo successivo + sWarn = 'Warning on mill side as blade : Cut machining can damage next piece' + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function DoHeadChainSaw( Proc, sName, sSawing, tFData, nFaceUse, nFacAdj, vtN, vtNE, vtNS, dSawWidth, + dOffs, dDistToNextPiece, dMaxDepth, bOpenStart, bOpenEnd) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- controllo direzione taglio e se il minimo della feature sborda in coda + if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( _b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL then + -- se ho lato partenza aperto e lato uscita chiuso e direzione lato chiuso è negativa, allora controllo uscita lama + if bOpenStart and not bOpenEnd and vtNE:getX() < -0.99 and dDistToNextPiece < ( dSawWidth / 2) then + -- imposto accorciamento iniziale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dDistToNextPiece - 1 - ( dSawWidth / 2)) + else + -- imposto accorciamento iniziale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + end + -- se ho lato uscita aperto e lato partenza chiuso e direzione lato partenza è negativa, allora controllo uscita lama + if bOpenEnd and not bOpenStart and vtNS:getX() < -0.99 and dDistToNextPiece < ( dSawWidth / 2) then + -- imposto accorciamento finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dDistToNextPiece - 1 - ( dSawWidth / 2)) + else + -- imposto accorciamento finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + end + else + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + end + -- imposto angolo 3° asse rot e eventuale angolo suggerito per inizio + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, tFData.rfFac:getVersZ())) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se necessario, limito l'affondamento + if tFData.dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + local sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( tFData.dFacElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + local dDepth = dMaxDepth - tFData.dFacElev + EgtOutLog( sWarn) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH ' .. EgtNumToString( dDepth, 1)) + end + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( tFData.dFacElev, 2) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + if EgtGetOutstrokeInfo() then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- impostazione alternativa angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, tFData.rfFac:getVersZ())) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + if EgtIsMachiningEmpty() then + local _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + return true +end + +--------------------------------------------------------------------- +local function DoSideChainSaw( Proc, sName, sSawing, tFData, vtN, vtOrtho, nLongFaceId, + dOffs, dMaxMat, dSawCornerRad, bOpenStart, bOpenEnd) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLongFaceId}}) + -- imposto uso del lato faccia + local nFaceUse + -- se non è un tunnel a 4 facce + if Proc.Fct < 4 then + nFaceUse = BL.GetNearestParalOpposite( tFData.rfFac:getVersZ(), vtN) + -- altrimenti vero tunnel (solo sopra-sotto o davanti-dietro) + else + if abs( vtOrtho:getZ()) >= 0.707 then + nFaceUse = MCH_MILL_FU.PARAL_DOWN + else + nFaceUse = MCH_MILL_FU.PARAL_BACK + end + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho)) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se non è un tunnel a 4 facce + if Proc.Fct < 4 then + -- imposto sempre massimo affondamento + local dBoxDepth + if nFaceUse == MCH_MILL_FU.PARAL_LEFT or nFaceUse == MCH_MILL_FU.PARAL_RIGHT then + dBoxDepth = Proc.Box:getDimX() + elseif nFaceUse == MCH_MILL_FU.PARAL_FRONT or nFaceUse == MCH_MILL_FU.PARAL_BACK then + dBoxDepth = Proc.Box:getDimY() + else + dBoxDepth = Proc.Box:getDimZ() + end + EgtSetMachiningParam( MCH_MP.DEPTH, dBoxDepth) + if dBoxDepth > dMaxMat then + local sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- sistemo inizio e fine + if bOpenStart then EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) end + if bOpenEnd then EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) end + -- altrimenti vero tunnel (solo sopra-sotto o davanti-dietro) + else + -- se possibile aumento l'affondamento pari al raggio corner + 1 + if dMaxMat > ( dDepth + dSawCornerRad + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, ( dDepth + dSawCornerRad + 1)) + -- se massimo affondamento supera altezza fessura, uso massimo affondamento + elseif dMaxMat > ( dDepth + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, ( dMaxMat - 1)) + -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning + elseif dMaxMat < dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) + local sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + end + if Q_MAX_ELEVATION and Q_MAX_ELEVATION > 10 then + local sNotes = 'MaxElev=' .. EgtNumToString( Q_MAX_ELEVATION, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + end + -- eseguo + if not EgtApplyMachining( true, false) then + if EgtGetOutstrokeInfo() then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- impostazione alternativa angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho)) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + if EgtIsMachiningEmpty() then + local _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + return true +end + +--------------------------------------------------------------------- +local function MakeByChainOrSaw( Proc, tFData, dDimMin, dDimMax, vtOrtho, nLongFaceId, + bOrthoFacesMaster, nBottomFace, nSurfInt) + local bIs3Faces = Proc.Fct == 3 + local bOrthoFaces + local sWarn + -- ottengo la distanza tra la fine del pezzo e il pezzo successivo + local dDistToNextPiece = EgtGetInfo( _nRawId, 'BDST', 'd') or 5.4 + if bIs3Faces then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd1, dFacElev1, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, _nPartId, bIs3Faces) + if not nFacInd1 or nFacInd1 < 0 then + if nFacInd1 == -1 then + bOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeByChainOrSaw could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + else + bOrthoFaces = bOrthoFacesMaster + end + + if bOrthoFaces then + -- ottengo le dimensioni del tunnel + dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) + -- verifico la direzione + -- se devo inserire il chamfer + if _nChamfer > 0 then + local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt) + if nOk < 0 then return false, sErr end + end + end + -- Recupero le facce adiacenti alla principale (solo quelle esistenti) + local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd) + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Cerco una faccia adiacente alla principale sul lato più lungo + local nFacAdj + local dMaxLen = 0 + for i = 1, #vAdj do + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > dMaxLen then + nFacAdj = vAdj[i] + dMaxLen = dLen + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, tFData.dH, tFData.dV), 3) + end + end + if not nFacAdj then + local sErr = 'Error : long adjacent face not found' + EgtOutLog( sErr) + return false, sErr + end + -- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT) + if abs( vtN * tFData.rfFac:getVersX()) > abs( vtN * tFData.rfFac:getVersY()) then + tFData.dH, tFData.dV = tFData.dV, tFData.dH + end + -- Determino se estremi aperti o chiusi + local bOpenStart = false + local bOpenEnd = false + local vtNS, vtNE + -- se non ho la faccia di fondo (che comporta essere una fessura) verifico se ho lati aperti + if not nBottomFace then + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3) + for j = 1, #vAdj2 do + if vAdj2[j] == tFData.nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == tFData.nFacInd do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- se è chiusa acquisisco vettore faccia tappo + if not bOpenStart and vAdj2[i] >= 0 then + _, vtNS = EgtSurfTmFacetCenter( Proc.Id, vAdj2[i], GDB_ID.ROOT) + end + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == tFData.nFacInd do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + -- se è chiusa acquisisco vettore faccia tappo + if not bOpenEnd and vAdj2[k] >= 0 then + _, vtNE = EgtSurfTmFacetCenter( Proc.Id, vAdj2[k], GDB_ID.ROOT) + end + end + end + end + -- Recupero il massimo affondamento possibile con la lama + local dSawMaxDepth = 0 + local sCutting = ML.FindCutting( 'HeadSide') + if sCutting then + local TI = GetToolInfoForMachining( sCutting) + if TI then + dSawMaxDepth = TI.dMaxDepth or dSawMaxDepth + end + end + -- se lavorazione sulle teste e altezza trave supera il limite (che causa collisione con la forcella) e direzione taglio lungo la Z + -- e limite profondità BeamData è maggiore del taglio massimo lama, assegno il massimo affondamento pari al limite profondità del BeamData + if bOpenStart and bOpenEnd and _bForceUseBlade and ( Proc.Head or Proc.Tail) and abs( tFData.rfFac:getVersY():getY()) > 0.866 and + _b3Solid:getDimZ() > BD.MIN_DIM_HBEAM and dSawMaxDepth > BD.MAX_DIM_HTCUT_HBEAM then + dSawMaxDepth = BD.MAX_DIM_HTCUT_HBEAM + end + -- Se entrambi gli estremi sono aperti e possibile, lavoro con la lama + if bOpenStart and bOpenEnd and _bForceUseBlade and tFData.dFacElev < dSawMaxDepth + 10 * GEO.EPS_SMALL then + -- Recupero la lavorazione di lama + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : HeadSide (cutting) not found in library' + EgtOutLog( sErr) + return false, sErr, 'MNF' + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 4 + local TI = GetToolInfoForMachining( sCutting) + if TI then + dSawDiam = TI.dDiam or dSawDiam + dSawThick = TI.dThick + end + if dSawThick > tFData.dV + 10 * GEO.EPS_SMALL then + local sErr = 'Error : sawblade too thick' + EgtOutLog( sErr) + return false, sErr + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( tFData.rfFac:getVersZ()) + -- Eseguo i tagli + local nStep = ceil( ( tFData.dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( tFData.dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + local dOffs = ( i - 1) * dStep + local bOk, sErr = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, 0, 0, nil, _b3Raw) + if not bOk then return bOk, sErr end + end + -- in base all'elevazione calcolo l'impronta della lama + local dUsedBladeLen = sqrt( ( ( dSawDiam / 2) * ( dSawDiam / 2)) - ( ( ( dSawDiam / 2) - tFData.dFacElev) * ( ( dSawDiam / 2) - tFData.dFacElev))) + -- controllo direzione taglio e se il minimo della feature sborda in coda + if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( _b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then + -- do avviso che la lama può sbordare nel pezzo successivo + sWarn = 'Warning on saw cut : Cut machining can damage next piece' + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + -- altrimenti con sega a catena + else + -- Recupero la lavorazione + local sSawing = ML.FindSawing( 'Sawing') + if not sSawing then + local sErr = 'Error : Sawing not found in library' + EgtOutLog( sErr) + return false, sErr, 'MNF' + end + -- Recupero i dati dell'utensile + local dSawWidth = 75 + local dSawThick = 8 + local dMaxDepth = 200 + local TI = GetToolInfoForMachining( sSawing) + if TI then + dSawWidth = TI.dDiam or dSawWidth + dSawThick = TI.dThick or dSawThick + dMaxDepth = TI.dMaxDepth or dMaxDepth + end + if dSawThick > tFData.dV + 10 * GEO.EPS_SMALL then + local sErr = 'Error : chainsaw too thick' + EgtOutLog( sErr) + return false, sErr + end + local bGoFromHead = true + -- se la lunghezza utensile non riesce ad arrivare sul fondo assegno la possibilità di lavorare di testa o di fianco + if tFData.dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + -- lavora di testa se è un tunnel, lavora di fianco se non è un tunnel + bGoFromHead = not bOrthoFaces + end + -- se continuo a lavorare di testa + if bGoFromHead then + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( tFData.rfFac:getVersZ()) + -- Calcolo normale faccia adiacente + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) + -- Verifico se necessarie più passate + local nStep = ceil( ( tFData.dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( tFData.dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- Applico la lavorazione con sega a catena a questa faccia + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local dOffs = ( i - 1) * dStep + local bOk, sErr = DoHeadChainSaw( Proc, sName, sSawing, tFData, nFaceUse, nFacAdj, vtN, vtNE, vtNS, dSawWidth, dOffs, dDistToNextPiece, dMaxDepth, bOpenStart, bOpenEnd) + if not bOk then + return false, sErr + end + end + -- altrimenti segacatena di fianco + else + -- verifico se posso farlo con la sega-catena + local bMakeChainSaw, sSawing2, dMaxMat2, dSawCornerRad2, dSawThick2 = VerifyChainSaw( dDimMin, dDimMax) + if bMakeChainSaw then + -- Verifico se necessarie più passate + local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick2) + local dStep = 0 + if nStep > 1 then + dStep = ( dDimMin - dSawThick2) / ( nStep - 1) + end + for i = 1, nStep do + -- inserisco la lavorazione di sawing + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local dOffs = ( i - 1) * dStep + local bOk, sErr = DoSideChainSaw( Proc, sName, sSawing2, tFData, vtN, vtOrtho, nLongFaceId, dOffs, dMaxMat2, dSawCornerRad2, bOpenStart, bOpenEnd) + if not bOk then + return false, sErr + end + end + end + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeAntiSplintBySaw( Proc, nFacet, vtN, nFacInd, bReduceDepth, bMillDown) + -- Recupero la lavorazione di lama + local sCutting = ML.FindCutting( 'HeadSide' .. EgtIf( bMillDown, '_H2', '')) + if not sCutting then + local sErr = 'Error : HeadSide (cutting) not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- valuto l'angolo tra le due facce + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT) + local ptPm = (ptP1 + ptP2) / 2 + -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta l'elevazione della faccia + -- laterale sul punto medio della linea in comune + local frFc = Frame3d( ptPm, vtN) + local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) + local dDepth = b3BoxLoc:getDimZ() or 0 + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 0 + local dMaxDepth = 0 + local TI = GetToolInfoForMachining( sCutting) + if TI then + dSawDiam = TI.dDiam or dSawDiam + dSawThick = TI.dThick or dSawThick + dMaxDepth = TI.dMaxDepth or dMaxDepth + end + local dExtraOffs = 0 + -- se profondità superiore al massimo lama modifico elevazione + if dDepth > dMaxDepth then + dExtraOffs = dMaxDepth - dDepth + end + -- se devo ridurre l'affondamento + if bReduceDepth then + local dLimitDepth = 100 + -- se ho ridotto l'affondamento ne riduco ulteriormente l'affondamento (50mm) + if abs( dExtraOffs) > 0 then + if dMaxDepth > dLimitDepth then + dExtraOffs = dLimitDepth - dDepth + end + else + if dDepth > dLimitDepth then + dExtraOffs = dLimitDepth - dDepth + else + dExtraOffs = -( dDepth / 2) + end + end + end + -- eseguo il taglio + local bMadeASbyBld, sWarn, nIdMach = Fbs.MakeOne( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, ( -0.5 + dExtraOffs), BD.CUT_SIC, 0, 0, 0, nil, _b3Raw) + if bMadeASbyBld then + sWarn = nil + if abs( dExtraOffs) > 0 then + sWarn = 'Warning : antisplint elevation is bigger than max tool depth' + end + end + return bMadeASbyBld, sWarn, nIdMach, dSawThick, dMaxDepth, dAng +end + +--------------------------------------------------------------------- +local function DoPocketing( sName, sPocketing, sMchFind, vtN, nPathInt, nFaceIdx, nUseRoughTool, dMachDepth, dMaxElev, bInvertTool, bInvertPath, bFaceOrtho, bSCCEvaluateOppositeVector, bSCCYSpecialStrategy) + -- inserisco la lavorazione di svuotatura + 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( {{ nPathInt, nFaceIdx}}) + if bInvertTool then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + if bFaceOrtho then + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if EgtIf( bSCCEvaluateOppositeVector, AreSameOrOppositeVectorApprox( vtN, Z_AX()), AreSameVectorApprox( vtN, Z_AX())) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif bSCCYSpecialStrategy then + if vtN:getY() > 0.1 then + nSCC = MCH_SCC.ADIR_YP + else + nSCC = MCH_SCC.ADIR_YM + end + else + if vtN:getY() < GEO.EPS_SMALL then + nSCC = EgtIf( bInvertTool, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + else + nSCC = EgtIf( bInvertTool, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) + end + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- se tasca aperta, imposto opportuno attacco + if (sMchFind == 'OpenPocket' and nUseRoughTool == 0) or sMchFind == 'OpenPocket_H2' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + if bInvertPath then + -- inverto il percorso di lavorazione se necessario lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, bInvertPath) + end + if dMachDepth ~= 0 then + -- imposto affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'VMRS=0;' + if dMaxElev > 0 then + sNotes = sNotes .. 'MaxElev=' .. EgtNumToString( dMaxElev, 1) .. ';' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local bOk, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, '', nMchFId +end + +--------------------------------------------------------------------- +local function MakePocket( Proc, ptPs, tvtN, nFaceRef, sMchFind, nUseRoughTool, + sMasterPocket, dPrevFaceElev, tDimAndRef, dAng) + -- calcolo l'elevazione dal punto medio + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( _nPartId, ptPs, tvtN[2]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + local dCollSic = 2 * BD.COLL_SIC + -- calcolo il diametro utensile + local dDiamTool + local dFaceDiamTool + if tDimAndRef then + -- prendo il valore dalle dimensioni minime delle facce + dFaceDiamTool = min( tDimAndRef[2][1], tDimAndRef[2][2]) + end + -- se ho lavorazione precedente ricalcolo grossolanamente l'elevazione + if dPrevFaceElev and dPrevFaceElev > 0 and dAng then + dElev = dElev + ( sqrt( ( dElev * dElev) - ( dPrevFaceElev * dPrevFaceElev)) * sin( dAng)) + elseif dPrevFaceElev and dPrevFaceElev > dElev then + dElev = dPrevFaceElev + end + local sPocketing + if sMasterPocket then + sPocketing = sMasterPocket + else + sPocketing = ML.FindPocketing( sMchFind, dFaceDiamTool, dElev + dCollSic) + end + if not sPocketing then + local sErr = 'Error : ' .. sMchFind .. ' not found in library' + EgtOutLog( sErr) + return false, sErr + end + dDiamTool = 20 + local dMaxDepth = 0 + local sTuuidPk + if EgtMdbSetCurrMachining( sPocketing) then + sTuuidPk = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidPk) or '') then + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- se nome svuotatura non è stato ricalcolato, confronto il diametro utensile utilizzato con il minimo faccia e se non sono compatibili esco + if sMasterPocket and dFaceDiamTool and dDiamTool >= dFaceDiamTool then + return false, '', sTuuidPk, dDiamTool, dElev + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef) + local dMachDepth = 0 + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + dMachDepth = dMaxDepth - dElev + dElev = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + local bOk, sWarn, nMchFId = DoPocketing( sName, sPocketing, sMchFind, tvtN[2], Proc.Id, nFaceRef, nUseRoughTool, dMachDepth, dElev, false, false, true, false, true) + if not bOk then + return bOk, sWarn + end + return true, sWarn, sTuuidPk, dDiamTool +end + +--------------------------------------------------------------------- +local function DoHeadCut( Proc, sName, sMilling, nMchFId, dElev, nSideFace, tvtN) + 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( {{ Proc.Id, nSideFace}}) + -- imposto uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( tvtN[1]) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + -- imposto posizione braccio porta testa + if tvtN[2]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MachineByMill( Proc, tvtN, nBaseFace, nSideFace, ptPs, tDimAndRef, + nDiffWidth, nUseRoughTool, dAng, sPocketing, sTuuidPk, dPrevFaceElev) + -- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto + if ( 180 + dAng) > 90.1 then + local sMchFind = 'Pocket' + local dAngLimit = 40 + + -- se feature é larga come trave imposto openpocket + if nDiffWidth == 0 then + sMchFind = 'OpenPocket' + -- altrimenti non è passante disabilito il truciolatore + else + nUseRoughTool = 0 + end + -- calcolo l'angolo dalla verticale dall'angolo tra le due facce, perchè la feature potrebbe essere ruotata sulla Z locale della + -- faccia principale e quindi la componente X del versore della faccia potrebbe dare un valore non coerente + local dDiffFromSqAng = dAng + 90 + -- se l'angolo dalla verticale si discosta di più dell'angolo limite impostato, utilizzo la svuotatura + if cos( dDiffFromSqAng) < cos( dAngLimit) then + -- applico la svuotatura + local bOk, sWarn, sTuuidPk, dDiamTool, dElev = MakePocket( Proc, ptPs, tvtN, nSideFace, sMchFind, nUseRoughTool, sPocketing, dPrevFaceElev, tDimAndRef, dAng) + if not bOk then + if sTuuidPk then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Long2Cut', dElev, sTuuidPk) + if not sMilling then + local sErr = 'Error : Long2Cut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + bOk, sWarn = DoHeadCut( Proc, sName, sMilling, nMchFId, dElev, nSideFace, tvtN) + if not bOk then + return false, sWarn + end + end + else + return bOk, sWarn + end + -- altrimenti contornatura di fianco + else + local bOpenStart = false + local bOpenEnd = false + if nDiffWidth == 0 then + bOpenStart = true + bOpenEnd = true + else + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBaseFace))[1] + for j = 1, #vAdj2 do + if vAdj2[j] == nSideFace then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == nSideFace do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == nSideFace do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + end + end + local sMilling + if nUseRoughTool > 0 then + sMilling = ML.FindMilling( 'Long2Cut', nil, sTuuidPk) + else + sMilling = ML.FindMilling( 'LongSmallCut', nil, sTuuidPk) + end + if not sMilling then + local sErr = 'Error : Long2Cut & LongSmallCut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 50 + local TI = GetToolInfoForMachining( sMilling) + if TI then + dTDiam = TI.dDiam or dTDiam + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( tDimAndRef[1][3]:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, (nSideFace)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- setto inversione del percorso + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- setto a 0 eventuali offset + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- calcolo elevazione per allungamenti attacchi con fianchi chiusi + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( _nPartId, ptPs, tvtN[2]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + -- applico gli allungamenti o accorciamenti + if bOpenStart then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dTDiam / 2) + if dElev > 0 then + EgtSetMachiningParam( MCH_MP.LIPERP, dElev) + end + end + if bOpenEnd then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2) + else + EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dTDiam / 2) + if dElev > 0 then + EgtSetMachiningParam( MCH_MP.LOPERP, dElev) + end + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + return true +end + +--------------------------------------------------------------------- +local function GetUShapeWidth( Proc, nFacInd) + -- Recupero le facce adiacenti alla principale (solo quelle esistenti) + local vAdj = GetValidFacetAdjacencies( Proc.Id, nFacInd) + -- se non ho facce adiacenti esco subito + if not vAdj or #vAdj == 0 then return nil end + -- Normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- Cerco le facce adiacenti alla principale con angolo concavo >= 90 + local dWidth = 0 + for i = 1, #vAdj do + -- verifico l'angolo tra le facce ( esco se angolo compreso < 90) + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + if bAdj and dAng < -90 - 20 * GEO.EPS_ANG_SMALL then return nil end + -- larghezza della faccia ortogonalmente alla adiacente + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT) + local vtX = vtN2 ^ vtN + local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2) + local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, nFacInd, GDB_BB.STANDARD, frRef) + if b3Ref then + dWidth = max( dWidth, b3Ref:getDimY()) + end + end + return dWidth +end + +--------------------------------------------------------------------- +local function MakeByPockets( Proc, bOrthoFacesMaster, bMillDown) + local nFirstMachId + local bOrthoFaces + local sWarn + local sMchFind = 'Pocket' + local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt + local bBadMach = false + local bIs3Faces = Proc.Fct == 3 + + if bIs3Faces then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, _, nFacInd2, _ = BL.GetFaceWithMostAdj( Proc.Id, _nPartId, bIs3Faces) + if not nFacInd or nFacInd < 0 then + if nFacInd == -1 then + bOrthoFaces = nFacInd2 + else + local sErr = 'Error : MakeByPockets could not find reference face' + EgtOutLog( sErr) + return -1, sErr + end + end + else + bOrthoFaces = bOrthoFacesMaster + end + -- se è un tunnel verifico se è possibile usare la svuotatura + if bOrthoFaces then + -- ottengo le dimensioni del tunnel + dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) + local nPathInt + -- se devo inserire il chamfer + if _nChamfer > 0 then + local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt) + if nOk < 0 then return -1, sErr end + end + -- se smusso non è esclusivo + if _nChamfer < 2 then + -- ricalcolo se è lavorabile da sotto + bMillDown = ( BD.DOWN_HEAD == true) + -- verifico se può essere fatto con svuotatura + local bMakePocket, sPocketing, dMaxDepth, dDiamTool = VerifyPocket( dDimMin, dDepth / 2, nil, sMchFind) + local bMakePocketDn, sPocketingDn, dMaxDepthDn + if bMillDown then + bMakePocketDn, sPocketingDn, dMaxDepthDn = VerifyPocket( dDimMin, dDepth / 2, nil, sMchFind .. '_H2') + -- se è negativo inverto il versore e la faccia + if vtOrtho:getZ() < 0 then + vtOrtho = -vtOrtho + EgtInvertSurf( nSurfInt) + end + end + if bMakePocket then + -- gestione svuotatura da un solo lato o anche dal lato opposto (se non verticale) + -- estraggo il contorno dalla superfice per evitare i problemi con la svuotatura + -- e assegno l'estrusione + nPathInt = EgtExtractSurfTmLoops( nSurfInt, _nAddGrpId) + EgtModifyCurveExtrusion( nPathInt, vtOrtho, GDB_RT.GLOB) + -- se ho 3 facce, ciclo sulle entità del percorso per segnare quelle che sono aperte + if bIs3Faces then + SetOpenSide( nPathInt, vtOrtho) + end + -- variabili per parametri lavorazione + local dMachDepth + local dElev = 0 + local bDoubleSide + local bOneShot + local bComplete = true + -- imposto altezza aggiuntiva di elevazione + local dCollSic = CalcCollisionSafety( vtOrtho) + -- se possibile svuotare completamente da una sola parte + if dMaxDepth > ( dDepth + BD.CUT_EXTRA + dCollSic) then + dMachDepth = ( dDepth / 2) + BD.CUT_EXTRA + dElev = dDepth + BD.CUT_EXTRA + bOneShot = true + else + -- se direzione verso la verticale setto max affondamento possibile ed + -- emetto messaggio di warning perché non lavorabile interamente + if abs( vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then + dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic + dElev = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + bComplete = false + -- altrimenti setto il flag per fare la svuotatura da due parti + else + -- se l'altezza utensile riesce a lavorare completamente da due parti + if dMaxDepth > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then + dMachDepth = BD.CUT_EXTRA_MIN + dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN + -- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione + else + dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic + dElev = dMaxDepth + -- se molto inclinato rispetto alla normale della faccia di riferimento, lavorazione non idonea per probabili collisioni + local vtRef = Y_AX() + if abs( vtOrtho:getX()) > abs( vtOrtho:getY()) and abs( vtOrtho:getX()) > abs( vtOrtho:getZ()) then + vtRef = X_AX() + elseif abs( vtOrtho:getZ()) > abs( vtOrtho:getX()) and abs( vtOrtho:getZ()) > abs( vtOrtho:getY()) then + vtRef = Z_AX() + end + if abs( vtOrtho * vtRef) < 0.5 then + bBadMach = true + end + end + bDoubleSide = true + end + end + -- se lavorazione non idonea esco + if bIs3Faces and bBadMach then + local sErr = 'Impossible apply perpendicular pocketing: ' .. sPocketing + return -2, sErr + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local bToolInvert = false + -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) + if vtOrtho:getZ() < BD.NZ_MINA and abs( vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then + bToolInvert = true + -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti + elseif not bDoubleSide and vtOrtho:getY() > GEO.EPS_SMALL and not ( -(vtOrtho:getZ()) < BD.NZ_MINA) then + bToolInvert = true + end + -- eseguo svuotatura + local bOk, sErr, nMchFId = DoPocketing( sName, sPocketing, sMchFind, vtOrtho, nPathInt, -1, 0, dMachDepth, dElev, bToolInvert, true, false, true) + if not bOk then + return -1, sErr + end + -- prendo l'id della prima lavorazione inserita + if not nFirstMachId then + nFirstMachId = nMchFId + end + -- se posso applicare la svuotatura sul lato opposto + if bDoubleSide then + -- se ho la lavorazione da sotto ricalcolo in base a questa lavorazione + if bMakePocketDn then + -- sPocketing = sPocketingDn + -- dMaxDepth = dMaxDepthDn + -- dDiamTool = dDiamToolDn + -- se l'altezza utensile riesce a lavorare completamente da due parti + if dMaxDepthDn > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then + dMachDepth = BD.CUT_EXTRA_MIN + dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN + -- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione + else + dMachDepth = dMaxDepthDn - ( dDepth / 2) - dCollSic + dElev = dMaxDepthDn + bComplete = false + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + else + -- se anche lavorando dal lato opposto non riesco a svuotare completamente la fessura + -- setto i parametri affondamento ed emetto warning + if dMaxDepth < ( dDepth / 2) + BD.CUT_EXTRA + dCollSic then + dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic + dElev = dMaxDepth + bComplete = false + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'PockOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + -- eseguo svuotatura in direzione invertita + local bOk, sErr, nMchFId = DoPocketing( sName, sPocketing, sMchFind, vtOrtho, nPathInt, -1, 0, dMachDepth, dElev, true, true, false, false) + if not bOk then + return -1, sErr + end + -- prendo l'id della prima lavorazione inserita + if not nFirstMachId then + nFirstMachId = nMchFId + end + end + -- se non completo e U, cerco di lavorare anche la faccia di fondo (con il massimo affondamento possibile) + if not bComplete and bIs3Faces then + -- recupero la faccia da lavorare + local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, _nPartId) + local vtN + local bPock3rd = false + if nFacInd then + vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + bPock3rd = ( vtN and ( vtN:getZ() >= BD.NZ_MINA or bMakePocketDn)) + end + if bPock3rd then + -- recupero la distanza di sicurezza aggiuntiva + local dFacCollSic = CalcCollisionSafety( vtN) + -- scelgo se lavorare da sotto + local bFacPocketDn = ( bMakePocketDn and vtN:getZ() < -0.174) + -- calcolo affondamento + local dDepth = 0 + local dActMaxDepth = EgtIf( bFacPocketDn, dMaxDepthDn, dMaxDepth) + if dActMaxDepth < dFacElev + dFacCollSic then + dDepth = dActMaxDepth - dFacElev + dFacCollSic + end + -- inserisco la lavorazione di svuotatura + local sName = EgtIf( bDoubleSide, 'Pock3rd_', 'Pock2nd_') .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + -- eseguo svuotatura + local bOk, sErr, nMchFId = DoPocketing( sName, sPocketing, sMchFind, vtN, Proc.Id, nFacInd, 0, dDepth, 0, false, true, false, true) + if not bOk then + return -1, sErr + end + -- prendo l'id della prima lavorazione inserita + if not nFirstMachId then + nFirstMachId = nMchFId + end + end + end + return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId + end + end + end + + return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, bOrthoFaces +end + +--------------------------------------------------------------------- +local function ManageAntiSplintBySaw( Proc, bIsU, vtN, nFacInd, sWarn, bMillDown, bReduceDepth) + local bMadeASbyBld = false + local nNumFac = EgtIf( bIsU, 2, 1) + local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra + -- se a U cerco di ottimizzare il lato di lavoro della lama + if bIsU then + if abs( vtN:getY()) > 0.996 then + nPrefSide = 0 + elseif abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then + -- se X è negativa allora devo tenere il motore a destra + if vtN:getX() < -(10 * GEO.EPS_SMALL) then + nPrefSide = 2 + end + end + end + -- va eseguito sulle facce diverse dalla principale + local nPrevSCC = nil + for nFacet = 0, nNumFac do + if nFacet ~= nFacInd then + -- lavoro + local dSawThick = 0 + local dAng, sWarn2, nIdMach + bMadeASbyBld, sWarn2, nIdMach, dSawThick, dMaxDepth, dAng = MakeAntiSplintBySaw( Proc, nFacet, vtN, nFacInd, bReduceDepth, bMillDown) + if not bMadeASbyBld then return bMadeASbyBld, false, sWarn2 end + sWarn = FormatWarning( sWarn, sWarn2) + -- se antischeggia veramente inserito perchè necessario + if nIdMach then + -- verifico se da invertire + local bInvertMach = false + if bIsU then + if abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then +-- if abs( vtN:getZ()) > 0.7 or abs( vtN:getY()) > 0.7 then + -- prendo il vettore normale alla faccia + local ptC, vtNFc = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + -- se superficie principale parallela al piano XZ + if nPrefSide == 0 then + -- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto) + if vtNFc:getX() * vtNFc:getZ() > 0 then + nPrefSide = 2 + -- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto) + else + nPrefSide = 1 + end + end + -- se faccia verso X+ e mandrino verso sinistra + if vtNFc:getX() > 0 and nPrefSide == 1 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + -- se faccia verso X- e mandrino verso destra + elseif vtNFc:getX() < 0 and nPrefSide == 2 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + end + end + end + -- eseguo inversione + if bInvertMach then + local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT) + local nWS = EgtGetMachiningParam( MCH_MP.WORKSIDE) + local nInvWS = EgtIf( nWS == MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT) + local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE) + local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT) + if not bOrtUp then + -- assegno i parametri invertiti + EgtSetMachiningParam( MCH_MP.WORKSIDE, nInvWS) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert) + -- setto l'offset pari allo spessore lama + EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick) + end + end + -- posizione del braccio : se primo taglio la recupero, altrimenti la imposto + if not nPrevSCC then + nPrevSCC = EgtGetMachiningParam( MCH_MP.SCC) + else + EgtSetMachiningParam( MCH_MP.SCC, nPrevSCC) + end + -- rieseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nIdMach, false) + return false, false, sErr + end + end + end + end + + return bMadeASbyBld, true, sWarn +end + +--------------------------------------------------------------------- +local function MakePathsOnExtremePoints( nIdPath, pPaths, dTDiam) + + local dLength = 2 + if not nIdPath then return pPaths end + + -- prendo i punti iniziali e finali del percorso e i versori direzione + local ptIni = EgtSP( nIdPath, GDB_RT.GLOB) + local ptEnd = EgtEP( nIdPath, GDB_RT.GLOB) + + -- se distanza tra i punti è <= del diametro utensile esco + if dist( ptIni, ptEnd) <= dTDiam then return pPaths end + + -- prendo i versori iniziali e finali + local vtIni = EgtSV( nIdPath, GDB_RT.GLOB) + local vtEnd = EgtEV( nIdPath, GDB_RT.GLOB) + + local ptIniP = ptIni + local ptEndP = ptIniP + (vtIni * dLength) + local nAuxId = EgtLine( _nAddGrpId, ptIniP, ptEndP, GDB_RT.GLOB) + table.insert( pPaths, { nAuxId, 1, ptIniP}) + + ptIniP = ptEnd + ptEndP = ptEnd - ( vtEnd * dLength) + nAuxId = EgtLine( _nAddGrpId, ptIniP, ptEndP, GDB_RT.GLOB) + table.insert( pPaths, { nAuxId, 2, ptIniP}) + + return pPaths +end + +--------------------------------------------------------------------- +local function MakeAntiSplintByMill( Proc, pPaths, nPathInt, vtN1, + bDoubleSide, bOppoSide, sMilling, sMyWarn, + dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId) + + local sMyWarn2 + + -- assegno lavorazioni ad ogni percorso + for i = 1, #pPaths do + local nIdPath = pPaths[i][1] + local nSide = pPaths[i][2] + -- modifico versore direzione + EgtModifyCurveExtrusion( nIdPath, vtN1, GDB_RT.GLOB) + local sName + if bOppoSide then + sName = 'AntiSplintOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + else + sName = 'AntiSplint_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + end + local nMchId = EgtAddMachining( sName, sMilling) + if nMchId then + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nIdPath, -1}}) + if ( bOppoSide and nSide == 1) or ( not bOppoSide and nSide == 2) then + -- imposto lato di lavoro destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + else + -- imposto lato di lavoro sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + local nSCC + if bOppoSide then + -- imposto direzione utensile opposta + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- imposto posizione braccio porta testa + nSCC = MCH_SCC.ADIR_YM + if not BD.C_SIMM then + if AreSameVectorApprox( vtN1, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN1:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtN1:getY() < GEO.EPS_SMALL then + nSCC = MCH_SCC.ADIR_YP + else + nSCC = MCH_SCC.ADIR_YM + end + end + else + local bInvertMach = false + if not nPathInt then + -- imposto posizione braccio porta testa + nSCC = MCH_SCC.ADIR_YM + if vtN1:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + else + -- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale) + if vtN1:getZ() < BD.NZ_MINA and abs(vtN1:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + -- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti + elseif not bDoubleSide and vtN1:getY() > GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + bInvertMach = true + end + -- imposto posizione braccio porta testa + nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + if AreSameOrOppositeVectorApprox( vtN1, Z_AX()) then + nSCC = MCH_SCC.ADIR_YM + elseif abs( vtN1:getX()) < 0.1 then + nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + elseif vtN1:getY() < GEO.EPS_SMALL then + nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + else + nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) + end + end + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- parametri attacco + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 1) + -- allungo inizio + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 2) + EgtSetMachiningParam( MCH_MP.LITANG, 10) + EgtSetMachiningParam( MCH_MP.LIPERP, -5) + -- parametri uscita + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) + local dMachDepth = 0 + local dExtraElev = 0 + if bDoubleSide then + dExtraElev = BL.GetFaceElevationFromPointDir( Proc.Id, _nPartId, pPaths[i][3], EgtIf( bOppoSide, -vtN1, vtN1)) - dMaxElevMaster + end + local dMaxElev = dMaxElevMaster + dExtraElev + if ( dMaxElev + BD.CUT_EXTRA + dCollSic) > dMaxDepth then + dMachDepth = dMaxDepth - ( dMaxElev + dCollSic) + end + -- setto se devo invertire il percorso + local bInvert = CheckToInvert( nIdPath, true) + if bOppoSide then + EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth) + EgtSetMachiningParam( MCH_MP.INVERT, bInvert) + else + EgtSetMachiningParam( MCH_MP.DEPTH, (dMachDepth + dExtraDepth)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bInvertMach, not bInvert, bInvert)) + end + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione + local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if EgtApplyMachining( true, false) then + _, sMyWarn2 = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + else + -- se ho la lavorazione di svuotatura riloco la lavorazione antischeggia prima di questa + if nFirstMachId then + EgtRelocateGlob( nMchId, nFirstMachId, GDB_IN.BEFORE) + end + end + -- altrimenti lavorazione non applicata + else + _, sMyWarn2 = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + end + -- altrimenti non è stata inserita lavorazione + else + sMyWarn2 = 'warning adding machining ' .. sName .. '-' .. sMilling + end + end + + if sMyWarn2 and #sMyWarn2 > 0 then + sMyWarn = sMyWarn .. '\n' .. sMyWarn2 + end + return sMyWarn +end + +--------------------------------------------------------------------- +local function ManageAntiSplintByMill( Proc, nFacInd, bMillDown, bDoubleSide, + vtOrtho, nPathInt, nSurfInt, dDepth, + bOneShot, nFirstMachId) + local sMyWarn = '' + local pPaths = {} + local nAuxId + local sMilling + + -- recupero la lavorazione tenendo conto dell'elevazione + local dCheckDepth + if bDoubleSide then + dCheckDepth = 0.5 * dDepth + else + if not nPathInt then + dCheckDepth = BL.GetFaceElevation( Proc.Id, nFacInd) + else + dCheckDepth = dDepth + end + end + sMilling = ML.FindMilling( 'AntiSplintMillCut' .. EgtIf( bMillDown and not bDoubleSide, '_H2', ''), dCheckDepth) or + ML.FindMilling( 'AntiSplintMillCut' .. EgtIf( bMillDown and not bDoubleSide, '_H2', ''), 2/3 * dCheckDepth) or + ML.FindMilling( 'AntiSplintMillCut' .. EgtIf( bMillDown and not bDoubleSide, '_H2', '')) + + if sMilling then + + local vtN1 + local nFirstId, nNumId + local dMaxElevMaster + local dExtraDepth = 0 + local dCollSic + -- recupero i dati dell'utensile + local dTDiam = 50 + local dMaxDepth = 0 + local TI = GetToolInfoForMachining( sMilling) + if TI then + dTDiam = TI.dDiam or dTDiam + dMaxDepth = TI.dMaxDepth or dMaxDepth + end + + -- se non ho la faccia aggiunta + if not nPathInt then + -- ottengo i percorsi da cui estrapolare il percorso di antischeggia + local tFacAdjMain = ChooseContour( Proc, nFacInd, false) + local tPaths = {} + -- se non trovato nessun angolo interno valido esco + if #tFacAdjMain == 0 then + return true, sMyWarn + end + -- prendo il primo versore + _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + dCollSic = CalcCollisionSafety( vtN1) or 0 + -- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra + if abs( vtN1:getX()) > 0.7 or abs( vtN1:getY()) > 0.7 or abs( vtN1:getZ()) > 0.7 then dCollSic = 0 end + + -- se fresatura da sotto salto la lavorazione + if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then + local sErr = 'Error : milling from bottom' + EgtOutLog( sErr) + return false, sErr + end + local ptIniPath + local nMaxLen = 0 + dMaxElevMaster = BL.GetFaceElevation( Proc.Id, nFacInd) + -- ciclo tutta la tabella + for i = 1, #tFacAdjMain do + -- le 2 facce di contatto devono essere perpendicolari o non sottosquadra rispetto alla faccia di fondo + local ptP1, ptP2, dAng + ptP1 = tFacAdjMain[i][3] + ptP2 = tFacAdjMain[i][4] + dAng = tFacAdjMain[i][5] + if ( dAng < 0 and 180 + dAng >= 90 - 10 * GEO.EPS_SMALL) then + -- creo la linea da P1 a P2 + nAuxId = EgtLine( _nAddGrpId, ptP1, ptP2, GDB_RT.GLOB) + table.insert( tPaths, nAuxId) + -- prendo la lunghezza massima e il punto iniziale + if tFacAdjMain[i][2] > nMaxLen then + ptIniPath = ptP1 + nMaxLen = tFacAdjMain[i][2] + end + end + end + -- costruisco il/i percorso/i + nFirstId, nNumId = EgtCurveCompoByReorder( _nAddGrpId, tPaths, ptIniPath, true, GDB_RT.GLOB) + local bOkPath = true + for i = 1, nNumId do + local nIdPath = nFirstId + i - 1 + if EgtCurveIsClosed( nIdPath) then + bOkPath = false + end + end + -- se ho un percorso chiuso cancello tutto + if not bOkPath then + for i = 1, nNumId do + local nIdPath = nFirstId + i - 1 + EgtErase(nIdPath) + end + else + -- creo percorsi antisplint dagli estremi dei percorsi di contorno trovati + for i = 1, nNumId do + local nIdPath = nFirstId + i - 1 + pPaths = MakePathsOnExtremePoints( nIdPath, pPaths, dTDiam) + end + end + -- alrimenti ho la faccia aggiunta + else + dCollSic = CalcCollisionSafety( vtOrtho) + nFirstId = EgtCopyGlob( nPathInt, _nAddGrpId) + nNumId = 1 + -- calcolo elevazione dalla faccia trasversale aggiunta + if bDoubleSide then + dMaxElevMaster = 0.5 * dDepth + else + dMaxElevMaster = dDepth + -- se la precedente svuotatura è stata fatta completamente in una sola volta + -- valuto di nuovo se devo fare due passate o una sola + if bOneShot then + -- se non è possibile svuotare completamente da una sola parte + if dMaxDepth <= ( dMaxElevMaster + BD.CUT_EXTRA + dCollSic) then + bDoubleSide = true + dMaxElevMaster = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + else + dExtraDepth = dMaxElevMaster - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + end + -- altrimenti non è stata fatta completamente calcolo la distanza tra faccia aggiunta e profondità superficie + else + dExtraDepth = dMaxElevMaster - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0) + end + end + vtN1 = Vector3d(vtOrtho) + local bOkPath = SetOpenSide( nFirstId, vtOrtho, 2) + -- se non ho un percorso chiuso estraggo i percorsi + if bOkPath then + -- creo percorsi antisplint dagli estremi dei percorsi di contorno trovati + pPaths = MakePathsOnExtremePoints( nFirstId, pPaths, dTDiam) + end + EgtErase(nFirstId) + end + + if #pPaths > 0 then + sMyWarn = MakeAntiSplintByMill( Proc, pPaths, nPathInt, vtN1, + bDoubleSide, false, sMilling, sMyWarn, + dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId) + if bDoubleSide then + if bMillDown then + local sMillingDn = ML.FindMilling( 'AntiSplintMillCut_H2', dCheckDepth) or + ML.FindMilling( 'AntiSplintMillCut_H2', 2/3 * dCheckDepth) or + ML.FindMilling( 'AntiSplintMillCut_H2') + sMilling = sMillingDn + -- controllo dati lavorazione + local TI = GetToolInfoForMachining( sMilling) + if TI then + dTDiam = TI.dDiam or dTDiam + dMaxDepth = TI.dMaxDepth or dMaxDepth + end + end + -- se lavorazione valida + if sMilling then + sMyWarn = MakeAntiSplintByMill( Proc, pPaths, nPathInt, vtN1, + bDoubleSide, true, sMilling, sMyWarn, + dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId) + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library' + end + end + -- altrimenti non c'è il percorso + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path' + end + -- altrimenti non è stata trovata lavorazione + else + sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library' + end + if #sMyWarn > 0 then + EgtOutLog( sMyWarn) + end + + return true, sMyWarn +end + +--------------------------------------------------------------------- +local function DoSideMill( Proc, sName, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir, bHalf, dV) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + sName = EgtGetName( nMchFId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, tFData.nFacInd}}) + -- imposto uso del lato faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHeadDir, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT)) + -- calcolo step effettivo ed elevazione + local dVcalc = dV - dMaxMat + local dStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMaxMat + local nStep = ceil( dVcalc / dStep) + if tFData.vtN:getZ() < - 0.5 and ( nStep % 2) == 0 then + nStep = nStep + 1 + end + dStep = dVcalc / nStep + 0.1 + EgtSetMachiningParam( MCH_MP.STEP, dStep) + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dVcalc + dStep, 2) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- attacchi e uscite + if tFData.vtN:getZ() > -0.5 then + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, tFData.dFacElev + BD.CUT_SIC) + else + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + BD.CUT_SIC) + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.LINEAR) + EgtSetMachiningParam( MCH_MP.LOTANG, 0) + EgtSetMachiningParam( MCH_MP.LOPERP, tFData.dFacElev + BD.COLL_SIC) + if bHalf then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dH / 2) + end + end + -- tipo passate multiple + local nStepType = EgtIf( ( Proc.HeadDir and tFData.vtN:getY() < -0.5) or ( not Proc.HeadDir and tFData.vtN:getY() > 0.5), MCH_MILL_ST.ONEWAY, MCH_MILL_ST.ZIGZAG) + EgtSetMachiningParam( MCH_MP.STEPTYPE, nStepType) + -- imposto posizione braccio porta testa + local nSCC = EgtIf( ( tFData.vtN:getY() > 0.5 or ( bHeadDir and tFData.vtN:getZ() > 0.5 ) or ( not bHeadDir and tFData.vtN:getZ() < -0.5)), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- se divisa in due metà + if bHalf then + local nMchFNId = EgtCopyMachining( sName .. '_2', sName) + if not nMchFNId then + local sErr = 'Error copying machining ' .. sName + EgtOutLog( sErr) + return false, sErr + end + -- inverto direzione e lato di lavoro e direzione ausiliaria + local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvert) + local nWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE) + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nWorkSide == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( nSCC == MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFNId, false) + return false, sErr + end + end + + return true, '' +end + +--------------------------------------------------------------------- +local function MakeSideMill( Proc, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir) + local dH, dV + -- recupero la larghezza della faccia perpendicolarmente alle altre 2 + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, EgtIf( tFData.nFacInd == 0, 1, 0), GDB_ID.ROOT) + local vtX = vtN2 ^ tFData.vtN + local frRef = Frame3d( tFData.ptC, tFData.ptC + 100 * vtX, tFData.ptC + 100 * vtN2) + local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, tFData.nFacInd, GDB_BB.STANDARD, frRef) + if b3Ref then + dV = b3Ref:getDimY() + dH = b3Ref:getDimX() + end + -- se lavorazione da sotto e lunga, va divisa in due metà + local bHalf = ( tFData.vtN:getZ() < -0.5 and dH > ( BD.MAX_LEN_BH_FROM_BOTTOM or 200)) + -- inserisco la lavorazione di fresatura + local sName = 'BHMill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + local bOk, sErr = DoSideMill( Proc, sName, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir, bHalf, dV) + return bOk, sErr +end + +--------------------------------------------------------------------- +local function MakeSpecialThreeFaces( Proc, tFData) + -- se orientata verso il basso, verifico l'alternativa + if tFData.vtN:getZ() < BD.NZ_MINA and tFData.vtN2:getZ() < BD.NZ_MINA then + local sErr = 'Error : special LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- eventuali tagli preliminari + do + local bOk, sErr = MakePreCuts( Proc) + if not bOk then return false, sErr end + end + -- Recupero la lavorazione di fresa + local sMilling = ML.FindMilling( 'LongSmallCut') + if not sMilling then + local sErr = 'Error : LongSmallCut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero la lavorazione di svuotatura + local sMchFind = 'Pocket' + -- se forzato uso truciolatore + if Q_USE_ROUGH_TOOL == 1 then + sMchFind = 'OpenPocket' + end + local dDiam = min( tFData.dH, tFData.dV) + local dDiam2 = min( tFData.dH2, tFData.dV2) + local dCollSic = 2 * BD.COLL_SIC + local dCollSic2 = 2 * BD.COLL_SIC + if abs( tFData.vtN:getX()) > 0.7 or abs( tFData.vtN:getY()) > 0.7 or abs( tFData.vtN:getZ()) > 0.7 then dCollSic = 0 end + if abs( tFData.vtN2:getX()) > 0.7 or abs( tFData.vtN2:getY()) > 0.7 or abs( tFData.vtN2:getZ()) > 0.7 then dCollSic2 = 0 end + local sPocketing = ML.FindPocketing( sMchFind, dDiam2, tFData.dFacElev2 + dCollSic2) + local nPockFace = tFData.nFacInd2 + -- se non trova una svuotatura adatta provo ad assegnarla all'altra faccia + if not sPocketing then + dDiam, dDiam2 = dDiam2, dDiam + dCollSic, dCollSic2 = dCollSic2, dCollSic + tFData = SwapFacetsData( tFData) + + -- prendo a riferimento la seconda faccia per la svuotatura + sPocketing = ML.FindPocketing( sMchFind, dDiam2, tFData.dFacElev2 + dCollSic2) + + if not sPocketing then + local sErr = 'Error : ' .. sMchFind .. ' not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + + -- provo con contornatura + local dDiamTool = 20 + -- verifico se forma ad L + local bIsU, bIsL = TestUL( Proc) + if bIsL then + local bOk, sWarn + bOk, sWarn, _ = MakeByMill( Proc, tFData, dCollSic, true, sMilling) + if not bOk then return bOk, sWarn end + else + local sErr = 'Error : Impossible mill special LapJoint' + EgtOutLog( sErr) + return false, sErr + 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( {{ Proc.Id, nPockFace}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if tFData.vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- se tasca aperta, imposto opportuno attacco + if sMchFind == 'OpenPocket' then + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + end + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( tFData.dFacElev2, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + -- se abilitato dal parametro Q inserisco foro sullo spigolo + if Q_BORE_ON_CORNER == 1 then + local bOk, sWarn = MakeDrillOnCorner( Proc, 0, dDiamTool, true) + if not bOk then return false, sWarn end + -- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura + elseif Q_BORE_ON_CORNER == 2 then + local bOk, sWarn = MakeSharpCleanCorner( Proc, 0, dDiamTool) + if not bOk then return false, sWarn end + end + + return true, '' +end + +--------------------------------------------------------------------- +local function MakeByChainsaw( Proc, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId) + -- verifico se posso farlo con la sega-catena + local bMakeChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick = VerifyChainSaw( dDimMin, dDimMax) + + if bMakeChainSaw then + -- Verifico se necessarie più passate + local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dDimMin - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- inserisco la lavorazione di sawing + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLongFaceId}}) + -- imposto uso del lato faccia + -- al momento, dato che la fessura è passante da parte a parte, gestisco solo la lavorazione + -- dall'alto e di fronte (da dietro è disabilitata perchè ho exracorsa con la FAST). + -- Questa feature non è applicata su facce di testa e quindi non controllo l'entrata in X + if abs(vtOrtho:getZ()) >= 0.707 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nLongFaceId, GDB_ID.ROOT) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho)) + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se possibile aumento l'affondamento pari al raggio corner + 1 + if dMaxMat > (dDepth + dSawCornerRad + 1) then + EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad + 1)) + -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning + elseif dMaxMat < dDepth then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) + local sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- eseguo + if not EgtApplyMachining( true, false) then + if EgtGetOutstrokeInfo() then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2)) + EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho)) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + if EgtIsMachiningEmpty() then + local _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeSidePocketings( Proc, tFData, dCollSic, bSpecialMillOnSide, + nBottomFace, sMillingOnSide, dToolDiamOnSide, dThickMillOnSide, + bSinglePart, bIsU, bIsL, dDiam, bMillDown, bMillUp, sMchFind, sMchFindBackUp) + local bTryWithBlades = true + local nOk, bOk, sWarn, sStat, sErr, dDimMin, dDimMax, dDepth, vtOrtho, bOrthoFaces, nSurfInt, sPocketing, nLongFaceId + if bSpecialMillOnSide then + -- eseguo + bOk, sWarn = MakeByMillAsSaw( Proc, tFData, nBottomFace, sMillingOnSide, dToolDiamOnSide, dThickMillOnSide) + if bOk then + return 1, true, sWarn + end + end + -- se feature 16 o 17 e se forzata lama provo prima con questa e poi con la fresa + if ( Proc.Prc == 16 or Proc.Prc == 17) and _bForceUseBlade then + -- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame + if bTryWithBlades and _nChamfer < 2 then + -- anche su macchine con testa da sotto, la sega a catena è solo da sopra + if tFData.vtN:getZ() < BD.NZ_MINA and BD.DOWN_HEAD and tFData.nFacInd2 then + tFData = SwapFacetsData( tFData) + end + -- eseguo + bOk, sWarn, sStat = MakeByChainOrSaw( Proc, tFData, dDimMin, dDimMax, vtOrtho, nil, bOrthoFaces, nBottomFace, nSurfInt) + if not bOk then + -- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e + -- se non è possibile allora provo in seguito con lama o segacatena + -- o passare subito dalla lavorazione con lama/sega catena + if Proc.Fct == 3 and bIsU then + -- lavoro con svuotature (singola o doppia contrapposta) + nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, _, _, _, _, _, _, _, _, bOrthoFaces = MakeByPockets( Proc, nil, bMillDown) + -- se lavorazione non idonea (asse della feature troppo inclinato e impossibile lavorare completamente da due parti) + if nOk == -2 then + if not sMchFind then + sMchFind = sMchFindBackUp + end + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr = 'Error : ' .. sMchFind .. ' not found in library' + EgtOutLog( sErr) + return 1, false, sErr + end + elseif nOk < 0 then + return 1, false, sErr + elseif nOk == 0 then + if sStat == 'MNF' then + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr = 'Error : ' .. sMchFind .. ' not found in library' + EgtOutLog( sErr) + return 1, false, sErr + end + else + return 1, bOk, sWarn + end + else + bOk = true + return 1, bOk, sErr + end + else + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr = 'Error : ' .. sMchFind .. ' not found in library' + EgtOutLog( sErr) + return 1, false, sErr + end + end + else + return 1, bOk, sWarn + end + else + -- se devo inserire il chamfer + if ( ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 2 and bIsL)) and _nChamfer > 0 then + -- ottengo le dimensioni dello pseudotunnel + local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) + local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt) + if nOk < 0 then return 1, false, sErr end + end + bOk = true + return 1, bOk, sWarn + end + else + -- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo + -- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa + -- 2021.04.27 esegue antischeggia di lama se forma U o L con feature passante in Y o Z + -- 2021.07.16 Per poter eseguire antischeggia di lama su feature che non sono passanti da faccia a faccia + -- ma che sono su un angolo (coinvolgono 2 facce contigue) è stato modificato il confronto in: + -- esegue antischeggia di lama se forma U o L con feature passante in Y o Z, oppure se feature a furma U e con 3 facce oppore a forma a L e con 2 facce + local bPassThrou = ( Proc.Box:getDimY() > _b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > _b3Raw:getDimZ() - 1) + local bPassEdge = ( ( ( bIsU and Proc.Fct == 3) or ( bIsL and Proc.Fct == 2)) and bSinglePart and Proc.Box:getDimX() < 0.9 * _b3Raw:getDimX()) + if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 1 and ( ( bIsU or bIsL) and ( bPassThrou or bPassEdge)) then + local bOk + local bSawDown = ( bMillDown and not bMillUp) + _, bOk, sWarn = ManageAntiSplintBySaw( Proc, bIsU, tFData.vtN, tFData.nFacInd, sWarn, bSawDown, true) + if not bOk then return 1, false, sWarn end + end + -- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e + -- se non è possibile allora provo in seguito con lama o segacatena + -- o passare subito dalla lavorazione con lama/sega catena + if _bTrySidePocketAtFirst and Proc.Fct == 3 and bIsU then + -- lavoro con svuotature (singola o doppia contrapposta) + local dDiamTool = 100 + local nPathInt, nSurfInt, bOneShot, nFirstMachId, bDoubleSide + nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, dDiamTool, + bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, bOrthoFaces = MakeByPockets( Proc, nil, bMillDown) + if nOk == -2 then + if not sMchFind then + sMchFind = sMchFindBackUp + end + sPocketing = ML.FindPocketing( sMchFind, dDiam) + if not sPocketing then + local sErr2 = 'Error : ' .. sMchFind .. ' not found in library' + EgtOutLog( sErr2) + return 1, false, sErr2 + end + bTryWithBlades = false + sWarn = sErr + elseif nOk < 0 then + return 1, false, sErr + elseif nOk > 0 then + bTryWithBlades = false + sWarn = sErr + -- se ho antischeggia con fresa le inserisco + if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 2 then + local bOk, sWarn2 = ManageAntiSplintByMill( Proc, tFData.nFacInd, bMillDown, bDoubleSide, vtOrtho, + nPathInt, nSurfInt, dDepth, bOneShot, nFirstMachId) + sWarn = FormatWarning( sWarn, sWarn2) + end + -- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola + if Q_CONTOUR_SMALL_TOOL > 0 then + local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, tFData.nFacInd, dDiamTool, bMillDown, + bDoubleSide, vtOrtho, nPathInt, nSurfInt, dDepth, bOneShotm) + if not bOk then return 1, false, sWarn2 end + sWarn = FormatWarning( sWarn, sWarn2) + end + end + bOk = true + end + -- 03/09/2020 da conferma di Fabio Squaratti: Per ora solo sulla feature 016: + -- se ha fallito la fresatura (qua sopra) allora di default (anche se il flag Q della lama è disattivato) prima provo la lama + if Proc.Prc == 16 then + _bForceUseBlade = true + end + -- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame + if bTryWithBlades and _nChamfer < 2 then + -- anche su macchine con testa da sotto, la sega a catena è solo da sopra + if tFData.vtN:getZ() < BD.NZ_MINA and BD.DOWN_HEAD and tFData.nFacInd2 then + tFData = SwapFacetsData( tFData) + end + -- eseguo + bOk, sWarn, sStat = MakeByChainOrSaw( Proc, tFData, dDimMin, dDimMax, vtOrtho, nLongFaceId, bOrthoFaces, nBottomFace, nSurfInt) + if not bOk and sStat == 'MNF' then + _, sPocketing = VerifyPocket( dDiam, tFData.dFacElev + dCollSic, nil, sMchFind) + if sPocketing then + sWarn = '' + else + local sErr2 = 'Error : ' .. sMchFind .. ' not found in library' + EgtOutLog( sErr2) + return 1, false, sErr2 + end + else + -- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola + if Q_CONTOUR_SMALL_TOOL > 0 then + local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, tFData.nFacInd, 100, bMillDown) + if not bOk then return 1, false, sWarn2 end + sWarn = FormatWarning( sWarn, sWarn2) + end + return 1, bOk, sWarn + end + -- altrimenti verifico se ho già svuotato dal fianco, se si esco + else + -- se non ho annullato la/le svuotatura/e dal fianco + if nOk ~= -2 then + return 1, bOk, sWarn + end + end + end + + return 0, true, '' +end + +--------------------------------------------------------------------- +local function MakePocketingOrMilling( Proc, tFData, bSinglePart) + -- verifico se forma ad U o L + local bIsU, bIsL = TestUL( Proc) + local bUseOtherFace + -- se orientata verso il basso e non c'è testa da sotto, verifico l'alternativa + if tFData.vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD and tFData.nFacInd2 then + tFData = SwapFacetsData( tFData) + bUseOtherFace = true + end + -- verifico non sia orientata verso il basso o ci sia una testa dal basso + local bFaceDown = ( tFData.vtN:getZ() < BD.NZ_MINA) + if bFaceDown and not BD.DOWN_HEAD then + local sErr = 'Error : LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- se forma a L e la componente in X è maggiore di 60° e non in testa allora verifico se posso utilizzare la faccia secondaria + if bIsL and abs( tFData.vtN:getX()) > 0.866 and + ( Proc.Box:getMax():getX() < _b3Solid:getMax():getX() - 10 or tFData.vtN:getX() < 0) and + ( not Proc.Tail or tFData.vtN:getX() > 0) then + -- se non ho scambiato la faccia + if not bUseOtherFace then + if tFData.nFacInd2 then + tFData = SwapFacetsData( tFData) + -- altrimenti cerco la faccia secondaria per adiacenza alla principale + else + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj, sErr = GetFaceAdj( Proc, tFData) + if nFacAdj < 0 then + EgtOutLog( sErr) + return false, sErr + end + tFData = UpdateFacet1Data( Proc.Id, tFData, nFacAdj) + end + -- altrimenti se ho già cambiato faccia do errore per impossibilità di lavorazione + else + local sErr = 'Error : impossible to machine by side angle too big that cause collision' + EgtOutLog( sErr) + return false, sErr + end + end + -- eventuali tagli preliminari + do + local bOk, sErr = MakePreCuts( Proc) + if not bOk then return false, sErr end + end + -- imposto altezza aggiuntiva di elevazione + local dCollSic = CalcCollisionSafety( tFData.vtN) + -- abilitazione lavorazione da sotto + local bMillUp = ( BD.DOWN_HEAD and tFData.vtN:getZ() > -0.259) + local bMillDown = ( BD.DOWN_HEAD and tFData.vtN:getZ() < 0.342) + -- settaggio voluto da Alessandro/Fabio (per fare angoli con fresa piccola) + local sMchFind = 'Pocket' + local dDiam = min( tFData.dH, tFData.dV) + local bTailOnSide = ( Proc.Box:getMin():getX() - _b3Solid:getMin():getX() < 0.1 and not Proc.Tail) + if ( Proc.Fct == 1) or ( ( Proc.Fct == 2 or Proc.Fct == 3) and bIsL) or ( ( ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 4 and not bTailOnSide)) and bSinglePart) then + sMchFind = 'OpenPocket' + if bIsU then + dDiam = GetUShapeWidth( Proc, tFData.nFacInd) or dDiam + elseif Proc.Fct == 4 then + -- per rifinire gli angoli premio utensile diam 25 o da BD + dDiam = min( dDiam, BD.MAXDIAM_POCK_CORNER or 30) + elseif Proc.Fct == 3 and bIsL then + -- per rifinire gli angoli premio utensile diam 25 o da BD + dDiam = min( 2 * dDiam, BD.MAXDIAM_POCK_CORNER or 30) + else + dDiam = 2 * dDiam + end + end + sMchFindBackUp = sMchFind + local nUseRoughTool = EgtIf( bSinglePart, 0, 1) + -- 04/08/2020 Se settato parametro uso truciolatore (parametro Q), non si devono prendere altre frese, si da errore (Fabio) + -- Questa opzione si scontra facilmente con altre interpretazioni dello stasso parametro Q (per tornare indietro bNewCheck = false) + local bNewCheck = true + -- se processo 20 e non sto usando il truciolatore + if bNewCheck and Proc.Prc == 20 and nUseRoughTool == 0 then + -- verifico se forzato uso truciolatore + if Q_USE_ROUGH_TOOL and Q_USE_ROUGH_TOOL ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + end + end + -- 03/12/2020 aggiunto controllo su feature 30 senza uso truciolatore + if bNewCheck and Proc.Prc == 30 and nUseRoughTool == 0 then + -- verifico se forzato uso truciolatore + if Q_SIDE_ROUGH_TOOL and Q_SIDE_ROUGH_TOOL ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + end + end + -- se processo 20 e non sto usando il truciolatore + if Proc.Prc == 20 and nUseRoughTool == 0 then + if Q_USE_ROUGH_TOOL and Q_USE_ROUGH_TOOL ~= 0 then + sMchFind = 'OpenPocket' + nUseRoughTool = 1 + end + end + -- se da sotto, imposto massima lunghezza secondo la direzione + local dMaxTotLen + if bMillDown and BD.GetBottomToolMaxTotLen then + dMaxTotLen = BD.GetBottomToolMaxTotLen( tFData.vtN) + end + -- ricerca lavorazione + local sPocketing + local _, sMyPocketing, dMyTMaxDepth, _ = VerifyPocket( dDiam, tFData.dFacElev + dCollSic, dMaxTotLen, sMchFind .. EgtIf( bMillDown, '_H2', '')) + if not sMyPocketing and bMillUp then + _, sMyPocketing, dMyTMaxDepth, _ = VerifyPocket( dDiam, tFData.dFacElev + dCollSic, dMaxTotLen, sMchFind) + bMillDown = false + end + --local sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, dFacElev + dCollSic, dMaxTotLen) + --if not sMyPocketing then + -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, nil, dMaxTotLen) + --end + --if not sMyPocketing and bMillUp then + -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic) + -- if not sMyPocketing then + -- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam) + -- end + -- bMillDown = false + --end + if sMyPocketing and + ( dMyTMaxDepth > tFData.dFacElev + dCollSic - 10 * GEO.EPS_SMALL or ( dMyTMaxDepth > 0.8 * tFData.dFacElev + dCollSic and not bIsU) or ( bIsL and nUseRoughTool == 0)) then + sPocketing = sMyPocketing + end + if bMillDown then + sMchFind = sMchFind .. '_H2' + end + -- 2021.09.16 Richiesta di Fabio Squaratti per lavorazione "Lamello": + -- se ho attiva questo tipo di lavorazione (delle fresature) e una di queste feature: L016, L030, L032, L039 + -- verifico se sono compatibili con questa lavorazione forma a U e larga più dell'altezza tagliente e profondità compatibile con + local bSpecialMillOnSide + local dThickMillOnSide = 0 + local sMillingOnSide + local dToolDiamOnSide = 0 + local dMaxDepthOnSide = 0 + if ( Proc.Prc == 16 or Proc.Prc == 30 or Proc.Prc == 32 or Proc.Prc == 39) then + -- verifico se ho una gola con 3 facce ed eventualmente delle facce terminali: + -- faccio una copia della superfice ed elimino le facce che hanno dimensione X < 1 e le facce risultanti devono essere una U + local nTestId = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL + if nTestId then + local bNewIsU + local bExit + local nFaces = EgtSurfTmFacetCount( nTestId) + while not bExit and nFaces >= 3 do + local bDeleteFace + local nInt = 0 + while not bDeleteFace and nInt < nFaces do + nInt = nInt + 1 + local b3Facet = EgtSurfTmGetFacetBBoxGlob( nTestId, nInt - 1, GDB_BB.STANDARD) + local vtNi = EgtSurfTmFacetNormVersor( nTestId, nInt - 1, GDB_ID.ROOT) + -- se dimensione faccia sulla X + if b3Facet:getDimX() < 1 or abs( vtNi:getX()) > 0.1 then + EgtSurfTmRemoveFacet( nTestId, nInt - 1) + bDeleteFace = true + end + end + nFaces = EgtSurfTmFacetCount( nTestId) + -- se non ho cancellato una faccia faccio il test per forma ad U + if not bDeleteFace then + -- ottengo il numero di facce rimanenti + bNewIsU = ( nFaces == 3 and not TestElleShape3( nTestId, true)) + bExit = true + end + end + -- verifico che la componente x della faccia 0 deve essere nulla + local vtN1 = EgtSurfTmFacetNormVersor( nTestId, 0, GDB_ID.ROOT) + if bNewIsU and abs( vtN1:getX()) > 0.01 then + bNewIsU = false + end + -- cancello la copia del percorso + EgtErase( nTestId) + + if bNewIsU and ( not BD.MIN_LEN_LAMELLO or + ( Proc.TotBox and Proc.TotBox:getDimX() > BD.MIN_LEN_LAMELLO) or + ( not Proc.TotBox and Proc.Box:getDimX() > BD.MIN_LEN_LAMELLO)) then + -- recupero la lavorazione + if BD.DOWN_HEAD and tFData.vtN:getZ() < BD.NZ_MINA then + sMillingOnSide = ML.FindMilling( 'SideMillAsBlade_H2') + else + sMillingOnSide = ML.FindMilling( 'SideMillAsBlade') + end + + if sMillingOnSide then + -- recupero i dati dell'utensile + local dToolLength = 0 + local TI = GetToolInfoForMachining( sMillingOnSide) + if TI then + dToolLength = TI.dLength or dToolLength + dToolDiamOnSide = TI.dDiam or dToolDiamOnSide + dThickMillOnSide = TI.dMaxMat or dThickMillOnSide + dMaxDepthOnSide = TI.dSideDepth or dMaxDepthOnSide + end + -- 2021.09.17 Su conferma di Fabio Squaratti, se la gola è più stretta dell'utensile o la profondità della gole è maggiore + -- del valore parametro SIDEDEPTH (preso dalle note utente dell'utensile) allora si prosegue come se non fosse abilitata + -- questo tipo di lavorazione SideMillAsBlade + if dDiam > dThickMillOnSide - 10 * GEO.EPS_SMALL and tFData.dFacElev < dMaxDepthOnSide + 10 * GEO.EPS_SMALL then + bSpecialMillOnSide = true + -- disabilito eventuale svuotatura + sPocketing = nil + end + end + end + end + end + -- se feature 16 e forzata lama e forma ad U, annulla la svuotatura + if Proc.Prc == 16 and _bForceUseBlade and Proc.Fct == 3 and bIsU then + sPocketing = nil + end + -- se lavorazione fresa come lama disabilito eventuale antischegggia + if bSpecialMillOnSide then Q_ANTISPLINT_TYPE = 0 end + -- se non trova una svuotatura adatta + if not sPocketing then + -- se forma a L provo con contornatura + if bIsL and not bSpecialMillOnSide then + -- se smusso non è esclusivo + if _nChamfer < 2 then + return MakeByMill( Proc, tFData, dCollSic) + end + -- altrimenti, in base alla forma, provo con svuotature di fianco o con la sega a catena o lama + else + local stat, bOk, sWarn = MakeSidePocketings( Proc, tFData, dCollSic, bSpecialMillOnSide, nBottomFace, + sMillingOnSide, dToolDiamOnSide, dThickMillOnSide, bSinglePart, + bIsU, bIsL, dDiam, bMillDown, bMillUp, sMchFind, sMchFindBackUp) + if stat == 1 then + return bOk, sWarn + end + end + else + -- se devo inserire il chamfer + if ( ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 2 and bIsL)) and _nChamfer > 0 then + -- ottengo le dimensioni dello pseudotunnel + local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) + local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt) + if nOk < 0 then return false, sErr end + end + end + -- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo + -- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa + -- 2021.04.27 esegue antischeggia di lama se forma U o L con feature passante in Y o Z + -- 2021.07.16 Per poter eseguire antischeggia di lama su feature che non sono passanti da faccia a faccia + -- ma che sono su un angolo (coinvolgono 2 facce contigue) è stato modificato il confronto in: + -- esegue antischeggia di lama se forma U o L con feature passante in Y o Z, oppure se feature a forma U e con 3 facce oppore a forma a L e con 2 facce + local bMadeASbyBld = false + local bPassThrou = ( Proc.Box:getDimY() > _b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > _b3Raw:getDimZ() - 1) + local bPassEdge = ( ( ( bIsU and Proc.Fct == 3) or ( bIsL and Proc.Fct == 2)) and bSinglePart and Proc.Box:getDimX() < 0.9 * _b3Raw:getDimX()) + if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 1 and ( ( bIsU or bIsL) and ( bPassThrou or bPassEdge)) then + local bOk + local bSawDown = ( bMillDown and not bMillUp) + bMadeASbyBld, bOk, sWarn = ManageAntiSplintBySaw( Proc, bIsU, tFData.vtN, tFData.nFacInd, sWarn, bSawDown) + if not bOk then return false, sWarn end + end + if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 2 then + local bOk, sWarn2 + bOk, sWarn2 = ManageAntiSplintByMill( Proc, tFData.nFacInd, bMillDown) + if not bOk then return false, sWarn2 end + end + -- se smusso non esclusivo + if _nChamfer < 2 then + -- eseguo la svuotatura della faccia principale, mi restituisce id utensile, il diametro utensile per il foro opzionale + local tvtNx = {} + tvtNx[2] = tFData.vtN + local bOk, sWarn2, sTuuidPk, dDiamTool + bOk, sWarn2, sTuuidPk, dDiamTool = MakePocket( Proc, tFData.ptC, tvtNx, tFData.nFacInd, sMchFind, nUseRoughTool, sPocketing, tFData.dFacElev + dCollSic) + if not bOk then return false, sWarn2 end + sWarn = FormatWarning( sWarn, sWarn2) + -- se ho più di 3 facce e non di forma ad U oppure ho 3 facce e di forma ad U + -- e non sono stati inseriti antischeggia di lama + -- controllo se c'è una faccia non ortogonale alla principale e la lavoro con una contornatura o svuotatura + if ( ( Proc.Fct > 3 and not bIsU) or ( Proc.Fct == 3 and bIsU)) and not bMadeASbyBld then + -- Recupero le facce adiacenti alla principale (solo quelle esistenti) + local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd) + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + -- Cerco una faccia adiacente alla principale con angolo > 90 + local tDimAndRef = {} + tvtNx = {} + tvtNx[1] = tFData.vtN + tDimAndRef[1] = { tFData.dH, tFData.dV, tFData.rfFac} + for i = 1, #vAdj do + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT) + if bAdj and dAng < 0 and 180 + dAng > 90.1 then + local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vAdj[i], GDB_ID.ROOT) + _, tvtNx[2] = EgtSurfTmFacetCenter( Proc.Id, vAdj[i], GDB_ID.ROOT) + tDimAndRef[2] = { dH2, dV2, rfFac2} + local ptPs = ( ptP1 + ptP2) / 2 + local bOk, sWarn2 = MachineByMill( Proc, tvtNx, tFData.nFacInd, vAdj[i], ptPs, tDimAndRef, + EgtIf( Proc.Fct == 3 and bIsU, 0, 2), nUseRoughTool, dAng, sPocketing, sTuuidPk, tFData.dFacElev) + if not bOk then return bOk, sWarn2 end + sWarn = FormatWarning( sWarn, sWarn2) + end + end + end + -- se abilitato dal parametro Q inserisco foro sullo spigolo + if Q_BORE_ON_CORNER == 1 then + local bOk, sWarn2 = MakeDrillOnCorner( Proc, tFData.nFacInd, dDiamTool) + if not bOk then return false, sWarn2 end + sWarn = FormatWarning( sWarn, sWarn2) + -- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura + elseif Q_BORE_ON_CORNER == 2 then + local bOk, sWarn2 = MakeSharpCleanCorner( Proc, tFData.nFacInd, dDiamTool) + if not bOk then return false, sWarn2 end + sWarn = FormatWarning( sWarn, sWarn2) + -- altrimenti se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola + elseif Q_CONTOUR_SMALL_TOOL > 0 then + local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, tFData.nFacInd, dDiamTool, bMillDown) + if not bOk then return false, sWarn2 end + sWarn = FormatWarning( sWarn, sWarn2) + end + end + + return true, '' +end + +--------------------------------------------------------------------- +local function MakeTwoFaces( Proc, bSinglePart, bPrevBhSideMill) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if _nChamfer < 0 then + return false, _sErrCham + end + + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local tFData = GetFacetsData( Proc.Id) + if not tFData.nFacInd or tFData.nFacInd < 0 then + local sErr = 'Error : MakeTwoFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + + -- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia + local bMakeBySideMill, _, bHeadDir, sMilling, dMaxMat, dToolDiam = VerifyBHSideMill( Proc, bSinglePart, bPrevBhSideMill) + if bPrevBhSideMill == nil then + bPrevBhSideMill = bMakeBySideMill + end + if bMakeBySideMill and ( dMaxMat <= tFData.dH + 15 * GEO.EPS_SMALL) then + -- se smusso non è esclusivo + if _nChamfer < 2 then + local bOk, sErr = MakeSideMill( Proc, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir) + return bOk, sErr + end + -- altrimenti lavoro con svuotatura + else + local bOk, sErr = MakePocketingOrMilling( Proc, tFData, bSinglePart) + return bOk, sErr + end + + return true, '', bPrevBhSideMill +end + +--------------------------------------------------------------------- +local function MakeThreeFaces( Proc, bSinglePart, bPrevBhSideMill) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if _nChamfer < 0 then + return false, _sErrCham + end + + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local tFData = GetFacetsData( Proc.Id) + if not tFData.nFacInd or tFData.nFacInd < 0 then + local sErr = 'Error : MakeThreeFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + + -- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia + local bMakeBySideMill, _, bHeadDir, sMilling, dMaxMat, dToolDiam = VerifyBHSideMill( Proc, bSinglePart, bPrevBhSideMill) + if bPrevBhSideMill == nil then + bPrevBhSideMill = bMakeBySideMill + end + --if bMakeBySideMill and ( dMaxMat <= tFData.dV + 15 * GEO.EPS_SMALL) then + if bMakeBySideMill and ( dMaxMat <= tFData.dH + 15 * GEO.EPS_SMALL) then + -- se smusso non è esclusivo + if _nChamfer < 2 then + local bOk, sErr = MakeSideMill( Proc, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir) + return bOk, sErr + end + -- altrimenti lavoro con svuotatura + else + local bSpecial3faces = false + local bBoxF = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, tFData.rfFac) + + if tFData.dH * tFData.dV < 0.9 * ( bBoxF:getDimX() * bBoxF:getDimY()) then + bSpecial3faces = true + end + + -- se riconosciuta gestione special (limitata per ora alla feature 20) + if bSpecial3faces and Proc.Prc == 20 and tFData.nFacInd2 then + -- se smusso non è esclusivo + if _nChamfer < 2 then + local bOk, sErr = MakeSpecialThreeFaces( Proc, tFData) + return bOk, sErr + end + -- altrimenti lavorazione di svuotatura o contornatura + else + local bOk, sErr = MakePocketingOrMilling( Proc, tFData, bSinglePart) + return bOk, sErr + end + end + + return true, '', bPrevBhSideMill +end + +--------------------------------------------------------------------- +local function MakeMoreFaces( Proc, bSinglePart, bPrevBhSideMill) + local bClosedOrthoFaces + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local tFData = GetFacetsData( Proc.Id) + if not tFData.nFacInd or tFData.nFacInd < 0 then + if tFData.nFacInd == -1 then + bClosedOrthoFaces = tFData.isOrthoFaces + else + local sErr = 'Error : MakeMoreFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + -- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche + if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then + local nBottomFace + -- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura + for i = 1, Proc.Fct do + local nNewProcId = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL + -- elimino una faccia + nBottomFace = i - 1 + if EgtSurfTmRemoveFacet( nNewProcId, nBottomFace) then + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + tFData = GetFacetsData( nNewProcId) + if not tFData.nFacInd or tFData.nFacInd < 0 then + if tFData.nFacInd == -1 then + bClosedOrthoFaces = tFData.isOrthoFaces + EgtErase( nNewProcId) + break + else + EgtErase( nNewProcId) + local sErr = 'Error : MakeMoreFaces could not find reference face' + EgtOutLog( sErr) + return false, sErr + end + end + -- altrimenti esco + else + EgtErase( nNewProcId) + break + end + end + -- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo + if bClosedOrthoFaces then + local dFacElev = BL.GetFaceElevation( Proc.Id, nBottomFace) + tFData = UpdateFacet1Data( Proc.Id, tFData, nBottomFace, dFacElev) + -- rendo nulla la faccia opzionale perchè si tratta di una fessura + tFData = UpdateFacet2Data( Proc.Id, tFData, nil) + -- non setto come tunnel + bClosedOrthoFaces = false + end + end + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if _nChamfer < 0 then + return false, _sErrCham + end + -- se è un tunnel provo a vedere se è possibile lavorarlo con la svuotatura o con la sega catena + if bClosedOrthoFaces then + local bTryWithBlades = true + -- lavoro fessura con svuotature (singola o doppia contrapposta) + local nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId = MakeByPockets( Proc, bClosedOrthoFaces) + if nOk < 0 then + return false, sErr + elseif nOk > 0 then + bTryWithBlades = false + end + -- Se la svuotatura precedente non è stata fatta e chamfer non è mutuamente esclusivo provo con la sega-catena + if bTryWithBlades and _nChamfer < 2 then + -- verifico se posso farlo con la sega-catena + local bOk, sErr = MakeByChainsaw( Proc, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId) + if not bOk then + return false, sErr + end + end + -- altrimenti non è una fessura + else + local bOk, sErr = MakePocketingOrMilling( Proc, tFData, bSinglePart) + return bOk, sErr, bPrevBhSideMill + end + + return true, '', bPrevBhSideMill +end + +--------------------------------------------------------------------- +local function MakeLongFaces( Proc, Func) + -- divido in parti lungo X + local vAddId = {} + local nPart = max( ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN), 2) + local dPartLen = Proc.Box:getDimX() / nPart + local Xmin = Proc.Box:getMin():getX() + for i = 1, nPart do + -- eseguo divisione + local AddId = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL + EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i)) + if i > 1 then + local ptOn = Point3d( Xmin + ( i - 1) * dPartLen, 0, 0) + EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB) + end + if i < nPart then + local ptOn = Point3d( Xmin + i * dPartLen, 0, 0) + EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB) + end + -- eseguo inserimento in modo da ordinare da X+ a X- + table.insert( vAddId, 1, AddId) + end + -- applico le lavorazioni sulle diverse parti + local sWarn + local bPrevBhSideMill + for i = 1, #vAddId do + local b3Box = EgtGetBBoxGlob( vAddId[i], GDB_BB.STANDARD) + local nFct = EgtSurfTmFacetCount( vAddId[i]) + local AddProc = { Id = vAddId[i], Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Box, TotBox = Proc.Box, Fct = nFct, Flg = Proc.Flg} + local bOk, sMyWarn + -- richiamo la funzione necessaria (passata come parametro) + bOk, sMyWarn, bPrevBhSideMill = Func( AddProc, false, bPrevBhSideMill) + if not sWarn then sWarn = sMyWarn end + if not bOk then return bOk, sWarn end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function TestTwoFacesDownHead( Proc) + -- verifico ci siano due facce + if Proc.Fct ~= 2 then return false end + -- verifico se da lavorare con testa da sotto + local bDownHead = false + if BD.DOWN_HEAD then + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + bDownHead = ( vtNm:getZ() < -0.5) + end + return bDownHead +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +--------------------------------------------------------------------- +function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- inizializzo variabili globali al modulo + local bOk, sErr = InitGlob( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then + return bOk, sErr + end + -- limiti di fresatura semplice + local MAX_MILL_LIN = 80 + -- se non forzate frese, uso la lama + local bUseBlade = Q_USE_ROUGH_TOOL ~= 1 and Q_USE_MILL ~= 1 + local nForceUseBladeOnNotContinueFace + -- se ho attiva la lama e ho la feature 30, verifico i parametri Q propri della feature + if bUseBlade then + if Proc.Prc == 30 then + nForceUseBladeOnNotContinueFace = Q_BLADE_ON_ALONG_FACE + -- se antischeggia di fresa o abilitato sgrossatore di fianco + if Q_ANTISPLINT_TYPE == 2 or Q_SIDE_ROUGH_TOOL == 1 then + bUseBlade = false + end + -- se ho attiva la lama e ho la feature 32, verifico i parametri Q propri della feature + elseif Proc.Prc == 32 then + -- se antischeggia di fresa o abilitato sgrossatore di fianco + if Q_ANTISPLINT_TYPE == 2 or Q_SIDE_ROUGH_TOOL == 1 then + bUseBlade = false + end + -- se ho attiva la lama e ho la feature 34, verifico i parametri Q propri della feature + elseif Proc.Prc == 34 then + -- se antischeggia di fresa o abilitato sgrossatore di fianco + if Q_ANTISPLINT_TYPE == 2 then + bUseBlade = false + end + end + end + -- se lunghezza richiede spezzatura + if ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or + ( Proc.Box:getDimX() > 0.7 * _b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN) then + -- una faccia + if Proc.Fct == 1 then + if bUseBlade and nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId) + end + -- due facce + elseif Proc.Fct == 2 then + -- verifico se da lavorare con testa da sotto + local bDownHead = TestTwoFacesDownHead( Proc) + -- determino se due facce lunghe oppure una lunga e l'altra terminale + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) + local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD) + if abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 then + -- leggo i parametri Q per utilizzare la fresa di fianco e/o lama + return Long2Cut.Make( Proc, _nPhase, _nRawId, _nPartId, Q_ANTISPLINT_TYPE == 1, Q_SIDE_ROUGH_TOOL) + elseif b3Fac1:getDimX() < 1 or b3Fac2:getDimX() < 1 then + -- la faccia 0 deve essere quella lunga + if b3Fac1:getDimX() < 1 then EgtSurfTmSwapFacets( Proc.Id, 0, 1) end + if bUseBlade then + if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return Fbs.MakeTwo( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead) + end + else + return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId) + end + else + if bUseBlade then + return Fbs.MakeTwo( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead) + else + return MakeLongFaces( Proc, MakeTwoFaces) + end + end + -- tre facce + elseif Proc.Fct == 3 then + -- determino se due facce lunghe oppure una lunga e l'altra terminale + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) + local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD) + local b3Fac3 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 2, GDB_BB.STANDARD) + local bApplyBladeOnLongNotContinueFace + + if b3Fac1:getDimX() < 1 and b3Fac3:getDimX() < 1 then + -- la faccia 0 deve essere quella lunga + EgtSurfTmSwapFacets( Proc.Id, 0, 1) + bApplyBladeOnLongNotContinueFace = true + elseif b3Fac1:getDimX() < 1 and b3Fac2:getDimX() < 1 then + -- la faccia 0 deve essere quella lunga + EgtSurfTmSwapFacets( Proc.Id, 0, 2) + bApplyBladeOnLongNotContinueFace = true + elseif b3Fac2:getDimX() < 1 and b3Fac3:getDimX() < 1 then + bApplyBladeOnLongNotContinueFace = true + end + + if bApplyBladeOnLongNotContinueFace and bUseBlade and nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then + return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, nForceUseBladeOnNotContinueFace) + else + return MakeLongFaces( Proc, MakeThreeFaces) + end + -- 4 o 5 facce + else + return MakeLongFaces( Proc, MakeMoreFaces) + end + -- altrimenti lavorazione unica + else + -- una faccia + if Proc.Fct == 1 then + -- se piccola, con fresa + if not bUseBlade and ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then + return MakeOneFaceByMill( Proc) + -- altrimenti, con lama + else + return Cut.Make( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead) + end + -- due facce + elseif Proc.Fct == 2 then + -- se praticamente è lunga come la trave + if Proc.Box:getDimX() > 0.8 * _b3Solid:getDimX() then + return Long2Cut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, Q_SIDE_ROUGH_TOOL) + -- altrimenti + else + -- verifico se da lavorare con testa da sotto + local bDownHead = TestTwoFacesDownHead( Proc) + if BD.DOWN_HEAD then + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + local vtNm = ( vtN[1] + vtN[2]) + vtNm:normalize() + bDownHead = ( vtNm:getZ() < -0.5) + end + -- determino l'angolo tra le facce + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + -- se ortogonali e non forzata lama oppure con testa da sotto, con fresa + if ( not bUseBlade or bDownHead) and bAdj and abs( dAng + 90) < 1 then + -- se piccole + if Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN) then + return MakeTwoFacesByMill( Proc, bDownHead) + else + return MakeTwoFaces( Proc, true) + end + -- altrimenti, con lama + else + -- verifico se due facce o L con una o due facce di terminazione + local _, bIsL = TestUL( Proc) + if bIsL and _nChamfer > 0 then + local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc) + local nOk, sErr = MakeChamfer( Proc, vtOrtho, _b3Solid, nSurfInt) + if nOk < 0 then return false, sErr end + end + return Fbs.MakeTwo( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead) + end + end + -- tre facce + elseif Proc.Fct == 3 then + return MakeThreeFaces( Proc, true) + -- 4 o 5 facce + else + return MakeMoreFaces( Proc, true) + end + end +end + +--------------------------------------------------------------------- +return ProcessLapJoint \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLongCut.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLongCut.lua new file mode 100644 index 0000000..c2ae721 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLongCut.lua @@ -0,0 +1,1460 @@ +-- ProcessLongCut.lua by Egaltech s.r.l. 2022/03/07 +-- Gestione calcolo taglio longitudinale per Travi +-- 2021/02/03 Corretto FaceUse con fresa orizzontale su taglio orizzontale. +-- 2021/05/18 Possibile taglio con lama anche di fianco su macchina con testa da sotto. +-- 2021/07/20 Possibile taglio con lama anche di fianco e da sotto su macchina con testa da sopra. +-- 2021/07/20 Con utensile di fianco e con determinati angoli e se altezza utensile è inferiore all'altezza faccia +-- è possibile fare doppio taglio opposto su tutte le facce(sopra, sotto e fianchi) +-- 2021/09/03 Gestione facce lunghe non passanti con taglio di lama +-- 2021/10/29 Aggiunta opzione tipo lavorazione 'LongCut'. +-- 2021/11/04 Migliorata gestione sicurezza aggiuntiva in fresate di fianco (distinzione tra larga come tutta la faccia o meno). +-- 2021/11/08 Se con lama e flag BD.USE_LONGCUT si lavora in direzione contraria allo standard. +-- 2022/03/07 Razionalizzata gestione casi con fresa di fianco. Aggiunta gestione Long2Cut anche con testa sotto. + +-- Tabella per definizione modulo +local ProcessLongCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessLongCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +local dLimMinPiece = BD.LEN_SHORT_PART or 1000 +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLongCut.Identify( Proc) + return (( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 10) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLongCut.Classify( Proc) + -- se una sola faccia non ci sono limiti + if Proc.Fct == 1 then + return true, false + end + -- verifico la normale della faccia principale + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 then + return true, true + end + return true, false +end + +----------------------------------------------------------------------------------------------- +local function MakeSideFace( nId, nFac, nSide, sMilling, dToolDiam, bForcedLim, dDistToMachine, bUnderDir) + -- inserisco la lavorazione + local nM = 1 + local nP = 1 + local nFirstOverlap = 2 + -- calcolo il numero di passata che devo fare per coprire l'impronta dells lama + if dDistToMachine and abs(dDistToMachine) > 0 then + nP = ceil( ( abs(dDistToMachine) + EgtIf( bForcedLim, 2 + nFirstOverlap, 2)) / ( dToolDiam - 2)) + end + for i = 1, nP do + local sNameF = 'L2C_' .. ( EgtGetName( nId) or tostring( nId)) .. '_' .. tostring( nFac) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nId, nFac}}) + -- uso della faccia + local nFaceUse + if bForcedLim then + nFaceUse = MCH_MILL_FU.ORTHO_LEFT + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + else + nFaceUse = EgtIf( bUnderDir, MCH_MILL_FU.PARAL_TOP, MCH_MILL_FU.PARAL_DOWN) + if nSide == -2 then + nFaceUse = MCH_MILL_FU.PARAL_BACK + elseif nSide == 2 then + nFaceUse = MCH_MILL_FU.PARAL_FRONT + end + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- modifico offset radiale + if i < nP or i == 1 then + EgtSetMachiningParam( MCH_MP.OFFSR, ((dToolDiam-2)*(i-1)) + EgtIf( bForcedLim, -nFirstOverlap, 0)) + else + local dPrevStep = (dToolDiam-2)*(i-2) + EgtSetMachiningParam( MCH_MP.OFFSR, ( dDistToMachine + 2 - dToolDiam)) + end + -- attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end +end + +--------------------------------------------------------------------- +local function MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw, nFacInd, bReduceDepth, bMillDown, sMasterCutting) + -- Recupero la lavorazione di lama o prendo quella passata + local sCutting + if sMasterCutting and #sMasterCutting > 0 then + sCutting = sMasterCutting + else + sCutting = ML.FindCutting( 'HeadSide' .. EgtIf( bMillDown, '_H2', '')) + end + if not sCutting then + local sErr = 'Error : HeadSide (cutting) not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- valuto l'angolo tra le due facce + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT) + local ptPm = (ptP1+ptP2)/2 + -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta l'elevazione della faccia + -- laterale sul punto medio della linea in comune + local frFc = Frame3d( ptPm, vtN) ; + local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc) + dDepth = b3BoxLoc:getDimZ() or 0 + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + local dExtraOffs = 0 + -- se profondità superiore al massimo lama modifico elevazione + if dDepth > dMaxDepth then + dExtraOffs = dMaxDepth - dDepth + end + -- se devo ridurre l'affondamento + if bReduceDepth then + local dLimitDepth = 100 + -- se ho ridotto l'affondamento ne riduco ulteriormente l'affondamento (50mm) + if abs(dExtraOffs) > 0 then + if dMaxDepth > dLimitDepth then + dExtraOffs = dLimitDepth - dDepth + end + else + if dDepth > dLimitDepth then + dExtraOffs = dLimitDepth - dDepth + else + dExtraOffs = - (dDepth/2) + end + end + end + -- eseguo il taglio + local bMadeASbyBld, sWarn, nIdMach = Fbs.MakeOne( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, ( -0.5 + dExtraOffs), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if bMadeASbyBld then + sWarn = nil + if abs(dExtraOffs) > 0 then + sWarn = 'Warning : antisplint elevation is bigger than max tool depth' + end + end + return bMadeASbyBld, sWarn, nIdMach, dSawThick, dMaxDepth, bAdj, dAng, dExtraOffs +end + +--------------------------------------------------------------------- +local function ManageAntiSplintBySaw( Proc, b3Raw, bIsU, vtN, nFacet, nFacInd, sWarn, bMillDown, bReduceDepth, sCutting) + + local bMadeASbyBld = false + local nNumFac = EgtIf( bIsU, 2, 1) + local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra + -- se a U cerco di ottimizzare il lato di lavoro della lama + if bIsU then + if abs( vtN:getY()) > 0.996 then + nPrefSide = 0 + elseif abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then + -- se X è negativa allora devo tenere il motore a destra + if vtN:getX() < -(10 * GEO.EPS_SMALL) then + nPrefSide = 2 + end + end + end + -- va eseguito sulle facce diverse dalla principale + local nPrevSCC = nil + for nFacet = 0, nNumFac do + if nFacet ~= nFacInd then + -- lavoro + local dSawThick = 0 + local dMaxDepth = 200 + local bAdj, dAng, dExtraOffs, sWarn2, nIdMach + bMadeASbyBld, sWarn2, nIdMach, dSawThick, dMaxDepth, bAdj, dAng, dExtraOffs = MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw, nFacInd, bReduceDepth, bMillDown, sCutting) + if not bMadeASbyBld then return bMadeASbyBld, false, sWarn2 end + if sWarn2 then + if not sWarn then sWarn = '' end + sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2) + end + -- se antischeggia veramente inserito perchè necessario + if nIdMach then + -- verifico se da invertire + local bInvertMach = false + local dDepth = 0 + if bIsU then + if abs(vtN:getZ()) > 0.63 or abs(vtN:getY()) > 0.63 then +-- if abs(vtN:getZ()) > 0.7 or abs(vtN:getY()) > 0.7 then + -- prendo il vettore normale alla faccia + local _, vtNFc = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + -- se superficie principale parallela al piano XZ + if nPrefSide == 0 then + -- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto) + if vtNFc:getX() * vtNFc:getZ() > 0 then + nPrefSide = 2 + -- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto) + else + nPrefSide = 1 + end + end + -- se faccia verso X+ e mandrino verso sinistra + if vtNFc:getX() > 0 and nPrefSide == 1 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + -- se faccia verso X- e mandrino verso destra + elseif vtNFc:getX() < 0 and nPrefSide == 2 then + -- se angolo interno e circa -90 + if abs( dAng + 90) < 5 then + bInvertMach = true + end + end + end + end + -- eseguo inversione + if bInvertMach then + local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT) + local nWS = EgtGetMachiningParam( MCH_MP.WORKSIDE) + local nInvWS = EgtIf( nWS == MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT) + local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE) + local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT) + if not bOrtUp then + -- assegno i parametri invertiti + EgtSetMachiningParam( MCH_MP.WORKSIDE, nInvWS) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert) + -- setto l'offset pari allo spessore lama + EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick) + end + end + -- posizione del braccio : se primo taglio la recupero, altrimenti la imposto + if not nPrevSCC then + nPrevSCC = EgtGetMachiningParam( MCH_MP.SCC) + else + EgtSetMachiningParam( MCH_MP.SCC, nPrevSCC) + end + -- rieseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nIdMach, false) + return false, false, sErr + end + end + end + end + + return bMadeASbyBld, true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +local function MakeByPocketing( Proc, nPhase, nRawId, nPartId) + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId) + -- cerco la svuotatura opportuna + local sPocketing = ML.FindPocketing( 'OpenPocket', Proc.Box:getDimX()) + if not sPocketing then + local sErr = 'Error : OpenPocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + end + end + -- inserisco la lavorazione + 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( {{ Proc.Id, 0}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto attacco per tasca aperta + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev) + dFacElev = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade, nCustForceUseBladeOnNCF) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local _, dLen, dWidth = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + -- limitazioni su inizio e fine derivanti da altre facce + local bLimXmin = false + local bLimXmax = false + if Proc.Fct >= 3 then + bLimXmin = true + bLimXmax = true + elseif Proc.Fct >= 2 then + local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if vtN1:getX() > 0 then + bLimXmin = true + else + bLimXmax = true + end + end + -- Verifico lato di lavorazione (limite di lato a 45deg per FAST e 36deg per PF) + local nSide = 1 + if vtN:getZ() < - 0.5 then + nSide = -1 + elseif vtN:getY() < - EgtIf( BD.C_SIMM, 0.588, 0.7072) then + nSide = -2 + elseif vtN:getY() > EgtIf( BD.C_SIMM, 0.588, 0.7072) then + nSide = 2 + end + -- Verifico se largo come faccia + local bLarghAsFace = false + if nSide == 1 or nSide == -1 then + bLarghAsFace = ( Proc.Box:getDimY() > b3Solid:getDimY() - 20) + else + bLarghAsFace = ( Proc.Box:getDimZ() > b3Solid:getDimZ() - 20) + end + -- Determino se parte da sopra + local bTopStart = ( Proc.Box:getMax():getZ() > b3Solid:getMax():getZ() - 20) + -- Determino se parte da sotto + local bBottomStart = ( Proc.Box:getMin():getZ() < b3Solid:getMin():getZ() + 20) + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN:getY() < 0) + -- ottengo la distanza tra la fine del pezzo e il pezzo successivo + local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or BD.OVM_MID + local bForcedLim + local sWarn + ---------------------------------------------------------------------------------------------------------------------------------------- + -- 2020/09/15 Fabio Squaratti: se sono attivi entrambe i Q05 (lavorare con lama) e Q07 (lavorare con fresa di fianco anche da sopra) + -- allora vince il Q7, cioè si utilizza la fresa di fianco ( per i tagli da sopra) + -- 2020/09/17 Fabio Squaratti: se lavorazione con fresa di fianco e se ci sono delle facce terminali, l'utensile deve arrivare + -- fino al punto più vicino della faccia terminale (prima l'arretramento era sempre del raggio utensile). + -- Questo viene fatto se Q07=1 o fresa da sotto + ---------------------------------------------------------------------------------------------------------------------------------------- + local nUseBlade = EgtIf( bCustUseBlade, 1, EgtGetInfo( Proc.Id, 'Q05', 'i') or 0) + local bForceUseBladeOnNotThruFace + if nCustForceUseBladeOnNCF then + bForceUseBladeOnNotThruFace = nCustForceUseBladeOnNCF > 2 + nUseBlade = EgtIf( nCustForceUseBladeOnNCF > 2, nCustForceUseBladeOnNCF-2, nCustForceUseBladeOnNCF) + else + -- bForceUseBladeOnNotThruFace = EgtGetInfo( Proc.Id, 'Q06', 'b') or false + -- non viene più usato un nuovo Q (Q06) ma dipende dal valore del Q05 + -- con nuovi valori 3: come 1 ma con forza lama su facce chiuse; 4: come 2 ma con forza lama su facce chiuse + if nUseBlade > 2 then + nUseBlade = nUseBlade - 2 + bForceUseBladeOnNotThruFace = true + end + end + -- se ho il parametro settato dal LapJoint (per ora è questo componente che setta questo parametro) allora setto a false l'uso della lama + -- perchè se ha questo parametro a true significa che la lama è forzata ad essere usata + local nUseMillOnSide + if nCustForceUseBladeOnNCF then + nUseMillOnSide = 0 + else + nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q07', 'i') or 0 + end + -- se entrambe i Q sono attivi, disabilito lama + if nUseMillOnSide > 0 then + nUseBlade = 0 + bForceUseBladeOnNotThruFace = false + end + + local bCanUseBlade = false + local bCanUseUnderBlade = false + + -- se lama abilitata per lavorare sopra e faccia da sopra + if nUseBlade == 1 and nSide == 1 then + bCanUseBlade = true + end + -- se lama abilitata per lavorare anche i fianchi e da sotto e non c'è testa da sotto + if nUseBlade == 2 and not BD.DOWN_HEAD then + if ( nSide == 1 or abs(nSide) == 2) and vtN:getZ() >= -0.0175 then + bCanUseBlade = true + end + end + -- se lama abilitata per lavorare i fianchi e da sotto e c'è testa da sotto + if nUseBlade == 2 and BD.DOWN_HEAD then + -- se faccia da sotto o di lato ma con versore Z negativo che supera i 30° da Z- + if ( nSide == -1 or abs(nSide) == 2) and vtN:getZ() <= -0.5 then + bCanUseUnderBlade = true + end + -- se faccia da sotto o di lato ma con versore Z negativo abilito la lavorazione con lame mixate + if ( nSide == -1 or abs(nSide) == 2) and vtN:getZ() <= -0.0175 then + bCanUseUnderBlade = true + end + -- se faccia da sopra o di lato ma con versore Z negativo verifico che abbia un angolo compatibile (28deg) per non avere extracorsa + if ( nSide == 1 or abs(nSide) == 2) and vtN:getZ() >= -0.4695 then + bCanUseBlade = true + end + end + + -- introduco messaggi di errore in caso sia settata la lama ma impossibile utilizzarla + -- se si toglie questa parte il processo continua utilizzandi però la fresa ma per il vincolo del parametro Q non è possibile + if nUseBlade == 2 and not BD.DOWN_HEAD and not bCanUseBlade then + local sErr = 'Error, impossible use blade on negative side face' + EgtOutLog( sErr) + return false, sErr + elseif nUseBlade == 1 and not bCanUseBlade then + local sErr = 'Error, impossible use blade' + EgtOutLog( sErr) + return false, sErr + elseif nUseBlade == 2 and BD.DOWN_HEAD and not bCanUseBlade and not bCanUseUnderBlade then + local sErr = 'Error, impossible use blade' + EgtOutLog( sErr) + return false, sErr + end + + -- Se non limitato o forzato uso lama e da sopra e richiesto con doppio taglio di lama e superiore al limite minimo + if ( ( not bLimXmin and not bLimXmax) or bForceUseBladeOnNotThruFace) and ( bCanUseUnderBlade or bCanUseBlade) and nUseBlade > 0 and b3Solid:getDimX() > dLimMinPiece - 1 then + local sCutting + local dToolDiam = 0 + local dThick = 0 + local dMaxDepth = 0 + local sCuttingDn + local dToolDiamDn = 0 + local dThickDn = 0 + local dMaxDepthDn = 0 + -- recupero la lavorazione + if bCanUseUnderBlade then + sCuttingDn = ML.FindCutting( 'HeadSide_H2') + if not sCuttingDn then + local sErr = 'Error : sawing HeadSide_H2 not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sCuttingDn) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiamDn = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamDn + dThickDn = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThickDn + dMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dMaxDepthDn + end + end + end + if bCanUseBlade then + local sCutType = EgtIf( BD.USE_LONGCUT, 'LongCut', 'HeadSide') + sCutting = ML.FindCutting( sCutType) + if not sCutting then + local sErr = 'Error : sawing '..sCutType..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + end + -- se la fine (a sinistra) non è limitata e ho un pezzo successivo meno distante di metà raggio. setto la fine come limitata + if ( bCanUseBlade or bCanUseUnderBlade) and ( dDistToNextPiece < dToolDiam/2 or dDistToNextPiece < dToolDiamDn/2) and not bLimXmin then + if bForceUseBladeOnNotThruFace then + bForcedLim = true + bLimXmin = true + else + sWarn = 'Warning on saw cut : Cut machining can damage next piece' + EgtOutLog( sWarn) + end + end + -- disabilitato la selezione del codolo, prende sempre quello più piccolo. Non cancellare quello disabiliato in caso di ripristino + local dDimStrip = BD.DIM_STRIP_SMALL * EgtIf( nSide == -1, -1, 1) + -- determino gli estremi + local bStartFixed + local bEndFixed + local dStartAccDist + local dStartDist + local dEndAccDist + local dEndDist + + local dStartAccDistUp = BD.LONGCUT_ENDLEN + local dStartDistUp = 0 + local dEndAccDistUp = BD.LONGCUT_ENDLEN + local dEndDistUp = 0 + + local dStartAccDistDn = BD.LONGCUT_ENDLEN + local dStartDistDn = 0 + local dEndAccDistDn = BD.LONGCUT_ENDLEN + local dEndDistDn = 0 + + if bForceUseBladeOnNotThruFace then + if bCanUseBlade then + bStartFixed = true + if bLimXmax then + local dRadius = dToolDiam / 2 + local dCat1 = dRadius - ( ( dWidth - dDimStrip) / 2) + dStartDistUp = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) + dStartAccDistUp = BD.LONGCUT_MAXLEN + bStartFixed = false + end + bEndFixed = true + if bLimXmin then + local dRadius = dToolDiam / 2 + local dCat1 = dRadius - ( ( dWidth - dDimStrip) / 2) + dEndDistUp = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) + dEndAccDistUp = BD.LONGCUT_MAXLEN + bEndFixed = false + end + end + if bCanUseUnderBlade then + bStartFixed = true + if bLimXmax then + local dRadius = dToolDiamDn / 2 + local dCat1 = dRadius - ( ( dWidth - dDimStrip) / 2) + dStartDistDn = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) + dStartAccDistDn = BD.LONGCUT_MAXLEN + bStartFixed = false + end + bEndFixed = true + if bLimXmin then + local dRadius = dToolDiamDn / 2 + local dCat1 = dRadius - ( ( dWidth - dDimStrip) / 2) + dEndDistDn = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1)) + dEndAccDistDn = BD.LONGCUT_MAXLEN + bEndFixed = false + end + end + end + local nC + local dC + local nCUp + local dCUp + -- determino numero di parti + if bCanUseBlade then + nCUp = ceil( ( dLen - dStartAccDistUp - dEndAccDistUp) / BD.LONGCUT_MAXLEN) + dCUp = 0 + if nCUp > 0 then + dCUp = ( dLen - dStartAccDistUp - dEndAccDistUp) / nCUp + if dCUp < min( dStartAccDistUp, dEndAccDistUp) then + dCUp = dLen / ( nCUp + 2) + dStartAccDistUp = dCUp + dEndAccDistUp = dCUp + end + nCUp = nCUp + 2 + else + if dLen > min( dStartAccDistUp, dEndAccDistUp) then + nCUp = 2 + dStartAccDistUp = dLen/2 + dEndAccDistUp = dStartAccDistUp + else + nCUp = 1 + dStartAccDistUp = 0 + dEndAccDistUp = 0 + end + end + end + local nCDn + local dCDn + if bCanUseUnderBlade then + nCDn = ceil( ( dLen - dStartAccDistDn - dEndAccDistDn) / BD.LONGCUT_MAXLEN) + dCDn = 0 + if nCDn > 0 then + dCDn = ( dLen - dStartAccDistDn - dEndAccDistDn) / nCDn + if dCDn < min( dStartAccDistDn, dEndAccDistDn) then + dCDn = dLen / ( nCDn + 2) + dStartAccDistDn = dCDn + dEndAccDistDn = dCDn + end + nCDn = nCDn + 2 + else + if dLen > min( dStartAccDistDn, dEndAccDistDn) then + nCDn = 2 + dStartAccDistDn = dLen/2 + dEndAccDistDn = dStartAccDistDn + else + nCDn = 1 + dStartAccDistDn = 0 + dEndAccDistDn = 0 + end + end + end + -- prendo il valore minimo di passi ( dato dal diametro utensile più grande) + if nCUp then + nC = nCUp + dC = dCUp + elseif nCDn then + nC = nCDn + dC = dCDn + end + + local nFaceUse + local nFaceUse2 + -- se ho solo lama da sotto + if bCanUseUnderBlade and not bCanUseBlade then + -- determino l'utilizzo della faccia + nFaceUse = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + nFaceUse2 = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + else + -- determino l'utilizzo della faccia + nFaceUse = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + nFaceUse2 = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + end + -- si percorrono i lati alto e basso della faccia + -- calcolo quanto è l'affondamento del taglio + local dOffset = ( dWidth + dDimStrip) / 2 + -- se lama da sotto verifico se la componente Y della profondità di taglio supera la capacità della lama + if ( nSide == -1 or abs(nSide) == 2) and bCanUseUnderBlade then + if (( dWidth - dDimStrip) / 2) > dMaxDepthDn then + local sErr = 'Error : side depth is bigger than underneath blade cut depth' + EgtOutLog( sErr) + return false, sErr + end + end + local nM = 0 + -- se abilitata la lavorazione di lama su faccia chiusa, aggiungo le eventuali lavorazioni di antischeggia + -- e di asporto dell'impronta lama + if bForceUseBladeOnNotThruFace and ( bLimXmin or bLimXmax) then + local nCountMilHead = 0 + -- determino la massima elevazione + local dElev = BL.GetFaceElevation( Proc.Id, 0, nPartId) + -- recupero la lavorazione + local sMilling + if bCanUseUnderBlade then + sMilling = ML.FindMilling( 'Long2Cut_H2', dElev) + else + sMilling = ML.FindMilling( 'Long2Cut', dElev) + end + if not sMilling then + local sErr = 'Error : milling Long2Cut (_H2) not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se ho facce di chiusura, per prima cosa faccio antischeggia + -- come richiesto da Fabio Squaratti il 03/09/2021 + if ( bLimXmin and not bForcedLim) or bLimXmax then + local bOk, nFacet + bMadeASbyBld, bOk, sWarn = ManageAntiSplintBySaw( Proc, b3Raw, (( bLimXmin and not bForcedLim) and bLimXmax), vtN, nFacet, 0, sWarn, bCanUseUnderBlade, nil, sCutting) + if not bOk then return false, sWarn end + end + -- eventuale lavorazione della faccia limitante l'inizio + if not bStartFixed then + local vtIni = -X_AX() + for j = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT) + if vtIni * vtN > 0 and nCountMilHead < 2 then + MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam, nil, max(dStartDistUp,dStartDistDn), bCanUseUnderBlade) + nCountMilHead = nCountMilHead + 1 + end + end + if bForcedLim and nCountMilHead < 1 then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim, max(dStartDistUp,dStartDistDn), bCanUseUnderBlade) + nCountMilHead = nCountMilHead + 1 + end + end + + -- eventuale lavorazione della faccia limitante la fine + if not bEndFixed then + local vtFin = X_AX() + for j = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT) + if vtFin * vtN > 0 and nCountMilHead < 2 then + MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam, nil, max(dEndDistUp,dEndDistDn), bCanUseUnderBlade) + nCountMilHead = nCountMilHead + 1 + end + end + if bForcedLim and nCountMilHead < 2 then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim, max(dEndDistUp,dEndDistDn), bCanUseUnderBlade) + nCountMilHead = nCountMilHead + 1 + end + end + end + -- inserisco tagli di lama + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- ciclo sulle passate + local dLioTang = 0 + + for k = 1, 2 do + local dLioPerp = ( dWidth - dDimStrip) / 2 + BD.CUT_SIC ; + local bAddOpposite = true + local dAddExtraPerp = 0 + -- se faccia da sotto e angolo inferiore ai 12° o faccia di fianco e angolo inferiore a 15° (al di sotto di questo angolo + -- l'attacco lama si comporta in modo diverso) allora calcolo il valore perpendicolare con la funzione CalcLeadInOutPerpGeom + if ( nSide == -1 and abs(vtN:getY()) >= 0.2079) or ( abs(nSide) == 2 and abs(vtN:getZ()) >= 0.2588) then + bAddOpposite = false + end + -- faccio in modo di calcolare il valore perpendicolare solo sulla faccia da sotto nel secondo passo o sulla faccia di fianco nel primo passo + if nSide == 1 or ( nSide == -1 and k == 1) or ( abs(nSide) == 2 and k == 2) then + bAddOpposite = false + end + if bAddOpposite then + -- controllo se devo aggiungere un extra all'attacco perpendicolare + if nSide == -1 then + if vtN:getY() > 0 then + dAddExtraPerp = Proc.Box:getMin():getY() - b3Solid:getMin():getY() + elseif vtN:getY() < 0 then + dAddExtraPerp = b3Solid:getMax():getY() - Proc.Box:getMax():getY() + end + elseif abs(nSide) == 2 then + dAddExtraPerp = Proc.Box:getMin():getZ() - b3Solid:getMin():getZ() + end + dLioPerp = dLioPerp + dAddExtraPerp + end + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF + local nMchFId + + if ( k == 1 and bCanUseBlade) or ( k == 2 and ( bCanUseBlade and not bCanUseUnderBlade)) then + sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- setto le variabili delle distanze dagli estremi + dEndDist = dEndDistUp + dEndAccDist = dEndAccDistUp + dStartDist = dStartDistUp + dStartAccDist = dStartAccDistUp + elseif ( k == 2 and bCanUseUnderBlade) or ( k == 1 and ( bCanUseUnderBlade and not bCanUseBlade)) then + sNameF = 'L2CD_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sCuttingDn) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCuttingDn + EgtOutLog( sErr) + return false, sErr + end + -- setto le variabili delle distanze dagli estremi + dEndDist = dEndDistDn + dEndAccDist = dEndAccDistDn + dStartDist = dStartDistDn + dStartAccDist = dStartAccDistDn + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == nC, -dEndDist, - dEndAccDist - ( nC - i - 1) * dC) + local dEal = EgtIf( i == 1, -dStartDist, - dStartAccDist - ( i - 2) * dC) + if ( not bFront and k == 1) or ( bFront and k == 2) then + dSal, dEal = dEal, dSal + end + + if bCanUseBlade and bCanUseUnderBlade then + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + dSal, dEal = dEal, dSal + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse2, nFaceUse)) + elseif bCanUseBlade and BD.USE_LONGCUT then + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + dSal, dEal = dEal, dSal + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse2, nFaceUse)) + elseif bCanUseUnderBlade then + if abs(nSide) ~= 2 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2)) + else + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2)) + end + + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, EgtIf( nSide == -1, -dOffset, dOffset)) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- se il flag uso lama custom abilitato (indica che questo script è lanciato dal ProcessCut) + -- controllo se componente X versore è maggiore di un valore limite cambio la direzione della forcella + if bCustUseBlade and abs(vtN:getX()) > 0.009 + 5 * GEO.EPS_SMALL then + if BD.USE_LONGCUT then + nSCC = EgtIf( ( bFront and k == 1) or ( not bFront and k == 2), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + else + nSCC = EgtIf( ( not bFront and k == 1) or ( bFront and k == 2), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + end + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + + -- se non è sotto e non uso fresa di fianco: lavorazione Long2Cut + elseif ( nSide ~= - 1 or BD.DOWN_HEAD) and nUseMillOnSide == 0 then + -- determino la massima elevazione + local dElev = BL.GetFaceElevation( Proc.Id, 0, nPartId) + -- recupero la lavorazione + local sMchType = EgtIf( nSide ~= - 1, 'Long2Cut', 'Long2Cut_H2') + local sMilling = ML.FindMilling( sMchType, dElev) + if not sMilling then + local sErr = 'Error : milling '..sMchType..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se la fine (a sinistra) non è limitata e ho un pezzo successivo meno distante di metà raggio. setto la fine come limitata + if dDistToNextPiece < dToolDiam/2 and not bLimXmin then + bForcedLim = true + bLimXmin = true + end + -- se chiuso e corto, applico svuotatura con fresa opportuna + if bLimXmin and bLimXmax and Proc.Box:getDimX() < 2 * dToolDiam then + return MakeByPocketing( Proc, nPhase, nRawId, nPartId) + end + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + if ( bLimXmin and bFront) or ( bLimXmax and not bFront) then + dStartDist = dToolDiam / 2 + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + if ( bLimXmin and not bFront) or ( bLimXmax and bFront) then + dEndDist = dToolDiam / 2 + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + local nIncStep = 2 + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + -- se distanza rimanente è < della metà del minimo della distanza estremi allora aggiungo un passo in più + local dMinDist = EgtIf( min( dStartAccDist, dEndAccDist) / 2 > 300 , 300, min( dStartAccDist, dEndAccDist) / 2) + if dC <= dMinDist then + dC = dLen / ( nC + 1) + dStartAccDist = dC + dEndAccDist = dC + nIncStep = 1 + elseif dC < min( dStartAccDist, dEndAccDist) then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + if dC < dStartAccDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + if dC < dEndAccDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + nIncStep + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- determino l'utilizzo della faccia + local nFaceUse = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + -- si percorre il lato basso della faccia + local nM = 0 + local nCountMilHead = 0 + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC + if bFront then + nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + else + nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- ciclo sulle passate + local nO = 1 + local dStep = 0 + if dWidth + 2 * BD.CUT_EXTRA > 0.8 * dToolDiam then + nO = ceil(( dWidth + 2 * BD.CUT_EXTRA) / ( 0.6 * dToolDiam)) + if nO > 1 then + dStep = ( dWidth + 2 * BD.CUT_EXTRA) / nO + end + end + for k = nO, 1, -1 do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2CH_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == 1, -dStartDist, - dStartAccDist - ( i - 2) * dC) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + local dEal = EgtIf( i == nC, -dEndDist, - dEndAccDist - ( nC - i - 1) * dC) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, ( k - 1) * dStep - BD.CUT_EXTRA) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- verifico massimo affondamento rispetto ad elevazione + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in LongCut : depth (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + end + local dDepth = min( 0, dMaxDepth - dElev ) + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- eventuale lavorazione della faccia limitante l'inizio + if i == 1 and not bStartFixed then + local vtIni = EgtIf( bFront, X_AX(), -X_AX()) + for j = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT) + if vtIni * vtN > 0 and nCountMilHead < 2 then + MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam) + nCountMilHead = nCountMilHead + 1 + end + end + if bForcedLim and nCountMilHead < 1 then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim) + nCountMilHead = nCountMilHead + 1 + end + end + end + + -- eventuale lavorazione della faccia limitante la fine + if not bEndFixed then + local vtFin = EgtIf( bFront, -X_AX(), X_AX()) + for j = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT) + if vtFin * vtN > 0 and nCountMilHead < 2 then + MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam) + nCountMilHead = nCountMilHead + 1 + end + end + if bForcedLim and nCountMilHead < 2 then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim) + nCountMilHead = nCountMilHead + 1 + end + end + + -- altrimenti è con fresa di fianco (Long2CutSide) o da sotto (Long2CutDown) + else + -- variabile che indica se ripassare sul raggio rimasto dalla lavorazione di fianco + local bRemoveToolRadius + -- se nExtendMach = 0 la lavorazione rimane arretrata dalla fine della faccia del raggio utensile + -- se nExtendMach = 1 la lavorazione arriva fino alla fine faccia (se non ha facce limite) ignorando il pezzo successivo + -- se nExtendMach = 2 la lavorazione viene estesa ma arretra per non segnare il pezzo successivo (se non ha facce limite) + local nExtendMach + -- recupero la lavorazione + local sMchType, sMchTypeDn + local sMilling, sMillingDn + local sPrefix, sPrefixDn + if nSide ~= - 1 then + sMchType = 'Long2CutSide' + sMilling = ML.FindMilling( sMchType) + sPrefix = 'L2CS_' + nExtendMach = nUseMillOnSide + if nUseMillOnSide == 2 then + bRemoveToolRadius = true + end + -- se testa da sotto + if nSide ~= 1 and BD.DOWN_HEAD then + sMchTypeDn = 'Long2CutSide_H2' + sMillingDn = ML.FindMilling( sMchTypeDn) + sPrefixDn = 'L2CSH2_' + end + -- lavorazione da sotto + else + sMchType = 'Long2CutDown' + sMilling = ML.FindMilling( sMchType) + sPrefix = 'L2CD_' + nExtendMach = 1 + if nUseMillOnSide ~= 1 then + nExtendMach = 2 -- arretro il minimo indispensabile per non segnare il pezzo successivo (se non ha facce limite) + end + -- se testa da sotto + if BD.DOWN_HEAD then + sMchTypeDn = 'Long2CutDown_H2' + sMillingDn = ML.FindMilling( sMchTypeDn) + sPrefixDn = 'L2CDH2_' + end + end + if not sMilling and ( nSide == 1 or not BD.DOWN_HEAD) then + local sErr = 'Error : milling '..sMchType..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + if not sMilling and not sMillingDn then + local sErr = 'Error : milling '..sMchType..' and '..sMchTypeDn..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dToolLength = 0 + local dMaxDepth = 0 + local dThDiam = 0 + local dThLen = 0 + if sMilling and EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dThDiam = ( EgtTdbGetCurrToolThDiam() or dThDiam) + dThLen = EgtTdbGetCurrToolThLength() or dThLen + end + end + -- recupero i dati dell'utensile da sotto + local dToolDiamDn = 0 + local dToolLengthDn = 0 + local dMaxDepthDn = 0 + local dThDiamDn = 0 + local dThLenDn = 0 + if sMillingDn and EgtMdbSetCurrMachining( sMillingDn) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiamDn = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamDn + dToolLengthDn = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLengthDn + dMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dMaxDepthDn + dThDiamDn = (EgtTdbGetCurrToolThDiam() or dThDiamDn) + dThLenDn = EgtTdbGetCurrToolThLength() or dThLenDn + end + end + -- distanza dalle eventuali facce estreme + local dDistToEnd = dToolDiam / 2 + local dDistToEndDn = dToolDiamDn / 2 + -- calcolo l'elevazione della faccia principale + local dFacElev = BL.GetFaceElevation( Proc.Id, 0, nPartId) + -- se fresa di fianco o da sotto calcolo quanto l'utensile può andare vicino all'estremo con l'elevazione della faccia minore del raggio utensile + if ( nUseMillOnSide <= 1 or nSide == -1) and dFacElev < dToolDiam / 2 then + dDistToEnd = sqrt( dFacElev * ( dToolDiam - dFacElev)) + end + if nUseMillOnSide <= 1 and dFacElev < dToolDiamDn / 2 then + dDistToEndDn = sqrt( dFacElev * ( dToolDiamDn - dFacElev)) + end + -- se la fine è già limitata allora setto per arretrare del raggio utensile + if bLimXmin then + nExtendMach = 0 + -- se la fine non è limitata e ho un pezzo successivo distante meno di metà raggio. setto la fine come limitata + elseif ( dDistToNextPiece < dDistToEnd or dDistToNextPiece < dDistToEndDn) and nExtendMach ~= 1 then + bLimXmin = true + end + -- larghezza faccia + local _, _, dWidth = BL.GetFaceHvRefDim( Proc.Id, 0) + -- aggiuntivo sull'affondamento + local dAgg = BD.CUT_EXTRA + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + if ( bLimXmin and bFront) or ( bLimXmax and not bFront) then + if ( bLimXmin and bFront) then + dStartDist = EgtIf( nExtendMach == 2, dDistToEnd - dDistToNextPiece + 0.5, dDistToEnd) + else + dStartDist = dDistToEnd + end + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + if ( bLimXmin and not bFront) or ( bLimXmax and bFront) then + if ( bLimXmin and not bFront) then + dEndDist = EgtIf( nExtendMach == 2, dDistToEnd - dDistToNextPiece + 0.5, dDistToEnd) + else + dEndDist = dDistToEnd + end + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino il numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- verifico se posso farlo da una sola parte o se necessario da due parti + local dMaxDepthZ = dMaxDepth + local dMaxDepthDnZ = dMaxDepthDn + local CosA = abs( vtN:getZ()) + if CosA >= 0.05 then + local SinA = sqrt( 1 - CosA * CosA) + local dRad = dThDiam / 2 - dToolDiam / 2 + BD.COLL_SIC + dMaxDepthZ = dMaxDepthZ - ( dRad * CosA / SinA) + if sMillingDn then + local dRadDn = dThDiamDn / 2 - dToolDiamDn / 2 + dMaxDepthDnZ = dMaxDepthDnZ - ( dRadDn * CosA / SinA) + end + end + local dMaxDepthY = dMaxDepth + local dMaxDepthDnY = dMaxDepthDn + local SinA = abs( vtN:getZ()) + if SinA >= 0.05 then + local CosA = sqrt( 1 - SinA * SinA) + local dRad = dThDiam / 2 - dToolDiam / 2 + BD.COLL_SIC + dMaxDepthY = dMaxDepthY - ( dRad * CosA / SinA) + if sMillingDn then + local dRadDn = dThDiamDn / 2 - dToolDiamDn / 2 + dMaxDepthDnY = dMaxDepthDnY - ( dRadDn * CosA / SinA) + end + end + local nPass = 0 + local vdMaxD = { 0, 0} + local vnHead = { 0, 0} + -- con testa da sopra + if nSide == 1 or ( sMilling and abs( nSide) == 2 and ( bTopStart or abs( vtN:getY()) < 0.866)) or not sMillingDn then + vnHead = { 1, 1} + -- se faccia sopra + if nSide == 1 then + vdMaxD[1] = EgtIf( bLarghAsFace, dMaxDepthY, dMaxDepthZ) + if dWidth + dAgg <= vdMaxD[1] then + nPass = 1 + else + nPass = 2 + dAgg = BD.CUT_EXTRA_MIN + vdMaxD[2] = dMaxDepthY + end + -- se altrimenti faccia sotto + elseif nSide == -1 then + if dWidth + dAgg <= dMaxDepthY or abs( vtN:getY()) > EgtIf( BD.C_SIMM, 0.588, 0.7072) then + nPass = 1 + vdMaxD[1] = dMaxDepthY + else + nPass = 2 + vdMaxD[1] = dMaxDepthY + local dDelta = b3Solid:getDimY() - Proc.Box:getDimY() + if bLarghAsFace then + vdMaxD[2] = min( dMaxDepthY, dMaxDepth - dDelta * abs( vtN:getZ()) - BD.COLL_SIC) + else + vdMaxD[2] = min( dMaxDepthZ, dToolLength - 5 - dDelta / abs( vtN:getZ()) - BD.COLL_SIC) + end + if vdMaxD[2] < 0 then nPass = 1 end + if nPass == 2 then dAgg = BD.CUT_EXTRA_MIN end + end + -- altrimenti faccia di fianco + else + nPass = 1 + local dDelta = b3Solid:getMax():getZ() - Proc.Box:getMax():getZ() + if abs( vtN:getY()) < 0.866 then + vdMaxD[1] = dMaxDepthY + elseif bTopStart then + vdMaxD[1] = min( dMaxDepthZ, dMaxDepth - dDelta * abs( vtN:getY()) - BD.COLL_SIC) + else + vdMaxD[1] = min( dMaxDepthY, dToolLength - 5 - dDelta * abs( vtN:getY()) - BD.COLL_SIC) + end + if vdMaxD[1] < 0 then nPass = 0 end + end + -- eventuale errore per lavorazione saltata + if nPass == 0 then + local sErr = 'Error in '..sMchType..' : impossible machining' + EgtOutLog( sErr) + return false, sErr + end + -- eventuale avviso per lavorazione incompleta + if dWidth + nPass * dAgg > vdMaxD[1] + vdMaxD[2] then + sWarn = 'Warning in '..sMchType..' : depth is bigger than max tool depth' + end + -- con testa da sotto + else + vnHead = { 2, 2} + -- se faccia sotto + if nSide == -1 then + vdMaxD[1] = EgtIf( bLarghAsFace, dMaxDepthDnY, dMaxDepthDnZ) + if dWidth + dAgg <= vdMaxD[1] then + nPass = 1 + else + nPass = 2 + dAgg = BD.CUT_EXTRA_MIN + vdMaxD[2] = dMaxDepthDnY + end + -- altrimenti faccia di fianco + else + nPass = 1 + local dDelta = Proc.Box:getMin():getZ() - b3Solid:getMin():getZ() + if bBottomStart then + vdMaxD[1] = min( dMaxDepthDnZ, dMaxDepthDn - dDelta * abs( vtN:getY()) - BD.COLL_SIC) + else + vdMaxD[1] = min( dMaxDepthDnY, dToolLengthDn - 5 - dDelta * abs( vtN:getY()) - BD.COLL_SIC) + end + if vdMaxD[1] < 0 then nPass = 0 end + end + -- eventuale errore per lavorazione saltata + if nPass == 0 then + local sErr = 'Error in '..sMchType..' : impossible machining' + EgtOutLog( sErr) + return false, sErr + end + -- eventuale avviso per lavorazione incompleta + if dWidth + nPass * dAgg > vdMaxD[1] + vdMaxD[2] then + sWarn = 'Warning in '..sMchType..' : depth is bigger than max tool depth' + end + end + -- profondità passate + local vdDepth = {} + vdDepth[1] = min( dWidth + dAgg, vdMaxD[1]) + vdDepth[2] = min( dWidth + dAgg - vdDepth[1], vdMaxD[2]) + -- ciclo sulle parti + local nM = 0 + local bMakeMillHeadEnd + local bMakeMillHeadStart + local dLioPerp1 = dFacElev + BD.COLL_SIC + local dLioPerp2 = dWidth * EgtIf( abs( vtN:getZ()) < GEO.EPS_SMALL, 1, sqrt( 1 - vtN:getZ() * vtN:getZ()) / abs( vtN:getZ())) + BD.COLL_SIC + -- valore sovrapposizione tra passate + local dOverLapExtend = 2 * BD.CUT_EXTRA_MIN + for j = 1, nC do + -- Limitazioni della lavorazione + local nPos = EgtIf( bFront, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, -dEndDist, -dEndAccDist - ( nPos - 2) * dC + dOverLapExtend) + local dEal = EgtIf( nPos == nC, -dStartDist, -dStartAccDist - ( nC - nPos - 1) * dC + dOverLapExtend) + -- Posizione braccio portatesta + local nSCC + for k = 1, nPass do + if bFront then + nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + else + nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = EgtIf( vnHead[k] ~= 2, sPrefix, sPrefixDn) .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, EgtIf( vnHead[k] ~= 2, sMilling, sMillingDn)) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMillingDn + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + local nUseFace = EgtIf( vnHead[k] ~= 2, MCH_MILL_FU.PARAL_DOWN, MCH_MILL_FU.PARAL_TOP) + if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then nUseFace = MCH_MILL_FU.PARAL_BACK end + EgtSetMachiningParam( MCH_MP.FACEUSE, nUseFace) + -- imposto lato di lavoro e inversione + if k == 1 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + dSal, dEal = dEal, dSal + end + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, vdDepth[k]) + -- assegno attacco perpendicolare + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp1) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp1) + -- eseguo + if not EgtApplyMachining( true, false) then + -- se feature orientata su faccia da sotto provo a cambiare l'attacco + if nSide == -1 then + EgtSetMachiningParam( MCH_MP.LIPERP, min( dLioPerp1, dLioPerp2)) + EgtSetMachiningParam( MCH_MP.LOPERP, min( dLioPerp1, dLioPerp2)) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + -- esco se non sono nella seconda lavorazione o non nella faccia da sotto + if k < 2 or ( nSide ~= - 1 and not BD.DOWN_HEAD) then + return false, sErr + end + end + else + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + -- esco se non sono nella seconda lavorazione o non nella faccia da sotto + if k < 2 or ( nSide ~= - 1 and not BD.DOWN_HEAD) then + return false, sErr + end + end + end + -- eventuale lavorazione della faccia limitante la fine + if j == EgtIf( bFront , 1, nC) and not bEndFixed and bRemoveToolRadius then + local vtFin = EgtIf( bFront, -X_AX(), X_AX()) + for i = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT) + if vtFin * vtN > 0 and not bMakeMillHeadEnd then + MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam) + bMakeMillHeadEnd = true + end + end + if bRemoveToolRadius and not bMakeMillHeadEnd then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bRemoveToolRadius) + end + end + -- eventuale lavorazione della faccia limitante l'inizio + if j == EgtIf( bFront , nC, 1) and not bStartFixed and bRemoveToolRadius then + local vtIni = EgtIf( bFront, X_AX(), -X_AX()) + for i = 1, Proc.Fct - 1 do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT) + if vtIni * vtN > 0 and not bMakeMillHeadStart then + MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam) + bMakeMillHeadStart = true + end + end + if bRemoveToolRadius and not bMakeMillHeadStart then + MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bRemoveToolRadius) + end + end + end + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessLongCut diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLongDoubleCut.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLongDoubleCut.lua new file mode 100644 index 0000000..51591b3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessLongDoubleCut.lua @@ -0,0 +1,1578 @@ +-- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2022/03/20 +-- Gestione calcolo doppio taglio longitudinale per Travi +-- 2021/05/18 Possibile taglio con lama anche di fianco su macchina con testa da sotto. +-- 2021/06/29 Corretta gestione caso equivalente a due smussi. +-- 2021/10/29 Aggiunta opzione tipo lavorazione 'LongCut'. +-- 2021/11/08 Se con lama e flag BD.USE_LONGCUT si lavora in direzione contraria allo standard. +-- 2022/02/08 Sistemate lunghezze fresature quando due sole. +-- 2022/02/15 Sistemati commenti. +-- 2022/03/20 Tolta da scelta milling tipo Long2CutDown controllo max diametro fresa. + +-- Tabella per definizione modulo +local ProcessLong2Cut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessLongDoubleCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +local dLimMinPiece = BD.LEN_SHORT_PART or 1000 + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLong2Cut.Identify( Proc) + return ( Proc.Grp == 0 and Proc.Prc == 12) +end + +--------------------------------------------------------------------- +-- Identificazione delle facce della feature. +-- Ritorna quattro valori : +-- flag delle facce limitanti (0= no, 1= a destra, 2= a sinistra, 3= entrambe) +-- vettore indici facce longitudinali +-- vettore dei centri delle facce longitudinali +-- vettore dei centri delle normali +local function IdentifyFaces( Proc) + + local nFaceLimit = 0 + local tFaceLong = {} + local tptC = {} + local tvtN = {} + + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se è una faccia limite a sinistra + if vtN:getX() > GEO.EPS_SMALL then + nFaceLimit = nFaceLimit | 2 + -- se è una faccia limite a destra + elseif vtN:getX() < -GEO.EPS_SMALL then + nFaceLimit = nFaceLimit | 1 + -- altrimenti è una faccia longitudinale + else + local nInd = #tFaceLong + 1 + tFaceLong[nInd] = i-1 + tptC[nInd], tvtN[nInd] = EgtSurfTmFacetCenter( Proc.Id, ( i-1), GDB_ID.ROOT) + end + end + return nFaceLimit, tFaceLong, tptC, tvtN +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLong2Cut.Classify( Proc) + + local nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0 + + -- se richiesto utensile di fianco + if nUseMillOnSide > 0 then + + -- carico i dati delle face già inserite nelle opportune tabelle + local nFaceLimit, tFaceLong, _, vtN = IdentifyFaces( Proc) + + -- verifico posizione (+1=sopra, -1=sotto, 0=sui lati) + local nSide = 0 + if vtN[1]:getZ() > -10 * GEO.EPS_SMALL and vtN[2]:getZ() > -10 * GEO.EPS_SMALL then + nSide = 1 + elseif vtN[1]:getZ() < 10 * GEO.EPS_SMALL and vtN[2]:getZ() < 10 * GEO.EPS_SMALL then + nSide = -1 + end + -- angolo diedro per stabilire se taglio convesso + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, tFaceLong[1], tFaceLong[2], GDB_ID.ROOT) + local bConvex + if bAdj then + bConvex = ( dAng >= 0) + else + bConvex = true + end + -- se feature di fianco e facce concave per lavorazione impossibile +-- if nSide == 0 and not bConvex then +-- -- do errore perchè su un lato entra nel pezzo (entra nel lato sopra) +-- Proc.ErrMsg = 'Error : impossible to machinine with tool on side' +-- return false, false +-- end + end + + return true, false +end + +--------------------------------------------------------------------- +function ProcessLong2Cut.GetLongFacesCount( Proc) + local nLongFaces = 0 + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if abs( vtN:getX()) < GEO.EPS_SMALL then + nLongFaces = nLongFaces + 1 + end + end + return nLongFaces +end + +--------------------------------------------------------------------- +local function MakeSideFace( nId, nFac, nSide, sMilling, dToolDiam, nL2CSide) + -- inserisco la lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( nId) or tostring( nId)) .. '_' .. tostring( nFac) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nId, nFac}}) + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- uso della faccia + local nFaceUse = EgtIf( nSide == 1, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.ORTHO_LEFT) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- annullo offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30) + -- se faccia di fianco e testa da sotto, aumento la sicurezza + if nL2CSide == 0 and BD.DOWN_HEAD then + EgtSetMachiningParam( MCH_MP.STARTPOS, 80) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +local function MakeByPocketing( Proc, nPhase, nRawId, nPartId, nSide, nFacInd, dFacElev) + -- cerco la svuotatura opportuna + local sPockType = EgtIf( nSide ~=1 and BD.DOWN_HEAD, 'OpenPocket_H2', 'OpenPocket') + local sPocketing = ML.FindPocketing( sPockType, Proc.Box:getDimX()) + if not sPocketing then + local sErr = 'Error : OpenPocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + end + end + -- inserisco la lavorazione + 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( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto attacco per tasca aperta + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev) + dFacElev = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione e dichiaro non si generano sfridi per VMill + local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev, 1) .. ';' + sNotes = sNotes .. 'VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function CalcBladeUse( bUseBlade, bDown_Head, nSide, vtN1, vtN2, bConvex, nOrd, bFront, dCustomAngle) + + local bCanUseBlade = false + local bCanUseUnderBlade = false + + -- se lama abilitata e faccia da sopra + if bUseBlade and nSide == 1 then + bCanUseBlade = true + end + -- se lama abilitata e non c'è testa da sotto + if bUseBlade and not bDown_Head then + if nSide >= 0 then + if nSide > 0 and ( ( vtN1 and vtN1:getZ() >= -0.0175) or ( vtN2 and vtN2:getZ() >= -0.0175)) then + bCanUseBlade = true + elseif nSide == 0 then + if ( ( vtN1 and vtN1:getZ() >= -0.0175) or ( vtN2 and vtN2:getZ() >= -0.0175)) then + bCanUseBlade = true + elseif not bConvex and nOrd and (( nOrd == 1 and bFront) or ( nOrd == 2 and not bFront)) and ( vtN1 and vtN1:getZ() >= -0.0175) then + bCanUseBlade = true + elseif not bConvex and nOrd and (( nOrd == 2 and bFront) or ( nOrd == 1 and not bFront)) and ( vtN1 and vtN1:getZ() >= -0.5) then + bCanUseBlade = true + elseif bConvex and ( vtN1 and vtN1:getZ() >= -0.0175) then + bCanUseBlade = true + end + end + else + if bConvex then + if vtN1 and vtN2 then + if vtN1:getZ() >= -0.5 then + if vtN2:getZ() >= -0.5 then + bCanUseBlade = true + end + else + if vtN2:getZ() >= -0.0175 then + bCanUseBlade = true + end + end + else + if ( vtN1 and vtN1:getZ() >= EgtIf( dCustomAngle, dCustomAngle, -0.5)) then + bCanUseBlade = true + end + end + else + if ( vtN1 and vtN1:getZ() >= EgtIf( dCustomAngle, dCustomAngle, -0.5)) or ( vtN2 and vtN2:getZ() >= -0.5) then + bCanUseBlade = true + end + end + end + end + -- se lama abilitata e c'è testa da sotto + if bUseBlade and bDown_Head then + -- se faccia da sotto o di lato ma con versore Z negativo che supera i 30° da Z- + if nSide <= 0 and ( ( vtN1 and vtN1:getZ() <= -0.5) or ( vtN2 and vtN2:getZ() <= -0.5)) then + bCanUseUnderBlade = true + end + -- se faccia da sotto o di lato ma con versore Z negativo abilito la lavorazione con lame mixate + if nSide <= 0 and ( ( vtN1 and vtN1:getZ() <= -0.0175) or ( vtN2 and vtN2:getZ() <= -0.0175)) then + bCanUseUnderBlade = true + end + -- se faccia da sopra o di lato ma con versore Z negativo verifico che abbia un angolo compatibile per non avere extracorsa + if nSide >= 0 and ( ( vtN1 and vtN1:getZ() > -0.4695) or ( vtN2 and vtN2:getZ() > -0.4695)) then + bCanUseBlade = true + end + -- se faccia da sotto ma con versore Z negativo verifico che abbia un angolo compatibile per non avere extracorsa + if nSide < 0 and ( ( vtN1 and vtN1:getZ() > -0.4695) or ( vtN2 and vtN2:getZ() > -0.4695)) then + bCanUseBlade = true + end + end + + return bCanUseBlade, bCanUseUnderBlade +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster, nUseSideToolMaster) + + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- carico i dati delle face già inserite nelle opportune tabelle + local nFaceLimit, tFaceLong, ptC, vtN = IdentifyFaces( Proc) + local dLen = Proc.Box:getDimX() + + -- verifico posizione (+1=sopra, -1=sotto, 0=sui lati) + local nSide = 0 + if vtN[1]:getZ() > -10 * GEO.EPS_SMALL and vtN[2]:getZ() > -10 * GEO.EPS_SMALL then + nSide = 1 + elseif vtN[1]:getZ() < 10 * GEO.EPS_SMALL and vtN[2]:getZ() < 10 * GEO.EPS_SMALL then + nSide = -1 + end + + -- angolo diedro per stabilire se taglio convesso + local bInt, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, tFaceLong[1], tFaceLong[2], GDB_ID.ROOT) + local bConvex + local bOrtho + local ptM + if bInt then + bConvex = ( dAng >= 0) + bOrtho = ( abs( dAng + 90) < 1) + ptM = ( ptP1 + ptP2) / 2 + else + bConvex = true + bOrtho = false + dAng = acos( vtN[1] * vtN[2]) + ptM = ( ptC[1] + ptC[2]) / 2 + end + local ptRef = ( ptC[1] + ptC[2]) / 2 + -- analisi del taglio + local vOrd = {} + local vFaceUse = {} + if nSide == 1 or ( nSide == -1 and BD.DOWN_HEAD) then + vOrd = EgtIf( ptC[1]:getY() < ptRef:getY(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + elseif nSide == -1 then + vOrd = EgtIf( ptC[1]:getY() < ptM:getY(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestParalOpposite( ptC[1] - ptM), BL.GetNearestParalOpposite( ptC[2] - ptM)} + else + local bFront = ( vtN[1]:getY() < 0) + if bFront then + vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 1, 2}, { 2, 1}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + else + vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 2, 1}, { 1, 2}) + vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)} + end + end + local vWidth = {} + _, _, vWidth[1] = BL.GetFaceHvRefDim( Proc.Id, tFaceLong[1]) + _, _, vWidth[2] = BL.GetFaceHvRefDim( Proc.Id, tFaceLong[2]) + + -- ottengo la distanza tra la fine del pezzo e il pezzo successivo + local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or 5.4 + local bForcedLim + local sWarn + ---------------------------------------------------------------------------------------------------------------------------------------- + -- 2020/09/17 Fabio Squaratti: se sono attivi entrambe i Q01 (lavorare con lama) e Q03 (lavorare con fresa di fianco anche da sopra) + -- allora vince il Q3, cioè si utilizza la fresa di fianco ( per i tagli da sopra) + -- 2020/09/17 Fabio Squaratti: se lavorazione con fresa di fianco e se ci sono delle facce laterali, l'utensile deve arrivare + -- fino al punto più vicino della faccia laterale (prima l'arretramento era sempre del raggio utensile). + -- Questo viene fatto se Q03=1 o fresa da sotto + ---------------------------------------------------------------------------------------------------------------------------------------- + local bUseBlade + local nUseMillOnSide + -- se presenti utilizzo i parametri dell'eventuale lua "padre" + if bForcedBladeMaster ~= nil then + bUseBlade = bForcedBladeMaster + else + bUseBlade = EgtGetInfo( Proc.Id, 'Q01', 'i') == 1 + end + if nUseSideToolMaster ~= nil then + nUseMillOnSide = nUseSideToolMaster + else + nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0 + end + + -- se entrambe i Q sono attivi, disabilito lama + if nUseMillOnSide > 0 then bUseBlade = false end + -- verifico se posso usare lame + local bCanUseBlade, bCanUseUnderBlade = CalcBladeUse( bUseBlade, BD.DOWN_HEAD, nSide, vtN[1], vtN[2], bConvex) + -- introduco messaggi di errore in caso sia settata la lama ma impossibile utilizzarla + -- se si toglie questa parte il processo continua utilizzandi però la fresa ma per il vincolo del parametro Q non è possibile + if bUseBlade and not BD.DOWN_HEAD and not bCanUseBlade then + local sErr = 'Error, impossible use blade on too negative face' + EgtOutLog( sErr) + return false, sErr + elseif bUseBlade and BD.DOWN_HEAD and not bCanUseBlade and not bCanUseUnderBlade then + local sErr = 'Error, impossible use blade' + EgtOutLog( sErr) + return false, sErr + end + + -- Se senza facce limitanti, da sopra o ( da tutte i lati con testa da sotto) e taglio di lama e lunghezza facce maggiore del parametro lunghezza minima + if nFaceLimit == 0 and ( bCanUseUnderBlade or bCanUseBlade) and bUseBlade and Proc.Box:getDimX() > dLimMinPiece - 1 then + + local sCutting + local dToolDiam = 0 + local dToolThick = 0 + local dMaxDepth = 0 + local sCuttingDn + local dToolDiamDn = 0 + local dToolThickDn = 0 + local dMaxDepthDn = 0 + -- recupero la lavorazione + if bCanUseUnderBlade then + sCuttingDn = ML.FindCutting( 'HeadSide_H2') + if not sCuttingDn then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawing underneath not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sCuttingDn) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiamDn = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamDn + dToolThickDn = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThickDn + dMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dMaxDepthDn + end + end + end + if bCanUseBlade then + local sCutType = EgtIf( BD.USE_LONGCUT, 'LongCut', 'HeadSide') + sCutting = ML.FindCutting( sCutType) + if not sCutting then + local sErr = 'Error : sawing '..sCutType..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + end + -- se la distanza dal pezzo successivo è inferiore della metà lama, do un warning + if ( bCanUseBlade or bCanUseUnderBlade) and ( dDistToNextPiece < dToolDiam/2 or dDistToNextPiece < dToolDiamDn/2) then + sWarn = 'Warning : Cut machining can damage next piece' + EgtOutLog( sWarn) + end + -- determino gli estremi + local dStartAccDist + local dEndAccDist + local dStartAccDistUp = BD.LONGCUT_ENDLEN + local dEndAccDistUp = BD.LONGCUT_ENDLEN + local dStartAccDistDn = BD.LONGCUT_ENDLEN + local dEndAccDistDn = BD.LONGCUT_ENDLEN + local nC + local dC + + local nCUp + local dCUp + -- determino numero di parti + if bCanUseBlade then + nCUp = ceil( ( dLen - dStartAccDistUp - dEndAccDistUp) / BD.LONGCUT_MAXLEN) + dCUp = 0 + if nCUp > 0 then + dCUp = ( dLen - dStartAccDistUp - dEndAccDistUp) / nCUp + if dCUp < min( dStartAccDistUp, dEndAccDistUp) then + dCUp = dLen / ( nCUp + 2) + dStartAccDistUp = dCUp + dEndAccDistUp = dCUp + end + nCUp = nCUp + 2 + else + if dLen > min( dStartAccDistUp, dEndAccDistUp) then + nCUp = 2 + dStartAccDistUp = dLen / 2 + dEndAccDistUp = dStartAccDistUp + else + nCUp = 1 + dStartAccDistUp = 0 + dEndAccDistUp = 0 + end + end + end + local nCDn + local dCDn + if bCanUseUnderBlade then + nCDn = ceil( ( dLen - dStartAccDistDn - dEndAccDistDn) / BD.LONGCUT_MAXLEN) + dCDn = 0 + if nCDn > 0 then + dCDn = ( dLen - dStartAccDistDn - dEndAccDistDn) / nCDn + if dCDn < min( dStartAccDistDn, dEndAccDistDn) then + dCDn = dLen / ( nCDn + 2) + dStartAccDistDn = dCDn + dEndAccDistDn = dCDn + end + nCDn = nCDn + 2 + else + if dLen > min( dStartAccDistDn, dEndAccDistDn) then + nCDn = 2 + dStartAccDistDn = dLen / 2 + dEndAccDistDn = dStartAccDistDn + else + nCDn = 1 + dStartAccDistDn = 0 + dEndAccDistDn = 0 + end + end + end + -- prendo il valore minimo di passi + if nCUp then + nC = nCUp + dC = dCUp + elseif nCDn then + nC = nCDn + dC = dCDn + end + + -- uso codolo piccolo + local dDimStrip = BD.DIM_STRIP_SMALL * EgtIf( nSide == -1, -1, 1) + local nM = 0 + -- se convesso lavoro ogni faccia in due metà lasciando attaccata la parte centrale + if bConvex then + -- si percorrono i lati alto e basso della faccia + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = EgtIf( ( i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + local nCountToShift = 0 + local bChangeBlade + local bMachDownGen + -- ciclo sulle due facce + for j = 1, #vOrd do + local nIdPrev + local nIdNext + nCountToShift = nCountToShift + 1 + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN[vOrd[j]]:getY() < 0) + -- determino se posso usare lame sulla faccia specifica + bCanUseBlade, bCanUseUnderBlade = CalcBladeUse( bUseBlade, BD.DOWN_HEAD, nSide, vtN[vOrd[j]], nil, bConvex, j, bFront) + if not bCanUseUnderBlade and not bCanUseBlade then + local sErr = 'Error : impossible use blade on too negative face' + EgtOutLog( sErr) + return false, sErr + end + local nFaceUse + local nFaceUse2 + -- se ho solo lama da sotto + if bCanUseUnderBlade and not bCanUseBlade then + -- determino l'utilizzo della faccia + nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + nFaceUse2 = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + else + -- determino l'utilizzo della faccia + nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT)) + nFaceUse2 = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK)) + end + -- se lama da sotto verifico se la componente Y della profondità di taglio supera la capacità della lama + if nSide <= 0 and bCanUseUnderBlade then + if (( vWidth[vOrd[j]] - dDimStrip) / 2) > dMaxDepthDn then + local sErr = 'Error : side depth is bigger than underneath blade cut depth' + EgtOutLog( sErr) + return false, sErr + end + end + local dOffset = ( vWidth[vOrd[j]] + dDimStrip) / 2 ; + local dLioTang = 0 + local nFaceSide = 0 + if vtN[vOrd[j]]:getZ() > 0.707 then + nFaceSide = 1 + elseif vtN[vOrd[j]]:getZ() < -0.707 then + nFaceSide = -1 + end + -- ricavo box della faccia + local b3Fac = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vOrd[j]-1, GDB_BB.STANDARD) + -- ciclo sulle passate + for k = 1, 2 do + local dLioPerp = ( vWidth[vOrd[j]] - dDimStrip) / 2 + BD.CUT_SIC + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF + local nMchFId + local sCuttingName + local bMachDown + if bCanUseBlade and not bCanUseUnderBlade then + sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sCutting) + sCuttingName = sCutting + -- setto le variabili delle distanze dagli estremi + dEndAccDist = dEndAccDistUp + dStartAccDist = dStartAccDistUp + elseif bCanUseUnderBlade and not bCanUseBlade then + sNameF = 'L2CD_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sCuttingDn) + sCuttingName = sCuttingDn + -- setto le variabili delle distanze dagli estremi + dEndAccDist = dEndAccDistDn + dStartAccDist = dStartAccDistDn + bMachDown = true + -- entrambe le possibilità di lama + else + -- se di fronte e prima faccia o dietro e seconda faccia, sta lavorando quella più in basso in Z (posizione) + if ( ( bFront and j == 1) or ( not bFront and j == 2)) and k == 1 then + -- prediligo quella inferiore + sNameF = 'L2CD_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sCuttingDn) + sCuttingName = sCuttingDn + -- setto le variabili delle distanze dagli estremi + dEndAccDist = dEndAccDistDn + dStartAccDist = dStartAccDistDn + bMachDown = true + -- se di fronte e prima faccia o dietro e seconda faccia, sta lavorando quella più in basso in Z (posizione) + elseif ( ( bFront and j == 1) or ( not bFront and j == 2)) and k == 2 then + sNameF = 'L2CD_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sCuttingDn) + sCuttingName = sCuttingDn + -- setto le variabili delle distanze dagli estremi + dEndAccDist = dEndAccDistDn + dStartAccDist = dStartAccDistDn + bMachDown = true + -- se di fronte e seconda faccia o dietro e prima faccia, sta lavorando la faccia più in alto in Z (posizione) + elseif ( ( bFront and j == 2) or ( not bFront and j == 1)) and k == 1 then + sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sCutting) + sCuttingName = sCutting + -- setto le variabili delle distanze dagli estremi + dEndAccDist = dEndAccDistUp + dStartAccDist = dStartAccDistUp + -- se di fronte e seconda faccia o dietro e prima faccia, sta lavorando la faccia più in alto in Z (posizione) + elseif ( ( bFront and j == 2) or ( not bFront and j == 1)) and k == 2 then + sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sCutting) + sCuttingName = sCutting + -- setto le variabili delle distanze dagli estremi + dEndAccDist = dEndAccDistUp + dStartAccDist = dStartAccDistUp + end + end + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCuttingName + EgtOutLog( sErr) + return false, sErr + end + if j == 1 and k == 1 then + bMachDownGen = bMachDown + else + if bMachDownGen ~= bMachDown then + bChangeBlade = true + end + end + local bAddOpposite = true + local dAddExtraPerp = 0 + if ( nFaceSide == -1 and abs(vtN[vOrd[j]]:getY()) >= 0.2079) then + bAddOpposite = false + end + if ( nFaceSide == 0 and abs(vtN[vOrd[j]]:getZ()) >= 0.2588) then + bAddOpposite = false + end + if ( nFaceSide == 1 and not bMachDown) or ( nFaceSide == -1 and bMachDown) or ( nFaceSide == -1 and k == 1) then + bAddOpposite = false + end + if bAddOpposite then + -- controllo se devo aggiungere un extra all'attacco perpendicolare + if nFaceSide == -1 then + if vtN[vOrd[j]]:getY() > 0 then + dAddExtraPerp = b3Fac:getMin():getY() - b3Solid:getMin():getY() + elseif vtN[vOrd[j]]:getY() < 0 then + dAddExtraPerp = b3Solid:getMax():getY() - b3Fac:getMax():getY() + end + elseif nFaceSide == 0 then + if ( ( bFront and j == 1) or ( not bFront and j == 2)) and vtN[vOrd[j]]:getZ() <= 0 and k == 2 then + dAddExtraPerp = b3Solid:getMax():getZ() - b3Fac:getMax():getZ() + elseif ( ( bFront and j == 2) or ( not bFront and j == 1)) and vtN[vOrd[j]]:getZ() >= 0 and k == 1 then + dAddExtraPerp = b3Fac:getMin():getZ() - b3Solid:getMin():getZ() + end + end + dLioPerp = dLioPerp + dAddExtraPerp + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vOrd[j]-1}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC) + local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC) + if ( not bFront and k == 1) or ( bFront and k == 2) then + dSal, dEal = dEal, dSal + end + if bCanUseBlade and bCanUseUnderBlade then + if bCanUseBlade and nSide == -1 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse2, nFaceUse)) + else + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2)) + end + elseif bCanUseBlade and BD.USE_LONGCUT then + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + dSal, dEal = dEal, dSal + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2)) + elseif bCanUseUnderBlade then + if nSide ~= 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2)) + else + if bCanUseBlade and nSide == -1 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + end + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2)) + end + + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, EgtIf( nSide == -1, -dOffset, dOffset)) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- se sono alla seconda faccia scambio le ultime due lavorazione per ottimizzare i percorosi + if nCountToShift == 2 then + -- se prima porzione di faccia memorizzo l'id della lavorazione + if k == 1 then + nIdPrev = nMchFId + else + nIdNext = nMchFId + end + -- alla fine della seconda porzione della seconda faccia se non ho cambiato utensile tra le facce sposta la prima dopo la seconda + if nIdPrev and nIdNext and k == 2 and not bChangeBlade then + EgtRelocateGlob( nIdPrev, nIdNext, GDB_IN.AFTER) + end + end + end + end + end + -- altrimenti concavo + else + -- si percorrono i lati alto e basso della faccia + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = EgtIf( ( i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + -- ciclo sulle due facce + for j = 1, #vOrd do + -- determino se lavorazione da davanti o da dietro + local bFront = ( vtN[vOrd[j]]:getY() < 0) + local OthFace = abs(j-3) + local dSinLimit + -- se faccia da sotto e Z centro faccia è minore del centro altra faccia, segno il limite angolare da passare + -- dovrebbe essere il limite angolare della testa 1 in sottosquadra + if nSide == -1 and not BD.DOWN_HEAD then + if ptC[vOrd[j]]:getZ() < ptC[vOrd[OthFace]]:getZ() then + dSinLimit = -0.0157 + else + dSinLimit = -0.5 + end + end + -- determino se posso usare lame sulla faccia specifica + bCanUseBlade, bCanUseUnderBlade = CalcBladeUse( bUseBlade, BD.DOWN_HEAD, nSide, vtN[vOrd[j]], nil, bConvex, j, bFront, dSinLimit) + if not bCanUseUnderBlade and not bCanUseBlade then + local sErr = 'Error : impossible use blade on too negative face' + EgtOutLog( sErr) + return false, sErr + end + -- se lama da sotto verifico se la componente Y della profondità di taglio supera la capacità della lama + if nSide <= 0 and bCanUseUnderBlade then + if ( vWidth[vOrd[j]] / 2) > dMaxDepthDn then + local sErr = 'Error : side depth is bigger than underneath blade cut depth' + EgtOutLog( sErr) + return false, sErr + end + end + -- ciclo sulle passate + local dOffset + local dLioPerp + if j == 1 then -- il primo taglio lo faccio completo se angolo interno maggiore di 90 + -- se angolo interno inferiore di 90° calcolo l'arretramento della lama + un piccolo delta di 0.3 + if dAng < - ( 90 + 10 * GEO.EPS_SMALL) then + dOffset = 0.3 + ((dToolThick* vtN[vOrd[1]]) * vtN[vOrd[2]] * vtN[vOrd[2]]):len() + else + dOffset = 0 + end + dLioPerp = vWidth[vOrd[j]] + BD.CUT_SIC + else -- il secondo ridotto della distanza minima e della componente spessore della lama + dOffset = dDimStrip + ((dToolThick* vtN[vOrd[1]]) - (dToolThick* vtN[vOrd[1]]) * vtN[vOrd[2]] * vtN[vOrd[2]]):len() + dLioPerp = vWidth[vOrd[j]] - dOffset + BD.CUT_SIC + end + local dLioTang = 0 + local sNameF + local nMchFId + nM = nM + 1 + if bCanUseBlade then + sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- setto le variabili delle distanze dagli estremi + dEndAccDist = dEndAccDistUp + dStartAccDist = dStartAccDistUp + elseif bCanUseUnderBlade then + sNameF = 'L2CD_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sCuttingDn) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCuttingDn + EgtOutLog( sErr) + return false, sErr + end + -- setto le variabili delle distanze dagli estremi + dEndAccDist = dEndAccDistDn + dStartAccDist = dStartAccDistDn + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vOrd[j]-1}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC) + local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC) + if j == 2 then + dSal, dEal = dEal, dSal + end + if nSide == -1 and BD.DOWN_HEAD then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + end + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- determino e imposto l'utilizzo della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[j]]) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + end + + -- se non è sotto e non uso fresa di fianco: lavorazione Long2Cut + elseif ( ( nSide ~= -1 or BD.DOWN_HEAD) or ( nSide == -1 and BD.DOWN_HEAD)) and nUseMillOnSide == 0 then + -- determino la massima elevazione + local dElev = 0 + local dFacElev1 = BL.GetFaceElevation( Proc.Id, tFaceLong[1], nPartId) + local dFacElev2 = BL.GetFaceElevation( Proc.Id, tFaceLong[2], nPartId) + -- 03/12/2020 + -- se facce concave e a 90 gradi, prendo l'elevazione minima + if bOrtho then + dElev = min( dFacElev1, dFacElev2) + else + dElev = max( dFacElev1, dFacElev2) + end + -- recupero la lavorazione + local sMilling + if nSide == -1 and BD.DOWN_HEAD then + sMilling = ML.FindMilling( 'Long2Cut_H2', dElev) + else + sMilling = ML.FindMilling( 'Long2Cut', dElev) + end + + if not sMilling then + local sErr = 'Error : Long2Cut not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- se angolo compreso è inferiore ai 90 gradi do errore + if dAng and dAng < - ( 90 + 10 * GEO.EPS_ANG_SMALL) then + local sErr = 'Error : Impossible use a mill with angle less than 90' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se la fine (a sinistra) non è limitata e ho un pezzo successivo più distante da metà raggio. setto la fine come limitata + if dDistToNextPiece < dToolDiam/2 and nFaceLimit < 2 then + bForcedLim = true + nFaceLimit = nFaceLimit + 2 + end + -- se chiuso e corto, applico svuotatura con fresa opportuna + if nFaceLimit == 3 and Proc.Box:getDimX() < 2 * dToolDiam then + -- svuotatura della prima faccia longitudinale + local bOk, sErr = MakeByPocketing( Proc, nPhase, nRawId, nPartId, nSide, tFaceLong[1], dFacElev1) + -- svuotatura della seconda faccia longitudinale + if not bOk then return bOk, sErr end + return MakeByPocketing( Proc, nPhase, nRawId, nPartId, nSide, tFaceLong[2], dFacElev2) + end + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + -- se ho faccia limite a destra + if nFaceLimit == 1 or nFaceLimit == 3 then + dStartDist = dToolDiam / 2 + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + -- se ho faccia limite a sinistra + if nFaceLimit >= 2 then + dEndDist = dToolDiam / 2 + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino il numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + local nIncStep = 2 + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + -- se distanza rimanente è < della metà del minimo della distanza estremi allora aggiungo un solo passo in più + local dMinDist = EgtIf( min( dStartAccDist, dEndAccDist) / 2 > 300 , 300, min( dStartAccDist, dEndAccDist) / 2) + if dC < dMinDist then + dC = dLen / ( nC + 1) + dStartAccDist = dC + dEndAccDist = dC + nIncStep = 1 + elseif dC < min( dStartAccDist, dEndAccDist) then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + if dC < dStartAccDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + if dC < dEndAccDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + nIncStep + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + local nIni, nFin = 1, 2 + local dLimitAngle = -0.5 - 20 * GEO.EPS_SMALL + -- se facce ortogonali (concave), mantengo la lavorazione di testa sulla faccia più grande purchè non superi di 30 gradi il sottosquadra + if bOrtho then + if vtN[vOrd[1]]:getZ() > 0.001 and vtN[vOrd[2]]:getZ() > 0.001 then + if vtN[vOrd[1]]:getZ() >= vtN[vOrd[2]]:getZ() then + nFin = 1 + else + nIni = 2 + end + else + if vtN[vOrd[1]]:getZ() < dLimitAngle then + nIni = 2 + elseif vtN[vOrd[2]]:getZ() < dLimitAngle then + nFin = 1 + else + if vtN[vOrd[1]]:getZ() >= vtN[vOrd[2]]:getZ() then + if vtN[vOrd[2]]:getZ() < dLimitAngle then + nFin = 1 + else + nIni = 2 + end + else + if vtN[vOrd[1]]:getZ() < dLimitAngle then + nIni = 2 + else + nFin = 1 + end + end + end + end + end + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + -- su entrambe le facce + for i = nIni, nFin do + -- valore sovrapposizione tra passate con fresa di fianco + local dOverLapExtend = 2 + -- Verifico se da fare di fianco perchè normale troppo verso il basso (minore di -30deg) + local bSide = ( vtN[vOrd[i]]:getZ() < dLimitAngle and not ( nSide == -1 and BD.DOWN_HEAD)) + -- Limitazioni della lavorazione + local nPos = EgtIf( i == 1, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC + EgtIf( bSide, dOverLapExtend, 0)) + local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC + EgtIf( bSide, dOverLapExtend, 0)) + -- Posizione braccio portatesta + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = EgtIf( ( j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + if bSide and not bConvex then + dSal, dEal = dEal, dSal + end + -- ciclo sulle passate + local nO = 1 + local dStep = 0 + local dAgg = EgtIf( bConvex, 2 * BD.CUT_EXTRA, BD.CUT_EXTRA) + local dLargh = vWidth[vOrd[i]] + if not bSide and dLargh > 0.8 * dToolDiam then + nO = ceil( dLargh / ( 0.6 * dToolDiam)) + if nO > 1 then + dStep = dLargh / nO + end + end + for k = 1, nO do + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, tFaceLong[vOrd[i]]}}) + -- limito opportunamente la lavorazione + if ( nSide == -1 and BD.DOWN_HEAD) then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + end + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + EgtOutLog( 'FaceUse='..tostring( vFaceUse[vOrd[i]])) + --EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bSide, BL.GetParallelOpposite( vFaceUse[vOrd[i]]), vFaceUse[vOrd[i]])) + EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bSide, MCH_MILL_FU.PARAL_DOWN, vFaceUse[vOrd[i]])) + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bSide, true, false)) + -- imposto offset radiale (nullo se concavo o di lato) + local dOffsR = EgtIf( k < nO, ( nO - k) * dStep, EgtIf( bConvex, - BD.CUT_EXTRA, 0)) + if bSide then dOffsR = 0 end + EgtSetMachiningParam( MCH_MP.OFFSR, dOffsR) + -- se di lato e convesso, imposto offset longitudinale + if bSide and bConvex then + EgtSetMachiningParam( MCH_MP.OFFSL, - BD.CUT_EXTRA) + end + -- attacco e uscita + local dLioPerp = EgtIf( bSide, dToolDiam, dLargh - dOffsR + BD.CUT_SIC) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- se faccia di fianco e testa da sotto, aumento la sicurezza + if nSide == 0 and BD.DOWN_HEAD then + EgtSetMachiningParam( MCH_MP.STARTPOS, 80) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante l'inizio (a destra) + if bConvex and j == 1 and not bStartFixed then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], 1, sMilling, dToolDiam, nSide) + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante la fine (a sinistra) + if bConvex and j == nC and not bEndFixed then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], -1, sMilling, dToolDiam, nSide) + end + end + end + + -- altrimenti lavorazione di fianco : Long2CutSide o Long2CutDown + else + -- da Analisi con Fabio Squaratti 15/09/2020 + -- variabile che indica se ripassare sul raggio rimasto dalla lavorazione di fianco + local bRemoveToolRadius + -- se nExtendMach = 0 la lavorazione rimane arretrata dalla fine della faccia del raggio utensile + -- se nExtendMach = 1 la lavorazione arriva fino alla fine faccia (se non ha facce limite) ignorando il pezzo successivo + -- se nExtendMach = 2 la lavorazione viene estesa ma arretra per non segnare il pezzo successivo (se non ha facce limite) + local nExtendMach + -- recupero la lavorazione + local sMchType, sMchTypeDn + local sMilling, sMillingDn + local sPrefix, sPrefixDn + if nSide ~= - 1 then + sMchType = 'Long2CutSide' + sMilling = ML.FindMilling( sMchType) + sPrefix = 'L2CS_' + nExtendMach = nUseMillOnSide + if nUseMillOnSide == 2 then + bRemoveToolRadius = true + end + -- se testa da sotto + if nSide ~= 1 and BD.DOWN_HEAD then + sMchTypeDn = 'Long2CutSide_H2' + sMillingDn = ML.FindMilling( sMchTypeDn) + sPrefixDn = 'L2CSH2_' + end + -- lavorazione da sotto + else + sMchType = 'Long2CutDown' + sMilling = ML.FindMilling( sMchType) + sPrefix = 'L2CD_' + nExtendMach = 1 + if nUseMillOnSide ~= 1 then + nExtendMach = 2 -- arretro il minimo indispensabile per non segnare il pezzo successivo (se non ha facce limite) + end + -- se testa da sotto + if BD.DOWN_HEAD then + sMchTypeDn = 'Long2CutDown_H2' + sMillingDn = ML.FindMilling( sMchTypeDn) + sPrefixDn = 'L2CDH2_' + end + end + if not sMilling and ( nSide == 1 or not BD.DOWN_HEAD) then + local sErr = 'Error : milling '..sMchType..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + if not sMilling and not sMillingDn then + local sErr = 'Error : milling '..sMchType..' and '..sMchTypeDn..' not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- se angolo compreso è inferiore ai 90 gradi do errore + if dAng < - ( 90 + 10 * GEO.EPS_SMALL) then + local sErr = 'Error : Impossible use a mill with angle less than 90' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dToolLength = 0 + local dMaxDepth = 0 + local dThDiam = 0 + local dThLen = 0 + local dExtraForSafety = EgtIf( BD.DOWN_HEAD, 8.5, 6.5) -- corrisponde al doppio valore di sicurezza dell'mlpe + 0.5 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + dThLen = EgtTdbGetCurrToolThLength() or dThLen + end + end + -- recupero i dati dell'utensile da sotto + local dToolDiamDn = 0 + local dToolLengthDn = 0 + local dMaxDepthDn = 0 + local dThDiamDn = 0 + local dThLenDn = 0 + if nSide ~= 1 and BD.DOWN_HEAD and EgtMdbSetCurrMachining( sMillingDn) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiamDn = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamDn + dToolLengthDn = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLengthDn + dMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dMaxDepthDn + dThDiamDn = (EgtTdbGetCurrToolThDiam() or dThDiamDn) + dThLenDn = EgtTdbGetCurrToolThLength() or dThLenDn + end + end + local dDistToEnd = dToolDiam / 2 + local dDistToEndDn = dToolDiamDn / 2 + -- calcolo l'elevazione della faccia principale + local dFacElev1 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[1]], nPartId) + local dFacElev2 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[2]], nPartId) + -- se fresa di fianco o da sotto calcolo quanto l'utensile può andare vicino al limite se l'elevazione della faccia è minore del raggio utensile + if nUseMillOnSide <= 1 or nSide == -1 then + local dFacElev = max( dFacElev1, dFacElev2) + if dFacElev < dDistToEnd then + dDistToEnd = sqrt( ( ( dToolDiam / 2) * ( dToolDiam / 2)) - ( ( dToolDiam / 2 - dFacElev) * (dToolDiam / 2 - dFacElev))) + end + if dFacElev < dDistToEndDn then + dDistToEndDn = sqrt( ( ( dToolDiamDn / 2) * ( dToolDiamDn / 2)) - ( ( dToolDiamDn / 2 - dFacElev) * (dToolDiamDn / 2 - dFacElev))) + end + end + -- se la fine è già limitata allora setto per arretrare del raggio utensile + if nFaceLimit >= 2 then + nExtendMach = 0 + -- se la fine non è limitata e ho un pezzo successivo distante meno di metà raggio. setto la fine come limitata + elseif ( dDistToNextPiece < dDistToEnd or dDistToNextPiece < dDistToEndDn) and nExtendMach ~= 1 then + nFaceLimit = nFaceLimit + 2 + end + -- aggiuntivo sull'affondamento + local dAgg = EgtIf( bConvex, BD.CUT_EXTRA, 0) + -- determino gli estremi + local dStartDist = 0 + local dStartAccDist = BD.LONGCUT_ENDLEN + local bStartFixed = true + -- se ho facce limite a destra + if nFaceLimit == 1 or nFaceLimit == 3 then + dStartDist = dDistToEnd + dStartAccDist = BD.LONGCUT_MAXLEN + bStartFixed = false + end + local dEndDist = 0 + local dEndAccDist = BD.LONGCUT_ENDLEN + local bEndFixed = true + -- se ho facce limite a sinistra + if nFaceLimit >= 2 then + dEndDist = EgtIf( nExtendMach == 2, dDistToEnd - dDistToNextPiece + 0.5, dDistToEnd) + dEndAccDist = BD.LONGCUT_MAXLEN + bEndFixed = false + end + -- determino il numero di parti in cui dividere la lavorazione + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + local nIncStep = 2 + if bStartFixed and bEndFixed then + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + -- se distanza rimanente è < della metà del minimo della distanza estremi allora aggiungo un solo passo in più + local dMinDist = EgtIf( min( dStartAccDist, dEndAccDist) / 2 > 300 , 300, min( dStartAccDist, dEndAccDist) / 2) + if dC < dMinDist then + dC = dLen / ( nC + 1) + dStartAccDist = dC + dEndAccDist = dC + nIncStep = 1 + elseif dC < min( dStartAccDist, dEndAccDist) then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + elseif bStartFixed then + dC = ( dLen - dStartAccDist) / ( nC + 1) + dEndAccDist = dC + if dC < dStartAccDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + elseif bEndFixed then + dC = ( dLen - dEndAccDist) / ( nC + 1) + dStartAccDist = dC + if dC < dEndAccDist then + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + else + dC = dLen / ( nC + 2) + dStartAccDist = dC + dEndAccDist = dC + end + nC = nC + nIncStep + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + if bStartFixed and not bEndFixed then + dStartAccDist = min( dStartAccDist, dLen/2) + dEndAccDist = dLen - dStartAccDist + elseif not bStartFixed and bEndFixed then + dEndAccDist = min( dEndAccDist, dLen/2) + dStartAccDist = dLen - dEndAccDist + else + dStartAccDist = dLen/2 + dEndAccDist = dStartAccDist + end + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + local nIni, nFin = 1, 2 + local nDir = 1 + -- se facce ortogonali (concave) controllo se con la lavorazione della prima faccia il diametro copre la seconda (e non la eseguo) + if bOrtho then + -- se da sotto scelgo la faccia (lavorata col fianco utensile) con direzione più sottosquadra + if nSide == -1 and vtN[vOrd[1]]:getZ() < -0.001 and vtN[vOrd[2]]:getZ() < -0.001 then + -- se gli angoli delle due facce sono uguali ( sotto il grado di differenza) sgelgo la faccia più vicina a un fianco + if abs(vtN[vOrd[1]]:getZ() - vtN[vOrd[2]]:getZ()) < 0.017 then + -- se punto medio più vicino al lato dietro + if b3Solid:getMax():getY() - ptM:getY() < ptM:getY() - b3Solid:getMin():getY() then + -- se prima faccia più vicina alla faccia dietro eseguo prima questa + if ptC[vOrd[1]]:getY() > ptC[vOrd[2]]:getY() then + if dToolDiam > vWidth[vOrd[2]] then + nFin = 1 + end + -- se è più lontana inverto la direzione di lavoro + else + -- inverto la direzione di lavorazione delle facce + nDir = -1 + nIni, nFin = 2, 1 + if dToolDiam > vWidth[vOrd[1]] then + nFin = 2 + end + end + -- altrimenti punto medio più vicino al lato davanti + else + -- se prima faccia più vicina alla faccia dietro inverto la direzione di lavorazione + if ptC[vOrd[1]]:getY() > ptC[vOrd[2]]:getY() then + -- inverto la direzione di lavorazione delle facce + nDir = -1 + nIni, nFin = 2, 1 + if dToolDiam > vWidth[vOrd[1]] then + nFin = 2 + end + else + if dToolDiam > vWidth[vOrd[2]] then + nFin = 1 + end + end + end + elseif vtN[vOrd[2]]:getZ() < vtN[vOrd[1]]:getZ() then + -- inverto la direzione di lavorazione delle facce + nDir = -1 + nIni, nFin = 2, 1 + if dToolDiam > vWidth[vOrd[1]] then + nFin = 2 + end + else + if dToolDiam > vWidth[vOrd[2]] then + nFin = 1 + end + end + -- in tutti gli altri casi + else + if dToolDiam > vWidth[vOrd[2]] then + nFin = 1 + end + end + end + -- ciclo sulle facce selezionate + for i = nIni, nFin, nDir do + -- valore sovrapposizione tra passate + local dOverLapExtend = 2 + -- Limitazioni della lavorazione + local nPos = EgtIf( i == 1, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC + dOverLapExtend) + local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC + dOverLapExtend) + -- Posizione braccio portatesta + local nSCC = EgtIf( BD.C_SIMM, MCH_SCC.NONE, MCH_SCC.ADIR_XP) + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF + local nMchFId + local bUseDownHead + local bFront = (vtN[vOrd[i]]:getY() < 0) + if BD.DOWN_HEAD and nSide ~= 1 then + local ptC3 = EgtSurfTmFacetCenter( Proc.Id, tFaceLong[vOrd[i]], GDB_ID.ROOT) + local ptDir = ptC3 - ptM ; ptDir:normalize() + -- se concave e dal versore Z della faccia (> -20°) o convesso e versore Z ( > -30°) decido se eseguire la lavoraione con la testa da sopra o da sotto + if ( not bConvex and vtN[vOrd[i]]:getZ() > -0.9397 and ptDir:getZ() > 0) or + ( bConvex and vtN[vOrd[i]]:getZ() > -0.866 and ptDir:getZ() > 0) then + sNameF = sPrefix .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sMilling) + bUseDownHead = false + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + else + sNameF = sPrefixDn .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sMillingDn) + bUseDownHead = true + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMillingDn + EgtOutLog( sErr) + return false, sErr + end + end + else + sNameF = sPrefix .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + nMchFId = EgtAddMachining( sNameF, sMilling) + bUseDownHead = false + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, tFaceLong[vOrd[i]]}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- se fresa di fianco e non da sotto + if nUseMillOnSide > 0 and nSide ~= -1 then + if bConvex then + local vFaceUse2 + -- se da sopra + if nSide == 1 then + if vtN[vOrd[i]]:getZ() > 0.866 then + vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 1, 2)], vtN[EgtIf(vOrd[i] == 1, 2, 1)]) + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + end + -- altrimenti è di fianco + else + if vtN[vOrd[i]]:getY() > 0.866 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_TOP) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + end + end + -- se concavo + else + local vFaceUse2 + -- se da sopra + if nSide == 1 then + vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)], vtN[EgtIf(vOrd[i] == 1, 1, 2)]) + -- altrimenti è di fianco + else + vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)]) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end + else + -- se con fresa di fianco + if nUseMillOnSide > 0 then + if bConvex then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + if vtN[vOrd[i]]:getZ() >= 0 then + if BD.DOWN_HEAD and nSide ~= 1 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end + end + else + -- lascio lo stesso le lavorazioni anche se viene intercettato l'errore + local vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)], vtN[EgtIf(vOrd[i] == 1, 1, 2)]) + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2) + if vtN[vOrd[i]]:getZ() < 0 then + if BD.DOWN_HEAD and nSide ~= 1 then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + end + end + end + else + -- se faccia da sotto + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]]) + end + end + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + -- calcolo la componente dNz non in base alla classificazione della feature (sopra, sotto, fianchi) ma alla componente maggiore +-- local dNz = EgtIf( nSide == 0, vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ()) +-- local dNz = EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ()) + local dNz = EgtIf( abs(nSide) == 1, vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ()) + local dNzMin = EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ()) + local dLioPerp1, dLioPerp2 + -- nel caso concavo, devo impostare la lunghezza di attacco ortogonale + if not bConvex then + dLioPerp1 = EgtIf( i == 1, dFacElev1, dFacElev2) +-- dLioPerp1 = vWidth[vOrd[i]] * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, sqrt( 1 - dNz * dNz) / abs( dNz)) + BD.COLL_SIC + dLioPerp2 = vWidth[ EgtIf( vOrd[i] == 1, 2,1)] + BD.COLL_SIC + EgtSetMachiningParam( MCH_MP.LIPERP, max( dLioPerp1, dLioPerp2)) + EgtSetMachiningParam( MCH_MP.LOPERP, max( dLioPerp1, dLioPerp2)) + end + -- verifico massimo affondamento (tengo conto dell'inclinazione utensile e della pinza con estremità conica) + -- 08/09/2020 tolti i 3mm ( per la ghiera smussata) perchè nella verifica collisione vine creato un cilindro non smussato che rileva la collisione +-- local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * abs( vtN[vOrd[i]]:getY() / vtN[vOrd[i]]:getZ()) - 3) +-- local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( vtN[vOrd[i]]:getY() / dNz))) + local dCollSic + local dDepth + -- assegno affondamento + local dExtraElev = 0 + -- se uso testa da sotto + if bUseDownHead then + dCollSic = max( BD.COLL_SIC, ( dThDiamDn - dToolDiamDn) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getZ(), vtN[vOrd[i]]:getY()) / dNz))) + if vWidth[vOrd[i]] + dAgg > dMaxDepthDn - dCollSic then + sWarn = 'Warning in LongDoubleCut : depth (' .. EgtNumToString( vWidth[vOrd[i]] + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepthDn - dCollSic, 1) .. ')' + end + dDepth = min( dMaxDepthDn - dCollSic, vWidth[vOrd[i]] + dAgg) + dDepth2 = vWidth[vOrd[i]] + dAgg - dDepth + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth - dExtraElev) + else + dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getZ(), vtN[vOrd[i]]:getY()) / dNz))) + if vWidth[vOrd[i]] + dAgg > dMaxDepth - dCollSic then + sWarn = 'Warning in LongDoubleCut : depth (' .. EgtNumToString( vWidth[vOrd[i]] + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth - dCollSic, 1) .. ')' + end + dDepth = min( dMaxDepth - dCollSic, vWidth[vOrd[i]] + dAgg) + dDepth2 = vWidth[vOrd[i]] + dAgg - dDepth + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth - dExtraElev) + end + -- eseguo + if not EgtApplyMachining( true, false) then + -- se feature orientata su faccia da sotto e concave provo a cambiare l'attacco + if nSide == -1 and not bConvex then + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp1) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + else + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante l'inizio (a destra) + if bConvex and j == 1 and not bStartFixed and bRemoveToolRadius then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], 1, sMilling, dToolDiam) + end + -- se facce principali convesse, eventuale lavorazione della faccia limitante la fine (a sinistra) + if bConvex and j == nC and not bEndFixed and bRemoveToolRadius then + MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], -1, sMilling, dToolDiam) + end + end + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessLong2Cut diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessMark.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessMark.lua new file mode 100644 index 0000000..ca44922 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessMark.lua @@ -0,0 +1,140 @@ +-- ProcessMark.lua by Egaltech s.r.l. 2021/05/03 +-- Gestione calcolo marcatura per Travi +-- 2020/05/28 Tipo di lavorazione passato da Mark a Text. +-- 2021/05/03 Aggiunta gestione testa da sotto. + +-- Tabella per definizione modulo +local ProcessMark = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessMark started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessMark.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 60) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessMark.Classify( Proc) + -- recupero il versore estrusione o normale se testo + local vtN + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtN = EgtCurveExtrusion( Proc.Id, GDB_ID.ROOT) + else + vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtN then + return false + end + -- verifico se la marcatura è lavorabile solo da sotto + local bDown = (( vtN:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessMark.Make( Proc, nPhase, nRawId, nPartId) + -- recupero eventuale geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero i dati della marcatura + local vtExtr + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + else + vtExtr = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtExtr then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che la marcatura non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 and not BD.DOWN_HEAD then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- abilitazione lavorazione da sotto + local bMillUp = ( BD.DOWN_HEAD and vtExtr:getZ() > -0.259) + local bMillDown = ( BD.DOWN_HEAD and vtExtr:getZ() < 0.174) + -- recupero la lavorazione + local sMillType = 'Text' + local sMchExt = EgtIf( bMillDown, '_H2', '') + local sMilling = ML.FindMilling( sMillType..sMchExt) + if not sMilling and bMillUp then + sMilling = ML.FindMilling( sMillType) + end + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale lavorazione su seconda geometria + if AuxId then + -- inserisco la lavorazione di fresatura + local sName2 = 'Decor2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchF2Id = EgtAddMachining( sName, sMilling) + if not nMchF2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + 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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchF2Id, false) + return false, sErr + end + -- se geometria a X maggiore, la sposto prima + local ptS1 = EgtSP( Proc.Id, GDB_ID.ROOT) + local ptS2 = EgtSP( AuxId, GDB_ID.ROOT) + if ptS2:getX() > ptS1:getX() then + EgtRelocateGlob( nMchF2Id, nMchFId, GDB_IN.BEFORE) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessMark diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessMortise.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessMortise.lua new file mode 100644 index 0000000..bd291cc --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessMortise.lua @@ -0,0 +1,376 @@ +-- ProcessMortise.lua by Egaltech s.r.l. 2021/12/01 +-- Gestione calcolo mortase per Travi +-- 2021/07/20 Aggiunta gestione rinvio angolare su FAST. +-- 2021/12/01 Se frontale aggiungo taglio con Grp e Proc di vero taglio (per aggiornare ingombro di testa /coda). + +-- Tabella per definizione modulo +local ProcessMortise = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessMortise started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessMortise.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 50) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 51) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 53)) +end + +--------------------------------------------------------------------- +-- Riconoscimento della sola feature frontale +function ProcessMortise.FrontIdentify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 51) +end + +--------------------------------------------------------------------- +-- Classificazione della feature: decide se la feature è in una posizione che per lavorala +-- deve essere ribaltata o no +function ProcessMortise.Classify( Proc) + -- recupero e verifico il percorso supplementare + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero versore estrusione della curva supplementare e non più della superficie + -- perché quest'ultima potrebbe non avere il fondo e dare quindi un risultato non corretto + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtExtr then + return false + end + if not vtN then + return false + end + local bDown + -- Confronto le direzioni Z dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante + if abs( vtExtr:getZ() - vtN:getZ()) > GEO.EPS_SMALL then + bDown = false + -- altrimenti è chiusa + else + -- verifico se la mortasa è lavorabile solo da sotto + bDown = ( vtN:getZ() < - 0.1) + end + -- se da sotto e presente rinvio angolare verifico se c'è opportuna lavorazione + if bDown and BD.ANG_TRASM then + if ML.FindPocketing( 'Mortise_AT') then + bDown = false + end + end + return true, bDown +end + +--------------------------------------------------------------------- +-- Piano di taglio della feature +function ProcessMortise.GetCutPlane( Proc) + if ProcessMortise.FrontIdentify( Proc) then + return EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + else + return nil, nil + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessMortise.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + local bForceOneSide + local bRevertSide + if AuxId then + AuxId = AuxId + Proc.Id + end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero versore estrusione della curva supplementare + local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT) + -- Se curva di contorno aperta + if not EgtCurveIsClosed( AuxId) then + local NewId, nCount = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id)) + if NewId then + -- elimino eventuali loop interni (non dovrebbero comunque esserci) + for i = 1, nCount - 1 do + EgtErase( NewId + i) + end + -- sostituisco il loop esterno alla curva originale + EgtModifyCurveExtrusion( NewId, vtExtr, GDB_ID.ROOT) + EgtRelocate( NewId, AuxId, GDB_IN.AFTER) + EgtErase( AuxId) + EgtChangeId( NewId, AuxId) + -- sistemo i lati aperti + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, 0)[1] + if vFacAdj then + local sOpen = '' + for i = 1, #vFacAdj do + if vFacAdj[i] < 0 then + sOpen = sOpen .. EgtIf( #sOpen > 0, ',', '') .. tostring( i - 1) + end + end + if #sOpen > 0 then + EgtSetInfo( AuxId, 'OPEN', sOpen) + end + end + end + end + -- verifico se frontale + local bFront = ( Proc.Prc == 51) + -- recupero i dati della faccia di fondo + local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + local ptC = ORIG() + local vtN = V_NULL() + if frMor then + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + end + -- Confronto le direzioni dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante + local bOpenBtm = not AreSameVectorApprox( vtExtr, vtN) + if bOpenBtm then + -- creo superficie chiusa + local nFlat = EgtSurfTmByFlatContour( EgtGetParent( AuxId), AuxId, 0.05) + if nFlat then + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + -- verifico se copiare la geometria lungo l'asse Z + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frMor) + local bxMax = b3Aux:getMax() + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local bxMin = b3Mor:getMin() + local dMove = bxMin:getZ()-bxMax:getZ() + -- se il percorso ausiliario è esterno al grezzo, lo riavvicino + if abs( dMove) > GEO.EPS_SMALL then + AuxId = EgtCopyGlob( AuxId, BL.GetAddGroup(nPartId)) + EgtMove( AuxId, Vector3d(0,0,-dMove)) + EgtMove( nFlat, Vector3d(0,0,-dMove)) + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + end + -- cancello le prove del misfatto (superficie piana) + EgtErase( nFlat) + end + end + -- scrivo info nel log + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- Se mortasa chiusa + if not bOpenBtm then + -- verifico che la mortasa non sia orientata verso il basso (limite -5 deg) o che ci sia una testa da sotto o un rinvio angolare + if vtN:getZ() < -0.1 and not BD.DOWN_HEAD and not BD.ANG_TRASM then + local sErr = 'Error : Mortise from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- altrimenti passante + else + -- determino se la mortasa da lavorare sul lato opposto sia di angolo inferiore a quello consentito + if abs( vtN:getZ()) > 0.1 then + bForceOneSide = true + end + -- determino se è meglio lavorare la mortasa nel lato opposto + if vtN:getZ() < -GEO.EPS_SMALL then + bRevertSide = true + end + end + + -- se mortasa di fronte, eseguo il taglio della faccia + if bFront then + -- verifico esista la faccia di taglio + local ptCutC, vtCutN = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if ptCutC and vtCutN and AreSameVectorApprox( vtExtr, vtCutN) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptCutC, vtCutN, b3Solid, GDB_RT.GLOB) + local b3Cut = EgtGetBBoxGlob( AddId or GDB_ID.NULL, GDB_BB.STANDARD) + local CutProc = { Id = AddId, Grp = Proc.Grp - 2, Prc = 10, Box = b3Cut, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtExtr:getZ() > 0.25) + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH, bFromBottom) + if not bOk then return bOk, sErr end + end + end + + -- determino altezza della mortasa + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local dMorH = b3Mor:getDimZ() + -- elevazione del punto centro + if not bFront then + local _, dCenElev = BL.GetPointDirDepth( nPartId, ptC, vtN) + dMorH = max( dMorH, dCenElev or 0) + end + -- determino larghezza della mortasa + if dL < dW then dL, dW = dW, dL end + -- abilitazione lavorazione da sotto + local bPockUp = ( BD.DOWN_HEAD and vtExtr:getZ() > -0.259) + local bPockDown = ( BD.DOWN_HEAD and vtExtr:getZ() < 0.174) + local bPockAngTrasm = ( BD.ANG_TRASM and vtExtr:getZ() < -0.1) + -- recupero la lavorazione + local sPockType = 'Mortise' + local sMchExt = '' + if bPockDown then + sMchExt = '_H2' + elseif bPockAngTrasm then + sMchExt = '_AT' + end + local sPocketing + if Proc.Prc ~= 53 then + sPocketing = ML.FindPocketing( sPockType..sMchExt, dW) + if not sPocketing and bPockUp then + sPocketing = ML.FindPocketing( sPockType, dW) + end + end + if not sPocketing then + sPockType = 'Pocket' + sPocketing = ML.FindPocketing( sPockType..sMchExt, dW) + if not sPocketing and bPockUp then + sPocketing = ML.FindPocketing( sPockType, dW) + end + end + if not sPocketing then + local sErr = 'Error : Mortise or Pocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local bCW = true + 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) + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'Mort_' .. ( 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 + -- verifico se invertire versore estrusione geometria + if bRevertSide then + EgtModifyCurveExtrusion( AuxId, -vtExtr, GDB_ID.ROOT) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo la direzione di lavoro + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if bPockAngTrasm then + nSCC = MCH_SCC.ADIR_NEAR + elseif not BD.C_SIMM then + if vtN:getY() < GEO.EPS_SMALL then + nSCC = EgtIf( bRevertSide, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + else + nSCC = EgtIf( bRevertSide, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP) + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + local sWarn + local nDepthMin + -- se la mortasa è passante e non è forzata a un solo lato, riduco l'affondamento a metà profondità + if bOpenBtm and not bForceOneSide then + dMorH = dMorH * 0.5 + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + if dMorH > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in mortise : elevation (' .. EgtNumToString( dMorH,1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth,1) .. ')' + -- se non ho invertito la direzione di estrusione + if not bRevertSide then + nDepthMin = dMaxDepth - EgtIf( bOpenBtm and not bForceOneSide, dMorH * 2, dMorH) + else + nDepthMin = dMaxDepth + end + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + dMorH = dMaxDepth + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + else + if bOpenBtm and not bForceOneSide then -- se mortasa passante setto metà profondità + nDepthMin = -dMorH + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + end + end + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMorH, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- Se non c'è il fondo e la lavorazione non ha lavorato tutta la superficie per limite altezza utensile + -- inserisco una ulteriore lavorazione contraria + if bOpenBtm and not bForceOneSide and nDepthMin and abs(nDepthMin) > 0 then + -- inserisco la lavorazione di svuotatura opposta + sName = 'Mort_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_Oppo' + nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + EgtOutLog( sErr) + return false, sErr + end + -- faccio la copia e la metto nel layer dedicato alle geometrie aggiunte + local AuxId_oppo = EgtCopyGlob( AuxId, BL.GetAddGroup(nPartId)) + -- inverto la direzione estrusione di questa + EgtModifyCurveExtrusion( AuxId_oppo, - vtExtr, GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId_oppo, -1}}) + -- sistemo la direzione di lavoro + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + -- se altezza mortasa differente da altezza massima lavorabile + if abs( dMorH - dMaxDepth) > GEO.EPS_SMALL then + nDepthMin = -dMorH + else -- se sono uguali setto + nDepthMin = -( dMorH - BD.CUT_EXTRA) + end + -- setto profondità + EgtSetMachiningParam( MCH_MP.DEPTH, -nDepthMin+BD.CUT_EXTRA) + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (-nDepthMin+BD.CUT_EXTRA), 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessMortise diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfCamb.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfCamb.lua new file mode 100644 index 0000000..0bd4cc7 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfCamb.lua @@ -0,0 +1,699 @@ +-- ProcessProfCamb.lua by Egaltech s.r.l. 2022/02/02 +-- Gestione calcolo profilo caudato per Travi +-- 2021/05/03 Aggiunta gestione smusso da sopra e sotto per macchina con testa da sotto. +-- 2021/06/28 Per macchine con testa sotto, smussi di lato con questa testa se non c'è lav.ne da sopra. +-- 2021/10/12 Estesa gestione di testa da sotto, se presente. +-- 2021/10/12 Portato a 30deg l'angolo limite per fare l'antischeggia. +-- 2022/01/26 Migliorato controllo lavorazione con fresa su testa da sotto. +-- 2022/02/02 Aggiunta funzione OnlyChamfer. + +-- Tabella per definizione modulo +local ProcessProfCamb = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfCamb started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q01' -- i +local sEnableExtraBladeUpperFace = 'Q02' -- i +local sDepthChamferMill = 'Q03' -- d +local sOverMaterialForFinish = 'Q04' -- d +local sPreemptiveChamfer = 'Q05' -- i + +-- abilitazioni extra +local dMakeAntiSplintOnHead = 1 -- valore impronta antischeggia, per disattivare settare = nil o = 0 +local dActivateCompoAng = 0.5 -- valore componente Y o Z per antischeggia + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfCamb.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 103) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfCamb.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +-- Verifico se richiesto il solo smusso +function ProcessProfCamb.OnlyChamfer( Proc) + return (( EgtGetInfo( Proc.Id, sDepthChamferMill, 'd') or 0) > 0.1 and EgtGetInfo( Proc.Id, sPreemptiveChamfer, 'i') == 1) +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtNF) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtNF) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtSP( AuxId, GDB_ID.ROOT) + vtNP * 5.0 + -- determino asse di rotazione + local vtRot = - Y_AX() + if vtNF:getX() < 0 then vtRot = - vtRot end + if vtNF:getZ() < -0.1 then + vtRot = - vtRot + elseif vtNF:getY() < -0.1 then + vtRot:rotate( X_AX(), 90) + elseif vtNF:getY() > 0.1 then + vtRot:rotate( X_AX(), -90) + end + -- miglioro l'inclinazione (ripartendo da faccia perpendicolare asse trave) + vtNP[2] = 0 vtNP[3] = 0 + local dRot = 45 + for i = 1, 4 do + local vtNP2 = Vector3d( vtNP) + vtNP2:rotate( vtRot, dRot) + local frRef = Frame3d( ptStart, vtNP2) + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frRef) + if b3Box:getMax():getZ() < -3 then + vtNP = Vector3d( vtNP2) + end + dRot = dRot / 2 + end + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideAndInvert( Proc, bHead, bForceInvert, nCutLengthMach) + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if bForceInvert or ( nMachMode == 1 and ptSP and ptEp) then + if bForceInvert or ( abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX())) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + -- se devo tagliare il percorso setto anche i parametri per l'antischeggia + if nCutLengthMach then + EgtSetMachiningParam( MCH_MP.OFFSR, 0.5) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, nCutLengthMach) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0.1 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if nChamfer == 1 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error : not horizontal chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling, sMilling2 + if nChamfer > 0 then + if BD.DOWN_HEAD and abs( vtExtr:getZ()) < 0.1 and BD.DH_MAX_TOP and ( Proc.Box:getMax():getZ() - b3Raw:getMax():getZ()) < BD.DH_MAX_TOP then + sMilling = ML.FindMilling( 'Mark_H2') + if not sMilling then sMilling = ML.FindMilling( 'Mark') end + else + sMilling = ML.FindMilling( 'Mark') + end + if not sMilling then + local sErr = 'Error : chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + if BD.DOWN_HEAD and abs( vtExtr:getZ()) > 0.9 then + sMilling2 = ML.FindMilling( 'Mark_H2') + if not sMilling2 then + local sErr = 'Error : chamfer2 not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + end + + return nChamfer, dDepth, sMilling, sMilling2 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- ultima faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nLastFacet, GDB_ID.ROOT) + local nRefFacet = nLastFacet - 1 -- penultima faccia + local vtNF = EgtSurfTmFacetNormVersor( Proc.Id, nLastFacet, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nRefFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtNF:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- abilitazione lavorazione da sotto + local bMillDown = ( BD.DOWN_HEAD and nSide == -1) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local bMakeVertCham = BD.DOWN_HEAD + local nChamfer, dDepthCham, sChamfer, sChamfer2 = VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + --variabili utilizzate in varie parti + local dMillDiam = 0 + local dToolMaxDepth = 0 + local dToolMaxMat = 0 + local sMilling + -- in base alla direzione iniziale della curva e al valore di entrata valido, setto l'antischeggia + local bMakeAs + local vtStart = EgtSV( AuxId, GDB_ID.ROOT) + if nSide == 0 then + if abs(vtStart:getY()) >= dActivateCompoAng and dMakeAntiSplintOnHead and abs(dMakeAntiSplintOnHead) > 0 then + bMakeAs = true + end + else + if abs(vtStart:getZ()) >= dActivateCompoAng and dMakeAntiSplintOnHead and abs(dMakeAntiSplintOnHead) > 0 then + bMakeAs = true + end + end + -- se smusso non è esclusivo, aggiungo sgrossatura con taglio di lama + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtNF) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId and BL.GetFaceElevation( AddId, 0, nPartId) > 20.0 then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH) + if not bOk then return bOk, sErr end + end + -- leggo anticipatamente i parametri utensile fresa per dare un valore opportuno all'elevazione della lama + -- recupero la lavorazione di fresatura + local sMillType = 'Prof' + sMilling = ML.FindMilling( sMillType .. EgtIf( bMillDown, '_H2', '')) + if not sMilling and bMillDown then + sMilling = ML.FindMilling( sMillType) + bMillDown = false + end + 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 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() or dToolMaxDepth + dToolMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dToolMaxMat + end + end + -- se non da sotto e abilitato dal parametro Q aggiungo taglio di lama + if ( nSide ~= -1 or bMillDown) and nLastFacet and EgtGetInfo( Proc.Id, sEnableExtraBladeUpperFace, 'i') == 1 then + -- recupero la lavorazione + local sCutType = 'HeadSide' + local sCutting = ML.FindCutting( sCutType .. EgtIf( bMillDown, '_H2', '')) + -- se richiesto taglio con lama da sotto e non trovato non posso utilizzare quello da sopra + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 0 + local dMaxDepth = 0 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + local vtOrthoO = Vector3d( vtN) + local dVzLimDwnUp = EgtIf( bMillDown, -2, nil) + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, nLastFacet, sCutting, dToolDiam, vtOrthoO, dVzLimDwnUp, -((dMillDiam/2)+1), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se profilo sopra o sotto (lavorazioni di fianco) + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti profilo davanti o dietro (lavorazioni da sopra e/o sotto) + else + bDoubleCham = BD.DOWN_HEAD + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local sMachining2 = EgtIf( BD.DOWN_HEAD and sChamfer2, sChamfer2, sChamfer) + local nMchId = EgtAddMachining( sName, sMachining2) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMachining2 + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName + if bMakeAs then + sName = 'Prof_As_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + else + sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + end + 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtNF:getY() > 0.1) or + ( not bHead and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead) + end + -- se devo fare l'antischeggia in testa + if bMakeAs then + local sNewName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + -- copio lavorazione per ingresso antischeggia (la copia è la lavorazione finale) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + -- rendo corrente la precedente, la inverto e modifico il parametri di uscita + EgtSetCurrMachining( nMchId) + local dCrvLen = EgtCurveLength( AuxId) + if dCrvLen > abs(dMakeAntiSplintOnHead) then + ModifySideAndInvert( Proc, bHead, true, ( abs(dMakeAntiSplintOnHead) - dCrvLen)) + end + -- rendo corrente la copia (cioè la lavorazione completa) + EgtSetCurrMachining( nMch2Id) + nMchId = nMch2Id + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sNewName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi inutili + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, dToolMaxMat) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName + if bMakeAs then + sName = 'ProfB_As_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + else + sName = 'ProfB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + end + 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideAndInvert( Proc, bHead) + end + -- se devo fare l'antischeggia in testa + if bMakeAs then + local sNewName = 'ProfB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + -- copio lavorazione per ingresso antischeggia (la copia è la lavorazione finale) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + -- rendo corrente la precedente, la inverto e modifico il parametri di uscita + EgtSetCurrMachining( nMchId) + local dCrvLen = EgtCurveLength( AuxId) + if dCrvLen > abs(dMakeAntiSplintOnHead) then + ModifySideAndInvert( Proc, bHead, true, ( abs(dMakeAntiSplintOnHead) - dCrvLen)) + end + -- rendo corrente la copia (cioè la lavorazione completa) + EgtSetCurrMachining( nMch2Id) + nMchId = nMch2Id + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi inutili + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, dToolMaxMat) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se non da sotto e parametro Q abilitato, inserisco lavorazione finitura angolo + if ( nSide ~= -1 or bMillDown) and EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') == 1 then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, -0.5) + -- imposto tipo uso faccia + local nFaceUse = EgtIf( bMillDown, MCH_MILL_FU.ORTHO_TOP, MCH_MILL_FU.ORTHO_DOWN) + if nSide == 0 then + nFaceUse = EgtIf( vtN:getY() > 0.1, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then -- se feature di fianco o da sotto + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + -- altrimenti feature da sopra + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfCamb diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfConcave.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfConcave.lua new file mode 100644 index 0000000..799a891 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfConcave.lua @@ -0,0 +1,663 @@ +-- ProcessProfConcave.lua by Egaltech s.r.l. 2022/02/02 +-- Gestione calcolo profilo concavo per Travi +-- 2021/05/03 Aggiunta gestione smusso da sopra e sotto per macchina con testa da sotto. +-- 2021/06/28 Per macchine con testa sotto, smussi di lato con questa testa se non c'è lav.ne da sopra. +-- 2022/02/02 Aggiunta funzione OnlyChamfer. + +-- Tabella per definizione modulo +local ProcessProfConcave = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfConcave started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q03' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q01' -- d +local sOverMaterialForFinish = 'Q02' -- d +local sPreemptiveChamfer = 'Q04' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfConcave.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 101) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfConcave.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +-- Verifico se richiesto il solo smusso +function ProcessProfConcave.OnlyChamfer( Proc) + return (( EgtGetInfo( Proc.Id, sDepthChamferMill, 'd') or 0) > 0.1 and EgtGetInfo( Proc.Id, sPreemptiveChamfer, 'i') == 1) +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, + bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + end + -- modifico attacco e uscita + if dLenIni and dLenLst then + -- se entità agli estremi sono inferiori del raggio utensile ed è abilitata la ripresa della faccia, + -- allungo attacco e/o uscita + local dStartAddLen = 0 + if bFirstTrim and dLenIni < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dStartAddLen = dToolDiam / 2 - dLenIni + dOffsetPar + 1 + end + local dEndAddLen = 0 + if bLastTrim and dLenLst < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dEndAddLen = dToolDiam / 2 - dLenLst + dOffsetPar + 1 + end + if bFlagInvert then + dStartAddLen, dEndAddLen = dEndAddLen, dStartAddLen + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0.1 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if nChamfer == 1 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error : not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning : skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling, sMilling2 + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + if BD.DOWN_HEAD and abs( vtExtr:getZ()) < 0.1 then + sMilling = ML.FindMilling( 'Mark_H2') + end + if not sMilling then + local sErr = 'Error : chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + if BD.DOWN_HEAD and abs( vtExtr:getZ()) > 0.9 then + sMilling2 = ML.FindMilling( 'Mark_H2') + if not sMilling2 then + local sErr = 'Error : chamfer2 not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + end + + return nChamfer, dDepth, sMilling, sMilling2 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) // 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- acquisisco informazioni sulle facce estreme + local _, _, dLenIni = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFirstFacet, GDB_ID.ROOT) + local _, _, dLenLst = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nLastFacet, GDB_ID.ROOT) + -- flag percorso invertito + local bFlagInvert = false + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local bMakeVertCham = BD.DOWN_HEAD + local nChamfer, dDepthCham, sChamfer, sChamfer2 = VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo, aggiungo sgrossatura con taglio di lama + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId and BL.GetFaceElevation( AddId, 0, nPartId) > 20.0 then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- Recupero i dati dell'utensile + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sChamfer) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- altrimenti lavorazione dal davanti o dal dietro + else + bDoubleCham = BD.DOWN_HEAD + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dExtra) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local sMachining2 = EgtIf( BD.DOWN_HEAD and sChamfer2, sChamfer2, sChamfer) + local nMchId = EgtAddMachining( sName, sMachining2) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMachining2 + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dExtra) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero i dati dell'utensile + local dToolDiam = 0 + local dToolMaxDepth = 0 + local dToolMaxMat = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() or dToolMaxDepth + dToolMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dToolMaxMat + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi inutili + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, dToolMaxMat) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi inutili + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, dToolMaxMat) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bLastTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + elseif vtN:getY() < -0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTUP_TOP) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (dToolMaxDepth/2), 1)) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bFirstTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then -- se feature di fianco o da sotto + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + -- altrimenti feature da sopra + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfConcave diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfConvex.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfConvex.lua new file mode 100644 index 0000000..9baa0fe --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfConvex.lua @@ -0,0 +1,662 @@ +-- ProcessProfConvex.lua by Egaltech s.r.l. 2022/02/02 +-- Gestione calcolo profilo convesso per Travi +-- 2021/05/03 Aggiunta gestione smusso da sopra e sotto per macchina con testa da sotto. +-- 2021/06/28 Per macchine con testa sotto, smussi di lato con questa testa se non c'è lav.ne da sopra. +-- 2022/02/02 Aggiunta funzione OnlyChamfer. + +-- Tabella per definizione modulo +local ProcessProfConvex = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfConvex started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q05' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q02' -- d +local sOverMaterialForFinish = 'Q04' -- d +local sPreemptiveChamfer = 'Q01' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfConvex.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 102) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfConvex.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +-- Verifico se richiesto il solo smusso +function ProcessProfConvex.OnlyChamfer( Proc) + return (( EgtGetInfo( Proc.Id, sDepthChamferMill, 'd') or 0) > 0.1 and EgtGetInfo( Proc.Id, sPreemptiveChamfer, 'i') == 1) +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, + bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + end + -- modifico attacco e uscita + if dLenIni and dLenLst then + -- se entità agli estremi sono inferiori del raggio utensile ed è abilitata la ripresa della faccia, + -- allungo attacco e/o uscita + local dStartAddLen = 0 + if bFirstTrim and dLenIni < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dStartAddLen = dToolDiam / 2 - dLenIni + dOffsetPar + 1 + end + local dEndAddLen = 0 + if bLastTrim and dLenLst < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dEndAddLen = dToolDiam / 2 - dLenLst + dOffsetPar + 1 + end + if bFlagInvert then + dStartAddLen, dEndAddLen = dEndAddLen, dStartAddLen + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0.1 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if nChamfer == 1 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error : not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning : skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling, sMilling2 + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + if BD.DOWN_HEAD and abs( vtExtr:getZ()) < 0.1 then + sMilling = ML.FindMilling( 'Mark_H2') + end + if not sMilling then + local sErr = 'Error : chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + if BD.DOWN_HEAD and abs( vtExtr:getZ()) > 0.9 then + sMilling2 = ML.FindMilling( 'Mark_H2') + if not sMilling2 then + local sErr = 'Error : chamfer2 not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + end + + return nChamfer, dDepth, sMilling, sMilling2 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) // 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- acquisisco informazioni sulle facce estreme + local _, _, dLenIni = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFirstFacet, GDB_ID.ROOT) + local _, _, dLenLst = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nLastFacet, GDB_ID.ROOT) + -- flag percorso invertito + local bFlagInvert = false + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local bMakeVertCham = BD.DOWN_HEAD + local nChamfer, dDepthCham, sChamfer, sChamfer2 = VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo, aggiungo sgrossatura con taglio di lama + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId and BL.GetFaceElevation( AddId, 0, nPartId) > 20.0 then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- Recupero i dati dell'utensile + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sChamfer) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- altrimenti lavorazione dal davanti o dal dietro + else + bDoubleCham = BD.DOWN_HEAD + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dExtra) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local sMachining2 = EgtIf( BD.DOWN_HEAD and sChamfer2, sChamfer2, sChamfer) + local nMchId = EgtAddMachining( sName, sMachining2) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMachining2 + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dExtra) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero i dati dell'utensile + local dToolDiam = 0 + local dToolMaxDepth = 0 + local dToolMaxMat = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() or dToolMaxDepth + dToolMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dToolMaxMat + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi inutili + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, dToolMaxMat) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi inutili + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, dToolMaxMat) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bLastTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + elseif vtN:getY() < -0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTUP_TOP) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( (dToolMaxDepth/2), 1)) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bFirstTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfConvex diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfFront.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfFront.lua new file mode 100644 index 0000000..d5e0ba2 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfFront.lua @@ -0,0 +1,594 @@ +-- ProcessProfFront.lua by Egaltech s.r.l. 2022/02/02 +-- Gestione calcolo profilo frontale per Travi +-- 2021/05/03 Aggiunta gestione smusso da sopra e sotto per macchina con testa da sotto. +-- 2021/06/28 Per macchine con testa sotto, smussi di lato con questa testa se non c'è lav.ne da sopra. +-- 2022/02/02 Aggiunta funzione OnlyChamfer. + +-- Tabella per definizione modulo +local ProcessProfFront = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfFront started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = '' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q01' -- d +local sOverMaterialForFinish = 'Q02' -- d +local sPreemptiveChamfer = 'Q03' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfFront.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 100) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfFront.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +-- Verifico se richiesto il solo smusso +function ProcessProfFront.OnlyChamfer( Proc) + return (( EgtGetInfo( Proc.Id, sDepthChamferMill, 'd') or 0) > 0.1 and EgtGetInfo( Proc.Id, sPreemptiveChamfer, 'i') == 1) +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + local vtNP = Vector3d( vtN) + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideInvertLead( Proc, bHead, dToolDiam) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0.1 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if nChamfer == 1 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error : not horizontale chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning : skipped not horizontale chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling, sMilling2 + if nChamfer > 0 then + sMilling = ML.FindMilling( 'Mark') + if not sMilling then + if BD.DOWN_HEAD and abs( vtExtr:getZ()) < 0.1 then + sMilling = ML.FindMilling( 'Mark_H2') + end + if not sMilling then + local sErr = 'Error : chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + if BD.DOWN_HEAD and abs( vtExtr:getZ()) > 0.9 then + sMilling2 = ML.FindMilling( 'Mark_H2') + if not sMilling2 then + local sErr = 'Error : chamfer2 not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + end + + return nChamfer, dDepth, sMilling, sMilling2 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- ultima faccia + local nRefFacet = nLastFacet - 1 -- penultima faccia + -- determino la normale media + local CvxHullId = EgtSurfTmConvexHullInBBox( EgtGetParent( Proc.Id), Proc.Id, b3Raw, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( CvxHullId, 0, GDB_ID.ROOT) + EgtErase( CvxHullId) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + --EgtOutLog( 'vtN=' .. tostring( vtN)) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local bMakeVertCham = BD.DOWN_HEAD + local nChamfer, dDepthCham, sChamfer, sChamfer2 = VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo, aggiungo sgrossatura con taglio di lama + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId and BL.GetFaceElevation( AddId, 0, nPartId) > 20.0 then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + bDoubleCham = BD.DOWN_HEAD + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dMillDiam) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local sMachining2 = EgtIf( BD.DOWN_HEAD and sChamfer2, sChamfer2, sChamfer) + local nMchId = EgtAddMachining( sName, sMachining2) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMachining2 + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- allungo inizio e fine attacco + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dMillDiam) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Prof') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero i dati dell'utensile + local dToolDiam = 0 + local dToolMaxDepth = 0 + local dToolMaxMat = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() or dToolMaxDepth + dToolMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dToolMaxMat + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi inutili + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, dToolMaxMat) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi inutili + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, dToolMaxMat) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and bFirstTrim and + ( nSide ~= -1 or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1)) then + -- se non da sotto, inserisco lavorazione finitura angolo + --if nSide ~= -1 then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- setto inversione e lato lavoro per lavorare sinistro + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- imposto tipo uso faccia + local nFaceUse = MCH_MILL_FU.PARAL_DOWN + if nSide ~= 1 then + nFaceUse = EgtIf( vtN:getY() > 0.1, MCH_MILL_FU.PARAL_FRONT, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + -- aggiorno ingombro testa o coda per presa + --if nSide == 0 then + -- if bHead then + -- BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + -- else + -- BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + -- end + --end + return true +end + +--------------------------------------------------------------------- +return ProcessProfFront diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfHead.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfHead.lua new file mode 100644 index 0000000..65d8cc1 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessProfHead.lua @@ -0,0 +1,695 @@ +-- ProcessProfHead.lua by Egaltech s.r.l. 2022/02/02 +-- Gestione calcolo profilo di testa per Travi +-- 2021/05/03 Aggiunta gestione smusso da sopra e sotto per macchina con testa sotto. +-- 2021/06/28 Per macchine con testa sotto, smussi di lato con questa testa se non c'è lav.ne da sopra. +-- 2021/10/12 Estesa gestione di testa da sotto, se presente. +-- 2022/02/02 Aggiunta funzione OnlyChamfer. + +-- Tabella per definizione modulo +local ProcessProfHead = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfHead started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sEnableExtraMillUpperFace = 'Q03' -- i +local sEnableExtraBladeUpperFace = '' -- i +local sDepthChamferMill = 'Q01' -- d +local sOverMaterialForFinish = 'Q04' -- d +local sPreemptiveChamfer = 'Q02' -- i +local sMachFacesUnderneath = 'Q99' -- i + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfHead.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 106) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessProfHead.Classify( Proc, b3Raw) + -- recupero la curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + AuxId = EgtIf( AuxId, AuxId + Proc.Id, GDB_ID.NULL) + local vtN = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if not vtN then return false end + -- se profilo orizzontale + if abs( vtN:getZ()) < 0.5 then + return true, false, false + -- altrimenti è profilo verticale che interessa tutta la sezione + else + -- recupero la massima capacità di lavoro dell'utensile da utilizzare + local sMilling, dMaxDepth = ML.FindMilling( 'Prof') + if not sMilling then dMaxDepth = 0 end + if Proc.Box:getDimZ() > dMaxDepth and BD.ROT90 then + return true, false, true + else + return true, false, false + end + end +end + +--------------------------------------------------------------------- +-- Verifico se richiesto il solo smusso +function ProcessProfHead.OnlyChamfer( Proc) + return (( EgtGetInfo( Proc.Id, sDepthChamferMill, 'd') or 0) > 0.1 and EgtGetInfo( Proc.Id, sPreemptiveChamfer, 'i') == 1) +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- assegno la normale + local vtNP = Vector3d( vtN) + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +local function ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, dLenLst, + bFirstTrim, bLastTrim, bFlagInvert, dOffsetPar) + + -- confronto il punto iniziale e finale della lavorazione con il box della feature + -- e se è vicino alla parte esterna della trave inverto la lavorazione + ptSP = EgtGetMachiningStartPoint() + ptEp = EgtGetMachiningEndPoint() + local nMachMode = EgtGetMachiningParam( MCH_MP.STEPTYPE) + if nMachMode == 1 and ptSP and ptEp then + if abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptSP:getX()) < + abs( EgtIf( bHead, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) - ptEp:getX()) then + -- ottengo il lato lavoro e lo inverto + local nSideWork = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nSideWork > 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nSideWork == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + end + -- ottengo l'inversione e setto il contrario + local bInvertMode = EgtGetMachiningParam( MCH_MP.INVERT) + EgtSetMachiningParam( MCH_MP.INVERT, not bInvertMode) + end + -- modifico attacco e uscita + if dLenIni and dLenLst then + -- se entità agli estremi sono inferiori del raggio utensile ed è abilitata la ripresa della faccia, + -- allungo attacco e/o uscita + local dStartAddLen = 0 + if bFirstTrim and dLenIni < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dStartAddLen = dToolDiam / 2 - dLenIni + dOffsetPar + 1 + end + local dEndAddLen = 0 + if bLastTrim and dLenLst < dToolDiam / 2 + ( 20 * GEO.EPS_SMALL) then + dEndAddLen = dToolDiam / 2 - dLenLst + dOffsetPar + 1 + end + if bFlagInvert then + dStartAddLen, dEndAddLen = dEndAddLen, dStartAddLen + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- riapplico la lavorazione + EgtApplyMachining( true, false) + end +end + +--------------------------------------------------------------------- +local function VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDephtCham, sOnlyCham) + local nChamfer = 0 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0.1 then + nChamfer = 1 + end + -- verifico se posso fare solo lo smusso + if EgtGetInfo( Proc.Id, sOnlyCham, 'i') == 1 then + if nChamfer == 1 then + nChamfer = nChamfer + 1 + -- altrimenti se non ho l'affondamento esco + else + local sErr = 'Error : no chamfer depth' + EgtOutLog( sErr) + return -1, dDepth, sErr + end + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale e il flag di lavorazione verticale è disabilitato + if abs( vtExtr:getZ()) > 0.1 then + if not bMakeVertCham then + if nChamfer == 2 then -- se devo fare solo smusso, genero errore + local sErr = 'Error : not horizontal chamfer' + EgtOutLog( sErr) + return -1, dDepth, sErr + else + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return 0, dDepth + end + end + end + -- recupero la lavorazione + local sMilling, sMilling2 + if nChamfer > 0 then + if BD.DOWN_HEAD and abs( vtExtr:getZ()) < 0.1 and BD.DH_MAX_TOP and ( Proc.Box:getMax():getZ() - b3Raw:getMax():getZ()) < BD.DH_MAX_TOP then + sMilling = ML.FindMilling( 'Mark_H2') + if not sMilling then sMilling = ML.FindMilling( 'Mark') end + else + sMilling = ML.FindMilling( 'Mark') + end + if not sMilling then + local sErr = 'Error : chamfer not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + if BD.DOWN_HEAD and abs( vtExtr:getZ()) > 0.9 then + sMilling2 = ML.FindMilling( 'Mark_H2') + if not sMilling2 then + local sErr = 'Error : chamfer2 not found in library' + EgtOutLog( sErr) + return -1, 0, sErr + end + end + end + + return nChamfer, dDepth, sMilling, sMilling2 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dProfDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + -- determino la normale media + local CvxHullId = EgtSurfTmConvexHullInBBox( EgtGetParent( Proc.Id), Proc.Id, b3Raw, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( CvxHullId or GDB_ID.NULL, 0, GDB_ID.ROOT) + EgtErase( CvxHullId) + if not vtN then + local nRef= Proc.Fct // 3 + local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nRef, GDB_ID.ROOT) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, 2 * nRef, GDB_ID.ROOT) + vtN = vtN1 + vtN2 + vtN:normalize() + end + -- acquisisco informazioni sulle facce estreme + local _, _, dLenIni = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFirstFacet, GDB_ID.ROOT) + local _, _, dLenLst = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nLastFacet, GDB_ID.ROOT) + -- flag percorso invertito + local bFlagInvert = false + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- abilitazione lavorazione da sotto + local bMillDown = ( BD.DOWN_HEAD and nSide == -1) + -- verifico se necessari ripassi negli angoli + local vAngs = {} + for i = 1, Proc.Fct do + local _, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, i-1, i, GDB_ID.ROOT) + if ( dAng and dAng < -30) then + table.insert( vAngs, i - 1) + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local bMakeVertCham = BD.DOWN_HEAD + local nChamfer, dDepthCham, sChamfer, sChamfer2 = VerifyCham( Proc, AuxId, nRawId, bMakeVertCham, sDepthChamferMill, sPreemptiveChamfer) + -- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer + -- genero errore e non faccio nulla + if nChamfer < 0 then + return false, sChamfer + end + -- se smusso non è esclusivo, aggiungo sgrossatura con taglio di lama + if nChamfer < 2 then + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId and BL.GetFaceElevation( AddId, 0, nPartId) > 20.0 then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dCurrOvmH) + if not bOk then return bOk, sErr end + end + end + -- se devo inserire il chamfer + if nChamfer > 0 then + local bDoubleCham = false + local dExtra = 2 + -- Recupero i dati dell'utensile + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sChamfer) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + -- inserisco la lavorazione + local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sNameCh, sChamfer) + if not nMchId then + local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sChamfer + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + bDoubleCham = true + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- altrimenti lavorazione dal davanti o dal dietro + else + bDoubleCham = BD.DOWN_HEAD + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, + dLenLst, ( #vAngs > 0 and vAngs[1] == 0), ( #vAngs > 0 and vAngs[#vAngs] == (Proc.Fct-2)), bFlagInvert, dExtra) + end + -- se lavorazione da due parti, aggiungo la seconda + if bDoubleCham then + -- inserisco la lavorazione + local sName = 'ChamB_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local sMachining2 = EgtIf( BD.DOWN_HEAD and sChamfer2, sChamfer2, sChamfer) + local nMchId = EgtAddMachining( sName, sMachining2) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMachining2 + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepthCham + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- cambio il tipo di attacco in tangente + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 2) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione + ModifySideInvertLead( Proc, bHead, dToolDiam + ( 2 * dExtra), dLenIni, + dLenLst, ( #vAngs > 0 and vAngs[1] == 0), ( #vAngs > 0 and vAngs[#vAngs] == (Proc.Fct-2)), bFlagInvert, dExtra) + end + end + end + -- se il chamfer non è esclusivo continuo con le altre lavorazioni + if nChamfer < 2 then + -- recupero la lavorazione + local sMillType = 'Prof' + local sMilling = ML.FindMilling( sMillType .. EgtIf( bMillDown, '_H2', '')) + if not sMilling then + sMilling = ML.FindMilling( sMillType) + end + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero i dati dell'utensile + local dToolDiam = 0 + local dToolMaxDepth = 0 + local dToolMaxMat = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolMaxDepth = EgtTdbGetCurrToolMaxDepth() or dToolMaxDepth + dToolMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dToolMaxMat + end + end + -- verifico se necessario lavorare in doppio + local bDouble = ( nSide ~= 0 and dProfDepth + BD.CUT_EXTRA > dToolMaxDepth) + local dDepth = min( dToolMaxDepth, dProfDepth / 2 + BD.MILL_OVERLAP) + -- inserisco la lavorazione + local sName = 'Prof_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- se lavorazione da sopra o da sotto + if nSide ~= 0 then + if not bDouble and nSide == -1 then + -- se lavorazione a sinistra di fronte o destra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + else + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtN:getY() > 0.1) or + ( not bHead and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + end + -- se in doppio, imposto l'affondamento + if bDouble then + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- variabili per gestione direzione percorso e per gestione lavorazione di finitura opzionale + local ptSP, ptEp + local bFinish + local dOriOffset = 0 + local dOffsetPar = EgtGetInfo( Proc.Id, sOverMaterialForFinish, 'i') or 0 + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + bFinish = true + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, + dLenLst, ( #vAngs > 0 and vAngs[1] == 0), ( #vAngs > 0 and vAngs[#vAngs] == (Proc.Fct-2)), bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'Prof_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi inutili + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, dToolMaxMat) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + -- se lavorazione da due parti, aggiungo la seconda + if bDouble then + -- inserisco la lavorazione + local sName = 'ProfB_' .. ( 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}}) + -- resetto il flag inversione percorso + bFlagInvert = false + -- sempre lavorazione da sopra o da sotto + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + bFlagInvert = not bFlagInvert + end + -- imposto l'affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- se parametro sovramateriale è maggiore di 0 lo aggiungo al sovramateriale precedente + if dOffsetPar > 0 then + EgtSetMachiningParam( MCH_MP.OFFSR, ( dOriOffset + dOffsetPar)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + -- applico controllo del punto entrata lavorazione e se non è distante dall'esterno + -- della feature inverto il punto di inizio della lavorazione e modifico i parametri dell'attacco + -- e uscita + ModifySideInvertLead( Proc, bHead, dToolDiam, dLenIni, + dLenLst, ( #vAngs > 0 and vAngs[1] == 0), ( #vAngs > 0 and vAngs[#vAngs] == (Proc.Fct-2)), bFlagInvert, dOffsetPar) + end + -- se abilitata, aggiungo lavorazione di finitura + if bFinish then + -- inserisco la lavorazione + local sNewName = 'ProfB_Fin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtCopyMachining( sNewName, EgtGetName( nMchId)) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + else + -- riporto il sovramateriale originale e tolgo i passi inutili + EgtSetMachiningParam( MCH_MP.OFFSR, dOriOffset) + EgtSetMachiningParam( MCH_MP.STEP, dToolMaxMat) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMch2Id, false) + return false, sErr + end + end + end + end + -- se parametro Q disabilitato, e consentito anche in alcuni casi lavorarlo con la feature da sotto + -- inserisco eventuale finitura faccia finale (ortogonale alla trave o, se da sotto, parallela) + if EgtGetInfo( Proc.Id, sEnableExtraMillUpperFace, 'i') ~= 1 and #vAngs > 0 then + -- dimensioni feature + local dLen = Proc.Box:getDimX() + local dDep = EgtIf( nSide == 1, Proc.Box:getDimZ(), Proc.Box:getDimY()) + -- se più alta che lunga o da sotto con il parametro Q abilitato + if ( dDep > dLen) or ( nSide == -1 and EgtGetInfo( Proc.Id, sMachFacesUnderneath, 'i') == 1) then + for i = 1, #vAngs do + sName = 'ProfV'.. tostring( i)..'_'..( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dElev = EgtSurfTmFacetOppositeSide( Proc.Id, vAngs[i], EgtIf( bHead, X_AX(), -X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vAngs[i]}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dElev, 1)) + -- imposto posizione braccio + local nSCC = MCH_SCC.ADIR_YM + if nSide == 0 then + nSCC = EgtIf( vtN:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + -- altrimenti + elseif nSide ~= -1 then + for i = 1, #vAngs do + sName = 'ProfV'.. tostring( i)..'_'..( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dElev = EgtSurfTmFacetOppositeSide( Proc.Id, vAngs[i]+1, vtN, GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vAngs[i]+1}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dElev, 1)) + -- imposto posizione braccio + local nSCC = MCH_SCC.ADIR_YM + if nSide == 0 then + nSCC = EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + end + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Solid:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfHead diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessRidgeLap.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessRidgeLap.lua new file mode 100644 index 0000000..392fda3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessRidgeLap.lua @@ -0,0 +1,220 @@ +-- ProcessRidgeLap.lua by Egaltech s.r.l. 2021/09/10 +-- Gestione calcolo mezzolegno di testa per Travi + +-- Tabella per definizione modulo +local ProcessRidgeLap = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local Cut = require( 'ProcessCut') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessRidgeLap started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessRidgeLap.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 30) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessRidgeLap.Classify( Proc, b3Raw) + -- se PF con testa da sotto, ammessa qualunque orientazione + if BD.C_SIMM and BD.DOWN_HEAD then + return true, false + end + -- Se più corta del limite si può fare anche da sotto + if Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then + return true, false + end + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.707 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + return true + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getX()) < 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i-1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- determino se da lavorare con testa da sotto + local bDownHead = ( BD.DOWN_HEAD and vtN[vFaceOrd[3]]:getZ() < -0.1) + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide' .. EgtIf( bDownHead, '_H2', '')) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + local dMaxVertDepth = dMaxDepth - ( BD.DECR_VERT_CUT or 0) + local dVzLimDwnUp = EgtIf( bDownHead, -2, nil) + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla faccia esterna e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico taglio di lama + local b3Cut = EgtGetBBoxGlob( AddId or GDB_ID.NULL, GDB_BB.STANDARD) + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Cut, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead, false) + if not bOk then return bOk, sErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo riferimenti per facce inclinate + local vtRef = Vector3d( vtN[vFaceOrd[3]]) + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local nOrthoOpposite + if i % 2 == 1 then + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + else + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, dVzLimDwnUp, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[3]]) + local bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, dVzLimDwnUp, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( EgtIf( bHead, X_AX(), -X_AX())) + local bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, nOrthoOpposite, dVzLimDwnUp, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtN[vFaceOrd[3]]:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtN[vFaceOrd[3]]:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessRidgeLap diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessRoundArch.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessRoundArch.lua new file mode 100644 index 0000000..2be3a31 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessRoundArch.lua @@ -0,0 +1,250 @@ +-- ProcessRoundArch.lua by Egaltech s.r.l. 2021/01/29 +-- Gestione calcolo archi per Travi + +-- Tabella per definizione modulo +local ProcessRoundArch = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessRoundArch started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local Q_DIM_STRIP = 'Q02' -- d + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessRoundArch.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 104) +end +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessRoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessRoundArch.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di coda + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessRoundArch.Classify( Proc) + -- se di testa o coda, è indifferente alla posizione + if Proc.Head or Proc.Tail then + return true, false + end + -- è intermedia, devo verificare la normale del centro + local nMidFacet = Proc.Fct // 2 + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se la feature è lavorabile solo da sotto + --local bDown = ( vtN:getZ() < - 0.1) + local bDown = false + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessRoundArch.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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') + 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) + local bDown = ( b3Aux:getMin():getZ() < b3Raw:getMin():getZ() + 5) + -- 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 + -- ne verifico la lunghezza per eventuale spezzatura e lavorazione in doppio + local nStep = 1 + local dStep = 0 + local dLenMax = BD.LONGCUT_ENDLEN + if b3Aux:getDimX() > dLenMax then + local dCrvLen = EgtCurveLength( AuxId) + nStep = ceil( dCrvLen / dLenMax) + dStep = dCrvLen / nStep + EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) + end + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local bCross = false + if abs( vtExtr:getY()) > 0.707 then + if b3Aux:getDimY() > b3Raw:getDimY() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimY()) + end + elseif abs( vtExtr:getZ()) > 0.707 then + if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then + bCross = true + dDepth = min( dDepth, b3Raw:getDimZ()) + end + end + local nDouble = 1 + local bCanDouble = ( abs( vtExtr:getY()) > 0.707 and bCross) + local dDimStrip = BD.DIM_STRIP + if dDimStrip < 0 then + dDimStrip = EgtGetInfo( Proc.Id, Q_DIM_STRIP, 'd') or 0 + end + local bStripOnSide = false + if bCross then + if dDimStrip > 10 * GEO.EPS_SMALL and ( nStep > 1 or ( bDown and b3Aux:getDimX() > 0.5 * b3Raw:getDimX())) then + -- devo lasciare un codolo + dDepth = dDepth - dDimStrip + bStripOnSide = true + else + -- devo affondare un poco oltre + dDepth = dDepth + BD.CUT_EXTRA + end + end + -- se parametro beamdata forza codolo in centro e lavorazione orizzontale e se larghezza trave è sufficientemente larga + if BD.DIM_TO_CENTER_STRIP and BD.DIM_TO_CENTER_STRIP > 10 * GEO.EPS_SMALL and nStep > 1 and + bCanDouble and b3Raw:getDimY() > BD.DIM_TO_CENTER_STRIP - 0.1 then + nDouble = 2 + dDepth = min( ( b3Raw:getDimY() - dDimStrip) * 0.5, dMaxDepth) + else + -- se altezza geometria supera capacità taglio utensile ed è orizzontale setto per eseguire codolo in centro + if dDepth > dMaxDepth then + if bCanDouble then + nDouble = 2 + dDepth = min( 0.5 * dDepth, dMaxDepth) + else + dDepth = dMaxDepth + end + end + end + -- se utensile orizzontale verso Y+, non in doppio e codolo da lasciare, devo invertire per lavorare sempre da Y- + if vtExtr:getY() > 0.707 and nDouble == 1 and bStripOnSide then + bToolInv = true + end + -- eseguo + for i = 1, nStep do + for j = 1, nDouble do + -- 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}}) + -- eventuale accorciamento di testa + if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then + local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + end + -- eventuale accorciamento di coda + if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then + local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- se estrusione da sotto, inverto direzione fresa + if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- se seconda passata, inverto direzione di lavoro + if j == 2 then + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + if bToolInv then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + -- posizione braccio porta testa + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Solid:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessRoundArch diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessSawCut.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessSawCut.lua new file mode 100644 index 0000000..077d144 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessSawCut.lua @@ -0,0 +1,232 @@ +-- ProcessSawCut.lua by Egaltech s.r.l. 2022/03/07 +-- Gestione calcolo taglio di lama per Travi + +-- Tabella per definizione modulo +local ProcessSawCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') +local LongCut = require( 'ProcessLongCut') + +EgtOutLog( ' ProcessSawCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSawCut.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 13) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessSawCut.Classify( Proc, b3Raw) + -- recupero i dati del versore direzione di accesso della lavorazione + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtDir = EgtSV( AuxId, GDB_ID.ROOT) + return true, ( vtDir:getZ() <= - 0.5) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSawCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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à vettore + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.GEO_VECTOR then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing access direction' + EgtOutLog( sErr) + return false, sErr + end + local vtDir = EgtSV( AuxId, GDB_ID.ROOT) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local frFace = Frame3d( ptC, vtDir ^ vtN, vtDir, vtN) + local b3Face = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFace) + local dLen = b3Face:getDimX() + local dWidth = b3Face:getDimY() + -- se taglio di testa + if Proc.Head then + -- se coincide con il taglio di separazione precedente, non va fatto + if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- altrimenti taglio di coda + else + -- se coincide con taglio di separazione, non va fatto + if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + end + -- recupero flag per inizio e fine interni + local bInside = (( EgtGetInfo( Proc.Id, 'Q01', 'i') or 0) ~= 0) + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 2 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- determino se lavorazione da davanti o da dietro e se da sotto + local bFront = ( vtDir ^ vtN):getX() > 0 + local bDownUp = ( vtN:getZ() < -0.259) + local bFillAreaPiece + -- se non da sotto + if not bDownUp then + -- se poco inclinata ( inclinazione inferiore a 21.56 deg) + if vtN:getZ() > 0.93 then + -- verifico se la superfice è prevelentemente orizzontale con Z positiva e occupa tutta la trave o occupa sicuramente la faccia in Y + -- e almeno 3/4 della lunghezza in X e sborda in X e non interessa la faccia inferiore, + -- si possono far partire i tagli a cubetti dalla testa o lasciare il cordoncino centrale + if ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) or + ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) and + ( Proc.Box:getDimX() > 0.75 * b3Solid:getDimX() or Proc.Box:getDimX() > 1500.000))) and + abs( Proc.Box:getMin():getY() - b3Solid:getMin():getY()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getY() - b3Solid:getMax():getY()) < 10*GEO.EPS_SMALL and + b3Solid:getMin():getZ() < Proc.Box:getMin():getZ() - 100 * GEO.EPS_SMALL then + bFillAreaPiece = true + end + -- se praticamente verticale di fianco ( inclinazione inferiore a 21.56deg) + elseif abs( vtN:getY()) > 0.93 then + -- se la faccia occupa tutta la trave in X e Z o occupa sicuramente la faccia in Z e almeno 3/4 della faccia in X e sborda in X, + if ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) or + ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) and + ( Proc.Box:getDimX() > 0.75 * b3Solid:getDimX() or Proc.Box:getDimX() > 1500.000))) and + abs( Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getZ() - b3Solid:getMax():getZ()) < 10*GEO.EPS_SMALL then + local sErr = 'Error : Impossible to machine by orientation (on side)' + EgtOutLog( sErr) + return false, sErr + end + end + end + -- se ho il parametro Q04 = 1 e il taglio copre la lunghezza della trave allora lancio il processo dell'L10 + local nAsLongCut = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 + if nAsLongCut == 1 and bFillAreaPiece then + return LongCut.Make( Proc, nPhase, nRawId, nPartId, true) + -- se non ho taglio lungo passo al Cut per taglio a cubetti + elseif bFillAreaPiece and abs(( vtDir ^ vtN):getY()) > 0.866 then + local bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, 0, false, true) + -- se è andata a buon fine oppure ha fallito esco + -- nel caso non ha fatto i tagli a cubetti (sErr vale -1) continuo + if bOk or ( not bOk and type(sErr) ~= 'number') then + return bOk, sErr + end + end + -- determino affondamento e distanza interna da inizio e fine + local dDepth = min( dWidth, dMaxDepth - BD.COLL_SIC) + local dInsDist = 0 + if bInside then + dInsDist = sqrt( dSawDiam * dDepth - dDepth * dDepth) + if 2 * dInsDist > dLen - 2 then + dInsDist = ( dLen - 2) / 2 + dDepth = dSawDiam / 2 - sqrt( dSawDiam * dSawDiam / 4 - dInsDist * dInsDist) + end + end + -- determino numero di parti + local dStartAccDist = BD.LONGCUT_ENDLEN + local dEndAccDist = BD.LONGCUT_ENDLEN + local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then + dC = dLen / ( nC + 2) + dStartAccDist = min( dC, dStartAccDist) + dEndAccDist = min( dC, dEndAccDist) + dC = ( dLen - dStartAccDist - dEndAccDist) / nC + nC = nC + 2 + else + if dLen > min( dStartAccDist, dEndAccDist) then + nC = 2 + dStartAccDist = dLen / 2 + dEndAccDist = dStartAccDist + else + nC = 1 + dStartAccDist = 0 + dEndAccDist = 0 + end + end + -- determino l'utilizzo della faccia + local nFaceUse = BL.GetNearestOrthoOpposite( vtDir) + if bDownUp then + nFaceUse = BL.GetOrtupOpposite( nFaceUse) + end + -- si percorrono i lati alto e basso della faccia + for i = 1, nC do + -- Posizione braccio portatesta + local nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- ciclo sulle passate + local dOffset = dWidth - dDepth ; + local dLioTang = 0 + local dLioPerp = dDepth + BD.CUT_SIC ; + -- inserisco le parti di lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nC) + local nMchFId = EgtAddMachining( sNameF, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == 1, -dInsDist, -dStartAccDist - ( i - 2) * dC) + local dEal = EgtIf( i == nC, -dInsDist, -dEndAccDist - ( nC - i - 1) * dC) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto offset radiale + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- imposto offset longitudinale + if Proc.Grp == 0 then + EgtSetMachiningParam( MCH_MP.OFFSL, EgtIf( bDownUp, dSawThick / 2, -dSawThick / 2)) + end + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bFront ~= bDownUp, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)) + EgtSetMachiningParam( MCH_MP.INVERT, bFront) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessSawCut diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessScarfJoint.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessScarfJoint.lua new file mode 100644 index 0000000..5428281 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessScarfJoint.lua @@ -0,0 +1,510 @@ +-- ProcessScarfJoint.lua by Egaltech s.r.l. 2021/06/28 +-- Gestione calcolo giunto Gerber per Travi +-- 2021/06/28 Aggiunto extra-taglio alle lamate orizzontali. + +-- Tabella per definizione modulo +local ProcessScarfJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessScarfJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessScarfJoint.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 71) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessScarfJoint.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q02', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function ApplyDiceCut( vFaceOrd, nGoodFace1, nGoodFace4, nAddGrpId, b3Solid, ptC, vtN, Proc, vtRef, bHead, sCutting, dSawDiam, b3Raw, dNewDiceDim) + + local vCuts = {} + local bOk = true + local sErr = '' + + if nGoodFace1 and nGoodFace4 and nGoodFace1 > 0 and nGoodFace4 > 0 then + -- lavoro solo la faccia inclinata perché la faccia tappo completa la lavoro successivamente + -- questo evita di lavorare due volte la faccia tappo + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[4]], vtN[vFaceOrd[4]], false, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], nil, dNewDiceDim) + elseif nGoodFace4 and nGoodFace4 > 0 then + vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[4]], vtN[vFaceOrd[4]], true, nil, nil, nil, dNewDiceDim) + end + + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + -- extra taglio + local dExtraCut = EgtIf( i % 2 == 1, 0, BD.CUT_EXTRA) + -- lavoro la faccia + for j = 1, #vCuts[i] do + bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, dExtraCut, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- lavoro la faccia interna in ogni caso + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- lavoro la faccia opposta (definita dal parametro P11) + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + local bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + return bOk, sErr, vCuts +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessScarfJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + + -- verifico che ci siano almeno quattro facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 3 then + local sErr = 'Error : number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + + -- ordino le facce in base al loro numero e al parallelismo delle due facce principali + -- faccia 1: superficie tappo + -- faccia 2: superficie principale di fondo + -- faccia 3: superficie opposta alla faccia 1 + -- faccia 4: superficie principale superiore + -- faccia 5: superficie di testa + local vtRef + local vFaceOrd = { 0, 0, 0, 0, 0} + if nFacetCnt == 5 then -- se ho 5 facce controllo il parallelismo della faccia 2 e 4 + if not AreSameVectorApprox( vtN[2], vtN[4]) then + local sErr = 'Error : main faces are not parallel (btl import problems)' + EgtOutLog( sErr) + return false, sErr + end + -- carico gli id delle facce + for i = 1, nFacetCnt do + vFaceOrd[i] = i + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[4]]:getY(), vtN[vFaceOrd[4]]:getZ()) + elseif nFacetCnt == 4 then -- se ho 4 facce + if AreSameVectorApprox( vtN[1], vtN[3]) then -- sono nel caso in cui manca la faccia 1 + for i = 1, nFacetCnt do + vFaceOrd[i+1] = i + end + elseif AreSameVectorApprox( vtN[2], vtN[4]) then -- sono nel caso in cui manca la faccia 5 + for i = 1, nFacetCnt do + vFaceOrd[i] = i + end + else -- altrimenti ho una condizione di facce non previsto e do errore + local sErr = 'Error : crazy faces(4)' + EgtOutLog( sErr) + return false, sErr + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[4]]:getY(), vtN[vFaceOrd[4]]:getZ()) + elseif nFacetCnt == 3 then -- se ho 3 facce + if AreSameVectorApprox( vtN[1], vtN[3]) then -- sono nel caso in cui manca la faccia 1 + for i = 1, nFacetCnt do + vFaceOrd[i+1] = i + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[4]]:getY(), vtN[vFaceOrd[4]]:getZ()) + else + for i = 1, nFacetCnt do + vFaceOrd[i] = i + end + -- vettore di riferimento per le facce ortogonali all'asse trave + vtRef = Vector3d( 0, vtN[vFaceOrd[2]]:getY(), vtN[vFaceOrd[2]]:getZ()) + end + end + + -- determino se di testa o di coda + local bHead = ( vtN[1]:getX() > 0) + + -- normalizzo vettore di riferimento per le facce ortogonali all'asse trave + vtRef:normalize() + + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + + -- creo superfici partendo da punto e versore delle facce 4 (inclinata) e 1 (tappo) + local nFace1 + local nFace4 + local nGoodFace1 + local nGoodFace4 + if vtN[vFaceOrd[4]] then + nFace4 = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vFaceOrd[4]], vtN[vFaceOrd[4]], b3Solid, GDB_ID.ROOT) + end + if vtN[vFaceOrd[1]] then + nFace1 = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], b3Solid, GDB_ID.ROOT) + end + if nFace4 and nFace1 then + -- taglio la superficie di tappo e quella inclinata per capire se per il taglio a cubetti si devono considerare una o due superfici + local bOk = EgtCutSurfTmPlane( nFace1, ptC[vFaceOrd[4]], -vtN[vFaceOrd[4]], false, GDB_ID.ROOT) + bOk = bOk and EgtCutSurfTmPlane( nFace4, ptC[vFaceOrd[1]], -vtN[vFaceOrd[1]], false, GDB_ID.ROOT) + + if not bOk then + local sErr = 'Error : wrong cut surfaces' + EgtOutLog( sErr) + return false, sErr + end + + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + nGoodFace1 = EgtSurfTmFacetCount( nFace1) + nGoodFace4 = EgtSurfTmFacetCount( nFace4) + elseif nFace4 then + nGoodFace4 = EgtSurfTmFacetCount( nFace4) + elseif nFace1 then + nGoodFace1 = EgtSurfTmFacetCount( nFace1) + end + + local bOkd, sErrD, vCuts = ApplyDiceCut( vFaceOrd, nGoodFace1, nGoodFace4, nAddGrpId, b3Solid, ptC, vtN, Proc, vtRef, bHead, sCutting, dSawDiam, b3Raw) + if not bOkd then return bOkd, sErrD end + + if #vCuts == 0 then + -- se ho la faccia intermedia, per prima cosa verifico se ho intersezione con la faccia tappo + if nGoodFace4 ~= 0 then + -- taglio sulla faccia interna + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = Fbs.MakeOne( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + -- se non ho intersezione con la faccia tappo posso fare il taglio sul fianco + if not nGoodFace1 or nGoodFace1 == 0 then + -- lavoro la faccia opposta (definita dal parametro P11) + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + -- inserisco la lavorazione + local vtRef2 = EgtIf( abs(vtRef:getZ()) < GEO.EPS_SMALL, Z_AX(), EgtIf( bHead, Y_AX(), -Y_AX())) + bOkd, sErrD = Fbs.MakeOne( nFace4, nGoodFace4 - 1, sCutting, dSawDiam, vtRef2, nil, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + else -- altrimenti se ho intersezione forzo il DiceCut ad essere eseguito con distanze più piccole + -- definisco la nuova dimensione massima del dice cut + local dNewDiceDim = EgtIf( abs(vtRef:getZ()) < GEO.EPS_SMALL, b3Raw:getDimZ(), b3Raw:getDimY()) + bOkd, sErrD = ApplyDiceCut( vFaceOrd, nGoodFace1, nGoodFace4, nAddGrpId, b3Solid, ptC, vtN, Proc, vtRef, bHead, sCutting, dSawDiam, b3Raw, dNewDiceDim) + if not bOkd then return bOkd, sErrD end + end + else + -- taglio sulla faccia interna + if vFaceOrd[1] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = Fbs.MakeOne( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + -- lavoro la faccia opposta (definita dal parametro P11) + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtOrthoO = Vector3d( vtRef) + bOkd, sErrD = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOkd then return bOkd, sErrD end + end + end + end + + -- taglio sulla faccia esterna + if vFaceOrd[5] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[5]], X_AX()) and abs( ptC[vFaceOrd[5]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[5]], - X_AX()) and abs( ptC[vFaceOrd[5]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[5] - 1) + if DimV > DimH then + vtOrthoO = Vector3d( frHV:getVersX()) + else + vtOrthoO = Vector3d( vtRef) + end + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[5] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + + -- lavoro superficie principale di fondo con una svuotatura + if vFaceOrd[2] ~= 0 then + + local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vFaceOrd[2]-1, GDB_ID.ROOT) + -- calcolo la dimensione da passare + local dDiamMax + -- se normale verso Y (in orizzontale) + if abs(vtRef:getY()) > 0.866 then + dDiamMax = EgtIf( abs( frMor:getVersX():getZ()) < abs( frMor:getVersY():getY()), dL, dW) + else + dDiamMax = EgtIf( abs( frMor:getVersX():getY()) < abs( frMor:getVersY():getY()), dL, dW) + end + -- determino la distanza tra le due facce inclinate + local dDistFaces + if vFaceOrd[4] ~= 0 then + dDistFaces = abs((ptC[vFaceOrd[2]]-ptC[vFaceOrd[4]])*vtN[vFaceOrd[2]]) + end + -- recupero la lavorazione. considerando l dimensione del lato e l'affondamento + local sPocketing + if dDistFaces then + sPocketing = ML.FindPocketing( 'OpenPocket', dDiamMax, dDistFaces) + else + sPocketing = ML.FindPocketing( 'OpenPocket', dDiamMax) + end + + 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( {{ Proc.Id, vFaceOrd[2]-1}}) + -- imposto elevazione + if dDistFaces then + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dDistFaces, 1) .. ';') + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + dHCI = 0.75 * dHCI + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + dTCI = 0.75 * dTCI + BL.UpdateTCING( nRawId, dTCI) + end + + return true, sErrC +end + +--------------------------------------------------------------------- +return ProcessScarfJoint diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessSimpleScarf.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessSimpleScarf.lua new file mode 100644 index 0000000..927ce70 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessSimpleScarf.lua @@ -0,0 +1,325 @@ +-- ProcessSimpleScarf.lua by Egaltech s.r.l. 2020/06/04 +-- Gestione calcolo giunto Gerber per Travi + +-- Tabella per definizione modulo +local ProcessSimpleScarf = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessSimpleScarf started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSimpleScarf.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 70) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessSimpleScarf.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSimpleScarf.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Error : number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getY()) > 0.1 or abs( vtN[i]:getZ()) > 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error : missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + bHead = ( vtN[vFaceOrd[1]]:getX() > 0) + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local vtOrthoO = Vector3d( vtRef) + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtOrthoO, nil, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, 0, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vFaceOrd[1] - 1, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true, sErrC +end + +--------------------------------------------------------------------- +return ProcessSimpleScarf diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessSplit.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessSplit.lua new file mode 100644 index 0000000..db4d1b1 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessSplit.lua @@ -0,0 +1,292 @@ +-- ProcessSplit.lua by Egaltech s.r.l. 2022/01/25 +-- Gestione calcolo tagli di separazione per Travi + +-- Tabella per definizione modulo +local ProcessSplit = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') + +EgtOutLog( ' ProcessSplit started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSplit.Identify( Proc) + return ( Proc.Grp == 2 and Proc.Prc == 350) +end + +--------------------------------------------------------------------- +-- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) +local function VerifyCurveForChamfer( AuxId) + if not AuxId then + return -2 + end + if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + return -1 + end + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- va bene solo se direzione estrusione orizzontale + if abs( vtExtr:getZ()) > 0.1 then + return 0 + end + return 1 +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( nOriId, 'Q06', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico le entità curva associate (max 2) + local sVal = EgtGetInfo( nOriId, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local AuxId, Aux2Id + if vsAuxId and #vsAuxId >=1 then + AuxId = tonumber( vsAuxId[1]) + end + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if AuxId then AuxId = AuxId + nOriId end + if Aux2Id then Aux2Id = Aux2Id + nOriId end + local nRes = VerifyCurveForChamfer( AuxId) + if nRes == 0 and Aux2Id then + AuxId = Aux2Id + nRes = VerifyCurveForChamfer( AuxId) + end + if nRes == -2 then + return true + end + if nRes == -1 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + if nRes == 0 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMilling = ML.FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true, nil +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSplit.Make( Proc, nPhase, nRawId, nPartId) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- inserimento smussi + local nOriId = EgtGetInfo( Proc.Id, 'ORI', 'i') + if nOriId then + local bOkc, sErrC = MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'TailSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 50 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + local dMaxVertDepth = dMaxDepth - ( BD.DECR_VERT_CUT or 0) + -- caratteristiche taglio + local bHorizCut = (( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL or BD.TURN) and b3Raw:getDimZ() < dMaxVertDepth - BD.CUT_EXTRA) + local dDimYRef = EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, dMaxDepth, BD.MAX_DIM_HTCUT_HBEAM) + local bDoubleHorizCut = ( BD.DOWN_HEAD and not bHorizCut and b3Raw:getDimY() > 2 * dDimYRef - BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL) + local bDoubleCut = ( not bHorizCut and not bDoubleHorizCut and b3Raw:getDimY() > dDimYRef - BD.CUT_EXTRA + 10 * GEO.EPS_SMALL) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- flag di lavorazione faccia + local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_BACK) + -- separazione solo se esiste grezzo successivo con pezzi o scaricabile + local nNextRawId = EgtGetNextRawPart( nRawId) + local bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() >= BD.MinRaw)) + -- determino se più tagli con offset + local nCuts = 1 + local dOffsL = 0 + if not bSplit then + -- cerco grezzo successivo che sia nella fase + if nNextRawId and EgtVerifyRawPartPhase( nNextRawId, nPhase) then + local b3NextRaw = EgtGetRawPartBBox( nNextRawId) + local dLenEndRaw = ptC:getX() - b3NextRaw:getMin():getX() + nCuts = ceil( dLenEndRaw / BD.MAX_LEN_SCRAP) + dOffsL = dLenEndRaw / nCuts + -- aggiorno ingombro del grezzo corrente con quello del successivo + b3Raw:Add( b3NextRaw) + end + end + -- se tagli standard + if not bDoubleHorizCut then + -- calcolo extra taglio ed accorciamento + local dCutExtra = 0 + local dAccStart = 0 + local dAccEnd = 0 + if b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL or b3Raw:getDimY() < 2 * BD.MAX_DIM_HTCUT_HBEAM + 10 * GEO.EPS_SMALL then + dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN, BD.CUT_EXTRA) + else + dCutExtra = - ( b3Raw:getDimY() - dMaxDepth) + local dSawRad = dSawDiam / 2 + local dKL = dSawRad - dMaxDepth + b3Raw:getDimY() / 2 + BD.CUT_EXTRA_MIN + if BD.C_SIMM then + dAccEnd = sqrt( dSawRad * dSawRad - dKL * dKL) + else + dAccStart = sqrt( dSawRad * dSawRad - dKL * dKL) + end + end + -- se necessari tagli in doppio, eseguo gli opposti + if bDoubleCut then + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes = EgtIf( bSplit, 'Presplit;', 'Precut;') + local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_FRONT, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, dAccEnd, sNotes, b3Raw) + if not bOk then return false, sErr end + end + end + -- eseguo i tagli necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes + if bSplit then + sNotes = EgtIf( i == 1, 'Split;', 'Presplit;') + else + sNotes = EgtIf( i == 1, 'Cut;', 'Precut;') + end + local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, dAccEnd, sNotes, b3Raw) + if not bOk then return false, sErr end + end + -- altrimenti necessari tagli da sopra e sotto con testa opportuna + else + -- recupero la lavorazione con lama da sotto + local sCutting2 = ML.FindCutting( 'TailSide_H2') + if not sCutting2 then + local sErr = 'Error : cutting H2 not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della seconda lama + local dSawDiam2 = 400 + local dMaxDepth2 = 50 + if EgtMdbSetCurrMachining( sCutting2) then + local sTuuid2 = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid2) or '') then + dSawDiam2 = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam2 + dMaxDepth2 = EgtTdbGetCurrToolMaxDepth() or dMaxDepth2 + end + end + -- verifico che le due lame riescano a lavorare la sezione + local dDimZ = b3Raw:getDimZ() + local dExtra = dMaxVertDepth + dMaxDepth2 - dDimZ + if dExtra - 2 * BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL < 0 then + local sErr = 'Error : section too big for tail cut' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo extra taglio ed accorciamento + local dCutExtra = -dMaxDepth2 + dExtra / 2 + BD.CUT_EXTRA_MIN + local dCutExtra2 = -dMaxVertDepth + dExtra / 2 + BD.CUT_EXTRA_MIN + local dAccStart = 0 + -- eseguo i tagli da sotto necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes = EgtIf( bSplit, 'Presplit;', 'Precut;') + local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting2, dSawDiam2, MCH_MILL_FU.ORTHO_TOP, nil, dCutExtra2, BD.CUT_SIC, dCutOffset, dAccStart, 0, sNotes, b3Raw) + if not bOk then return false, sErr end + end + -- eseguo i tagli da sopra necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes + if bSplit then + sNotes = EgtIf( i == 1, 'Split;', 'Presplit;') + else + sNotes = EgtIf( i == 1, 'Cut;', 'Precut;') + end + local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_DOWN, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, 0, sNotes, b3Raw) + if not bOk then return false, sErr end + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessSplit diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessStepJoint.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessStepJoint.lua new file mode 100644 index 0000000..bcef6b6 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessStepJoint.lua @@ -0,0 +1,487 @@ +-- ProcessStepJoint.lua by Egaltech s.r.l. 2022/01/26 +-- Gestione calcolo giunto a gradino per Travi + +-- Tabella per definizione modulo +local ProcessStepJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessStepJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessStepJoint.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 80) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessStepJoint.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- gestisco solo 2 o 3 facce + if nFacetCnt ~= 2 and nFacetCnt ~= 3 then + return false, false + end + -- se due facce, verifico se convesso + local bConvex = false + if nFacetCnt == 2 then + local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + bConvex = not bAdj or ( dAng > 0) + end + -- verifico le normali delle facce + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if not bConvex and vtN:getZ() < - 0.72 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0 + if dDepth < 0.1 then return true end + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- eseguo lo smusso solo se direzione orizzontale (non propago la segnalazione a TS3) + if abs( vtExtr:getZ()) > 0.1 then + local sWarn = 'Warning : skipped not horizontal chamfer' + EgtOutLog( sWarn) + return true + end + -- eseguo lo smusso solo se feature larga come la trave + if dWidth < b3Raw:getDimY() - 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn + end + local dExtra = 2 + -- recupero la lavorazione + local sMillType = 'Mark' + local bDownHead = ( BD.DOWN_HEAD and abs( vtExtr:getZ()) < 0.1) + local sMilling = ML.FindMilling( sMillType .. EgtIf( bDownHead, '_H2', '')) + if not sMilling and bDownHead then + sMilling = ML.FindMilling( sMillType) + bDownHead = false + end + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione al caso due facce +local function MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- delta negativo affondamento lama per facce concave + local dExtraUp = -0.3 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso (due facce separate sono sicuramente convesse) + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se convesso, lo tratto come due tagli singoli + if bConvex then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- lavoro per prima la faccia più diretta in alto + local vOrd = { 1, 2} + if vtN[2]:getZ() > vtN[1]:getZ() then + vOrd = { 2, 1} + end + -- creo piano di taglio coincidente con la prima faccia e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[1]], vtN[vOrd[1]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + end + -- creo piano di taglio coincidente con la seconda faccia e lo lavoro + AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[2]], vtN[vOrd[2]], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + end + -- altrimenti concavo + else + -- calcolo direzione di lavoro + local vtRef = {} + local vtTg = ptP2 - ptP1 ; + vtRef[1] = vtN[1] ^ vtTg + if vtRef[1] * vtN[2] < 0 then vtRef[1] = - vtRef[1] end + vtRef[2] = vtN[2] ^ vtTg + if vtRef[2] * vtN[1] < 0 then vtRef[2] = - vtRef[2] end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- calcolo extra taglio + local dCutExtra = dExtraUp + if dAng < -90.5 and dAng > -179.5 then + dCutExtra = - dSawThick / tan( 180 + dAng) + dExtraUp + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- assegno il modo di tagliare + local vtOrthO = EgtIf( ( i % 2) == 1, vtRef[nSmaInd], vtRef[nBigInd]) + -- lavoro la faccia + for j = 1, #vCuts[i] do + local dLocCutExtra = EgtIf( j == #vCuts[i], dCutExtra - dExtraUp, dCutExtra) + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthO, nil, dLocCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, EgtIf( bHead, 'HeadSide', 'TailSide')) + if not bOk then + return bOk, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione al caso tre facce +local function MakeThreeFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- delta negativo affondamento lama per facce concave + local dExtraUp = -0.3 + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- riduco a forma canonica ( concavo tra 0 e 1, faccia 2 oltre convesso) + local bAdj12, _, _, dAng12 = EgtSurfTmFacetsContact( Proc.Id, 1, 2, GDB_ID.ROOT) + local bAdj20, _, _, dAng20 = EgtSurfTmFacetsContact( Proc.Id, 2, 0, GDB_ID.ROOT) + if bAdj12 then + if dAng12 < 0 then + EgtSurfTmSwapFacets( Proc.Id, 0, 2) + end + elseif bAdj20 then + if dAng20 < 0 then + EgtSurfTmSwapFacets( Proc.Id, 1, 2) + end + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + ptC[3], vtN[3] = EgtSurfTmFacetCenter( Proc.Id, 2, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bConvex = true + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- calcolo direzione di lavoro + local vtRef = {} + local vtTg = ptP2 - ptP1 ; + vtRef[1] = vtN[1] ^ vtTg + if vtRef[1] * vtN[2] < 0 then vtRef[1] = - vtRef[1] end + vtRef[2] = vtN[2] ^ vtTg + if vtRef[2] * vtN[1] < 0 then vtRef[2] = - vtRef[2] end + -- determino quale faccia è più grande + local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0) + local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1) + local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + -- recupero la lavorazione + local sCutting = ML.FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- Taglio la faccia 2 + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio coincidente con la faccia 2 e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[3], vtN[3], b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + if not bOk then return bOk, sErr end + end + -- Taglio le facce 0 e 1 concave + -- calcolo extra taglio + local dCutExtra = dExtraUp + if dAng < -90.5 and dAng > -179.5 then + dCutExtra = - dSawThick / tan( 180 + dAng) + dExtraUp + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- assegno il modo di tagliare + local vtOrthO = EgtIf( ( i % 2) == 1, vtRef[nSmaInd], vtRef[nBigInd]) + -- lavoro la faccia + for j = 1, #vCuts[i] do + local dLocCutExtra = EgtIf( j == #vCuts[i], dCutExtra - dExtraUp, dCutExtra) + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthO, nil, dLocCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, EgtIf( bHead, 'HeadSide', 'TailSide')) + if not bOk then + return bOk, sErr + end + end + -- Eventuale segnalazione ingombro di testa o coda + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if vtNm:getZ() > 0.5 then + dOffs = 0.5 * dOffs + elseif abs( vtNm:getZ()) > 0.35 then + dOffs = 0.75 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessStepJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- inserimento smussi + local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- se due facce + if Proc.Fct == 2 then + local bOk, sErr = MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + return bOk, sErr or sErrC + -- se altrimenti tre facce + elseif Proc.Fct == 3 then + local bOk, sErr = MakeThreeFaces( Proc, nPhase, nRawId, nPartId, dOvmHead) + return bOk, sErr or sErrC + -- altrimenti errore + else + local sErr = 'Error : face number not allowed' + EgtOutLog( sErr) + return false, sErr + end +end + +--------------------------------------------------------------------- +return ProcessStepJoint diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessStepJointNotch.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessStepJointNotch.lua new file mode 100644 index 0000000..3de5eac --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessStepJointNotch.lua @@ -0,0 +1,637 @@ +-- ProcessStepJointNotch.lua by Egaltech s.r.l. 2022/01/25 +-- Gestione calcolo tacca a gradino per Travi + +-- Tabella per definizione modulo +local ProcessStepJointNotch = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessStepJointNotch started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessStepJointNotch.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 80) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessStepJointNotch.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- gestisco solo 2 o 4 facce + if nFacetCnt ~= 2 and nFacetCnt ~= 4 and nFacetCnt ~= 6 and nFacetCnt ~= 8 then + return false, false + end + -- verifico le normali delle facce + local bDown = false + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se faccia limite la salto + if AreSameOrOppositeVectorApprox( vtN, Y_AX()) or AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + -- attualmente non gestita + -- altrimenti faccia principale + elseif vtN:getZ() < -0.1 then + bDown = true + end + end + return true, bDown +end + +--------------------------------------------------------------------- +local function MachineByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Solid, ptC, vtN, nBigInd, nSmaInd, bOnY, ptPs, b3Raw, dAng) + + -- delta negativo affondamento lama + local dExtraUp = -0.3 + -- abilitazione lavorazione da sotto (testa da sotto e direzione normale sotto -30deg) + local bTopHead = ( BD.DOWN_HEAD and vtN[nBigInd]:getZ() > -0.5) + local bDownHead = ( BD.DOWN_HEAD and vtN[nBigInd]:getZ() < -0.5) + -- recupero la lavorazione + local sCutType = 'HeadSide' + local sCutting = ML.FindCutting( sCutType .. EgtIf( bDownHead, '_H2', '')) + if not sCutting and bTopHead then + sCutting = ML.FindCutting( sCutType) + bDownHead = false + end + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + local dSawThick = 5 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- calcolo extra taglio + local dCutExtra = dExtraUp + if dAng < -90.5 and dAng > -179.5 then + dCutExtra = - dSawThick / tan( 180 + dAng) + dExtraUp + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local k, l = nBigInd, nSmaInd + if ( i % 2) == 1 then + k, l = l, k + end + local nOrthoOpposite + if bOnY then + local bFront = ( ptC[k]:getY() < ptPs:getY()) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + local bOver = ( vtN[nBigInd]:getZ() > -0.1) + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local dLocCutExtra = EgtIf( j == #vCuts[i], dCutExtra - dExtraUp, dCutExtra) + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, EgtIf( bDownHead, -2, nil), dLocCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti, tagli diretti delle facce + else + local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), nil, bDownHead) + if not bOk then + return bOk, sErr + end + end + return true +end + +--------------------------------------------------------------------- +local function MakePocket( Proc, nPartId, ptPs, vtN, nFaceRef, nDiffWidth, sMchFind, nUseRoughTool, tBHx) + + -- calcolo il elevazione dal punto medio + local dElev + local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[nFaceRef]) + if dLenIn > 0 then + dElev = dLenIn + elseif dLedOut then + dElev = dLedOut + end + local dCollSic = 2 * BD.COLL_SIC + local sTuuidMstr + -- calcolo il diametro utensile + local dDiamTool + if nUseRoughTool == 1 then + dDiamTool = max( 80, min( tBHx[nFaceRef][1], tBHx[nFaceRef][2])) + else + -- se non uso truciolatore prendo il valore dalle dimensioni minime delle facce + dDiamTool = min( tBHx[nFaceRef][1], tBHx[nFaceRef][2]) + end + -- abilitazione lavorazione da sotto (testa da sotto e direzione normale sotto -30deg) + local bTopHead = ( BD.DOWN_HEAD and vtN[nFaceRef]:getZ() > -0.1) + local bDownHead = ( BD.DOWN_HEAD and vtN[nFaceRef]:getZ() < 0.1) + -- recupero la lavorazione + local sPocketing = ML.FindPocketing( sMchFind.. EgtIf( bDownHead, '_H2', ''), dDiamTool, dElev + dCollSic) + if not sPocketing and bTopHead then + sPocketing = ML.FindPocketing( sMchFind, dDiamTool, dElev + dCollSic) + bDownHead = false + end + if not sPocketing then + local sErr = 'Error : pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile + if EgtMdbSetCurrMachining( sPocketing) then + sTuuidMstr = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidMstr) or '') then + dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dDiamTool + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef - 1) + 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( {{ Proc.Id, (nFaceRef-1)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if vtN[nFaceRef]:getY() < GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- La tasca ha sempre almeno un lato aperto, imposto opportuno attacco + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN) + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + if not EgtApplyMachining( true, false) then + -- provo ad allargare leggermente la tasca + EgtSetMachiningParam( MCH_MP.OFFSR, -0.1) + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true, '', sTuuidMstr +end + +--------------------------------------------------------------------- +local function MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, ptC, vtN, nBigInd, nSmaInd, ptPs, tBHx, b3Raw, nDiffWidth, nUseRoughTool, dAng) + + local sMchFind = 'Pocket' + -- se feature é larga come trave imposto openpocket + if nDiffWidth == 0 then + sMchFind = 'OpenPocket' + -- altrimenti se non è passante disabilito il truciolatore + else + nUseRoughTool = 0 + end + -- applico la svuotatura + local bOk, sErr, sTuuidMstr = MakePocket( Proc, nPartId, ptPs, vtN, nBigInd, nDiffWidth, sMchFind, nUseRoughTool, tBHx) + if not bOk then + return bOk, sErr + end + -- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto + if dAng > -90.1 then + -- se la normale della faccia corta si discosta dalla trave di più di 40° utilizzo la svuotatura altrimenti la contornatura + if abs( vtN[nSmaInd]:getX()) < 0.766 then + -- applico la svuotatura + local bOk, sErr = MakePocket( Proc, nPartId, ptPs, vtN, nSmaInd, nDiffWidth, sMchFind, nUseRoughTool, tBHx) + if not bOk then + return bOk, sErr + end + -- altrimenti contornatura + else + local bOpenStart = false + local bOpenEnd = false + if nDiffWidth == 0 then + bOpenStart = true + bOpenEnd = true + else + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBigInd-1))[1] + for j = 1, #vAdj2 do + if vAdj2[j] == (nSmaInd-1) then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + while vAdj2[i] == (nSmaInd-1) do + i = EgtIf( i > 1, i - 1, #vAdj2) + end + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + while vAdj2[k] == (nSmaInd-1) do + k = EgtIf( k < #vAdj2, k + 1, 1) + end + bOpenEnd = ( vAdj2[k] < 0) + end + end + end + -- abilitazione lavorazione da sotto (testa da sotto e direzione normale sotto -30deg) + local bTopHead = ( BD.DOWN_HEAD and vtN[nBigInd]:getZ() > -0.1) + local bDownHead = ( BD.DOWN_HEAD and vtN[nBigInd]:getZ() < 0.1) + -- scelta lavorazione + local sMilling + local sTypeMill = EgtIf( nUseRoughTool > 0, 'Long2Cut', 'LongSmallCut') + sMilling = ML.FindMilling( sTypeMill .. EgtIf( bDownHead, '_H2', ''), nil, sTuuidMstr) + if not sMilling and bTopHead then + sMilling = ML.FindMilling( sTypeMill, nil, sTuuidMstr) + end + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 50 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( tBHx[nBigInd][3]:getVersZ()) + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, (nSmaInd-1)}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- setto inversione del percorso e lato di lavoro + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + -- setto a 0 eventuali offset + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2)) + -- attacchi e uscite lineari con parte tg nulla + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR) + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, 20) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + return true +end + +--------------------------------------------------------------------- +-- Lavorazione di due facce +local function MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local tBHx = {} + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- angolo diedro + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local bOnY = true + local ptPs = ( ptC[1] + ptC[2]) / 2 + local bConvex + if bAdj then + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + ptPs = ( ptP1 + ptP2) / 2 + bConvex = ( dAng > 0) + end + -- determino quale faccia è più grande + local rfFac1, dH1, dV1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1, GDB_ID.ROOT) + local nBigInd = EgtIf( dV1 * dH1 >= dV2 * dH2, 1, 2) + local nSmaInd = 3 - nBigInd + tBHx[1] = {dH1, dV1, rfFac1} + tBHx[2] = {dH2, dV2, rfFac2} + -- verifico parametro Q per stabilire se deve essere lavorato con truciolatore + -- o se larghezza inferiore del trave, utilizzare una svuotatura + local nUseRoughTool = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0 + -- se feature non è larga come trave o è selezionato l'utilizzo del truciolatore utilizzo svuotatura + if nDiffWidth > 0 or nUseRoughTool == 1 then + -- se angolo compreso è >= di 90° applico svuotatura con fresa + if not bConvex and dAng >= -90.1 then + local bOk, sErr = MachineByMill( Proc, nPhase, nRawId, nPartId, b3Solid, ptC, vtN, nBigInd, nSmaInd, ptPs, tBHx, b3Raw, nDiffWidth, nUseRoughTool, dAng) + if not bOk then + return bOk, sErr + end + else + local sErr = 'Error : internal angle less than square angle' + EgtOutLog( sErr) + return false, sErr + end + -- altrimenti provo a lavorare con la lama + else + local bOk, sErr = MachineByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Solid, ptC, vtN, nBigInd, nSmaInd, bOnY, ptPs, b3Raw, dAng) + if not bOk then + return bOk, sErr + end + end + return true +end + +--------------------------------------------------------------------- +-- Lavorazione di due facce +local function MakeFourFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + -- Prime due facce + local bOk, sErr = MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + -- Seconde due facce + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- copio la superficie e scambio le facce + local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) + if AddId then + EgtSurfTmSwapFacets( AddId, 0, 2) + EgtSurfTmSwapFacets( AddId, 1, 3) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local NewProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = MakeTwoFaces( NewProc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + end + return true +end + +--------------------------------------------------------------------- +-- lavorazione smussi +local function MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dWidth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- prendo il boundig box della feature + local bBoxExtr = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD ) + local nTypePos = 0 + -- determino se sborda da un lato + if abs( vtExtr:getZ()) < 0.1 then -- se orizzontale + -- se altezza percorso inferiore della larghezza trave + if dWidth < b3Raw:getDimY() - 1 then + nTypePos = 1 + -- verifico se sborda verso y+ + if abs( bBoxExtr:getMax():getY() - b3Raw:getMax():getY()) < 0.1 then + nTypePos = 2 + -- se sborda verso y- + elseif abs( bBoxExtr:getMin():getY() - b3Raw:getMin():getY()) < 0.1 then + nTypePos = 3 + end + end + elseif abs( vtExtr:getZ()) > 0.9 then -- se verticale + -- se altezza percorso inferiore della larghezza trave + if dWidth < b3Raw:getDimZ() - 1 then + nTypePos = 1 + -- verifico se sborda verso z+ + if abs( bBoxExtr:getMax():getZ() - b3Raw:getMax():getZ()) < 0.1 then + nTypePos = 4 + -- se sborda verso z- + elseif abs( bBoxExtr:getMin():getZ() - b3Raw:getMin():getZ()) < 0.1 then + nTypePos = 5 + end + end + else -- altrimenti se altra direzione setto per non fare smussi + nTypePos = 6 + end + + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0 + if dDepth < 0.1 then return true, '', nTypePos end + + -- disabilito smusso se feature non sborda dalla trave almeno da un lato + if nTypePos == 1 then + local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' + EgtOutLog( sWarn) + return true, sWarn , nTypePos + end + -- salto lo smusso se sborda dal lato in Z- o una direzione diversa da Y e Z + if nTypePos >= 5 then + local sWarn = 'Warning : skipped chamfer (wrong side to apply)' + EgtOutLog( sWarn) + return true, sWarn, nTypePos + end + local bExeNormal = true + local bExeOpposite = true + -- controllo le lavorazioni quando la feature è orizzontale + if abs( vtExtr:getY()) > 0.99 then + -- se diretta verso Y+ + if vtExtr:getY() > 0 then + -- se sborda verso Y+ abilito solo la lavorazione della parte normale + if nTypePos == 2 then + bExeOpposite = false + -- se sborda verso Y- abilito solo la lavorazione della parte opposta + elseif nTypePos == 3 then + bExeNormal = false + end + -- altrimenti diretta verso Y- + else + -- se sborda verso Y+ abilito solo la lavorazione della parte opposta + if nTypePos == 2 then + bExeNormal = false + -- se sborda verso Y- abilito solo la lavorazione della parte normale + elseif nTypePos == 3 then + bExeOpposite = false + end + end + -- se diretta verso Z + elseif abs( vtExtr:getZ()) > 0.99 then + -- se diretta verso Z+ + if vtExtr:getZ() > 0 then + -- se sborda verso Z+ abilito solo la lavorazione della parte normale + if nTypePos == 4 or nTypePos == 0 then + bExeOpposite = false + else -- altrimenti disabilito entrambe + bExeNormal = false + bExeOpposite = false + end + -- altrimenti diretta verso Z- + else + -- se sborda verso Z+ abilito solo la lavorazione della parte opposta + if nTypePos == 4 or nTypePos == 0 then + bExeNormal = false + else -- altrimenti disabilito entrambe + bExeNormal = false + bExeOpposite = false + end + end + end + + local dExtra = 2 + -- recupero la lavorazione + local sMillType = 'Mark' + local bDownHead = ( BD.DOWN_HEAD and abs( vtExtr:getZ()) < 0.1) + local sMilling = ML.FindMilling( sMillType .. EgtIf( bDownHead, '_H2', '')) + if not sMilling and bDownHead then + sMilling = ML.FindMilling( sMillType) + bDownHead = false + end + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + if bExeNormal then + -- Inserisco la lavorazione del lato standard + local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch1Id = EgtAddMachining( sName1, sMilling) + if not nMch1Id then + local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + if bExeOpposite then + -- Inserisco la lavorazione del lato opposto + local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMch2Id = EgtAddMachining( sName2, sMilling) + if not nMch2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- inverto direzione utensile + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + -- assegno affondamento e offset radiale + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) + EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + return true, '', nTypePos +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessStepJointNotch.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- esecuzione eventuale smusso + -- ottengo anche il flag che indica che la feature è larga come la trave + local bOkc, sErrC, nDiffWidth = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead) + if not bOkc then return bOkc, sErrC end + -- come fatto nella classify, conto solo le facce che non sono dirette in Y o Z + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + local nUsableFaces = 0 + + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- se faccia limite la salto + if AreSameOrOppositeVectorApprox( vtN, Y_AX()) or AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + -- altrimenti faccia principale + else + nUsableFaces = nUsableFaces + 1 + end + end + + -- se due facce + if nUsableFaces == 2 then + local bOk, sErr = MakeTwoFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + -- se quattro facce + elseif nUsableFaces == 4 then + local bOk, sErr = MakeFourFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, nDiffWidth) + if not bOk then return bOk, sErr end + -- altrimenti errore + else + local sErr = 'Error : face number not allowed' + EgtOutLog( sErr) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessStepJointNotch diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessTenon.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessTenon.lua new file mode 100644 index 0000000..970ffee --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessTenon.lua @@ -0,0 +1,341 @@ +-- ProcessTenon.lua by Egaltech s.r.l. 2022/02/15 +-- Gestione calcolo tenone per Travi +-- 2021/10/04 Corretto calcolo HCING per pezzi piccoli. +-- 2022/02/15 Aggiornata VerifyOrientation per macchine con testa da sotto. + +-- Tabella per definizione modulo +local ProcessTenon = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTenon started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + + +--------------------------------------------------------------------- +local function VerifyOrientation( Proc, vtN, b3Raw) + -- se PF con testa da sotto, ammessa qualunque orientazione + if BD.C_SIMM and BD.DOWN_HEAD then + return true + end + -- se trave molto bassa + if b3Raw:getDimZ() <= 120 then + -- se tenone praticamente in asse, accetto fino a -45 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.7072) + -- altrimenti accetto fino a -30deg + else + return ( vtN:getZ() >= -0.51) + end + -- se trave bassa + elseif b3Raw:getDimZ() <= 200 then + -- se tenone praticamente in asse, accetto fino a -30 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.51) + -- altrimenti accetto fino a -20deg + else + return ( vtN:getZ() >= -0.343) + end + -- se trave media + elseif b3Raw:getDimZ() <= 300 then + -- se tenone praticamente in asse, accetto fino a -20 deg + if abs( vtN:getY()) < 0.04 then + return ( vtN:getZ() >= -0.343) + -- altrimenti, accetto fino a -10 deg + else + return ( vtN:getZ() >= -0.174) + end + -- altrimenti + else + -- accetto fino a -5deg + return ( vtN:getZ() >= -0.088) + end +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessTenon.Identify( Proc) + return ( (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 50) or + (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 52)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessTenon.Classify( Proc, b3Raw) + -- recupero i dati della curva di contorno della faccia top + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se il tenone è lavorabile solo da sotto + local bDown = not VerifyOrientation( Proc, vtExtr, b3Raw) + return true, bDown +end + +--------------------------------------------------------------------- +local function ApplyPocket( Proc, sPocketing, nStep, dSurfStep, nIdSurf, vtExtr) + + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. nStep + local nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nIdSurf, -1}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + if dSurfStep > 0 then + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dSurfStep, 2) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + + return true +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessTenon.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error : part box not found' + EgtOutLog( sErr) + return false, sErr + end + local bShortPart = ( b3Solid:getDimX() < BD.LEN_SHORT_PART) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva di contorno della faccia top + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + local bClosed = EgtCurveIsClosed( AuxId) + -- verifico che il tenone non sia orientato troppo verso il basso + if not VerifyOrientation( Proc, vtExtr, b3Raw) then + local sErr = 'Error : Tenon from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza del tenone + local frTen = Frame3d( ptBC, vtExtr) + local b3Ten = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frTen) + local dTenH = b3Ten:getDimZ() + -- assegno centro e normale della faccia top + local vtN = vtExtr + local ptC = ptBC + vtN * dTenH + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- determino larghezza massima di svuotatura + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frTen) + local dPockX = max( b3Ten:getMax():getX() - b3Aux:getMax():getX(), b3Aux:getMin():getX() - b3Ten:getMin():getX()) + local dPockY = max( b3Ten:getMax():getY() - b3Aux:getMax():getY(), b3Aux:getMin():getY() - b3Ten:getMin():getY()) + local dPockL = sqrt( dPockX * dPockX + dPockY * dPockY) + -- abilitazione lavorazione da sotto + local bMillUp = ( BD.DOWN_HEAD and vtExtr:getZ() > -0.259) + local bMillDown = ( BD.DOWN_HEAD and vtExtr:getZ() < 0.1) + -- porto inizio curva il più possibile sul bordo + BL.PutStartNearestToEdge( AuxId, b3Solid, bMillDown and not bShortPart) + -- se vero tenone inclinato o non esattamente alle estremità, necessario taglio di lama sulla testa + if Proc.Prc ~= 52 and + ( not AreSameOrOppositeVectorApprox( vtN, X_AX()) or + ( Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dOvmHead - 100 * GEO.EPS_SMALL and + Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 100 * GEO.EPS_SMALL)) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error : missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla testa del tenone e lo lavoro + local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC, vtN, b3Solid, GDB_RT.GLOB) + if AddId then + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( AddId, 'TASKID', Proc.TaskId) + -- se pezzo piccolo, in coda, con piano inclinato verso il basso e macchina con testa da sotto applico svuotatura + if bShortPart and vtExtr:getX() < 0 and vtExtr:getZ() < -0.09 and BD.DOWN_HEAD then + local sPockType = EgtIf( bMillDown, 'OpenPocket_H2', 'OpenPocket') + local sPocketing = ML.FindPocketing( sPockType) + local dMaxDepth = 100 + local dStep = 30 + local nSurfStep + -- acquisisco i dati necessari dall'utensile + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + dStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dStep + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- acquisisco elevazione + local dElev = BL.GetFaceElevation( AddId, 0, nPartId) + nSurfStep = ceil( dElev / dMaxDepth) + dSurfStep = dElev / nSurfStep + local bOk = true + local sErr + -- copio superfice al passo superfice e ci applico la lavorazione + for i = nSurfStep, 2, -1 do + local nAddIdTmp = EgtSurfTmPlaneInBBox( nAddGrpId, ptC+((dSurfStep*(i-1))*vtN), vtN, b3Solid, GDB_RT.GLOB) + if nAddIdTmp then + EgtSetName( nAddIdTmp, 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( nAddIdTmp, 'TASKID', Proc.TaskId) + -- aggiungo lavorazione + bOk, sErr = ApplyPocket( Proc, sPocketing, i, (dSurfStep + 0), nAddIdTmp, vtExtr) + if not bOk then + break + end + end + end + if not bOk then + return false, sErr + end + -- faccio ultima superfice + bOk, sErr = ApplyPocket( Proc, sPocketing, 1, EgtIf( nSurfStep > 1, ( dSurfStep + 0), 0), AddId, vtExtr) + if not bOk then + return false, sErr + end + -- altrimenti applico taglio di lama + else + local b3Cut = EgtGetBBoxGlob( AddId or GDB_ID.NULL, GDB_BB.STANDARD) + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Cut, Fct = 1, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bFromBottom = ( bShortPart and vtExtr:getZ() > 0.25) + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom) + if not bOk then return bOk, sErr end + end + end + end + -- recupero la lavorazione + local sMillType = 'Tenon' + local sCurrType = sMillType .. EgtIf( bMillDown, '_H2', '') + local sMilling = ML.FindMilling( sCurrType, dTenH) or ML.FindMilling( sCurrType) + if not sMilling and bMillUp then + sMilling = ML.FindMilling( sMillType, dTenH) or ML.FindMilling( sMillType) + end + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth) + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local sWarn + local dDepth = 0 + if dTenH > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in tenon : elevation (' .. EgtNumToString( dTenH, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth - dTenH + dTenH = dMaxDepth + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + -- determino il numero di passate concentriche (max 6) + local MAX_PASS = 6 + local nPass = min( ceil( dPockL / ( 0.7 * dMillDiam)), MAX_PASS) + local dStep = min( dPockL, 0.7 * dMillDiam * MAX_PASS) / nPass + for i = nPass, 1, -1 do + -- inserisco la passata finale della lavorazione + local sNameF = 'TenF_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo i parametri + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dTenH - 100 * GEO.EPS_SMALL, 1) .. ';') + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + local dOffset = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- se contorno aperto, cambio parametri di attacco/uscita + if not bClosed then + EgtSetMachiningParam( MCH_MP.LITANG, 0.7 * dMillDiam) + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, 0.7 * dMillDiam) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.NONE + if not BD.C_SIMM then + nSCC = MCH_SCC.ADIR_YM + if abs( vtExtr:getY()) > 0.088 then + nSCC = EgtIf( vtExtr:getX() < GEO.EPS_SMALL, MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP) + end + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if abs( vtN:getY()) > 0.1 or ( b3Raw:getDimZ() - Proc.Box:getDimZ()) < BD.MIN_HEIGHT then + if Proc.Head then + local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + local dDelta = 0 + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dDelta = - 0.5 * dOffs + end + if bShortPart and b3Raw:getDimZ() < BD.VICE_MINH and abs( vtN:getZ()) > 0.575 then + local b3Base = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD) + dDelta = min( dDelta, - 0.825 * b3Base:getDimX()) + end + dOffs = dOffs + dDelta + BL.UpdateHCING( nRawId, dOffs) + elseif Proc.Tail then + local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + if abs( vtN:getY()) < 0.1 and vtN:getZ() > 0.5 then + dOffs = 0.5 * dOffs + end + BL.UpdateTCING( nRawId, dOffs) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +return ProcessTenon diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessText.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessText.lua new file mode 100644 index 0000000..e2d5efa --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessText.lua @@ -0,0 +1,95 @@ +-- ProcessText.lua by Egaltech s.r.l. 2021/05/03 +-- Gestione calcolo testi per Travi +-- 2021/05/03 Aggiunta gestione testa da sotto. + +-- Tabella per definizione modulo +local ProcessText = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessText started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessText.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 61) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessText.Classify( Proc) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + return false + end + -- verifico se il testo è lavorabile solo da sotto + local bDown = (( vtN:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessText.Make( Proc, nPhase, nRawId, nPartId) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Text with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che il testo non sia orientato verso il basso (-5 deg) + if vtN:getZ() < - 0.1 and not BD.DOWN_HEAD then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Text from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- abilitazione lavorazione da sotto + local bMillUp = ( BD.DOWN_HEAD and vtN:getZ() > -0.259) + local bMillDown = ( BD.DOWN_HEAD and vtN:getZ() < 0.174) + -- recupero la lavorazione + local sMillType = 'Text' + local sMchExt = EgtIf( bMillDown, '_H2', '') + local sMilling = ML.FindMilling( sMillType..sMchExt) + if not sMilling and bMillUp then + sMilling = ML.FindMilling( sMillType) + end + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Text_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -1}}) + -- imposto posizione braccio porta testa + if vtN:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessText diff --git a/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessTyroleanDovetail.lua b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessTyroleanDovetail.lua new file mode 100644 index 0000000..6beeff1 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/LuaLibs/ProcessTyroleanDovetail.lua @@ -0,0 +1,717 @@ +-- ProcessTyroleanDovetail.lua by Egaltech s.r.l. 2022/03/21 +-- Gestione calcolo giunzione tirolese + +-- Tabella per definizione modulo +local ProcessTyroleanDovetail = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Fbs = require( 'FacesBySaw') +local DC = require( 'DiceCut') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTyroleanDovetail started', 1) + +-- Dati +local BD = require( 'BeamData') +local ML = require( 'MachiningLib') + +-- variabili assegnazione parametri Q +local sDepthChamferMill = '' -- d + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessTyroleanDovetail.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 136) +end + +--------------------------------------------------------------------- +local function AssignQValues( Proc) + + -- reset delle variabili assegnazione parametri Q + sDepthChamferMill = '' + + if Proc.Prc == 136 then + sDepthChamferMill = 'Q01' -- d + end +end + +--------------------------------------------------------------------- +local function TestElleShape3( Proc) + -- valida solo nel caso di tre facce + if Proc.Fct ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessTyroleanDovetail.Classify( Proc, b3Raw) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + local nFlatFaceNeg + local bDown = false + -- individuo se c'è faccia rastremata verso Z- + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < -1 + GEO.EPS_SMALL then + nFlatFaceNeg = i-1 + break + end + end + -- se trovata faccia rastremata rivolta verso Z- + -- verifico se lunghezza faccia piatta è compatibile con il taglio di lama + if nFlatFaceNeg then + -- se ho 3 facce sicuramente è gruppo 3 o 4, setto il ribaltamento senza ulteriori controlli + if nFacetCnt == 3 then + bDown = true + -- altrimenti faccio controllo di lavorabilità da sotto e setto eventuale ribaltamento + -- ( può essere gruppi 1 o 2, oppure gruppo 3 o 4 ma spostati verso le teste) + else + -- prendo le dimensioni della faccia + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFlatFaceNeg, GDB_ID.ROOT) + local nOtherFace = EgtIf( nFlatFaceNeg == 0, nFlatFaceNeg + 1, nFlatFaceNeg - 1) + local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT) + local dDist = dist( ptP1, ptP2) + local dLargeface + local dDelta = 100000 + local dDeltadH = abs( dDist - dH) + local dDeltadV = abs( dDist - dV) + -- prendo la dimensione diversa dalla lunghezza di adiacenza + if dDeltadH < dDeltadV then + dLargeface = dV + else + dLargeface = dH + end + -- se lunghezza faccia maggiore di taglio lama da sotto setto il ribaltamento + if dLargeface > BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then + bDown = true + end + -- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama setto il ribaltamento + if dAng < 0 and dAng > -90 + 5 * GEO.EPS_SMALL then + bDown = true + end + end + -- altrimenti controllo la componente in Z delle facce + else + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + -- altrimenti se versore z è preponderante sulle altre componenti del vettore ed è verso il basso, + -- considerazioni: al momento non è possibile sapere se ci sono due rastremature o una quindi se è rivolta verso il basso + -- viene dato errore, altrimenti si potrebbe imporre la rotazione di 180 (ovviamente con una sola rastrematura rivolta verso il basso) + if abs(vtN:getZ()) > abs(vtN:getX()) and abs(vtN:getZ()) > abs(vtN:getY()) and vtN:getZ() < -0.5 then + -- se con due facce e corto è fattibile + if nFacetCnt < 3 and Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then + return true + else + return false + end + end + end + end + return true, bDown +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc, sDephtCham) + local nChamfer = 0 + -- verifico che lo smusso sia richiesto + local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0 + if dDepth > 0 then + nChamfer = 1 + end + + return nChamfer, dDepth +end + +--------------------------------------------------------------------- +local function MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- recupero la geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- ordino le facce (1=faccia ausiliaria, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + local dMinZedFace = 1 + for i = 1, nFacetCnt do + local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX())) + if dXVal < dMinZedFace then + dMinZedFace = dXVal + vFaceOrd[3] = i + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead + if vtN[vFaceOrd[2]] then + bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + else + if AuxId then + local vtNx = EgtSurfTmFacetNormVersor( AuxId, 0, GDB_ID.ROOT) + bHead = ( vtNx:getX() > 0) + end + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato + local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), 'b') + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT) + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + else + dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len() + end + local dFinalExtraTrim = 0.1 + local dMiddleExtraTrim = 0.3 + local dNullExtraTrim = 0 + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + elseif vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true) + end + if #vCuts > 0 then + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId) + end + end + -- calcolo secondo riferimento per testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- eseguo + for i = 1, #vCuts do + local vtOrthoO + if i % 2 == 1 then + vtOrthoO = Vector3d( vtRef) + else + if #vCuts[i-1] > 0 then + vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef)) + else + local vtO + for j = 1, #vCuts[i-1] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT) + break + end + if vtO then + vtOrthoO = Vector3d( vtO) + else + vtOrthoO = Y_AX() + end + end + end + local dExtraTrim = 0 + -- lavoro la faccia + for j = 1, #vCuts[i] do + -- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo + -- cioè non i tagli intermedi, aggiungo extratrim minimo + if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then + dExtraTrim = dFinalExtraTrim + -- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim + elseif i < (#vCuts-1) or (i == #vCuts) then + dExtraTrim = dNullExtraTrim + -- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim + else + dExtraTrim = dMiddleExtraTrim + end + local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia esterna + if AuxId and not bAuxMachined then + -- in generale va fatto + local bCut = true + local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT) + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, + Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead) + -- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta + if bOk then + bAuxMachined = true + EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true) + else + return bOk, sErr + end + end + end + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- calcolo secondo testa o coda + local vtRef2 = EgtIf( bHead, X_AX(), -X_AX()) + -- se non ho il taglio sulla faccia interna + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1) + if DimV > DimH then + vtRef2 = Vector3d( frHV:getVersX()) + end + end + -- inserisco la lavorazione + local bOk, sErr = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head and AuxId then + local dHCI = 00 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + -- altrimenti di fianco + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail and AuxId then + local dTCI = 0 + -- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2 + if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then + local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end + -- altrimenti di fianco + else + dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +local function MakeMillCut( Proc, i, j, k, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep) + local sWarn = '' + -- inserisco la lavorazione di fresatura + -- per evitare nomi lavorazioni coincidenti, concateno anche il Proc.Id se il nome (del Proc.Id) è presente + local s2ndName = EgtGetName( Proc.Id) or '' + local sName = 'MillTCone_' .. ( EgtIf( #s2ndName > 0, s2ndName, tostring( Proc.Id))) .. ( EgtIf( #s2ndName > 0, '_' .. tostring( Proc.Id), '')) .. '_' .. tostring(i) .. '_' .. tostring(j) + local kStep = k or 0 + if kStep > 0 then + sName = sName .. '_' .. tostring(k) + end + 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( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia + local nFaceUse = BL.GetNearestOrthoOpposite( TabNAD[j][1]) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + if kStep % 2 == 1 then + -- imposto lato destro + EgtSetMachiningParam( MCH_MP.WORKSIDE, 2) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + -- imposto lato sinistro + EgtSetMachiningParam( MCH_MP.WORKSIDE, 1) + -- tolgo inversione + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + -- imposto affondamento in base al passo del ciclo + EgtSetMachiningParam( MCH_MP.DEPTH, dOffs) + --imposto passo 0 + EgtSetMachiningParam( MCH_MP.STEP, 0) + -- imposto offset radiale in base all'angolo tra le due facce e alla posizione in Z + il passo laterale + dOffrRad = dOffrRad + dAddOffsRad + -- per le passate intermedie aggiungo un delta sull'offset radiale perchè c'è già il taglio di lama precedente + EgtSetMachiningParam( MCH_MP.OFFSR, dOffrRad + EgtIf( ( i < nStep) and ( kStep < 1), 0.5, 0)) + -- imposto offset longotudinale a 0 + EgtSetMachiningParam( MCH_MP.OFFSL, 0) + -- imposto gli attacchi + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( dToolDiam * 0.75)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( dToolDiam * 0.75)) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill solo in ultima passata in Z locale + local sUserNotes + if i < nStep then + sUserNotes = 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + else + sUserNotes = 'VMRS=0;' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + else + _, sWarn = EgtGetMachMgrWarning( 0) + if EgtIsMachiningEmpty() then + EgtSetOperationMode( nMchId, false) + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + + local sWarn = '' + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- recupero l'angolo di spoglia dell'utensile a tronco di cono + -- recupero la lavorazione + local sMchFind = 'ProfTCone' + local sMilling = ML.FindMilling( sMchFind) + if not sMilling then + local sErr = 'Milling not found in library : Error on TyroleanDovetail ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dToolDiam = 100 + local dMaxMat = 50 + local dSideAngle = 0 + local dStepmach = 0 + local bUCutMax + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle + -- ottengo il passo della lavorazione + dStepmach = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) + end + end + if dStepmach <= 0.1 then + dStepmach = dMaxMat * 0.5 + end + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, sin(dSideAngle)) + if not nFacInd or nFacInd < 0 then + -- provo eliminando i sottosquadra + nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, -2) + if not nFacInd or nFacInd < 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MakeMachByMill could not find reference face' + EgtOutLog( sErr) + return false, sErr + else + bUCutMax = true + end + end + -- verifico se sono presenti i parametri Q per la profondità smusso e + -- per eseguire in esclusiva solo lo smusso + local nChamfer, dDepthCham = EvaluateQParam( Proc, sDepthChamferMill) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se U + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc)) + -- verifico se due facce o L con una o due facce di terminazione + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc)) + -- faccio tagli di lama come antischeggia sulle altre 2 facce + -- recupero la lavorazione + local sCutting = ML.FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dToolThick = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick + end + end + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN:getY(), vtN:getZ()) + vtRef:normalize() + local TabNAD = {} + -- ciclo inserimento tagli antischeggia sulle facce + for i = 1, nFacetCnt do + if (i-1) ~= nFacInd then + -- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli + -- se angolo tra le due facce ottuso la distanza può essere messa a 0 + local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, (i-1), GDB_ID.ROOT) + local dTrim + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT) + if dAng then + TabNAD[i] = { vtN2, dAng, dist( ptP1, ptP2)} + end + if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then + dTrim = 0 + else + dTrim = ((dToolThick* vtN) * vtN2 * vtN2):len() + end + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, (i-1), sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + 1), BD.CUT_SIC, 0, 0, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- creo percorsi di lavorazione +-- local nCountSkipStep = 0 +-- local nMaxSkippedStep = 0 + local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dStepmach) + local dStep = dFacElev / nStep + local dLargeVal + local nLenSideMax + for i = 1, nStep do + local dOffs = ( i * dStep) - dFacElev + if i == nStep then dOffs = 0 end + local dOffsSide = 0 + local dDelta = 100000 + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + local dParzElev = dOffs + -- calcolo la larghezza (solo 1 volta) + if i == 1 then + -- se ho un sottosquadra maggiore dell'angolo di spoglia utensile + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dParzElev = dFacElev + end + local dDeltadH = abs( TabNAD[j][3] - dH) + local dDeltadV = abs( TabNAD[j][3] - dV) + if dDeltadH < dDeltadV then + if dDeltadH < dDelta + 10 * GEO.EPS_SMALL then + dDelta = dDeltadH + dLargeVal = dV + nLenSideMax = j + end + else + if dDeltadV < dDelta + 10 * GEO.EPS_SMALL then + dDelta = dDeltadV + dLargeVal = dH + nLenSideMax = j + end + end + end + -- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo) + dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev) + end + end + -- se la larghezza è più grande dell'utensile allora posso lavorare il passo + if ( dLargeVal - dOffsSide) >= dToolDiam then + -- resetto il contatore skip +-- nCountSkipStep = 0 + for j = 1, nFacetCnt do + if (j-1) ~= nFacInd then + -- calcolo l'offset radiale in base all'affondamento + local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs) + if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then + dOffrRad = -( tan( 90 + TabNAD[j][2]) * dFacElev) + end + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, 0, nStep, dToolDiam, dStep) + if not bOk then + return false, sErr + else + sWarn = sErr + end + -- se lato lavorato è il più lungo e la larghezza cava consente passi interni + if j == nLenSideMax and ( dLargeVal - dOffsSide) > 2*dToolDiam then + local nStepSide = ceil( ( ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5) + local dStepSide = ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) / nStepSide + for k = 1, nStepSide do + local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0) + -- inserisco la lavorazione di fresatura + local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep) + if not bOk then + return false, sErr + else + sWarn = sErr + end + end + end + end + end + -- altrimenti passo saltato esco con errore + else + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' + EgtOutLog( sErr) + return false, sErr + end + end + + -- se ho saltato più di un passo invalido le lavorazioni +-- if nMaxSkippedStep >= 2 or ( nStep >= nMaxSkippedStep and nMaxSkippedStep >= 1) then +-- local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool' +-- EgtOutLog( sErr) +-- return false, sErr +-- end + + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessTyroleanDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQValues( Proc) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, '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 + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough' + EgtOutLog( sErr) + return false, sErr + end + -- se ho due facce allora è di testa + if nFacetCnt == 2 then + local bOk, sErr = MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + if not bOk then return bOk, sErr end + else + local bOk, sErr = MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt) + if not bOk then return bOk, sErr end + end + + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = b3Solid:getMax():getX() - Proc.Box:getMin():getX() + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX() + BL.UpdateTCING( nRawId, dTCI) + end + + return true +end + +--------------------------------------------------------------------- +return ProcessTyroleanDovetail diff --git a/ProgramData/EgtCAM5/Beam/NestProcess.lua b/ProgramData/EgtCAM5/Beam/NestProcess.lua new file mode 100644 index 0000000..7bcb751 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/NestProcess.lua @@ -0,0 +1,345 @@ +-- BeamNestProcess.lua by Egaltech s.r.l. 2021/06/14 +-- Gestione nesting automatico pareti + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--NEST = {} +--NEST.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl' +--NEST.MACHINE = 'Essetre-90480019_MW' +--NEST.FLAG = 3 + +local sLog = ' +++ BeamNestProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. LEN["1"] +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( NEST.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 ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) 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 ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) 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 + +local function PartsToFill( Parts) + local nToFill = 0 + for i = 1, #Parts do + if Parts[i].Cnt > 0 then + nToFill = nToFill + Parts[i].Cnt + end + end + return nToFill +end + +local function ExecMaximumFilling( Raw, Parts) + -- Inizializzo maximum filler + EgtMaxFillerStart() + -- Inserisco i pezzi + for i = 1, #Parts do + EgtMaxFillerAddPart( i, Parts[i].Len, Parts[i].DispLen or Parts[i].Len, Parts[i].Cnt or 1) + end + -- Eseguo l'ottimizzazione + EgtStartCounter() + EgtMaxFillerCompute( Raw.LenToFill, Raw.StartGap, Raw.MidGap, Raw.EndGap, Raw.SortType) + local dTime = EgtStopCounter() + -- Recupero i risultati + local nFilledParts, nDiffParts, dTotFillRatio = EgtMaxFillerGetResults() + local OneRes = {} + for i = 0, nDiffParts - 1 do + local nPartId, nCount = EgtMaxFillerGetOneResult( i) + table.insert( OneRes, { Id=nPartId, Count=nCount}) + end + return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Time=dTime, Data=OneRes} +end + +-- Funzione per trovare nome MachGroup +local function NewMachGroupName() + local nMachGroupId = EgtGetFirstMachGroup() + if not nMachGroupId then return 1 end + local nMaxMachGroup = 0 + while nMachGroupId do + sMachGroupName = EgtGetMachGroupName(nMachGroupId) + local nMachGroupName = tonumber(sMachGroupName) + if nMachGroupName > nMaxMachGroup then + nMaxMachGroup = nMachGroupName + end + nMachGroupId = EgtGetNextMachGroup(nMachGroupId) + end + return nMaxMachGroup + 1 +end + +local function TotRawCount(Raws) + local nTotRaws = 0 + for RawIndex = 1, #Raws do + nTotRaws = nTotRaws + Raws[RawIndex].Count + end + return nTotRaws +end + +local function TotPartLen(Parts) + local nTotPartLen = 0 + for PartIndex = 1, #Parts do + nTotPartLen = nTotPartLen + ( Parts[PartIndex].Len * Parts[PartIndex].Cnt) + end + return nTotPartLen +end + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Imposto la macchina corrente e verifico sia abilitata per la lavorazione delle Travi +EgtSetCurrMachine( NEST.MACHINE) +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + NEST.ERR = 12 + NEST.MSG = 'Error not configured for beam machine : ' .. sMachine + WriteErrToLogFile( NEST.ERR, NEST.MSG) + PostErrView( NEST.ERR, NEST.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +---- Carico le librerie +--_G.package.loaded.WallExec = nil +--local WE = require( 'BeamExec') +--_G.package.loaded.WallLib = nil +--local WL = require( 'BeamLib') +--_G.package.loaded.WProcessLapJoint = nil +--local LapJoint = require( 'WProcessLapJoint') + +-- Inizializzo contatori errori e avvisi +local nErrCnt = 0 +local nWarnCnt = 0 + +-- Grezzi +-- lista dei grezzi +local Raws = {} +-- creo tabella dei grezzi +for nIndex, nLen in pairs( LEN) do + table.insert(Raws, {LenToFill = nLen, StartGap = NEST.STARTOFFSET, MidGap = NEST.OFFSET, EndGap = 0, SortType = -1}) +end +for nIndex, nQty in pairs( QTY) do + Raws[tonumber(nIndex)].Count = nQty +end + +local nTotRaws = Raws.Count + +-- Pezzi +local Parts = {} + +-- ciclo su pezzi per aggiungerli al nesting +for nPartId, nCount in pairs( PART) do + -- recupero lunghezza pezzo + local Len = EgtGetInfo( nPartId, "L", 'd') + local DispLen = EgtIf( Len <= 1000, 2000, 0) --EgtIf( Len <= 2000, max( 2000, 6000 - Len), 0) + table.insert( Parts, {Id = nPartId, Len = Len, DispLen = DispLen, Cnt = nCount}) +end + +-- lunghezza totale pezzi +local dTotPartLen = TotPartLen( Parts) +-- calcolo media delle barre necessarie +local NeededRawsForType = {} +for RawIndex = 1, #Raws do + NeededRawsForType[RawIndex] = ceil( dTotPartLen / Raws[RawIndex].LenToFill) +end +local RawQtySum = 0 +for NeededRawIndex = 1, #NeededRawsForType do + RawQtySum = RawQtySum + NeededRawsForType[NeededRawIndex] +end +local MediumRawQty = ceil( RawQtySum / #NeededRawsForType) +if MediumRawQty > 1 then + MediumRawQty = MediumRawQty - 1 +end +-- recupero pezzi piu' corti di mille +local ShortList = {} +local LongList = {} +for PartIndex = 1, #Parts do + if Parts[PartIndex].Len <= 1000 then + table.insert( ShortList, Parts[PartIndex]) + else + table.insert( LongList, Parts[PartIndex]) + end +end +-- numero di pezzi piccoli per barra +local ShortCount = 0 +for ShortIndex = 1, #ShortList do + ShortCount = ShortCount + ShortList[ShortIndex].Cnt +end +local ShortForRaw = floor( ShortCount / MediumRawQty) +local ExtraShortForRaw = fmod( ShortCount, MediumRawQty) +-- creo lista pezzi corti singoli +local SingleShortList = {} +for ShortIndex = 1, #ShortList do + for ShortCount = 1, ShortList[ShortIndex].Cnt do + table.insert( SingleShortList, {Id = ShortList[ShortIndex].Id, Len = ShortList[ShortIndex].Len, DispLen = ShortList[ShortIndex].DispLen, Cnt = 1}) + end +end +-- li divido per le barre previste +local RawsShortList = {} +local RawIndex = 0 +local ShortRawIndex = 0 +for ShortIndex = 1, #SingleShortList do + if ShortRawIndex > 0 then + table.insert( RawsShortList[RawIndex], SingleShortList[ShortIndex]) + ShortRawIndex = ShortRawIndex - 1 + else + table.insert( RawsShortList, {SingleShortList[ShortIndex]}) + RawIndex = RawIndex + 1 + ShortRawIndex = ShortForRaw + EgtIf( RawIndex <= ExtraShortForRaw, 1, 0) - 1 + end +end + +-- Ciclo fino ad esaurimento pezzi o barre +local nRawTot = 0 +local dTime = 0 +local nCycle = 1 +while TotRawCount( Raws) > 0 and PartsToFill( Parts) > 0 do + + -- creo lista pezzi con pezzi lunghi e pezzi corti di questo Cycle + local PartsToNest = {} + for PartIndex = 1, #LongList do + table.insert( PartsToNest, LongList[PartIndex]) + end + for CycleIndex = 1, #RawsShortList do + if CycleIndex <= nCycle then + for PartIndex = 1, #RawsShortList[CycleIndex] do + table.insert( PartsToNest, RawsShortList[CycleIndex][PartIndex]) + end + end + end + + -- se non ci sono pezzi da nestare, esco + if PartsToFill( PartsToNest) <= 0 then + break + end + -- Eseguo ottimizzazione per ogni lunghezza di barra + local Results = {} + for RawIndex = 1, #Raws do + Results[RawIndex] = ExecMaximumFilling( Raws[RawIndex], PartsToNest) + end + -- verifico quale e' quella con meno scarto + local nMinWasteRawIndex = GDB_ID.NULL + local dMinWaste = 100000 + for ResultIndex = 1, #Results do + local dWaste = (1 - Results[ResultIndex].FillRatio) * Raws[ResultIndex].LenToFill + if dWaste < dMinWaste then + dMinWaste = dWaste + nMinWasteRawIndex = ResultIndex + end + end + -- verifico se ci sono pezzi + if Results[nMinWasteRawIndex].DiffParts > 0 then + -- creo gruppo di lavorazione + local MachGroupName = NewMachGroupName() + nMachGroup = EgtAddMachGroup( MachGroupName) + EgtSetInfo( nMachGroup, "BARLEN", Raws[nMinWasteRawIndex].LenToFill) + EgtSetInfo( nMachGroup, "MATERIAL", NEST.MATERIAL) + EgtSetInfo( nMachGroup, "AUTONEST", 1) + -- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione + EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID) + EgtSetInfo( nMachGroup, "PATTID", nMachGroup) + -- Disegno i pezzi + local CurrX = Raws[nMinWasteRawIndex].StartGap + local nInfoIndex = 1 + for i = 1, Results[nMinWasteRawIndex].DiffParts do + local PartIndex = Results[nMinWasteRawIndex].Data[i].Id + local PartId = PartsToNest[PartIndex].Id + local dLen = PartsToNest[PartIndex].Len + for j = 1, Results[nMinWasteRawIndex].Data[i].Count do + -- creo pezzo copia + local nPartDuploId = EgtDuploNew( PartId) + EgtSetInfo( nMachGroup, "PART" .. nInfoIndex, nPartDuploId .. "," .. CurrX) + CurrX = CurrX + dLen + Raws[nMinWasteRawIndex].MidGap + nInfoIndex = nInfoIndex + 1 + end + end + nRawTot = nRawTot + 1 + end + -- Aggiorno per prossima iterazione + Raws[nMinWasteRawIndex].Count = Raws[nMinWasteRawIndex].Count - 1 + for i = 1, Results[nMinWasteRawIndex].DiffParts do + local PartId = Results[nMinWasteRawIndex].Data[i].Id + PartsToNest[PartId].Cnt = PartsToNest[PartId].Cnt - Results[nMinWasteRawIndex].Data[i].Count + end + nCycle = nCycle + 1 +end + +-- creo grezzi per ogni gruppo di lavorazione +local nRawCnt = 0 +_G.BEAM = {} +BEAM.FILE = NEST.FILE +BEAM.MACHINE = NEST.MACHINE +BEAM.FLAG = 6 -- CREATE_PANEL +nMachGroup = EgtGetFirstMachGroup() +while nMachGroup do + local nNextMachGroup = EgtGetNextMachGroup( nMachGroup) + EgtSetCurrMachGroup( nMachGroup) + if EgtGetInfo( nMachGroup, "AUTONEST",'i') == 1 then + EgtRemoveInfo( nMachGroup, "AUTONEST") + EgtSetInfo( nMachGroup, "UPDATEUI", 1) + local bOk, sErr = pcall( dofile, EgtGetSourceDir() .. "BatchProcessNew.lua") + if not bOk then + EgtOutLog( 'Error in BatchProcessNew.lua call (' .. ( sErr or '') ..')') + end + nRawCnt = nRawCnt + 1 + -- aggiorno interfaccia + EgtProcessEvents( 200 + ( nRawCnt / nRawTot * 100), 0) + end + nMachGroup = nNextMachGroup +end + +EgtResetCurrMachGroup() + +NEST.ERR = 0 + +EgtOutLog( ' +++ BeamNestProcess completed') diff --git a/ProgramData/EgtCAM5/Beam/Process.lua b/ProgramData/EgtCAM5/Beam/Process.lua new file mode 100644 index 0000000..f97e47a --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/Process.lua @@ -0,0 +1,274 @@ +-- Process.lua by Egaltech s.r.l. 2021/02/25 +-- Gestione calcolo disposizione e lavorazioni per Travi +-- Si opera sulla macchina corrente +-- 2020/01/08 Aggiunta seconda sezione limite (BD.MAX_WIDTH2 x BD.MAX_HEIGHT2). +-- 2020/10/25 Se assegno lunghezza barra nulla prende il minimo calcolato. +-- 2021/02/14 Modifica per macchine senza BD.MAX_WIDTH2 e BD.MAX_HEIGHT2. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not sMachDir then + EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Travi', 'ERROR') + return +end +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + EgtOutBox( 'La macchina corrente non è configurata per lavorare travi', 'Lavora Travi', 'ERROR') + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Segnalazione avvio +EgtOutLog( '*** Beam Process Start ***', 1) + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Variabili di modulo +local vBeam = {} +local dRawW +local dRawH + +------------------------------------------------------------------------------------------------------------- +-- *** Recupero le travi selezionate *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessInputData() + + -- Recupero le travi selezionate + local nId = EgtGetFirstSelectedObj() + while nId do + local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) + if nPartId then + local bFound = false + for i = 1, #vBeam do + if vBeam[i].Id == nPartId then + bFound = true + break + end + end + if not bFound then + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + end + nId = EgtGetNextSelectedObj() + end + if #vBeam == 0 then + EgtOutBox( 'Non sono state selezionate travi', 'Lavora Travi', 'ERROR') + return false + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi selezionate : ' .. sOut, 1) + end + + -- Ne recupero e verifico le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + EgtOutBox( 'Box non definito per la trave ' .. vBeam[i].Name, 'Lavora Travi', 'ERROR') + return false + else + vBeam[i].Box = b3Solid + end + end + dRawW = vBeam[1].Box:getDimY() + dRawH = vBeam[1].Box:getDimZ() + local vBeamErr = {} + for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end + end + if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + EgtDeselectPartObjs( vBeam[vBeamErr[i]].Id) + table.remove( vBeam, vBeamErr[i]) + end + EgtOutLog( sOut, 1) + EgtOutBox( sOut, 'Lavora Travi', 'INFO') + EgtDraw() + return false + end + EgtDeselectAll() + + -- Le ordino in senso di lunghezza crescente + table.sort( vBeam, function( B1, B2) return B1.Box:getDimX() < B2.Box:getDimX() end) + do + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi ordinate : ' .. sOut, 1) + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle travi nel grezzo *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessBeams() + + -- Determinazione minimo grezzo scaricabile + BE.CalcMinUnloadableRaw( dRawW, dRawH) + + -- Lunghezza totale delle travi + local dTotLen = 0 + for i = 1, #vBeam - 1 do + dTotLen = dTotLen + vBeam[i].Box:getDimX() + end + dTotLen = dTotLen + max( vBeam[#vBeam].Box:getDimX(), BD.MinRaw) + local dAddLen = BD.OVM_HEAD + ( #vBeam - 1) * BD.OVM_MID + EgtOutLog( 'Ltot : ' .. EgtNumToString( dTotLen, 1) .. ' Lagg : '.. EgtNumToString( dAddLen, 1), 1) + + -- Richiedo lunghezza del grezzo e sovramateriale di testa + local vsVal = EgtDialogBox( 'Lavora Travi' .. ' (Ltot='.. EgtNumToString( dTotLen + dAddLen + 0.5, 0) .. ', Lmax=' .. EgtNumToString( BD.MAX_RAW, 0) .. ')', + {'Lunghezza grezzo', EgtNumToString( BD.STD_RAW, 0)}, + {'Sovramateriale di testa', EgtNumToString( BD.OVM_HEAD, 0)}, + {'Forza sezione verticale', ' CB:true,*false'}) + if not vsVal then + EgtDraw() + return + end + local dRawL = EgtEvalNumExpr( vsVal[1]) + if not dRawL then + local sOut = 'Lunghezza grezzo errata : ' .. vsVal[1] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + if dRawL < GEO.EPS_SMALL then dRawL = dTotLen + dAddLen + 0.5 end + dRawL = min( dRawL, BD.MAX_RAW) + local dOvmHead = EgtEvalNumExpr( vsVal[2]) + if not dOvmHead then + local sOut = 'Sovramateriale di testa errato : ' .. vsVal[2] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo sezione barra con travi + local bVert = ( vsVal[3] == 'true') + if bVert then + if dRawW > dRawH then dRawW, dRawH = dRawH, dRawW end + end + EgtOutLog( 'Lraw : ' .. EgtNumToString( dRawL, 1) .. ' Lovm : '.. EgtNumToString( dOvmHead, 1), 1) + + -- Verifico sezione barra non troppo grande + if not BD.MAX_WIDTH2 or not BD.MAX_HEIGHT2 then + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + else + if ( dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL) and + ( dRawW > BD.MAX_WIDTH2 + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ') ' .. + 'e (' .. EgtNumToString( BD.MAX_WIDTH2, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT2, 2) .. ')' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + end + + -- Verifico sezione barra non troppo piccola + if dRawW < BD.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < BD.MIN_HEIGHT - 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'sotto i limiti della macchina (' .. EgtNumToString( BD.MIN_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MIN_HEIGHT, 2) .. ')' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo le travi nel grezzo + local bOk, sErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) + if not bOk then + EgtOutLog( sErr) + EgtOutBox( sErr, 'Lavora Travi', 'ERROR') + return false + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessFeatures() + + local bOk, Stats = BE.ProcessFeatures() + local nErrCnt = 0 + local nWarnCnt = 0 + local sOutput = '' + for i = 1, #Stats do + if Stats[i].Err > 0 then + nErrCnt = nErrCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + elseif Stats[i].Err < 0 then + -- se segnalazione scarico pezzo standard, incompleto o a caduta + if Stats[i].Err == -100 or Stats[i].Err == -101 or Stats[i].Err == -102 then + -- non faccio niente + else + nWarnCnt = nWarnCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + end + end + end + if #sOutput > 0 then EgtOutLog( sOutput) end + if nErrCnt > 0 then + EgtOutBox( sOutput, 'Lavora Travi', 'ERRORS') + return false + elseif nWarnCnt > 0 then + EgtOutBox( sOutput, 'Lavora Travi', 'WARNINGS') + return true + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Esecuzione *** +------------------------------------------------------------------------------------------------------------- +if not MyProcessInputData() then return end + +if not MyProcessBeams() then return end + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +if not MyProcessFeatures() then return end diff --git a/ProgramData/EgtCAM5/Beam/Rotate.lua b/ProgramData/EgtCAM5/Beam/Rotate.lua new file mode 100644 index 0000000..c7a6c9b --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/Rotate.lua @@ -0,0 +1,32 @@ +-- Rotate.lua by Egaltech s.r.l. 2017/11/04 +-- Gestione rotazione di una Trave + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Rotate Trave', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la trave ' .. sName, 'Rotate Trave', 'ERROR') + return +end + +-- eseguo rotazione di 90 gradi attorno asse X +local ptRot = b3Solid:getMin() + Vector3d( 0, b3Solid:getDimZ() / 2, b3Solid:getDimZ() / 2) +EgtRotate( nPartId, ptRot, X_AX(), 90, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Beam/Stato_lavori.xlsx b/ProgramData/EgtCAM5/Beam/Stato_lavori.xlsx new file mode 100644 index 0000000..b5b8067 Binary files /dev/null and b/ProgramData/EgtCAM5/Beam/Stato_lavori.xlsx differ diff --git a/ProgramData/EgtCAM5/Beam/Swap.lua b/ProgramData/EgtCAM5/Beam/Swap.lua new file mode 100644 index 0000000..c5d74a3 --- /dev/null +++ b/ProgramData/EgtCAM5/Beam/Swap.lua @@ -0,0 +1,31 @@ +-- Swap.lua by Egaltech s.r.l. 2017/11/02 +-- Gestione scambio testa coda di una Trave + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Swap Trave', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la trave ' .. sName, 'Swap Trave', 'ERROR') + return +end + +-- eseguo rotazione di 180 gradi attorno asse Z +EgtRotate( nPartId, b3Solid:getCenter(), Z_AX(), 180, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/BeamWall/BeamWall.ini b/ProgramData/EgtCAM5/BeamWall/BeamWall.ini new file mode 100644 index 0000000..8023848 --- /dev/null +++ b/ProgramData/EgtCAM5/BeamWall/BeamWall.ini @@ -0,0 +1,10 @@ +[BeamWall] +BtlEnable=1 +BaseDir=C:\EgtData\BeamWall +Button1=ClearProcess.lua,Images\ClearProcess.png,Cancella Lavorazioni Pezzo +Button2=DisableFeatures.lua,Images\DisableFeatures.png,Disabilita Lavorazioni +Button3=EnableFeatures.lua,Images\EnableFeatures.png,Abilita Lavorazioni +Button4=HideAll.lua,Images\HideAll.png,Nascondi i Pezzi non selezionati +Button5=ShowAll.lua,Images\ShowAll.png,Visualizza tutti i Pezzi +Button6=ShowSolid.lua,Images\ShowSolid.png,Visualizza/Nascondi Solido +Button7=ShowBuilding.lua,Images\ShowBuilding.png,Visualizza Struttura/Visualizza Pezzi diff --git a/ProgramData/EgtCAM5/BeamWall/ClearProcess.lua b/ProgramData/EgtCAM5/BeamWall/ClearProcess.lua new file mode 100644 index 0000000..d195645 --- /dev/null +++ b/ProgramData/EgtCAM5/BeamWall/ClearProcess.lua @@ -0,0 +1,57 @@ +-- ClearProcess.lua by Egaltech s.r.l. 2020/03/30 +-- Se la trave non è parte di un gruppo di lavoro, cancello geometrie aggiunte + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Recupero la prima trave selezionata +local ObjId = EgtGetFirstSelectedObj() +local PartId = EgtGetParent( EgtGetParent( ObjId or GDB_ID.NULL) or GDB_ID.NULL) +if not PartId then return end + +-- Recupero appartenenza a gruppi di lavoro +local vMGrps = {} +local sLst = EgtGetInfo( PartId, GDB_SI.LIST) +if sLst then + vLst = EgtSplitString( sLst) + if vLst then + for i = 1, #vLst do + local MGrpId = EgtGetParent( EgtGetParent( EgtGetParent( vLst[i]) or GDB_ID.NULL) or GDB_ID.NULL) + if MGrpId then + table.insert( vMGrps, EgtGetName( MGrpId)) + end + end + end +end + +-- Chiedo conferma della cancellazione +if #vMGrps > 0 then + local sOut = 'I seguenti gruppi di lavoro verranno cancellati :\n ' .. table.concat( vMGrps, ',') .. '.\nConfermi ?' + if not EgtOutBox( sOut, 'Cancella Lavorazioni', 'QUESTION') then + return + end +end + +-- Cancello i gruppi di lavoro e le geometrie aggiuntive relative +for i = 1, #vMGrps do + EgtRemoveMachGroup( EgtGetMachGroupId( vMGrps[i]) or GDB_ID.NULL) + EgtErase( EgtGetFirstNameInGroup( PartId, vMGrps[i]) or GDB_ID.NULL) +end + +-- Cancello eventuali altre geometrie aggiuntive per gruppi di lavoro +local LayId = EgtGetFirstLayer( PartId) +while LayId do + local NextLayId = EgtGetNextLayer( LayId) + if EgtGetInfo( LayId, GDB_SI.MGRPONLY) then + EgtErase( LayId) + end + LayId = NextLayId +end + +-- Aggiorno interfaccia grafica +EgtDeselectPartObjs( PartId) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/BeamWall/DisableFeatures.lua b/ProgramData/EgtCAM5/BeamWall/DisableFeatures.lua new file mode 100644 index 0000000..1ca71b6 --- /dev/null +++ b/ProgramData/EgtCAM5/BeamWall/DisableFeatures.lua @@ -0,0 +1,39 @@ +-- DisableFeatures.lua by Egaltech s.r.l. 2020/12/31 +-- Gestione disabilitazione delle feature selezionate + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +if EgtGetSelectedObjCount() == 0 then + EgtOutBox( 'Nessuna lavorazione selezionata', 'Disabilita lavorazioni', 'ERROR') +end + +-- Elenco dei pezzi interessati +local vParts = {} + +-- Disabilito features selezionate +local nId = EgtGetFirstSelectedObj() +while nId do + if EgtBeamEnableProcess( nId, false, false) then + table.insert( vParts, EgtGetParent( EgtGetParent( nId))) + end + nId = EgtGetNextSelectedObj() +end + +-- Forzo aggiornamento dei pezzi +table.sort( vParts) +local PrevPartId = GDB_ID.NULL +for i = 1, #vParts do + if vParts[i] ~= PrevPartId then + EgtBeamSetPart( vParts[i]) + EgtBeamUpdatePart() + PrevPartId = vParts[i] + end +end + +EgtDeselectAll() +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/BeamWall/EnableFeatures.lua b/ProgramData/EgtCAM5/BeamWall/EnableFeatures.lua new file mode 100644 index 0000000..0287bbf --- /dev/null +++ b/ProgramData/EgtCAM5/BeamWall/EnableFeatures.lua @@ -0,0 +1,39 @@ +-- DisableFeatures.lua by Egaltech s.r.l. 2020/12/31 +-- Gestione abilitazione delle feature selezionate + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +if EgtGetSelectedObjCount() == 0 then + EgtOutBox( 'Nessuna lavorazione selezionata', 'Abilita lavorazioni', 'ERROR') +end + +-- Elenco dei pezzi interessati +local vParts = {} + +-- Abilito features selezionate +local nId = EgtGetFirstSelectedObj() +while nId do + if EgtBeamEnableProcess( nId, true, false) then + table.insert( vParts, EgtGetParent( EgtGetParent( nId))) + end + nId = EgtGetNextSelectedObj() +end + +-- Forzo aggiornamento dei pezzi +table.sort( vParts) +local PrevPartId = GDB_ID.NULL +for i = 1, #vParts do + if vParts[i] ~= PrevPartId then + EgtBeamSetPart( vParts[i]) + EgtBeamUpdatePart() + PrevPartId = vParts[i] + end +end + +EgtDeselectAll() +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/BeamWall/HideAll.lua b/ProgramData/EgtCAM5/BeamWall/HideAll.lua new file mode 100644 index 0000000..abbc8fa --- /dev/null +++ b/ProgramData/EgtCAM5/BeamWall/HideAll.lua @@ -0,0 +1,40 @@ +-- HideAll.lua by Egaltech s.r.l. 2019/03/16 +-- Gestione nascondimento di tutte le Travi non selezionate + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- se non ci sono pezzi selezionati, esco +if not EgtGetFirstSelectedObj() then return end + +-- nascondo tutti i pezzi non selezionati +local bCurrPL = false +local nPartId = EgtGetFirstPart() +while nPartId do + local nStat = GDB_ST.ON + local nLayId = EgtGetFirstLayer( nPartId) + while nLayId do + local nEntId = EgtGetFirstInGroup( nLayId) + if nEntId then + nStat = EgtGetCalcStatus( nEntId) + break + else + nLayId = EgtGetNextLayer( nLayId) + end + end + if nStat ~= GDB_ST.SEL then + EgtSetMode( nPartId, GDB_MD.HIDDEN) + else + EgtDeselectPartObjs( nPartId) + if not bCurrPL then + bCurrPL = EgtSetCurrPartLayer( nPartId, EgtGetFirstLayer( nPartId)) + end + end + nPartId = EgtGetNextPart( nPartId) +end + +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/BeamWall/Images/ClearProcess.png b/ProgramData/EgtCAM5/BeamWall/Images/ClearProcess.png new file mode 100644 index 0000000..5b59c0c Binary files /dev/null and b/ProgramData/EgtCAM5/BeamWall/Images/ClearProcess.png differ diff --git a/ProgramData/EgtCAM5/BeamWall/Images/DisableFeatures.png b/ProgramData/EgtCAM5/BeamWall/Images/DisableFeatures.png new file mode 100644 index 0000000..10249b4 Binary files /dev/null and b/ProgramData/EgtCAM5/BeamWall/Images/DisableFeatures.png differ diff --git a/ProgramData/EgtCAM5/BeamWall/Images/EnableFeatures.png b/ProgramData/EgtCAM5/BeamWall/Images/EnableFeatures.png new file mode 100644 index 0000000..1753231 Binary files /dev/null and b/ProgramData/EgtCAM5/BeamWall/Images/EnableFeatures.png differ diff --git a/ProgramData/EgtCAM5/BeamWall/Images/HideAll.png b/ProgramData/EgtCAM5/BeamWall/Images/HideAll.png new file mode 100644 index 0000000..3ed46af Binary files /dev/null and b/ProgramData/EgtCAM5/BeamWall/Images/HideAll.png differ diff --git a/ProgramData/EgtCAM5/BeamWall/Images/ShowAll.png b/ProgramData/EgtCAM5/BeamWall/Images/ShowAll.png new file mode 100644 index 0000000..37a0de8 Binary files /dev/null and b/ProgramData/EgtCAM5/BeamWall/Images/ShowAll.png differ diff --git a/ProgramData/EgtCAM5/BeamWall/Images/ShowBuilding.png b/ProgramData/EgtCAM5/BeamWall/Images/ShowBuilding.png new file mode 100644 index 0000000..419a955 Binary files /dev/null and b/ProgramData/EgtCAM5/BeamWall/Images/ShowBuilding.png differ diff --git a/ProgramData/EgtCAM5/BeamWall/Images/ShowSolid.png b/ProgramData/EgtCAM5/BeamWall/Images/ShowSolid.png new file mode 100644 index 0000000..383a95e Binary files /dev/null and b/ProgramData/EgtCAM5/BeamWall/Images/ShowSolid.png differ diff --git a/ProgramData/EgtCAM5/BeamWall/ShowAll.lua b/ProgramData/EgtCAM5/BeamWall/ShowAll.lua new file mode 100644 index 0000000..15e9b5b --- /dev/null +++ b/ProgramData/EgtCAM5/BeamWall/ShowAll.lua @@ -0,0 +1,18 @@ +-- ClearAll.lua by Egaltech s.r.l. 2017/11/16 +-- Gestione visualizzazione di tutte le Travi + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +local nId = EgtGetFirstPart() +while nId do + EgtSetMode( nId, GDB_MD.STD) + -- EgtSetStatus( nId, GDB_ST.ON) + nId = EgtGetNextPart( nId) +end + +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/BeamWall/ShowBuilding.lua b/ProgramData/EgtCAM5/BeamWall/ShowBuilding.lua new file mode 100644 index 0000000..16b7517 --- /dev/null +++ b/ProgramData/EgtCAM5/BeamWall/ShowBuilding.lua @@ -0,0 +1,17 @@ +-- ShowBuilding.lua by Egaltech s.r.l. 2020/12/12 +-- Gestione visualizzazione travi come struttura + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Recupero l'attivazione dell'assemblaggio +local bOn = EgtBeamGetBuildingIsOn() + +-- Modifico lo stato dell'assemblaggio +EgtBeamShowBuilding( not bOn) + +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/BeamWall/ShowSolid.lua b/ProgramData/EgtCAM5/BeamWall/ShowSolid.lua new file mode 100644 index 0000000..95f78ed --- /dev/null +++ b/ProgramData/EgtCAM5/BeamWall/ShowSolid.lua @@ -0,0 +1,31 @@ +-- ShowSolid.lua by Egaltech s.r.l. 2020/12/12 +-- Gestione calcolo solido di una Trave + +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero il pezzo del primo oggetto selezionato +local ObjId = EgtGetFirstSelectedObj() +local PartId = EgtGetParent( EgtGetParent( ObjId or GDB_ID.NULL) or GDB_ID.NULL) +if not PartId or not EgtIsPart( PartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Show Solid', 'ERROR') + return +end +EgtDeselectAll() + +-- Se il solido già esiste, ne aggiorno lo stato di visualizzazione +local SolidId = EgtBeamGetSolid( PartId) +if SolidId and EgtGetInfo( SolidId, 'VALID') then + EgtBeamShowSolid( PartId, ( EgtGetCalcStatus( SolidId) == GDB_ST.OFF)) + EgtDraw() + return +end + +-- Creazione e visualizzazione del solido +EgtBeamCalcSolid( PartId, true) +EgtBeamShowSolid( PartId, true) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/BeamWall/SolidProcess.lua b/ProgramData/EgtCAM5/BeamWall/SolidProcess.lua new file mode 100644 index 0000000..1cbce30 --- /dev/null +++ b/ProgramData/EgtCAM5/BeamWall/SolidProcess.lua @@ -0,0 +1,110 @@ +-- 2021/03/18 +-- Parti solide gestite come travi BTL + + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- calcolo del riferimento del minimo box +local function SolidMinBox( nId) + -- ciclo sulle facce della superficie + local nFacCnt = EgtSurfTmFacetCount( nId) + local dVolMin + local refMin + local b3Min + for i = 1, nFacCnt do + local refFace = EgtSurfTmFacetMinAreaRectangle( nId, i - 1, GDB_ID.ROOT) + if refFace then + local b3Box = EgtGetBBoxRef( nId, GDB_BB.STANDARD, refFace) + if b3Box then + local dVol = b3Box:getDimX() * b3Box:getDimY() * b3Box:getDimZ() + if not dVolMin or dVol < dVolMin then + dVolMin = dVol + refMin = refFace + b3Min = b3Box + end + end + end + end + return refMin, b3Min +end + +-- Trasformazione di un oggetto solido +local function ProcessOneSolid( nId1, ptPos) + + -- Calcolo il riferimento del suo box minimo + local refMin, b3Min = SolidMinBox( nId1) + if not refMin then + EgtOutText( 'Errore nel calcolo del box minimo della superficie') + EgtPause( 1000) + return + end + + -- Modifico il riferimento in modo che X sia sul più lungo, quindi Z e poi Y + local dDimX = b3Min:getDimX() + local dDimY = b3Min:getDimY() + local dDimZ = b3Min:getDimZ() + if dDimX < dDimY then + refMin:rotate( refMin:getOrigin(), refMin:getVersZ(), 90) + dDimX, dDimY = dDimY, dDimX + end + if dDimX < dDimZ then + refMin:rotate( refMin:getOrigin(), refMin:getVersY(), 90) + dDimX, dDimZ = dDimZ, dDimX + end + if dDimZ < dDimY then + refMin:rotate( refMin:getOrigin(), refMin:getVersX(), 90) + dDimZ, dDimY = dDimY, dDimZ + end + + -- Porto il solido nell'origine + refMin:invert() + EgtTransform( nId1, refMin, GDB_RT.GLOB) + local b3Box = EgtGetBBoxGlob( nId1, GDB_BB.STANDARD) + local vtMove = ORIG() - b3Box:getMin() + EgtMove( nId1, vtMove, GDB_RT.GLOB) + b3Box:move( vtMove) + + -- Creo un nuovo pezzo + local PzId = EgtGroup( GDB_ID.ROOT) + local PartId = EgtGroup( PzId) + EgtSetName( PartId or GDB_ID.NULL, 'Part') + local BoxId = EgtGroup( PzId) + EgtSetName( BoxId or GDB_ID.NULL, 'Box') + local ProcId = EgtGroup( PzId) + EgtSetName( ProcId or GDB_ID.NULL, 'Proc') + + -- Sposto il solido nel pezzo + EgtRelocate( nId1, ProcId) + + -- Calcolo il box + local SboxId = EgtSurfTmBBox( BoxId, b3Box) + EgtSetColor( SboxId or GDB_ID.NULL, {206,199,113,30}) + + -- Assegno il nome + local sText = string.format( 'Part%d %.0f x %.0f x %.0f', PzId, dDimX, dDimY, dDimZ) + local ptText = b3Box:getCenter() + Vector3d( 0, 0, dDimZ / 2) + local TxtId = EgtTextAdv( PartId, ptText, 0, sText, '', 100, 'S', dDimY / 4, 1, 0, GDB_TI.MC) + EgtSetColor( TxtId or GDB_ID.NULL, {0,0,0,100}) + EgtSetName( PzId or GDB_ID.NULL, sText) + + -- Sposto il pezzo + if ptPos then + EgtMove( PzId, ptPos - ORIG()) + end + + EgtDraw() +end + +------------------------------------------------------------------- +local ptIns = ORIG() +local nId = EgtGetFirstSelectedObj() +while nId do + EgtDeselectObj( nId) + ProcessOneSolid( nId, ptIns) + ptIns = ptIns + Vector3d( 0, 300, 0) + nId = EgtGetFirstSelectedObj() +end diff --git a/ProgramData/EgtCAM5/BtlAux/Variant_1.nge b/ProgramData/EgtCAM5/BtlAux/Variant_1.nge new file mode 100644 index 0000000..273abf3 Binary files /dev/null and b/ProgramData/EgtCAM5/BtlAux/Variant_1.nge differ diff --git a/ProgramData/EgtCAM5/Config/EgalTechDeu.txt b/ProgramData/EgtCAM5/Config/EgalTechDeu.txt new file mode 100644 index 0000000..a3719a4 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgalTechDeu.txt @@ -0,0 +1,3312 @@ +// Message File EgalTech Deutsche 2022/04/11 +0=DEU +// File +1=File +3=New +5=Open +6=Open
Recent files (Shift) +7=Insert +9=Save +11=Save as +13=Import +15=Export +17=Exec +19=Recent Files +20=Recent Scripts +// View +101=View +103=WFrame +105=HLine +107=Shading +109=ZoomAll +111=ZoomIn +113=ZoomOut +115=Top +117=Front +119=Right +121=Back +123=Left +125=Bottom +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Grid +136=SetView perpendicular to current Grid +137=CurveDir +139=Analyze +141=GetDist +// Grid +201=Grid +203=Top +205=Front +207=Right +209=Back +211=Left +213=Bottom +215=View +216=Set Grid perpendicular to View +217=Elevat +218=Set Grid Elevation +219=Origin +220=Set Grid Origin +221=Rotate +222=Rotate Grid
3D Rotate Grid (Shift) +223=3 Points +224=Set Grid from 3 Points +225=Perp +226=Set Grid Perpendicular to Object +227=Object +228=Set Grid from Object +// Draw +301=Draw +303=Point +304=Point
Vector (Shift)
Frame (Ctrl) +305=Line 2P +306=Line : 2 Points
Line : 2 Points with Continue (Ctrl) +307=LineSDL +308=Line : Start, Direction, Length
Line : Start, Direction Vector, Length (Shift) +309=Circle +310=Circle : Center, Point
Circle : Center, Diameter (Shift) +311=Fillet +312=Fillet : Radius
Chamfer : Dist (Shift) +313=Arc CSE +314=Arc : Center, Start, End +315=Arc 3P +316=Arc : 3 Points +317=Arc SDE +318=Arc : Start, Direction, End
Arc : Start, Direction Vector, End (Shift)
Arc : Start, Direction, End with Continue (Ctrl) +319=Rect 2P +320=Rectangle : 2 Points +321=Polygon +322=Polygon : Radius or Apothem
Polygon : Side with 2 Points (Shift) +323=Text +324=Text
Advanced Text (Shift) +399=Continue : 'L' with line, 'A' with arc +// Construct +401=Construct +403=Plane +404=Surface : between planar curves
Flat Region (Shift) +405=Extrude +406=Surface : curve extrusion +407=Revolve +408=Surface : curve revolution +409=Screw +410=Surface : curve screwing +411=Ruled +412=Surface : ruled between 2 curves +413=Merge +414=Merge Surfaces +415=Flip +416=Flip Surface Outside +417=Explode +418=Explode Surfaces or Flat Regions +419=Swept +420=Surface :sweeping a curve along another +// Edit +501=Edit +503=Delete +504=Delete Objects +505=Layer +506=Change Object Layer to Current +507=Color +508=Change Color
Remove Color (Shift)
Change Trasparency (Ctrl) +509=Invert +510=Invert Curve +511=Trim/Ext +512=Trim or Extend Curve +513=Break +514=Break Curve
Split Curve in Pieces (Shift) +515=Join +516=Join Curves
Join Curves making a Copy (Shift)
Merge Curves in Composite (Ctrl) +517=Explode +518=Explode Text or Curve in Components +519=Thick +520=Set Curve Thickness and Extrusion +521=Start +522=Change Closed Curve Start Point +// Transform +601=Transform +603=Move +604=Object Move +605=Rotate +606=Object Rotate
3D Object Rotate (Shift) +607=Mirror +608=Object Mirror
3D Object Mirror (Shift) +609=Scale +610=Object Scale
3D Object Scale (Shift) +611=Offset +612=Curve Offset +// Special +701=Special +703=Flat Parts +704=Insert DXF or NGE flat parts +705=Compo +706=Insert parametric components +// Scene : Entity selection Menu +1001=Alle auswählen +1003=Alle abwählen +1005=Fenster auswählen +1007=Teil auswählen +1009=Ebene auswählen +1011=Pfad auswählen +1013=Vollständigen Pfad auswählen +1015=Entität auswählen +1016=Alle sichtbaren auswählen +// Scene : Point selection Menu + Statusbar +1101=Skizzenpunkt +1102=Skizzenpunkt +1103=Gitterpunkt +1104=Gitterpunkt +1105=Endpunkt +1106=Endpunkt +1107=Mittelpunkt +1108=Mittelpunkt +1109=Mittelpunkt +1110=Mitte +1111=Schwerpunkt +1112=Schwerpunkt +1113=Nahpunkt +1114=Nahpunkt +1115=Schnittpunkt +1116=Inters Point +1117=Tangentenpunkt +1118=Tang Point +1119=Senkrechter Punkt +1120=Perp Point +1121=Min.Distance Point +1122=MinDist Point +1123=Oberflächen ausschließen +// Scene : Other Menu +1201=Drag Off +1203=Drag On +// Scene : Others +1301=Dist= +// Controller +2001=Copy (V) +2002=Error +2003=Warning +2051=The Point must be different from previous +2052=The Points must be not aligned +2053=Zero or Negative Values not allowed +2054=Two Zero or Negative Values not allowed +2055=At least one Entity is not scalable +2056=Distance too big +2057=Curve not flat (in its plane) +// Controller : Draw +2101= +// Controller : Construct +2201= +// Controller : Modify +2301= +// Controller : Transform +2401=COPY +2402=MOVE +2403=Insert Base Point +2404=Insert Target Point +2406=ROTATE +2407=Insert Center +2408=Insert Base Point +2409=Insert Angle or Rotation Point +2411=ROTATE 3D +2412=Insert First Point on Axis +2413=Insert Second Point on Axis +2414=Insert Base Point +2415=Insert Angle or Rotation Point +2416=MIRROR +2417=Insert First Point +2418=Insert Second Point +2421=MIRROR 3D +2422=Insert First Point +2423=Insert Second Point +2424=Insert Third Point +2426=SCALE +2427=Insert Center +2428=Insert Factor +2431=SCALE 3D +2432=Insert Center +2433=Insert Factors +2436=OFFSET +2437=Insert Distance +2438=Fillet +2439=Chamfer +2440=Extend +// ----- EgtCAM5 ----- +5001=ZEICHNEN +5002=BEARBEITUNG +5003=Werkzeug Db +5004=Bearbeitung Db +5005=Optionen +5006=Werk Db +5007=Mach Db +5008=Maschinenoptionen +5009=SetUp Db +5010=Konfiguration Db +5020=Bearbeitungstabelle Db +//Top CommandBar +5101=Neu +5102=Öffnen
Letzte Datei öffnen (rechte Schaltfläche) +5103=Speichern +5104=Speichern unter +5105=Einfügen +5106=Importieren +5107=Exportieren +5108=Skript ausführen
Aktuelles Skript ausführen (rechte Schaltfläche) +5109=Optionen +5110=Support-Adresse kann nicht gefunden werden. +5111=Aktuelle Datei speichern, bevor Feedback gesendet wird? +5112=Senden Sie ein Feedback an {0} mit dem angehängten Verzeichnis {1}. +5113=Feedback +5114=Feedback-Mail bereit. +//Draw Panel +5150=Freie Kanten von Oberflächen und flachen Regionen extrahieren +5151=Oberflächen und flache Regionen verbinden +5152=Oberflächen und flache Bereiche subtrahieren +5153=Schnittflächen und flache Bereiche +5154=Punkte, Kurven und Flächen vom Schnittpunkt der Oberflächen +5155=Lineare Bemaßung
Ausgerichtete Bemaßung (Verschiebung) +5156=Kreis 3 Punkte +5157=Kanten von Oberflächenflächen und flachen Regionen extrahieren Teile +5158=Fläche von Oberfläche extrahieren +5159=???Arc Flip
Arc Explementary (Shift) +5160=???Modify Shape +5161=???Add Point
Modify in Arc (Shift)
Close Curve Composite (Ctrl) +5162=???Remove Point
Modify in Line (Shift)
Open Curve Composite (Ctrl) +5163=???Approx Curve
Approx Curve with Lines (Shift) +5201=Punkt
Vektor (Verschiebung)
Rahmen (Strg) +5202=Linie 2 Punkte
Linie 2 Punkte mit Weiter (Strg) +5203=Linienpunktrichtungslänge
Linienpunktrichtungsvektorlänge (Verschiebung) +5204=Kreismittelpunkt +5205=Kreismitteldurchmesser +5206=Arc Center Start Endpunkte +5207=Bogen 3 Punkte +5208=Bogenstartpunkt Richtung Endpunkt
Bogenstartpunkt Richtungsvektor Endpunkt (Verschiebung)
Bogenstartpunkt Richtung Endpunkt mit Weiter (Strg) +5209=Filet +5210=Fase +5211=Rechteck 2 Punkte +5212=Polygon +5213=Polygonseite +5214=Text
Erweiterter Text (Umschalt) +5215=Ebene aus Grenzkurven
Flacher Bereich (Verschiebung) +5216=Extrudieren +5217=drehen +5218=Schraube +5219=entschieden +5220=Oberflächen zusammenführen +5221=Oberflächen und flache Bereiche explodieren +5222=Oberfläche und flache Bereiche umkehren +5223=Löschen +5224=Ebene ändern
Ebene mit Transformationen ändern (Umschalt) +5225=Transparenz ändern +5226=Farbe zurücksetzen +5227=Farbe ändern +5228=Kurve umkehren +5229=Geschlossenen Kurvenstartpunkt ändern +5230=Kurve trimmen oder verlängern +5231=Bruchkurve +5232=Teilungskurve +5233=Kurven verbinden
Kurven verbinden, die eine Kopie erstellen (Shift)
Merge Curves in Composite (Ctrl) +5234=Kurven und Texte explodieren +5235=Dick- und Extrusionskurve +5236=Verschieben +5237=Drehen +5238=3D drehen +5239=Spiegeln +5240=3D spiegeln +5241=Skala +5242=3D skalieren +5243=Versatz +5244=2D-Zeichnung +5245=3D-Zeichnung +5246=Ändern +5247=Transformieren +5248=Gefegt (Abschnitt, Anleitung) +5249=Text bearbeiten +// Grid View Panel +5251=Drahtmodell +5252=Versteckte Linien +5253=Schattierung +5254=Alle zoomen +5255=Vergrößern +5256=Verkleinern +5257=Draufsicht +5258=Vorderansicht +5259=Ansicht von links +5260=Rückansicht +5261=Rechte Ansicht +5262=SW Isometrische Ansicht +5263=SE Isometrische Ansicht +5264=NE Isometrische Ansicht +5265=NW Isometrische Ansicht +5266=Kurvenrichtung anzeigen +5267=Analysieren +5268=Entfernung +5269=oberes Gitter +5270=Frontgitter +5271=rechtes Gitter +5272=Rückengitter +5273=linkes Gitter +5274=unteres Gitter +5275=Raster aus Ansicht +5276=Gitterhöhe +5277=Gitterursprung +5278=Gitterrotation
Gitter-3D-Rotation (Verschiebung) +5279=Gitter ab 3 Punkten +5280=Gitter senkrecht zur Kurve +5281=Gitter vom Objekt +5282=Ansicht vom Raster +5283=Zoomauswahl +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=ENDE +5302=Abschlag +5303=Werkzeugrichtung nicht erreichbar +5304=Fehler +5305=FEHLER +5306=Fehler in der Generierung! +5307=Simulation +5308=Ein Schritt +5309=Wiedergabe / Pause +5310=Stop / Home +5311=Pause +5312=STOP +5313=Kann jetzt nicht beendet werden. Stoppen Sie die Simulation oder warten Sie bis zum Ende! +5314=HOME +5315=WARNUNG +5316=Virtuelles Fräsen +5317=Fehler bei der Berechnung der Schätzungen! +5318=Schätzdatei fehlt +5319=Kollision! +5320=INFORMATION +5330=GENERIEREN +5331=Das Projekt muss vor der Generierung gespeichert werden. Speichern Sie es? +5332=Generierung erfolgreich abgeschlossen +5333=Die Lizenz erlaubt keine NC-Generierung +5340=Schätzungen +5341=Gesamtzeit +5342=Gesamtlänge +5343=Details +5344=Schätzungsdetails +// Draw Option +5351=Eigenschaften +5352=Neues Teil +5353=Neue Ebene +5354=Farbe +5355=Zeichnungsparameter +5356=Auswählen +5357=Abwählen +5358=Name +5359=Info +5360=Umzug +5361=Kopieren +5362=Löschen +5363=Speichern +5364=Anzeigen +5365=Ok +5366=Löschen Bestätigen +5367=Werkstück, möchten Sie es löschen? +// Operation +5401=Operationen +5402=Betriebsparameter +5403=Bearbeitung anwenden +5404=Neue Bear +5405=Neue Disp +5406=Löschen +5407=Allgemein +5408=Nach oben +5409=Nach unten bewegen +5410=Aktualisieren +5411=Update erfolgreich abgeschlossen +5412=Neue Bearbeitungen +5413=Werkzeugvorschau +5414=Weiter +5415=Zurück +5416=Duplizieren +5417=Nach Db kopieren +5418=Bearbeitungsname in Db +5419=Das Hinzufügen der Bearbeitung ist fehlgeschlagen +5420=Umbenennen +5421=Name kann nicht mit "Disp" beginnen +5422=Name bereits verwendet. +5423=Die Bearbeitung kann aus folgenden Gründen nicht durchgeführt werden: +// Disposition +5431=Ok +5432= +5433=Neu +5434=Entfernen +5435=Länge +5436=Breite +5437=Höhe +5438=Position +// Disposition Errors +5461=SCRIPT EXECUTION ERROR +5462=Fehler beim Ausführen des automatischen Dispositionsskripts +5463=Fehler beim Ausführen des Bearbeitungs-Init-Skripts +5464=Fehler beim Ausführen des Bearbeitungs-Exit-Skripts +// Mach Group +5501=Möchten Sie die Bearbeitungsgruppe wirklich zurücksetzen? +5502=Möchten Sie die Bearbeitungsgruppe wirklich löschen? +5551=Es gibt keine Bearbeitungsgruppen:
Wählen Sie die einzufügenden Teile aus und
wiederholen Sie den Befehl, um die erste zu erstellen +5552=Möchten Sie eine neue Bearbeitungsgruppe
mit den ausgewählten Teilen erstellen? +// Tools Db Page +6001=Bohrer +6002=Messer +6003=Fräser +6004=Mortise +6005=Compo +6006=Langer Bohrer +6007=Flachsäge +6008=Keine Spitzenmühle +6009=Meissel +6010=WaterJet +6051=Entschädigung +6052=Beenden +6053=Typ +6054=Kühlmittel +6055=Eckradius +6056=Durchmesser +6057=Gesamtdurchmesser +6058=Vorschub +6059=Vorschub beenden +6060=Vorschub starten +6061=Kopfvorschub +6062=Länge +6063=Gesamtlänge +6064=Scharf +6065=Längsversatz +6066=Radialversatz +6067=Drehung +6068=Seitenwinkel +6069=Maximale Drehung +6070=Dick +6071=Maximale Absorption +6072=Min. Vorschub +6073=Zeichnen +6074=Kopf +6075=Vorname +6076=Notizen +6077=Position des Werk +6078=Position +6079=Distance +6080=???Overtable +// Tools Errors +6100=Geändertes Werkzeug speichern? +6101=SPEICHERN +6102=Datei muss .nge sein +6103=Datei existiert nicht oder ist kein Nge-Typ +6104=ToolMaker existiert für diese Art von Werkzeug nicht +6105=Unmögliches Werkzeug zum Erstellen mit diesem Parameter +6106=MaxMat-Wert muss größer als 0 sein +6107=MaxMat-Wert muss kleiner als Len sein +6108=Dicker Wert muss größer als 0 sein +6109=Diam-Wert muss größer als 0 sein +6110=Len-Wert muss größer als 0 sein +6111=Der Geschwindigkeitswert muss kleiner als MaxSpeed ​​sein +6112=Ungültiger Name +6113=Der Längenwert muss kleiner als die Gesamtlänge sein +6114=Der Längenwert muss größer als das maximale Material sein +6115=Gesamtlänge muss größer als 0 sein +6116=Gesamtlänge muss größer als Länge sein +6117=Max. Material darf weniger als 1/3 Durchmesser haben +6118=Der Durchmesser muss kleiner als der Gesamtdurchmesser sein +6119=Durchmesser muss größer sein als das 3-fache des maximalen Materials +6120=Gesamtdurchmesser muss größer als 0 sein +6121=Länge mit Werkzeughalter zu klein +6122=Möchten Sie wirklich löschen? +6123=? +6124=LÖSCHEN +6125=SetUp-Konfigurationsdatei nicht gefunden! +6126=Fehler +6127=Kopfwert muss eingestellt sein +6128=Ausgangswert muss eingestellt sein +6129=Ungültiges Werkzeug, korrigieren oder löschen Sie es, bevor Sie Werkzeug Db beenden. +6130=Unmögliches Neuladen der Tool-Datenbank. Wenn sich das Computerverzeichnis auf einem Server befindet, überprüfen Sie, ob die Verbindung aktiv ist. +6131=Dicker Wert muss sich von 0 unterscheiden +6132=Der Seitenwinkelwert muss kleiner als 90 sein +6133=Der Seitenwinkelwert muss größer als -90 sein +6134=Die Gesamtlänge muss größer als Länge + Dicke sein +6135=Eckradiuswert ist zu groß +6136=Dicker Wert ist zu klein für den Einfügeradius +6137=Der berechnete Durchmesser muss kleiner als der Gesamtdurchmesser sein +6138=Der berechnete Durchmesser ist kleiner als 0 +6139=Der berechnete Durchmesser ist kleiner oder gleich 0 +6140=MaxMat-Wert muss größer als der Eckenradius sein +6141=Berechneter MaxMat muss> = 0 sein +6142=Der Eckenradius darf die Hälfte der Dicke nicht überschreiten +6143=Werkzeug speichern +6144=Werkzeug modifiziert! Alle Werkzeuge müssen gespeichert werden, bevor Aktivierungen geändert werden. Werkzeug speichern {0}? +6145=Position bereits besetzt! +6146=Position nicht definiert! +// Machinings Db Page +6201=Bohren +6202=Schnitt +6203=Fräsen +6204=Pocketing +6205=Mortising +6206=Sawroughing +6207=Sawfinishing +6208=Gen Machining +6209=Chiseling +6210=Surface Roughing +6211=Surface Finishing +6212=WaterJet +6251=Invert +6252=Leave Tab +6253=Type +6254=Work Side +6255=Head Side +6256=Lead In +6257=Link +6258=Lead Out +6259=Curve Use +6260=Step Type +6261=Sub Type +6262=Lead Link Type +6263=Speed +6264=Feed +6265=Start Feed +6266=End Feed +6267=Tip Feed +6268=Radial Offset +6269=Longitudinal Offset +6270=Depth +6271=Side Angle +6272=Approximation +6273=Start Safety Length +6274=Start Slow Length +6275=End Slow Length +6276=Throu Add Length +6277=Absenkung +6278=Return Position +6279=Length +6280=Distance +6281=Height +6282=Angle +6283=L.In Tangent Distance +6284=L.In Perp. Distance +6285=L.In Elevation +6286=L.In Comp. Length +6287=L.Out Tangent Distance +6288=L.Out Perp. Distance +6289=L.Out Elevation +6290=L.Out Comp. Length +6291=Start Add. Length +6292=End Add. Length +6293=Step External Arc +6294=Step Internal Arc +6295=Side Step +6296=Vertical Feed +6297=Name +6298=Tool +6299=Depth +6300=Notes +6301=Overlap +6302=Offset +6303=Sub Type +6304=SCC +6305=None +6306=Standard +6307=Opposite +6308=AuxDir X+ +6309=AuxDir X- +6310=AuxDir Y+ +6311=AuxDir Y- +6312=AuxDir Z+ +6313=AuxDir Z- +6314=Nearest AuxDir +6315=Farthest AuxDir +6320=Center +6321=Left +6322=Right +6323=Extend +6324=Standard +6325=Strict +6326=Out +6327=Extend Central +6328=Extend Out +6329=None +6330=Linear +6331=Tangent +6332=Glide +6333=Helix +6334=Extend Prev +6335=Extend Next +6336=Extend Both +6337=As Lead In +6338=Skip +6339=Approx +6340=Convex +6341=Keep +6342=ZigZag +6343=Oneway +6344=Spiral +6345=To And From +6346=Along +6347=Across +6348=Spiral In +6349=Spiral Out +6350=Advanced +6351=Invert tool direction +6352=Face machining +6353=Not defined +6354= Parallel +6355= Orthogonal +6356= Orthog. Up +6357=Down +6358=Top +6359=Front +6360=Back +6361=Left +6362=Right +6363=Contour +6364=Suggested Angles +6365=Blocked Axis +6366=Max count +6367=Min count +// Machining errors +6370=Save the modified machining? +6371=SAVE +6372=Invalid name +6373=Characters \ / : * ? " < > | are not allowed +6374=Are you sure you want to delete +6375=? +6376=DELETE +6377=Impossible reloading Machining database. If the machine dir is on a server, verify the connection is active. +6378=Oscillation +6379=Amplitude +6380=Ramp Length +6381=Flat Length +// Machining Option Page +6401=Sicherheit Z. +6402=Geteilte Bögen +6403=Niemals +6404=Gen-Ebene +6405=Keine XY-Ebene +6406=Immer +6407=Standardeinstellung +6408=Boden Aggregat Sicherheit Z +6409=Bohrungstreibung +// SetUp Window +6451=SetUp +6452=Apply +6453=Save +6454=Retrieves +6455=Auto +6456=Apply current setup before exit? +6457=???New +// SetUp Errors +6471=Error +6472=Warning +6473=Can't find tool +6474=in Tool Database. +6475=The tool's default position is not valid. +6476=Tools not setup because their default position is alredy occupied: +6477=SetUp configuration file doesn't exist! +6478=SetUp configuration use a head that doesn't exist on the machine! +6479=Error loading default setup +// Option Page +6501=Current language +6502=The new language become the current one from the next software run. +6503=Curves +6504=Surfaces +6505=Curves & Surfaces +6506=Selecting geometry +6507=New machining is the last one +6508=Use disposition script +6509=Measure Unit +6510=View top color +6511=View bottom color +6512=Default color +6513=Geometric tolerance +6514=Generic +6515=CAD +6516=CAM +6517=Grid color +6518=Smoothed surfaces +6519=Import +6520=DXF +6521=STL +6522=Images +6523=Export +6524=Image +6525=Width (pixel) +6526=Height (pixel) +6527=Update Machine +6528="{0}" machine already exists,
what do you want to do ? +6529=File {0} does not contain a machine. +6530=The machine "{0}" has been successfully updated. +6531=Replace +6532=Update +6533=Cancel +6534=Warning +6535=The update of the "{0}" machine failed. +6536=Thick lines +6537=???Extra line length +6538=???Arrow length +6539=???Text distance +6540=???Unit measure +6541=???Decimal +6542=???Font +6543=???Text height +6544=???Dimension +6545=???Current unit +6546=???Other +6547=???Unit of measure +6548=???Scale factor +6549=???Export Current Machine +6550=???Select the folder where you want to save the machine +6551=???The exportation of the "{0}" machine failed. +6552=???The machine "{0}" has been successfully exported. +6553=???Update Licence +// Heads +6601=Vertical +6602=Horizontal +6603=2 exit aggr. +6604=3 exit aggr. +6605=4 exit aggr. +6606=3 axis head +6607=4 axis head +6608=5 Achsen Kopf +6609=Shuttle 1 +6610=Shuttle 2 +6611=Carousel +6612=Gang drill +6613=Multi chisel +6614=Bottom aggr. +6615=5 Achs Säge +6616=Kettensäge +6617=1 exit aggr. +6618=Probe head +6619=Floating 360deg +6620=???2nd 5 axis head +6621=???Horizontal drill +6622=???Mortiser +6623=???2nd 5 axis saw +6624=???1 exit tilt. aggr. +6625=???Extruder +6799= +// StatusBar +6801=Machines dir not found. EgtCAM5 wil be run in CAD-ONLY mode. +// Doors +8001=Create new MTable +8002=Save MTable +8003=Save MTable As +8004=Delete MTable +8005=Save MTable file +8006=Are you sure to delete this MTable? +8007=Save the modified MTable? +8008=Active Machines List +8009=Machine Name +8010=Nc Generate +8011=Make Raw +8012=On +8013=Geometry Name +8014=Operation +8015=MId +8016=Shift +8017=Machining Type +8018=Machining 1 +8019=Machining 2 +8020=Machining 3 +8021=Add Machine +8022=Remove Machine +8023=Add Machining +8024=Remove Machining +8025=CURR +8026=Set active MTable +8027=GId +8028=Property +8029=Machining +8030=Join +// Door errors +8101=Error +8102=Error running Ddf file +8103=Warning +8104=MTable dir path not found +8105=MTable dir not exist +8106=Missing configuration files in MTable dir +8107=Unknown error +8108=This MTable is currently the active one. +8109=You can't delete it. +8110=Are you sure you want to delete the selected machining? +8111=DELETE +8112=Are you sure you want to delete the selected machine? +8113=Can't find {0} machine dir. If the machine dir is on a server, verify the connection is active. +8114=Try to reload the machine? +8115=Can't find {0} dir. If the Doors dir is on a server, verify the connection is active. +8116=Try to reload Doors dir? +8117=Execution error (see log file) +// GunStock +8201=New Part +8202=Gunstock new part +8203=Modify Part +8204=Gunstock modify part +8205=Gunstock parameters +8206=File name +8207=Description +8208=Ok +8209=Cancel +8210=must have a value. +8211=The value has to be between +8212=and +8213=Rawpart dimensions +// GunStock errors +8251=Error +8252=Error running Gunstock environment +8253=Error reading model file +8254=Error writing part file +// ----- Beams & Walls ----- +9000=Trägerbearbeitungstabellen +9001=Ein +9002=Name +9003=Typ +9004=Hinzufügen +9005=Löschen +9006=Speichern +9007=Änderungen speichern? +9008=Fehler +9009=Beam Machining Editor kann nicht geöffnet werden.
Konfigurationsdateien können nicht gefunden werden. +9010=Wandbearbeitungstische +9011=Wandbearbeitungseditor kann nicht geöffnet werden.
Konfigurationsdateien können nicht gefunden werden. +// ----- Fehler ----- +10001=Fehler +10002=Fehler bei neuer Datei +10003=Fehler beim Öffnen der Datei +10004=Fehler beim Speichern der Datei +10005=Dateityp unbekannt +10006=Fehler beim Importieren der Datei +10007=Fehler beim Export der Datei +10008=Fehler beim Laden oder Erstellen einer Bearbeitungsgruppe +10009=Fehlende Datei +// fehlendes Schlüsselfenster +10101=Fehler! +10102=Fehlender Schutzschlüssel. +10103=Dongle einlegen und das Programm neu starten. +10104=Ok +10105=Programm ohne Lizenz. +10106=Lizenz laden und das Programm neu starten. +10107=???Run GetMachineId and send results to supplier. +// Numerische virtuelle Tastatur +10201=Falscher Expression +// ----- MessageBox ----- +15001=Error +15002=Warning +15003=Information +15010=Unknown error +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Falscher Expression +// EgtCalculatorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Canc +20043=JA +20044=NEIN +// ----- EgtWPFLib5 ----- +// EgtFileDialog +30001=???Save +30002=???Cancel +30003=???alredy exists. +30004=???Do you want to replace it? +30005=???File name: +30006=???Open +30007=???ERROR +30008=???Name can't be empty! +30009=???WARNING +30010=???File Name +30011=???Folder Name +// Top CommandBar +30501=???New +30502=???Open +30503=???Save +30504=???Save as +30505=???Insert +30506=???Import +30507=???Export +30508=???Exec +30509=???Options +30510=???Can't find support address. +30511=???Save current file before sending feedback? +30512=???Send a feedback to {0} with the {1} directory attached. +30513=???Feedback +30514=???Feedback mail ready. +// Grid View Panel +30801=???Wireframe +30802=???Hidden Lines +30803=???Shading +30804=???Zoom All +30805=???Zoom In +30806=???Zoom Out +30807=???Top View +30808=???Front View +30809=???Left View +30810=???Back View +30811=???Right View +30812=???SW Isometric View +30813=???SE Isometric View +30814=???NE Isometric View +30815=???NW Isometric View +30816=???Show Curve Direction +30817=???Analyze +30818=???Distance +30819=???Top Grid +30820=???Front Grid +30821=???Right Grid +30822=???Back Grid +30823=???Left Grid +30824=???Bottom Grid +30825=???Grid From View +30826=???Grid Elevation +30827=???Grid Origin +30828=???Grid Rotation +30829=???Grid From 3 Points +30830=???Grid Perpendicular to Curve +30831=???Grid From Object +30832=???View From Grid +// MachGroupPanel +30901=???New Mach Group +30902=???Name: +30903=???Machine: +// ToolDbWindow +31001=Bohrer +31002=Sägeblatt +31003=Fräse +31004=Mortiser +31005=???Compo +31006=???Long drill +31007=???Flat saw +31008=???No tip mill +31009=???Chisel +31010=???Waterjet +31051=???Compensation +31052=???Exit +31053=???Type +31054=???Coolant +31055=???Corner Radius +31056=???Diameter +31057=???Total Diameter +31058=???Feed +31059=???End Feed +31060=???Start Feed +31061=Kopfvorschub +31062=???Length +31063=???Total Length +31064=???Max Material +31065=???Longitudinal Offset +31066=???Radial Offset +31067=???Speed +31068=???Side Angle +31069=???Max Speed +31070=???Thick +31071=???Max Absorption +31072=???Min Feed +31073=???Draw +31074=???Head +31075=???Name +31076=???Notes +31077=???Tool Changer Position +31078=???Position +31079=???Drilling +31080=???Cutting edge +// ToolDb Errors +31100=Geändertes Werkzeug speichern? +31101=SPEICHERN +31102=Datei muss .nge sein +31103=Datei existiert nicht oder ist kein Nge-Typ +31104=ToolMaker existiert für diese Art von Werkzeug nicht +31105=Unmögliches Werkzeug zum Erstellen mit diesem Parameter +31106=Fräserwert muss größer als 0 sein +31107=Der Fräserwert muss kleiner als Len sein +31108=Dicker Wert muss größer als 0 sein +31109=Durchmesserwert muss größer als 0 sein +31110=Längenwert muss größer als 0 sein +31111=Der Drehung muss kleiner als Maximale Drehung sein +31112=Ungültiger Name +31113=Der Längenwert muss kleiner als die Gesamtlänge sein +31114=Der Längenwert muss größer als das maximale Material sein +31115=Gesamtlänge muss größer als 0 sein +31116=Gesamtlänge muss größer als Länge sein +31117=Scharf muss kleiner als {0} sein +31118=Der Durchmesser muss kleiner als der Gesamtdurchmesser sein +31119=Durchmesser muss größer sein als das 3-fache des maximalen Materials +31120=Gesamtdurchmesser muss größer als 0 sein +31121=Länge mit Werkzeughalter zu klein +31122=Möchten Sie wirklich löschen? +31123=???? +31124=LÖSCHEN +31125=SetUp-Konfigurationsdatei nicht gefunden! +31126=Fehler +31127=Kopfwert muss eingestellt sein +31128=Ausgangswert muss eingestellt sein +31129=Ungültiges Werkzeug, korrigieren oder löschen Sie es, bevor Sie das Werkzeug Db beenden. +31130=Unmögliches Neuladen der Tool-Datenbank. Wenn sich das Computerverzeichnis auf einem Server befindet, überprüfen Sie, ob die Verbindung aktiv ist. +31131=Dicker Wert muss sich von 0 unterscheiden +31132=Der Seitenwinkelwert muss kleiner als 90 sein +31133=Der Seitenwinkelwert muss größer als -90 sein +31134=Die Gesamtlänge muss größer als Länge + Dicke sein +31135=Eckradiuswert ist zu groß +31136=Dicker Wert ist zu klein für Einfügeradius +31137=Der berechnete Durchmesser muss kleiner als der Gesamtdurchmesser sein +31138=Der berechnete Durchmesser ist kleiner als 0 +31139=Der berechnete Durchmesser ist kleiner oder gleich 0 +31140=Der MaxMat-Wert muss größer als der Eckenradius sein +31141=Berechneter MaxMat muss> = als 0 sein +31142=Schneide muss größer als 0 sein +31143=Die Schneide muss kleiner als Len sein +// ImportExportToolWindow +31161=???Import +31162=???Export +31163=???Tools +31164=???Tool already existing in DB. Overwrite? +31165=???Tool will be imported with the name followed by "_imp" +31166=???The following Tools have been imported succesfully: +31167=Reset +// MachiningDbWindow +31201=Bohren +31202=Sägen +31203=Fräsen +31204=Einstecken +31205=Einsteckschloss +31206=Sägen +31207=Sägen +31208=Gen Machining +31209=Meißeln +31210=Wasserstrahl +31211=???Surffinishing +31251=Invertieren +31252=Tab verlassen +31253=Typ +31254=Arbeitsseite +31255=Kopfseite +31256=Einführen +31257=Link +31258=Herausführen +31259=Kurvenverwendung +31260=Schritttyp +31261=Untertyp +31262=Lead Link-Typ +31263=Drehung +31264=Vorschub +31265=Vorschub starten +31266=Vorschub beenden +31267=Kopfvorschub +31268=Radialversatz +31269=Längsversatz +31270=Tiefe +31271=Seitenwinkel +31272=Annäherung +31273=Sicherheitslänge starten +31274=Verlang. Anfängliche +31275=Verlang. beenden +31276=Länge hinzufügen +31277=Absenkung +31278=Rücklaufposition +31279=Länge +31280=Höhe +31281=Winkel +31282=Entfernung +31283=Tangentenabstand +31284=Perp. Entfernung +31285=Höhe +31286=Comp. Länge +31287=Min. Anzahl +31288=Max. Anzahl +31291=zusätzliche Länge +31293=Externer Schrittbogen +31294=Interner Schrittbogen +31295=Seitenstufe +31296=Vertikaler Vorschub +31297=Vorname +31298=Werkzeug +31299=Tiefe +31300=Notizen +31301=Überlappung +31302=Versatz +31303=Untertyp +31304=SCC +31305=Keine +31306=Standard +31307=Gegenüber +31308=AuxDir X + +31309=AuxDir X- +31310=AuxDir Y + +31311=AuxDir Y- +31312=AuxDir Z + +31313=AuxDir Z- +31314=Nächster AuxDir +31315=Weiter AuxDir +31320=Mitte +31321=Links +31322=Richtig +31323=Erweitern +31324=Standard +31325=Streng +31326=Aus +31327=Central erweitern +31328=Ausfahren +31329=Keine +31330=linear +31331=Tangente +31332=Gleiten +31333=Helix +31334=Erweitern +31335=Als nächstes erweitern +31336=Beide erweitern +31337=Als Einführen +31338=Überspringen +31339=Approx +31340=konvex +31341=Behalten +31342=Zickzack +31343=Einfahrt +31344=Spirale +31345=Von und Von +31346=Mit +31347=Über +31348=Spiral In +31349=Spiral Out +31350=Erweitert +31351=Werkzeug umkehren +31352=Planbearbeitung +31353=Nicht definiert +31354=Parallel +31355=Orthogonal +31356=Orthog. Oben +31357=Unten +31358=Oben +31359=Front +31360=Zurück +31361=Links +31362=Richtig +31363=Kontur +31364=Vorgeschlagene Winkel +31365=Blockierte Achse +31366=Letzter Rückwärts-Feed +31367=Rückwärtsschritt +31368=Kippstufe +31369=GeneigtRück. Schritt +31370=Vorwärtswinkel +31371=Prüfen +31372=Min dist. Punkte +31373=Max dist. Punkte +31374=Extern +31375=Intern +31376=Verlangsamung len. +31377=Verlangsamung% +31378=Blei im Loch +31379=Radius +31380=LP dreht sich +31381=HP dreht sich +31382=Schwingung +31383=Amplitude +31384=Rampenlänge +31385=Flache Länge +31386=Allgemein +31387=Erweitert +31388=Tang+Perp +31389=Perp+Tang +// MachiningTreeView +31391=Standard +31392=Verlangsamung +31393=Schleife +31394=Aktivieren +31395=Länge hinzufügen +31396=Start +31397=Ende +31398=???System notes +31399=???Epicycles radius +31400=???Epicycles distance +// MachiningDb Errors +31401=???Save the modified machining? +31402=???SAVE +31403=???Invalid name +31404=???Characters \ / : * ? " < > | are not allowed +31405=???Are you sure you want to delete +31406=???? +31407=???DELETE +31408=???Impossible reloading Machining database. If the machine dir is on a server, verify the connection is active. +31409=???Machine material not recognized +31410=???Invalid machining, correct or delete it before exiting. +31411=???Length must be positive +31412=???Distance must be positive +31413=???Height must be positive +31414=???Angle must be between {0}° and {1}° +31415=???Max count must be null or positive +31416=???Max count must be equal or greater than Min +31417=???Min count must be null or positive +31418=???Min count must be equal or less than Max +31419=???Enabling {0} will disable {1}. Continue? +// ImportExportMachiningWindow +31450=???Import +31451=???Export +31452=???Machinings +31453=???Machining already existing in DB. Overwrite? +31454=???Machining will be imported with the name followed by "_imp" +31455=???The following Machinings have been imported succesfully: +31456=???Reset +// SetUp Window +31501=???SetUp +31502=???Apply +31503=???Archive +31504=???Retrieves +31505=???Auto +31506=???Apply current setup before exit? +// SetUp Errors +31551=???Error +31552=???Warning +31553=???Can't find tool +31554=???in Tool Database. +31555=???The tool's default position is not valid. +31556=???Tools not setup because their default position is alredy occupied: +31557=???SetUp configuration file doesn't exist! +31558=???SetUp configuration use a head that doesn't exist on the machine! +31559=???Error loading default setup +// Simulation +31601=???Complete simulation +31602=???Outstroke +31603=???Tool direction unreachable +31604=???Error +31605=???ERROR +31606=???Error in generation! +31607=???Simulation +31608=???One step at a time +31609=???Play/Pause +31610=???Stop/Home +31611=???Pause +31612=???Stopped simulation +31613=???Can't exit now. Stop the Simulation or wait until the end of it! +31614=???WARNING +31615=???Estimation file missing +31616=???Estimation details +//MachiningDbWindow/ToolDbWindow buttons +31701=Neu +31702=Speichern +31703=Entfernen +31704=???Edit +//Db Waterjet +31751=???Waterjet Db +31752=???Thickness +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=???Do you want to save edits? +// ----- EgtDOORCreator ----- +//General +50001=???Width +50002=???Height +50003=???Thickness +50004=???Swing +50005=???Lockedge +50006=???Hingeedge +50007=???Top +50008=???Bottom +50009=???Type +50010=???Corner +50011=???Extension +50012=???Side +50013=???Offset wide side +50014=???Back set +50015=???Top to center application +50016=???Bottom rail +50017=???Lock stile +50018=???Offset from center +50019=???Point to pocket +50020=???Pocket length +50021=???Pocket offset narrow side +50022=???Point to arm +50023=???Arm length +50024=???CenterHung +50025=???Offset +50026=???Offset intermediate +50027=???Radius +50028=???Top rail +50029=???Position +50030=???Lenght +50031=???Template +50032=???Up +50033=???Down +50034=???Shape +50035=???Hinge +50036=???Top to top application +50037=???Center from top application +50038=???Center from top lock +50039=???Depth +50040=???General +50041=???Center +50042=???Thru +50043=???Face to center line application +50044=???Edge Type +50045=???Over Material +50046=???Send Feedback +50047=???Weight +50048=???Angle +50049=???Face +50050=???Secure +50051=???Keyway +50052=???Brand +50053=???Folder +50054=???Main Folder +50055=???Jamb +50056=???Light Up +50057=???Light Lock +50058=???Light Bottom +50059=???Light Hinge +50060=???Thickness Head +50061=???Overlap Hinge +50062=???Overlap Lock +50063=???Overlap Top +50064=???Delta T +50065=???Exterior +50066=???Number of Doors +50067=???Jambs and Doors +50068=???Order +50069=???Disposition +50070=???Customer +50071=???Invert bevel on Lock +//Compo Name +50072=???Flush Bolt +50073=???Flush Pull +50074=???Hinge +50075=???Lock +50076=???Louver Cut Out +50077=???Mail Slot +50078=???Over Head +50079=???Pivot +50080=???Roller Latch +50081=???Stops And Closer +50082=???Strike +50083=???Edge pull +50084=???Viewer +50085=???Vision cut out +50086=???Grove +50087=???Rabbet +50088=???Ept +50089=???Raceway +50090=???Face Decoration +//error messages +50100=???Directory not founded +50101=???Error +50102=???Failed reading DDF file. Missing incumbent parameter {0}. +50103=???Failed reading value +50104=???Failed reading DDF file's row +50105=???Row +50106=???Invalid value in +50107=???Empty file. +50108=???You can not add a compo if there is not a dorr! +50109=???Do you want to save this file ({0}) ? +50110=???Question +50111=???Add new door +50112=???Remove door +50113=???New Door +50114=???File name already exists in the current directory ({0}). +50115=???Caution +50116=???Do you want to delete this file ({0}.ddf)? +50117=???Confirm deleting ({0})?. +50118=???Information +50119=???Error in reading messages. There is no match with the number {0}. +50120=???Error reading name {0} in {1}. Expected numeric match. +50121=???Error reading {0} param in {1} compo: do not exist. +50122=???Error in {0} param in {1} compo. +50123=???Error reading {0} param in {1} compo: do not exist list. +50124=???Error reading {0} param in {1} compo: {2}. +50125=???Error in {0} param in {1} compo: do not exist value. +50126=???Delete +50127=???Error in EgtLoadMessages +50128=???You can not save a file if there is not a door! +50129=???Error in Project scene creation +50130=???Error in reading: line {0}. +50131=???Error in reading {0}: line {1}. Expected ':' after the name. +50132=???Error in reading {0}: line {1}. Expected 'template' or 'shape'. +50133=???{0} has not been created. +50134=???Error reading 'Template' in file {0}\{1}. Expetcted name. +50135=???Error reading 'Template' in file {0}\{1}. File {0}\{2} .lua does not exist. +50136=???Error in reading {0}: line {1}. It does not exist in the list of components in file 'Default.ini'. +50137=???Error in reading {0}: line {1}. It is not a member of the list. +50138=???This param will be initialized by dafault. +50139=???Error in reading: line {0}. Expected {1}. +50140=???All missing params will be initialized by dafault. +50141=???Invalid expression in {0}. +50142=???Remove compo +50143=???Invalid expression. +50144=???Warning +50145=???Impossible to create the current door. +50146=???Do you want to open a template? +50147=???Error expression in {0}. {1} does not match anything. +50148=???Invalid value.ù +50149=???Caution: Weight is setted in OptionPage. Do you want to remove? +50150=???Caution: Weight is setted in DDF. Do you want to add? +50151=???{0} is not a member of the current list of EdgeType. Check Bevel in option page. +50152=???Do you want to save this file ({0})? +50153=???Caution. Weight is setted in the current door. Do you want to remove? +50154=???It is the bevel of the current door. Do You want to proced? +50155=???Impossible to create a template if there is not a door! +50156=???Errore nella lettura ddf: la porta non è completa o il ddf è stato separato male da '---'. +50157=???Script Lua ( {0}\{1} )has not been found. +50158=???Bevel {0} can not be acceptable in Jamb. +50159=??? Missing parameter in ddf! +50160=???File {0} in directory {1} has not been found. +50161=???parameter +50162=???In file {0} param 'Default' must be numeric. +50163=???Error in reading General Assembly in DDF +50164=???In General Assembly: +50165=???CompoDir not found : +50166=???Jamb compo does not exist +50167=???Empty Line +50168=???No matching param +50169=???Door disposition has been modify. +50170=???Incongruity between the bevel, it has been resolved by default. +50171=???In file StdTempate.ini is missing numeric param in [Type]. +50172=???File does not exist. +50173=???Definition type is not correct: +50174=???Missing name of the new template! +50175=???The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=???Error in copying: {0} +50177=???Do you want to save the current changes? +50179=???Doors Compo Default.ini not found in {0} . +50180=???Warning : {0} does not exist. +50181=???Error in creating the print image +50182=???Error executing print +50183=???Some Doors could use this hardware, do you want to proceed deleting? +50184=???Impossible to delete Hardware if there is no Hardware selected! +50185=???Impossible to duplicate Hardware if there is no Hardware selected! +50186=???Project must be saved before copying +50187=???Do you want to copy all files ? {0} (No to copy only the current file) +50188=???Export to machine +50189=???Machine Directory not found +50190=???Error in copying: {0} +50191=???Impossible to copy a door if there is not a door! +50192=???Impossible to export to machine a door if there is not a door! +50193=???Impossible to print a door if there is not a door! +50194=???Properties has been deleted +50195=???The current ddf configuration ({0}) is different from the current program configuration ({1}).{2}To load the current ddf configuration you have to restart the program, do you want it? +50196=???Configuration ddf ({0}) does not exist! +50197=???Top Arch has been modified because of configuration. +50198=???Bevel on lock edge would be inverted. +//Option +50200=???Unit measure +50201=???General +50202=???LockEdgeOverMaterial +50203=???HingeEdgeOverMaterial +50204=???TopOverMaterial +50205=???BottomOverMaterial +50206=???Open Window +50207=???Last Project +50208=???Empty +50209=???Option Page +50210=???StartUp +50211=???Unit measure new door. +50212=???Directory Project +50213=???Option Start +50214=???Current Directory +50215=???Edge Type +50216=???Over Material +50217=???Browse +50218=???Close +50219=???Bevel +50220=???Bevel Up +50221=???Bevel Down +50222=???Door positioning in machining +50223=???Save as template +50224=???Matching +50225=???Brand +50226=???File +50227=???Template +50228=???Enable template +50229=???Enable Order +50230=???Open template door. +50231=???Open window order. +50232=???Directory Template +//Scene +50301=???Refresh +50302=???Add New Door +50303=???Remuve Door +50304=???New Project +50305=???Help +50306=???Directory Machine +50307=???Machine +50308=???Door +50309=???Wide Side Down (BU) +50310=???Wide Side Up (BD) +50311=???Resize +50312=???Design +50313=???Save as pdf +//Launcher +50400=???Launcher +50401=???Open New Project +50402=???Open Project +50403=???Open Last Project +50404=???New Project +50405=???New Hardware +50406=???Elevation +50407=???Project +50408=???PO +50409=???Line +50410=???Save +50411=???Print +50412=???Cancel +50413=???Hardware +50414=???Dimensioning +50415=???Duplicate +50416=???Export to machine +50417=???New Template +50418=???Dimension +50419=???New Directory +50420=???Create Assembly +50421=???Reload Directories +50422=???Save As +50423=???Reaload Compo on Jamb +//Error messages +50501=???Error reading {0} param in {1} compo: incomplete definition (look at StdTemplate.ini). +50502=???Error reading {0} param in {1} compo: no matching (look at StdTemplate.ini and GeometryNameList.ini). +50503=???Do you want to save? +50504=???File name contains empty spaces, do you want to rename file deleting empty spaces? +50505=???DDF is not an assembly, there are only: {0}, do you want to save? +50506=???Impossible to find the first door (DO_1)! +50507=???The swing is not a member of the swing list of single door. +50508=???The swing of left door is not a member of the swing list of left door. +50509=???The swing of right door is not a member of the swing list of right door. +50510=???The swing of left door is on the right door and viceverse. +50511=???The swing of left door is not a member of the swing list of left door. +50512=???The swing of right door is not a member of the swing list of right door. +50513=???Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=???The swing are absolutly wrong! +50515=???The first door is not realy the first, check the ddf. +50516=???The current ddf contains {0} jambs. +50517=???The current ddf does not contains doors! +50518=???The current ddf is not an assembly. +50519=???Impossible to open a ddf with no doors. +50520=???The current ddf is an assembly. +50521=???The current ddf is a jamb: {0}. +50522=???The profile {0} is not a member of the {1} profile list. +50523=???Missing profile on {0}. +50524=???{0} file open by another EgtDOORCreator {1}. +50525=???{0} file open by another EgtDOORCreator {1}. +50526=???Directory {0} already exists! Do you want to overwrite it? +50527=???Impossible to overwrite {0} +50528=???Impossible to save the door out of the project! +50530=???Property {0} does not exist in the list of {1}. Look at file "../Compo/Default.ini". +50531=???The current material {0} does not exist in the list of material. Look at file "../Compo/Default.ini". +50532=???Missing list of material at file "../Compo/Default.ini". +50533=???Impossible to load more than one property at time. +50534=???Property {0} does not exist in the list. Look at file "../Compo/Default.ini". +50535=???Impossible to delete a project if there is not a project! +50536=???Do you want to delete entire project? +50537=???Do you want to delete subdirectory {0} ? +50538=???Impossible to vreate a template door if there is not a door! +50539=???Do you want to change project? ( All doors will be deleted!) +50540=???The current ddf is a part of a frame, do you want to save? +50541=???{0} in reading {1}. +50542=???{0}: Directory does not exist! +50543=???It has been renamed file: {0}, {1}. +50544=???It has been created new file: {0}, {1}. +50545=???It has been deleted file: {0}, {1}. +50546=???Enable single door. +50547=???Project +50548=???The new configuration will take effect after restart. +50549=???File {0} exist, but it is not in the correct Directory! +50550=???Every componente on jambs will be relocated, do you want to continue +50551=???The current parameters have been modified: +50552=???Do you want to overwrite? +50553=??? has not been created. +50554=???Parameter {0} is already deinfed in geometry {1}. +50555=???Impossible to save. +50556=???File has nge extension. +50557=???Error in deleting file: {0} +50558=???Impossible to import a different hardware! +50559=???Open File Dialog +50560=???The hardware part has not been generated correctly. +50561=???Directory already exists +50562=???Folder {0} does not exist. Check in OptionPage. +50563=???Compo {0} does not exist. +50564=???In group {0} at paramater {1} does not exist: {2} +50565=???Brand {0} has not been found in HardwareManager. +50566=???Template {0} has not been found in HardwareManager. +50567=???Error in executing EgtCam5. +50568=???Error in definition {0} in file GeometryNameList.ini . +50569=???Error in definition {0} in file StdTemplate.ini . +50570=???Nothing has been selected. +//Added General messages +50701=???Lines +50702=???Rectangle +50703=???None +50704=???Radius +50705=???Angle +50706=???Pos_x +50707=???Top Arc +50708=???Top Angle +50709=???Properties +50710=???Material +50711=???Mach. +50712=???HardwarePart +50713=???Assemby +50714=???Total Dimension +50715=???Depth +50716=???Overlap Bottom +50717=???Thickness Bottom +50718=???Depth Bottom +50719=???Delta Bottom +50720=???GoToAssembly +50721=???New Geometry +50722=???Geometry Name +50723=???Type Hardware +50724=???Parameter +50725=???Part Dimension +50726=???Apply +50727=???Frame +50728=???Refresh Directory +50729=???General +50730=???Report +50731=???Opposite face +// ----- EgtBEAMEditor ------ +60951=???Cut +60952=???Longitudinal Cut +60953=???Double Cut +60954=???Ridge or Valley Cut +60955=???Saw Cut +60956=???Slot +60957=???Front Slot +60958=???Birds Mouth +60959=???Hip or Valley Rafter Notch +60960=???Ridge Lap +60961=???Lap Joint +60962=???Notch/Rabbet +60963=???Block House Half Lap, Stairs Riser Dado +60964=???Seathing Cut +60965=???French Ridge Lap +60966=???Chamfer +60967=???Block House Half Lap +60968=???Block House Front +60969=???Pocket +60970=???Drilling +60971=???Tenon +60972=???Mortise +60973=???Mortise Front +60974=???House +60975=???House Mortise +60976=???Dovetail Tenon +60977=???Dovetail Mortise +60978=???Dovetail Mortise Front +60979=???Marking/Labeling +60980=???Text +60981=???Simple Scarf +60982=???Scarf Joint +60983=???Step Joint +60984=???Step Joint Notch +60985=???Planing +60986=???Profile Front +60987=???Profile Head concave +60988=???Profile Head convex +60989=???Profile Head cambered +60990=???Round Arch +60991=???Profile Head +60992=???Sphere +60993=???Triangle Cut +60994=???Tyrolean Dovetail +60995=???Dovetail +60996=???Free Contour +60997=???Outline +60998=???Aperture +61001=???Distance from beam start to the reference point +61002=???Distance from the reference edge to the reference point +61003=???Distance from the reference side to the reference point (orthogonal) +61004=???Angle between cut edge and reference edge +61005=???Inclination between face and reference side +61008=???Limit of the 2 ends, binary code +61009=???Inclination to the reference side +61010=???Depth: If P11 is zero, then the face of the cut dispreads to the neigbour-sides or opposite-side to referenceside +61011=???Length: If P12 and P04 equal to zero, the processing is performed along the whole component length +61012=???Angle in face at start +61013=???Angle in face at end +61015=???Distance from the reference point to the reference edge +61016=???Angle between the first cutting edge and the reference edge +61017=???Inclination of the first cutting towards the reference side +61018=???Angle between the second cutting edge and the reference edge +61019=???Inclination of the second cutting towards the reference side +61023=???Inclination between the first face and the reference side +61024=???Inclination between the second face and the reference side +61025=???Depth +61027=???Angle in face at reference edge at start +61028=???Angle in face at reference edge at end +61029=???Angle in face in opposite to reference edge at start +61030=???Angle in face in opposite to reference edge at end +61033=???Displacement to the reference side +61036=???Angle to the reference edge in the cut face +61037=???Depth, orthogonal to the reference side +61038=???Length +61041=???Distance to the reference point orthogonal to the reference side P03 = 0: Slot on one of the 4 sides of the component. P03 > 0: Slot on one of the 2 front sides of the component +61042=???Limit of the 6 faces of the slot, binary code +61043=???Angle to the reference edge in the reference side +61045=???Interior angle at reference point +61046=???Interior angle at opposite of reference point +61047=???Addition to P09 +61048=???Depth orthogonal to the reference side +61049=???Length +61050=???Thickness +61051=???Displacement of the entrance edge at reference point +61052=???Displacement of the entrance edge at opposite of reference point +61055=???Distance to the reference point orthogonal to the reference side +61056=???Limit of the 6 faces of the Frotn Slot, binary code +61059=???Angle between the longitudinal axis of the slot and the reference side +61060=???Depth +61061=???Length +61062=???Width +61065=???Location of P09/P10, if P09>0 and P10>0. If P04=-1, then the location must be defined on the machineside +61066=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole. +61067=???Angle to the reference edge in the reference area +61068=???Inclination between face 1 and reference side +61069=???Inclination between face 2 and reference side +61070=???First cut angle of the counterpart. If P09 is zero, the limit face beside face 1 is parallel to component side. +61071=???First cut inclination of the counterpart. If P10 is zero, the limit face beside face 1 is parallel to component side. +61072=???Depth 1 orthogonal to reference side +61073=???Depth 2 orthogonal to reference side +61074=???Grooving depth in the transverse direction of the component. If P13 is zero, then its value must be calculated:P13=WRS-P02 +61075=???Height Counterpart. Zero means: no limit. Measurement orthogonal to face 1 (P07). +61076=???Width Counterpart. Zero means: no limit. Measurement orthogonal to face 2 (P08). +61079=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole +61080=???Angle notch 1 to the reference edge in the reference area +61081=???Angle notch 2 to the opposite reference edge in the reference area +61082=???Inclination between base area of notches and reference side +61083=???Depth orthogonal to reference side +61084=???Width of notch 1. If this value is equal 0, then the notch is not limited. +61085=???Width of notch 2. If this value is equal 0, then the notch is not limited. +61087=???0: Reference point on referene edge. 1: Reference point on the opposite edge +61088=???Angle to the reference edge in the reference side +61089=???Depth of Half Lap +61090=???Width of Half Lap +61091=???Drill hole diameter +61094=???Displacement to the reference side +61095=???Limit of the 6 faces of the lap, binary code +61096=???Angle to the reference edge in the reference side +61098=???Angle between edge and reference side in face +61099=???Angle in the floor face +61100=???Angle between base face and one face of lap +61101=???Distance (orthogonal) from reference side to point below reference point +61102=???Length +61103=???Chamfer angle +61104=???Grooving depth (length of the lapped scarf in transverse direction). If P14 is zero, then its value must be calculated: P14=WRS-P02 +61107=???Limit of the 6 faces of the notch/rabbet, binary code +61108=???Notch/Rabbet depth +61109=???Notch/Rabbet length +61110=???Notch/Rabbet width +61113=???Depth of the Half Lap on the reference side +61114=???Depth of the Half Lap opposite of the reference side +61115=???Length of the Half Lap / Dado +61117=???Depth of Seathing Cut +61118=???Length of Seathing Cut +61120=???0: Reference point on reference edge; 1: Reference point on the opposite edge +61121=???Angle to the reference edge in the reference side +61122=???Drill hole diameter +61124=???Input of edge(s) to be beveled, binary code: Bit 0=edge 1 ; Bit 1=edge 2; Bit 2=edge 3; Bit 3=edge 4. Example: P04=9: edge 1+4; P04=3: edge 1+2 +61125=???Depth +61126=???Length: If P12 is equal to zero, the processing is performed along the whole component length. +61127=???Shape for bevel exit: 0 = orthogonal, 1 = at 45 deg, 2 = round; +61129=???Depth orthogonal to reference side of the lap 2 and 4. If P03 is zero, then its value must be calculated: P03=HRS +61130=???0:all laps are symmetric to each other; 1:lap on reference edge moved to start beam, lap in opposite of reference edge moved to end beam; 2: lap on reference edge moved to end beam, lap in opposite of reference edge moved to start beam; +61131=???P05=1: drilhole for drop rod, P05=0: no drillhole. The machines defines place and direction of the drillhole. +61132=???lap 1: Depth +61133=???lap 1: Length +61134=???lap 2: Depth +61135=???lap 2: Length +61136=???lap 3: Depth +61137=???lap 3: Length +61138=???lap 4: Depth +61139=???lap 4: Length +61140=???Distance from end of arc orthogonal to the reference side +61141=???Radius of arc +61142=???Distance reference point to center of arc +61143=???Which arc (A, B,C or D) is to produced, binary code +61145=???0:only one lap on reference side; 1:one lap on reference side and one on the opposite side +61146=???Angle to the reference edge in the reference side +61147=???Depth at reference point +61148=???Depth opposite to the reference point +61149=???Depth at reference edge +61150=???Length +61153=???Limit of the 6 faces of the pocket, binary code +61154=???Rotation angle around the local z-axis of the cuboid +61155=???Rotation angle around the local y-axis of the cuboid, rotated with P06 +61156=???Rotation angle around the local x-axis of the cuboid, rotated with P06 and P07 +61157=???Internal angle at the reference point +61158=???Depth of reference point orthogonal to reference side +61159=???Length of Half Lap +61160=???Width of Half Lap +61163=???Distance from the reference face to the reference point. P03 = 0:Drilling on one of the 4 sides of the component. P03 <> 0:Drilling on one of the 2 front sides of the component. +61164=???P03 = 0:Angle to the reference edge in the reference side. P03 <> 0:Angle in the front side. +61165=???Inclination between drilling and reference side. P03 = 0: Inclination between drilling and reference side. P03 > 0: Inclination between drilling and front side +61166=???Depth, orthogonal to reference side or front side. +61167=???Drill hole diameter +61170=???Rounding +61171=???Chamfer +61174=???Angle between axis of the tenon and reference side +61175=???Radius for P04=4 +61176=???Tenon height +61177=???Tenon width +61178=???Margin on the reference side +61179=???Margin opposite the reference side +61182=???Displacement to the reference side +61183=???Rounding +61184=???Angle between axis and reference edge +61185=???Inclination between strut and reference side +61186=???Inclination of hole side walls towards reference side +61187=???Radius for P04=4 +61188=???Mortise depth +61189=???Mortise width +61190=???Height of strut +61191=???Margin on the reference point +61192=???Margin opposite the reference point +61193=???Inclination of hole front side towards reference side +61196=???Rounding +61199=???Angle between axis of the tenon and reference side +61200=???Radius for P04=4 +61201=???Mortise depth +61202=???Mortise width +61203=???Margin on the reference side +61204=???Margin opposite the reference side +61205=???Processident of the associated tenon or dovetail tenon +61206=???Processident of the associated mortise or dovetail mortise +61209=???0:with rounding at the bottom; 1:without rounding, unbounded +61210=???Angle between edge and reference edge +61212=???Angle between axis of the tenon and reference side +61213=???Middle flattening +61214=???Angle of cone +61215=???Tenon height +61216=???Diameter of the curve: If P12 < 0, then the radius must be defined on the machineside. +61217=???Margin on the reference side +61218=???Margin opposite the reference side +61221=???Displacement to the reference side +61222=???0:with rounding at the bottom; 1:without rounding, unbounded +61223=???0:with elongation; 1:with pocket +61224=???Angle between axis and reference edge +61225=???Inclination between strut and reference side +61226=???Middle flattening +61227=???Angle of cone +61228=???Mortise depth +61229=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61230=???Height of strut +61231=???Margin on the reference point +61232=???Margin opposite the reference point +61235=???Displacement to the front side +61236=???0=with rounding at the bottom; 1=without rounding, unbounded +61237=???0=with elongation; 1=with pocket +61240=???Angle between axis of the tenon and reference side +61241=???Middle flattening +61242=???Angle of cone +61243=???Mortise depth +61244=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61245=???Margin on the reference side +61246=???Margin opposite the reference side +61249=???Position and alignment of the text. P04 = 0 if there is no text. +61250=???Angle between axis and reference edge. If P06 equals 180°, then a horizontal line is defined, P12 defines the length of the line. +61251=???Interior angle. If P07 equals zero, 2 single markings have to be produced. +61252=???Width of quadrangle. If P11 equals zero, there is only a single marking. +61253=???Height of quadrangle. If P12 equals zero, marking is limited by the edge opposite to the reference edge. +61254=???Height of text. If P13 equals zero, the machine determines the text height. +61255=???Text (String max. 256 characters) +61258=???Angle between axis and reference edge +61259=???Alignment vertical. 0 = bottom, 1=middle, 2=top +61260=???Alignment horizontal. 0 = left, 1=middle, 2=right +61261=???Alignment in case of a multiline text. 0 = left-aligned, 1=centered, 2=right-aligned. A new line must be defined with this 2 letters: \n +61262=???Letters standard or horizontal placed. 0 = standard, 1=letters horizontal placed +61263=???Height of text. If P13 equals zero, the machine determines the text height. +61266=???Depth at the reference side +61267=???Depth at the opposite of reference side +61268=???Length of the overlap +61269=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61270=???Drilling 2 diameter. Placed at 2/3 P13 +61272=???Angle of inclination of the lapped scarf base +61273=???Shape of the lapped scarf or classic data identification: 1:when cutting orthogonal to reference side; -1:when cutting orthogonal to base side; 0:classic definition, P10 and P12 are not used +61274=???Length of the lapped scarf base +61275=???Depth of the lapped scarf base +61276=???Depth of the lapped scarf base orthogonal to reference side +61277=???Length +61278=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61279=???Drilling 2 diameter. Placed at 2/3 P13 +61281=???Type of heel notch:0=normal; 1=tapered +61282=???Inclination strut +61283=???Depth step joint +61284=???Depth heel notch +61285=???Height tenon. Which implementation (A or B) is used depends on the machine +61286=???Width tenon +61289=???Type of heel notch: 0=normal; 1=tapered +61290=???Inclination between strut and reference side +61291=???Width of the notch +61292=???Depth step joint +61293=???Depth heel notch +61294=???Height of strut +61295=???Depth of mortise. Which implementation (A or B) is used depends on the machine +61296=???Width of mortise +61298=???Specification of side(s) to be planed; binary coded +61299=???Planing depth +61300=???Length of the area to be planed +61303=???Rotation angle of the first curve of the profile +61304=???Rotation angle of the profile towards the reference edge +61305=???Offset angle +61306=???Radius of the first curve +61307=???Radius of the second curve +61309=???Radius +61310=???Depth +61311=???Displacement +61312=???Depth +61313=???Displacement +61315=???Radius +61316=???Depth +61317=???Displacement +61318=???Depth +61319=???Displacement +61321=???Profile length +61322=???Depth at the reference point +61323=???Maximum depth of profile +61324=???Minimum depth of profile +61325=???Depth at the profile end +61326=???Premill: 0=round; 1=angular +61328=???Depth of the arch segment +61329=???Length of the arch segment +61331=???Type of arc (convex, concave), binary coded. See table below. +61332=???Length of lap 1 +61333=???Depth of lap 1 +61334=???Displacement arc 1 +61335=???Horizontal length arc 1 +61336=???Vertical length arc 1 +61337=???Camber arc 2 +61338=???Length of lap 2 +61339=???Depth of lap 2 +61340=???Displacement arc 2 +61341=???Horizontal length arc 2 +61342=???Vertical length arc 2 +61343=???Camber arc 2 +61344=???Length of lap 3 +61345=???Depth of lap 3 +61348=???Distance from the reference side to the reference point +61349=???Radius +61350=???Start offset +61351=???Length +61354=???Distance from the reference side to the reference point +61355=???Normal vector 1: Length of X-component +61356=???Normal vector 1: Length of Y-component +61357=???Normal vector 1: Length of Z-component +61358=???Normal vector 2: Length of X-component +61359=???Normal vector 2: Length of Y-component +61360=???Normal vector 2: Length of Z-component +61362=???Distance between "inside" an side of part +61363=???Distance orthogonal to the reference side +61364=???0:"inside" at reference edge, 1:"inside" at opposite of reference edge +61365=???0:Without rebate or mitre, -1:With mitre, >0:With rebate +61366=???Angle to the reference edge in the reference side +61367=???Width +61368=???Depth +61369=???Inclination +61370=???Height +61371=???Radius +61372=???Length of tool (part of arc) +61373=???0:Angular corner joint, 1:Straight T-wall connection +61374=???Length +61375=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61377=???Distance between "inside" an side of part +61378=???Distance orthogonal to the reference side +61379=???0:"inside" at reference edge, 1:"inside" at oppostite of reference edge +61380=???0:Without rebate or mitre, -1:with mitre, >0:with rebate +61381=???Inclination +61382=???Depth 1 +61383=???Depth 2 +61384=???0:European Dovetail, 1:American Dovetail +61385=???Length +61386=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61387=???Depth +61388=???Mode: 0=contour only, 1=countersink completely. Only for closed contours. +61389=???Contour type +61390=???Parameter depends on contour type(P13) +61391=???Parameter depends on the contour type(P13) +61400=???Reference point on referene edge +61401=???Reference point on the opposite edge +61402=???Reference point on referene edge +61403=???Reference point on the opposite edge +61404=???orthogonal +61405=???at 45 deg +61406=???round +61407=???all laps are symmetric to each other +61408=???lap on reference edge moved to end beam. lap in opposite of reference edge moved to start beam +61409=???lap on reference edge moved to start beam. lap in opposite of reference edge moved to end beam +61410=???only one lap on reference side +61411=???one lap on reference side and one on the opposite side +61412=???with rounding at the bottom +61413=???without rounding, unbounded +61414=???with elongation +61415=???with pocket +61416=???bottom +61417=???middle +61418=???top +61419=???left +61420=???right +61421=???left-aligned +61422=???centered +61423=???right-aligned +61424=???standard +61425=???letters horizontal placed +61426=???when cutting orthogonal to reference side +61427=???when cutting orthogonal to base side +61428=???classic definition, P10 and P12 are not used +61429=???normal +61430=???tapered +61431=???round +61432=???angular +61433=???"inside" at reference edge +61434=???"inside" at opposite of reference edge +61435=???Angular corner joint +61436=???Straight T-wall connection +61437=???Processing on the reference side and opposite the reference side +61438=???Processing only on the reference side +61439=???Processing only opposite the reference side +61440=???European Dovetail +61441=???American Dovetail +// ----- Custom Parameter (Q) +61451=???Profondità smusso +61452=???0=Automatico; 1=Ciclo longitudinale con lama +61453=???Spessore testimone centrale per ciclo Q02 +61454=???0=Attacco centrato; 1=Attacco interno +61455=???0=Automatico; 1=Lavorazione con fresa di lato +61456=???1=Forza Lama; 0=Automatico +61457=???1=Solo smusso +61458=???0=Automatico; 1=Massima profondità +61459=???0=Automatico; 1=Truciolatore; 2=Truciolatore di lato; 3=Fresa; 4=Fresa di lato +61460=???0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +61461=???0=Automatico; 1=Massimo raggio ammesso su tasche non passanti +61462=???Diametro utensile per Q05 +61463=???Diametro utensile per Q07 +61464=???0=Raggio su spigolo; 1=Foro su spigolo; 2=Spigolo vivo +61465=???Diametro foro quando P05=1 +61466=???0=Automatico; 1=Sgrossatura con lama +61467=???Antischeggia: 0=No; 1=Con lama; 2=Con fresa +61468=???Aumenta dimensioni tasca +61469=???Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico +61470=???0=Automatico; 1=Solo contorno ; 2=Drill or Pocket +61471=???0=Automatico; 1=Lavoro da un lato solo +61472=???Incrementare/decrementare valore P01 per fori nei tenoni +61473=???0=Foratura rompi truciolo; 1=Foratura scarico truciolo +61474=???Profondità smusso quando P05=1 +61475=???Riduzione profondità tenone +61476=???Riduzione larghezza tenone +61477=???Riduzione altezza tenone +61478=???Riduzione profondità tenone +61479=???Ridurre/Allargare sagoma tenone +61480=???Ridurre/Allargare altezza tenone +61481=???aumenta profondità mortasa +61483=???Profondità di lavoro +61484=???Aumenta dimensioni P10 +61485=???0=Automatico; 1=Truciolatore +61486=???Riduzione lunghezza P14 +61487=???Riduzione larghezza P15 +61488=???Sovramateriale finitura +61489=???Numero divisioni ondulazioni dello smusso sulla lunghezza +61490=???1=Disabilita fresatura gradini +61491=???1=Attiva smusso superiore +61492=???1=Smusso superiore con lama +61493=???Spessore legno per supporto lavorazione +61494=???Attiva antischeggia +61495=???Profondità antischeggia +61496=???Massima elevazione (0=Automatico, >10=Manuale) +61497=???0=Automatico; 1=Lama +61498=???0=Automatico; 1=Disabilita controllo lunghezza fresa +61499=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61500=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61501=???0=Automatico 1=Lavorazione con fresa orizzontale se sopra o sotto (disabilita lama) +61502=???0=Automatico 1=Usa truciolatore se sotto +61503=???0=Attacco e Uscita centrati 1=Attacco e Uscita interni +61504=???0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +61505=???0=Default; 1=Machine like LongCut +61506=???0=Default; 1=Machine with mill +// ----- EgtBEAMWALL - BTLParam ----- +61601=???SN +61602=???Abilita +61603=???Descrizione +61604=???L +61605=???W +61606=???H +61607=???Material +61608=???Richiesti +61609=???In produzione +61610=???Prodotti +61611=???Ruotare +61612=???Group +61613=???Unit Time +61614=???Parametro +61615=???Valore +61616=???Minimo +61617=???Massimo +61618=???Single member number +61619=???Assembly number +61620=???Order number +61621=???Designation +61622=???Annotation +61623=???Subgroup/Storey +61624=???Group +61625=???Package +61626=???Material +61627=???Timber grade +61628=???Quality grade +61629=???Count +61630=???Colour +61631=???Transparency +61632=???Planing length +61633=???Start offset +61634=???End offset +61635=???Transformation: Origin +61636=???Transformation: X-axis dir. vect. +61637=???Transformation: Y-axis dir. vect. +61638=???Camber: Reference side +61639=???Camber: P01,P02,P03,P04 +61640=???Part offset: ref. side fix clamp +61641=???Part offset: P11,P12,P13,P14 +61642=???Processing quality +61643=???Recess +61644=???Storey type +61645=???Element number +61646=???Layer +61647=???Module number +61648=???USERATTRIBUTE +61649=???Comment +61650=???Grain direction: X,Y,Z +61651=???Grain direction: Align +61652=???Reference side +61653=???Reference side: Align +61654=???Alignment: Location +61655=???Alignment: Endtype +61656=???Material type: Group +61657=???Material type: Specification +61658=???AUTOMATIC +61659=???VISIBLE +61660=???FAST +61661=???MANUAL +61662=???CEILING +61663=???ROOF +61664=???WALL +61665=???inactiv +61666=???BR +61667=???TR +61668=???BA +61669=???TA +61670=???HC +61671=???VC +61672=???AC +61673=???R +61674=???A +61675=???D +61676=???Batten +61677=???Cladding +61678=???Massive timber +61679=???Membrane +61680=???Gypsum Board +61681=???Gypsum Fibre +61682=???Insulation +61683=???Sheet Component +61684=???Facade Panel +61685=???Profiled Panel +61686=???Plaster +61687=???Reference side 1 +61688=???Reference side 2 +61689=???Reference side 3 +61690=???Reference side 4 +61691=???UID +61692=???Project number +61693=???Project name +61694=???Project part +61695=???GUID +61696=???Listname +61697=???Customer +61698=???Architect +61699=???Editor name +61700=???Delivery date +61701=???Export date +61702=???Export time +61703=???Export release +61704=???Language +61705=???Range +61706=???Computername +61707=???User name +61708=???Path & name of CAD-File +61709=???Path & name of BTL-File +61710=???STANDARD +61711=???EXTENDED +61712=???Vol unit +61713=???Vol tot +61714=???Time unit +61715=???Time tot +61716=???Total parts number +61717=???Total volume +61718=???Total time +61719=???Total estimed time +61720=???Remaining time +61721=???Rawpart counter +61722=???BTL part counter +61723=???Added part counter +61724=???Part in rawpart counter +61725=???Done part counter +61726=???Quantity +61727=???Print PDF +//Ware???house +61751=???Current S +61752=???Current L +61753=???StartOffset +61754=???Kerf +61755=???Offset +61756=???S Parameters +61757=???L Parameters +61758=???New Value: +61759=???W +61760=???L +61761=???Confirm +61762=???Save +61763=???Cancel +61764=???Error +61765=???Input value already present +61766=???Input value not correct +61767=???Input pair already present +61768=???One or more input values not correct +61769=???Attention +61770=???Selected parameter is equivalent to current L/S. Are you sure you want to remove it? +61771=???SectionXMaterial +61772=???Alias +61773=???Values +61774=???Quantity +61775=???Min thickness +61776=???Max thickness +61777=???Increment Max thickness of the last range before adding a new range +// +61801=???Custom +61802=???Default +61803=???L +61804=???T +61805=???Process +61806=???Section time +61807=???Part time +61808=???Name +61809=???PDN +61810=???DO +61811=???X position +61812=???Y position +61813=???Added +61814=???Done +61815=???ID +61816=???Start offset +61817=???% Used +61818=???Waste +61819=???BTL File Name +61820=???List Name +61821=???Export Date +61822=???Creation Date +61823=???Delete +61824=???Face +61825=???Group +61826=???Modify +61827=???Save +61828=???Cancel +61829=???Nesting +61830=???Viewer +61831=???Optimizer +61832=???Configuration +61833=???Optimize +61834=???Update BTL +61835=???Go to optimization +61836=???Filter type +61837=???Search +61838=???Export project +61839=???Import project +61840=???Import BTL +61841=???Copy to Clipboard +61842=???DisplayIndex +61843=???Column name +61844=???CanUserReorder +61845=???CanUserResize +61846=???CanUserSort +61847=???IsReadOnly +61848=???Visible +61849=???Variable Path +61850=???Type +// +61851=???This part modification will cause the removal of the part from {0} raw parts. Do you want to proceed anyway? +61852=???Impossible create feature with this values +61853=???Impossible create part with this values +61854=???Impossible create bar with this values +61855=???Impossible create wall with this values +61856=???Value outside minimum and maximum +61857=???Impossible to insert a quantity inferior to the number of parts already in rawparts! +61858=???Impossible to modify these values +61859=???Error in machine parameter writing +61860=???Save machine parameters modification? +61861=???Save default values modification? +61862=???Changing type second path will be deleted. Do you want to proceed? +61863=???To produce part number reached: +61864=??? from BTL; +61865=??? added. Do you want to add another one? +61866=???Selected part has different section from selected bar. Impossible to add. +61867=???Selected part lenght is more then the selected bar lenght. Impossible to add. +61868=???Selected part has different height from selected wall. Impossibl to add. +61869=???Error in macro file execution! +61870=???Impossible create a Macro without selecting a Feature or with empty name +61871=???File not found! +61872=???Impossibie deleting current project +61873=???Impossibile deleting the project because already linked to an optimization +61874=???Impossibile deleting the project because some parts are already sent to production +61875=???Do you want to save the project modifications? +61876=???Impossible creating a new file! +61877=???Save project modification before continuing? +61878=???Impossible proceding with a new unsaved project! +61879=???Type of current machine is both Beam and Wall. Select the type you want to set the project to: +61880=???Select one of the available machines and/or types. Otherwise cancel the project import. +61881=???The opened project type is not compatible with the current machine type +61882=???Do you want to save the modifications to the DataGrid columns? +61883=???The columnn specified as "{0}" in the "{1}" table in the datagrid columns ini file was not found in the program +61884=???Select the machine you want to associate to the project: +61885=???The machine linked to the opening project cannot be found among the available machines +61886=???Machine +61887=???Impossible creating the inserted rawparts quantity +61888=???How many copies of the rawpart do you want to create? +61889=???Long Drill Area +61890=???Min Rule +61891=???Can't send feedback from Optimizer if there is no open Prod +// +61900=???Change paramter +61901=???Verify +61902=???Simulate +61903=???New raw part +61904=???Add to raw part +61905=???Copy part +61906=???Add part +61907=???Remove part +61908=???Copy feature +61909=???Create macro +61910=???Add feature +61911=???Remove feature +61912=???Produce rawpart +61913=???Produce all rawpart +61914=???Copy rawpart +61915=???Remove rawpart +61916=???Reorder parts +61917=???Move up part +61918=???Move down part +61919=???Remove part +61920=???Warehouse +61921=???Add project to optimization +61922=???Go to project +61923=???Statistics +61924=???Reset +61925=???Show all parts +61926=???Show solid +61927=???Show building +61928=???Verify all +61929=???Can't change machine because the Proj is already linked to a Prod +61930=???Inputs +61931=???Outputs +61932=???Calculate Flip & Rotation +61933=???Unlock Flip +61934=???Unlock Rotation +61935=???Length +61936=???Width +61937=???Offset +61938=???Kerf +61939=???Edit +61940=???Reset +61941=???Choose machine +61942=???BTL file already imported and optimized. Do you want to import it again? +61943=???BTL file already imported. Do you want to overwrite it? +61944=???Shift parts +61945=???Shift direction +61946=???Shift length +61947=???Parts can't be shifted outside the raw part +61948=???The inserted shift value is not valid +61949=???Search & Filter +61950=???Parameter Type +61951=???Parameter Value +61952=???R +61953=???A +61954=???P +61955=???D +61956=???All +61957=???Filtered +61958=???Update +61959=???Append +61960=???Check the parts you would like to add to update BTL +61961=???Change material +61962=???Project material +61963=???Warehouse material +61964=???Standard +61965=???From BTL +61966=???Save +61967=???Do NOT save +61968=???Waiting for optimizer save +61969=???Cancel +// +62500=???Supervisor +62501=???Channel +62502=???OPMode +62503=???Produce All +62504=???Done RawPart +62505=???Reset RawPart +62506=???Delete RawPart +62507=???Print Label +62508=???Done Part +62509=???Resume started processing? +// Loading +63000=???Project opening +63001=???Loading project geometries +63002=???Loading machining groups +63003=???Loading production data +63004=???Optimization opening +63005=???Loading parts +63006=???Loading graphics +63007=???Project saving +63008=???BTL file importing +63009=???Reading BTL file +63010=???Project exporting +63011=???Loading environment +63012=???Saving geometry +63013=???Saving data on Db +63014=???Modifying parameters +63015=???Part viewer opening +63016=???Adding export info +63017=???Exporting... +63018=???Project importing +63019=???Loading project +63020=???Creating imported project +63021=???Modifying materials +// ----- FromLua ----- +65001= +// ----- OmagCUT ----- +// Allgemeines +90001=AKTUELLE BEARBEITUNG +90002=DIREKTER SCHNITT +90003=CAD SCHNITT +90004=PROFIL +90005=MASCHINE +90006=OPTIONEN +// Aktuelle Bearbeitung +90101= +// Direkter Schnitt +90201=Verschiebung +90202=Einzelschnitt +90203=Mehrfache Schnitte +90204=Netz Schnitte +90205=MTH +90206=Kalibrieren +90207=Sägetest +90208=Sägesonde +90209=Schablone einlesen +90210=P1 erwerben +90211=P2 erwerben +90212=Laser +90213=Tiefe +90214=Länge +90215=Richtung +90216=Seitenwinkel +90217=Anzahl +90218=Bemaßung +90219=Zahl X +90220=Maß X +90221=Zahl Y +90222=Bemaßung Y +90223=Spindelseitiger Schnitt +90224=Säge +90225=Unentschieden +90226=Breite +90227=Überschneidung +90228=???Offset +90229=???C Axis Lock +90230=Ausführen +90231=???Polishing +90232=???Saw thickness +90241=Sägenprüfung +90242=Probing läuft ... +90243=Erfolg erfolgreich beendet +90244=Fehler beim Sägen +90245=Neuer Vorlagenname +90246=???Probing canceled by user +90250=Zeile +90251=Bogen +90252=Entfernen +90253=Schließen +90254=Speichern +90255=???Test +90256=???Verifica posizione taglio +90257=???Verifica posizione in corso... +90258=???Single drill +// Cad Schnitte +90301=Simulieren +90302=Ausführen +90303=Neu +90304=Laden +90305=Speichern +90306=Speich unter +90307=Neuer Projektname +90308=CSV +90309=Vein Match +90310=Exportieren +90311=Werkzeug +90312=Bearbeitung +90313=Fotokamera fehlgeschlagen +90314=Fehler bei NC-Programmgenerierung +90315=Fehler bei NC-Programmübertragung +90316=Nicht an das Gerät angeschlossen +90317=NC-Programm übertragen +90318=NC-Programm wird von der Maschine abgelehnt +90319=NC-Programm bereits gesendet, senden? +90320=Unterschiedliche Maschine +90321=Reduziert einige Bearbeitungen, um Störungen zu vermeiden +90322=Fehlende Werkzeuge: +90323=???Background photo taken +90324=???Contour recognition failed +90325=???Error saving statistics +90326=???Confirm restart from phase {0} ? +90327=???New Ruined Parts +90328=???Parts Area : +90329=???To be Produced : +90330=???NC program already sent, new slab ? +// NestPage +90331=Einsetzen +90332=Ablegen +90333=Teil verwerfen +90334=Alles auswählen +90335=Alle abwählen +90336=Rücksetzen +90337=???One or more parts with non-compatible thickness, material or finish +90338=???Rotation beyond the limits +90339=???Rotation impossible +90340=???Automatic nesting in progress +// SplitPage +90341=Ein / Aus +90342=Alle Ein +90343=Alle Aus +90344=Vergrößern / Verkleinern +90345=Ext / Red starten +90346=Ende Ext / Rot +90347=Start Cnt / Out +90348=Alles startet +90349=All Starts Center +90350=Automatische Berechnung fehlgeschlagen +90351=Für den Vakuumbetrieb zu groß +90352=???End Cnt/Out +90353=???All End Out +90354=???All End Center +90355=???All Extend +90356=???All Reduce +90357=???Modify +90358=???Auto +90359=Restart +// MoveRawPart +90361=Entfernen +90362=Teil zu klein: nicht verschiebbar +90363=???Selected position already occupied +90364=???Part too havy : can not be moved +90365=???Part beyond strokes : can not be moved +// SplitPage 2 +90371=???Pause On/Off +90372=???Pause +90373=???Start Modif. +90374=???End Modif. +90375=???Elongation +90376=???Invert +// Zeichnungsseite +90381=Teilenummer +90382=Messen +90383=Seitenwinkel +90384=Markiere oben +90385=???Parametric Draw +90386=???Select a contour +90387=???No editable sides +90388=???Name +90389=???Trf Data +90390=???Order Code +90391=???Order Description +90392=???Material Code +90393=???Surface Code +90394=???Thickness +90395=???Select one or more holes +90396=???Part Code +90397=???Engrave +90398=???Csv Data +90399=???All machinings updated +90400=???Top Edge +// Komponente +// Massimo 17 caratteri senza immagine und massimo 12 kon l'immagine +90401=Dreieck +90402=Rechteck +90403=Trapez +90404=Viereckig +90405=Wickler +90406=Sill +90407=Küchenoberseite +90408=Waschtischplatte +90409=Andere +90410=2Seiten 1Ang +90411=3Seiten +90412=Isosceles +90413=Richtig +90414=Scalene +90415=Scalene +90416=4Seiten 1Ang +90417=3Seiten 2Ang +90418=3Seiten 2Diag +90419=4Seiten 1Diag +90420=4Seiten 3Diag +90421=4Seiten 3Ang +90422=4Seiten 3Ang +90423=rechter Winkel +90424=Angeschrägter rechter Winkel +90425=Winkel +90426=Abgeschrägter Winkel +90427=Teil A +90428=Teil B +90429=D1 +90430=D2 +90431=Ellipse +90432=Oval +90433=Bogen +90434=Bogen LHF +90435=Bogen LLH +90436=Bogen LLF +90437=Gerundetes Rechteck +90438=Konvex +90439=Loch +90440=2 Löcher +90441=3 Löcher +90442=Bogen RHa +90443=Polygon +90444=???Bottom Hole +90445=Dxf +90446=Tropfschale +90447=Interne Funktionen +90448=Hinzufügen +90449=Entfernen +90450=???Confirm +// Einführen +90451=Schichten verwenden +90452=Gebiete verwenden +90453=Rücksetzen +90454=mm +90455=inch +90456=Geschlossene Kurven verwenden +90457=Seitenwinkel +90458=???Drip +90459=Winkel +90460=Offset +90461=Tiefe +90462=Verkürzung +90463=???DXF import +90464=???Drill bottom +90465=???Number +90466=Offset2 +90467=???Order +90468=???List +90469=???Name +// Component 2 +90470=???Recess engravings +90471=???Engravings +90472=???TriangleCH +90473=???TriangleRT +90474=???TrapeziumRtA +90475=3Seiten 2Ang +90476=???Nuova soglia +// FastGrid +90480=???Order name +90481=???N. slab +90482=???Last slab +90483=???Piece type +90484=???Insert pieces +90485=???Confirm order +// Öffnen +90491=Ungültiges Projekt +90492=Projekt mit Kollisionen. So laden Sie deaktivieren ganze Schnitte Wache. +// RawPart +90499=???Undefined Raw part +90500=???Rotation +90501=Rechteck +90502=Durch Punkte +90503=Länge +90504=Breite +90505=Dicke +90506=Versatz X +90507=Versatz Y +90508=Kerf +90509=Material +90510=Beschädigter Bereich +90511=Neu +90512=Löschen +90513=Punkte +90514=Hinzufügen +90515=Entfernen +90516=Max. Länge = +90517=Max. Breite = +90518=Negative Dicke nicht erlaubt +90519=Min. Versatz X = +90520=Min. Versatz Y = +90521=Min. kerf = +90522=Max. kerf = +90523=Rohsonde +90524=Ok +90525=Raw Sondierung +90526=Probing läuft ... +90527=Erfolg erfolgreich beendet +90528=Fehler beim rohen Sondieren +90529=Aus Zeichnung +90530=Vom Laser +90531=Schließen +90532=Fehler bei der Laserpunkt-Erfassung +90533=Gliederung +90534=Saw zu groß für Sondieren +90535=???From photo +// ChooseMachining +90536=Wählen Sie Sägen +90537=Zusatzbearbeitung wählen +90538=Bohrung wählen +90539=Wählen Sie Fräsen +90540=Keine +90541=Bohren +90542=Fräsen +90543=Beide +90544=???Choose Current Machining +90545=???Choose waterjet +90546=???Waterjet Cut +90547=???Error in the position or size of the raw +90548=Max. Versatz X = +90549=Max. Versatz Y = +90550=???Scegliere la svuotatura +// Simulation +90551=Vollständige Simulation +90552=Outstroke +90553=Werkzeugrichtung nicht erreichbar +90554=Fehler +90555=???ERROR +90556=???Error in generation! +90557=???Simulation +90558=???One step at a time +90559=???Play/Pause +90560=???Stop/Home +90561=???Pause +90562=???Stopped simulation +90563=???Mach view +90564=???Home +90565=???Time +90566=???Length +90567=???Parts Area +90568=???Usage +90569=???Estimations +90570=???Details +// FrameCut +90601=Entlang X +90602=Entlang Y +90603=Entfernen +90604=Schruppen +90605=Fertigstellung +90606=Seitenveredelung +90607=Spiegel +90608=Oberer Abstand +90609=Seitenabstand +90610=???Trim start +90611=???Trim end +90612=Einzelschnitt +90613=???Arc +90614=???Guide +90615=???Section +90616=???Guide +90617=???Rad +90618=???Ang +90619=???Error : radius smaller then section width +90620=???Error : frame creation failed +90621=???X clearance +90622=???Y clearance +90623=???Opposite Side +// Maschine +90701=Msg_Ita.xpi +90705=Maschinendaten +90706=WKZ DB +90707=Bearbeitung DB +90708=Maschine Steuerung +90709=???Statistics +90715=Neu +90716=Neu +90717=Speichern +90718=Löschen +// ExtrasDb +// param +90719=???Tool holder length +90720=???Core +90721=Name +90722=Position +90723=Kopf +90724=Beenden +90725=RPM (Drehzahl) +90726=Standard +90727=Maximum +90728=Vorschub +90729=Normal +90730=Vertikal +90731=Eintritt +90732=Austritt +90733=Kühlmittel +90734=Korrektor +90735=Aufmaß +90736=Aufmaß Z +90737=Radial +90738=Max. Leistung +90739=Min. Vorschub +90740=Maximale Tiefe +90741=Länge +90742=Durchmesser +90743=Dicke +90744=Schneidegerät +90745=???Notiz +90746=???Serial Number +90747=???Code +90748=???Supplier +90749=???End Life +// Werkzeugfamilien +90751=Sägeblatt +90752=Bohren +90753=Fräse +90754=???Cupwheel +90755=???Waterjet +90756=???Polishingwheel +//Tool Setup +90759=???Default tool position already occupied +// MachiningsDb +// param +90761=Name +90762=Schnittzugabe (RB+ mm ) +90763=Seitenwinkel +90764=Umkehren +90765=Schritttyp +90766=Mach. Seite +90767=Kopfseite +90768=Anfang +90769=Eintritt +90770=Verbindung +90771=Austritt +90772=Kurven Vornahme +90773=Toleranz +90774=Absenkung +90775=Standard +90776=Tiefenstufe +90777=Innenbogen +90778=Außenbogen +90779=Verlangsamende Länge +90780=Starten +90781=Endung +90782=Zusätzliche Tiefe +90783=Rückstellposition +90784=Werkzeug +90785=Min. Dicke +90786=Maximale Dicke +90787=Schritt +90788=Unten +90789=Seite +90790=Vertikal +// Maschinenfamilien +90791=Sägen +90792=Bohren +90793=Fräsen +90794=3D Sägen Grob +90795=3D Sägen Fein +90796=???Pocketing +90797=???Waterjet +// ComboBox Param +90801=Nein +90802=Innen +90803=Außen +90804=Beides +90821=Mitte +90822=Links +90823=Rechts +90824=Zentriert +90825=Innen +90826=Außen +90827=Cent. Verlängert +90828=Außen verlängert +90829=Zurück Erweitert +90830=Weiter Erweitert +90831=Stand verlängert +90832=Zentriert +90833=Innen +90834=Außen +90835=Überspringen +90836=Ungefähre +90837=konvex +90838=Zickzack +90839=Ein Weg +90840=Hin und zurück +90841=Halten +90842=None +90843=???Standard +90844=???Slowdown +90845=???Loop +90846=???Linear +90847=???Tangent +90848=???Glide +90849=???Helix +90850=???As lead in +// param2 +90861=Seite +90862=Geneigt Vor. +90863=GeneigtRück. +90864=Vorwärts +90865=Rückwärts +90866=Letzer Schnitt Rückwärts +90867=???Forward angle +90868=???Probing +90869=???Min dist. points +90870=???Max dist. points +90871=???External +90872=???Internal +90873=???Slowdown len. +90874=???Slowdown % +90875=???Lead in hole +90876=???Radius +90877=???LP turns +90878=???HP turns +90879=???Enable +90880=???Corners +// Barcode +90881=Barcode +90882=Block +90883=Anzahl +90884=Plattendaten +// param3 +90890=???Dist. tang. +90891=???Dist. perp. +90892=???Dist. tang. +90893=???Dist. perp. +90894=???Leadin ceramic +90895=???Length +90896=???Step +90897=???Last cut +90898=???Side angle cuts +// Alarme +90900=???Current Waterjet +90901=Aktuelles Sägeblatt +90902=Zusätzliches WKZ +90903=Laufender Bohrer +90904=Aktuelle Mühle +90905=Sicherheit Z +90906=Schnittverkürzung +90907=Ecksicherheit +90908=Ganze Schnitte +90909=Offset Durchmesser +90910=Löcher überlappen +90911=Bohrungstoler. +90912=NC Bildschirm +90913=Material +90914=Hinzufügen +90915=Entfernen +90916=Aktuelle Werkzeuge +90917=Löcherparameter +90918=Außen Radius Minimum +90919=Sicherheit Parameter +90920=Keine +90921=Fräse +90922=Mühle +90923=Beide +90924=Innen Radius Maximum +90925=Saw-Parameter +90926=Einziges Loch in der Ecke +90927=Direkte Schnitte +90928=Parkposition am Ende +90929=Fräsparameter +90930=Immer drin +90931=Schachtelung +90932=Ausgerichtet +90933=WKZ Magazin +90934=Neues +90935=Löschen +90936=Zusätzlicher Tisch +90937=???Camera +90938=???Background +90939=???Threshold +90940=???Tolerance +90941=Waschen +90942=???Are you sure you want to delete selected material? +90943=???Default setup +90944=Immer an Ecken +90945=???Select tool to probe +90946=Vorshub Start/End +90947=Länge +90948=Kürzung% +90949=Verkürzung +90950=??? Probing +//Maschine +90951=Start +90952=Stop +90953=Aktualisieren +90954=Auto +90955=Einzeln +90956=MDI +90957=Manuell +90958=Startseite +90959=Herunterladen +90960=Hochladen +90961=Aktivieren +90962=Löschen +90963=Vornehmen +90964=CN-Modus +90965=Maschinenbefehle +90966=MDI +90967=Teilprogrammtransfer +90968=???Do you want to change table? +// Optionen +90981=Sprache +90982=Die neue Sprache wird beim nächsten Softwarestart angewendet. +90983=Maßeinheit +90984=Ansichtdrehung +90985=???Side angle +90986=???Same value +90987=???Multiple values +90988=???Direct insertion of parts +90989=???Parametrics and DXF +90990=???CSV +90991=???Fast grid +90992=???Enable standard pieces creation +90993=???Text color +90994=???Slab Dxf +90995=???Slab Layer +90996=???Parts Layer +90997=???Scrap Layer +90998=???Std Thick +90999=???ColorToSideAng +91000=???Enable +91001=???Tolerance +91002=???Heel +91003=???Side Angle +91004=???Feedback +91005=???Themes +91006=???Engrave from color +91007=???Depth +91008=???Width +91009=???Start program +91010=???Select start mode +91011=???Recent project +91012=???Last opening +91013=???Last project +91014=???New project +91015=???Open folder +91016=???Show window +//Alarms2 +91051=???Machinings +91052=???Sawing +91053=???Drilling +91054=???Milling +91055=???DripSawing +91056=???DripDrilling +91057=???WaterJet +91058=???Waterjet parameters +91059=???Automatic +91060=???Aligned and Guillotine +91061=???Engraving parameters +91062=???Use Mill +91063=???Depth +91064=???Width +91065=???Precut exit +91066=???Guillotine +91067=???Add pause +91068=???Frame +91069=???Pocketing +91070=???Scasso corrente +//Statistics +91071=???Day Production +91072=???Week Production +91073=???Project +91074=???Parts Area +91075=???Cuts Area +91076=???Day +91077=???Week +91078=???Reset +91079=???To Produce Area +//Lucidature +91089=Offset +91090=???Polishing DB +91091=???Polishings +91092=???Move +91093=???Count +91094=???LeadIn/LeadOut +91095=???Height +91096=???Tools +91097=???Length +91098=???Up +91099=???Down +91100=???Load +// EgtMsgBox +91101=Änderungen im aktuellen Projekt speichern? +91102=Änderungen am aktuellen Tool speichern? +91103=Änderungen der aktuellen Bearbeitung speichern? +91104=Bereits benutzter Name +91105=Es gibt Kollisionen, einige Stücke werden geparkt. Fortsetzen ? +91106=Eine andere Datei mit demselben Namen alredy existiert? Überschreibe es? +91107=NC-ANSCHLUSS +91108=Verbindung herstellen ... +91109=Verbindung fehlgeschlagen +91110=Erfolgreich verbunden +91111=Tabelle zu verwenden? +91112=Auch Teile aus der CSV-Liste löschen? +91113=Teile nicht entfernt, da frei +91114=oder aus anderen Csv-Listen +91115=Error +91116=Option Produktionslinie nicht freigegeben +91117=Fehler beim Kopieren der Datei für OmagVIEW +91118=Parkplätze aufbewahren? +91119=Fehler bei der ruinierten Teileverwaltung +91120=???Characters \ / : * ? " < > | are not allowed +91121=???Are you sure you want to delete selected pieces? +91122=???Warning +91123=Tabelle +91124=???Salvare la lucidatura corrente? +91125=???Salvare le modifiche correnti? +91126=???Export +91127=???Import +91128=???DB WaterJet +91129=???Origine da laser +91130=???Start program? +// CSV +91201=Öffnen +91202=Einfügen +91203=Neu +91204=Entfernen +91205=???Error saving CSV file, continue anyway ? +91206=???Error reading CSV file +// OmagVIEW +91301=Alles Gut +91302=guter Teil +91303=Ruinierter Teil +91304=Label drucken +91305=Bestätigen +91306=???Print +// OmagOFFICE +// OptionPanel +91401=???RawPart +91402=???Disposition +91403=???Work +91404=???Simulation +// MachiningDbWindow +91451=???Material +91452=???Min Thickness +91453=???MaxThickness +// TopCommandBar +91501=???Save project is mandatory before export +91502=???Select export directory +91503=???Error in export +91504=???Export completed successfully +91505=???Export to machine +91506=???DXF export +// Rawpart +91551=???Error loading photo +91552=???Import photo +// VeinMatching +91601=???Export +91602=???Show Info +91603=???Edit +91604=???Verify +91605=???Magnetic +91606=???Part not selectable in this situation +91607=???Part not selectable because belonging to non-current workgroup : +91608=???Dxf parts BoundingBox too big for VeinMatching +// Generic +91651=???Ok +91652=???Cancel +91653=W° +91654=H +91655=Start +91656=Ende +// ----- OmagPHOTO ----- +// General +92001=???Db not found! +92002=???Unable starting the program +// OptionPanel +92051=???Save +92052=???Add +92053=???Cancel +92054=???Remove +92055=???Are you sure you want to delete current slab? +92056=???Etichetta +92057=???Etichetta Freccia +92058=???Sfoglia +92059=???Stampa +92060=???Seleziona +// Slab +92071=???Id +92072=???Image name +92073=???State +92074=???Project assigned to +92075=???Warehouse position +92076=???Date +92101=???Name already used +92102=???Name is mandatory +92103=???Image is mandatory +// SearchPanel +92151=???Search +92152=???Thickness tolerance +92153=???Start date +92154=???End date +92155=???Reset +//Messaggi +92200=???Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=???Avviso +92202=???Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=???Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=???Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// Allgemeines +101001=Import BTL +101002=Unentschieden +101003=Ort +101004=Optionen +// ImportPage +101101 +// Zeichnungsseite +101201=Wand +101202=Tür +101203=Fenster +101204=Hinzufügen +101205=Abbrechen +101206=Anwenden +101207=Entfernen +101208=Abstandshalter +// PlacePage +101301=Generieren +101302=Trasmit +101303=Platzieren Sie die Wand +101304=Hinzufügen +101305=Park +101306=Entfernen +101307=Schichtdicke +101308=Tischanzahl oben +101309=Fehler beim Hinzufügen +101310=Erzeugung erfolgreich +101311=Erzeugungsfehler +101312=Übertragung erfolgreich +101313=Übertragungsfehler +101314=Übertragung erfolgreich abgeschlossen +101315=Übertragung fehlgeschlagen +101316=Alle Gantries deaktiviert +101317=Erzeugungsdatei fehlt +// OptionsPage +101401=Maschinenoptionen +101402=Klebeparameter +101403=X Extra Raw +101404=Y Extra Raw +101405=Extra Kleber +101406=Plankparameter +101407=Breitenbreite +101408=Tabellenanzahl in einer Ebene +101409=Gantries-Aktivierung +101410=Leimbrücke +101411=Säulenbrücke +101421=Softwareoptionen +101422=Sprachauswahl +101423=Die neue Sprache wird beim nächsten Softwarelauf zum aktuellen +101424=Gespeicherte Projektnummer +101425=Bretter an Türen und Fenstern anbringen +101426=Vorschubklebstoff +101427=Vorverschliessender Leim +// OpenPage +101501=Ungültiges Projekt +// ----- Ende ----- diff --git a/ProgramData/EgtCAM5/Config/EgalTechEng.txt b/ProgramData/EgtCAM5/Config/EgalTechEng.txt new file mode 100644 index 0000000..a69be31 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgalTechEng.txt @@ -0,0 +1,3312 @@ +// Message File EgalTech English 2022/04/11 +0=ENG +// File +1=File +3=New +5=Open +6=Open
Recent files (Shift) +7=Insert +9=Save +11=Save as +13=Import +15=Export +17=Exec +19=Recent Files +20=Recent Scripts +// View +101=View +103=WFrame +105=HLine +107=Shading +109=ZoomAll +111=ZoomIn +113=ZoomOut +115=Top +117=Front +119=Right +121=Back +123=Left +125=Bottom +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Grid +136=SetView perpendicular to current Grid +137=CurveDir +139=Analyze +141=GetDist +// Grid +201=Grid +203=Top +205=Front +207=Right +209=Back +211=Left +213=Bottom +215=View +216=Set Grid perpendicular to View +217=Elevat +218=Set Grid Elevation +219=Origin +220=Set Grid Origin +221=Rotate +222=Rotate Grid
3D Rotate Grid (Shift) +223=3 Points +224=Set Grid from 3 Points +225=Perp +226=Set Grid Perpendicular to Object +227=Object +228=Set Grid from Object +// Draw +301=Draw +303=Point +304=Point
Vector (Shift)
Frame (Ctrl) +305=Line 2P +306=Line : 2 Points
Line : 2 Points with Continue (Ctrl) +307=LineSDL +308=Line : Start, Direction, Length
Line : Start, Direction Vector, Length (Shift) +309=Circle +310=Circle : Center, Point
Circle : Center, Diameter (Shift) +311=Fillet +312=Fillet : Radius
Chamfer : Dist (Shift) +313=Arc CSE +314=Arc : Center, Start, End +315=Arc 3P +316=Arc : 3 Points +317=Arc SDE +318=Arc : Start, Direction, End
Arc : Start, Direction Vector, End (Shift)
Arc : Start, Direction, End with Continue (Ctrl) +319=Rect 2P +320=Rectangle : 2 Points +321=Polygon +322=Polygon : Radius or Apothem
Polygon : Side with 2 Points (Shift) +323=Text +324=Text
Advanced Text (Shift) +399=Continue : 'L' with line, 'A' with arc +// Construct +401=Construct +403=Plane +404=Surface : between planar curves
Flat Region (Shift) +405=Extrude +406=Surface : curve extrusion +407=Revolve +408=Surface : curve revolution +409=Screw +410=Surface : curve screwing +411=Ruled +412=Surface : ruled between 2 curves +413=Merge +414=Merge Surfaces +415=Flip +416=Flip Surface Outside +417=Explode +418=Explode Surfaces or Flat Regions +419=Swept +420=Surface :sweeping a curve along another +// Edit +501=Edit +503=Delete +504=Delete Objects +505=Layer +506=Change Object Layer to Current +507=Color +508=Change Color
Remove Color (Shift)
Change Trasparency (Ctrl) +509=Invert +510=Invert Curve +511=Trim/Ext +512=Trim or Extend Curve +513=Break +514=Break Curve
Split Curve in Pieces (Shift) +515=Join +516=Join Curves
Join Curves making a Copy (Shift)
Merge Curves in Composite (Ctrl) +517=Explode +518=Explode Text or Curve in Components +519=Thick +520=Set Curve Thickness and Extrusion +521=Start +522=Change Closed Curve Start Point +// Transform +601=Transform +603=Move +604=Object Move +605=Rotate +606=Object Rotate
3D Object Rotate (Shift) +607=Mirror +608=Object Mirror
3D Object Mirror (Shift) +609=Scale +610=Object Scale
3D Object Scale (Shift) +611=Offset +612=Curve Offset +// Special +701=Special +703=Flat Parts +704=Insert DXF or NGE flat parts +705=Compo +706=Insert parametric components +// Scene : Entity selection Menu +1001=Select All +1003=Deselect All +1005=Select Window +1007=Select Part +1009=Select Layer +1011=Select Path +1013=Select Full Path +1015=Select Entity +1016=Select All Visible +// Scene : Point selection Menu + Statusbar +1101=Sketch Point +1102=Sketch Point +1103=Grid Point +1104=Grid Point +1105=End Point +1106=End Point +1107=Mid Point +1108=Mid Point +1109=Center Point +1110=Center +1111=Centroid +1112=Centroid +1113=Near Point +1114=Near Point +1115=Intersection Point +1116=Inters Point +1117=Tangent Point +1118=Tang Point +1119=Perpendicular Point +1120=Perp Point +1121=Min.Distance Point +1122=MinDist Point +1123=Exclude Surfaces +// Scene : Other Menu +1201=Drag Off +1203=Drag On +// Scene : Others +1301=Dist= +// Controller +2001=Copy (V) +2002=Error +2003=Warning +2051=The Point must be different from previous +2052=The Points must be not aligned +2053=Zero or Negative Values not allowed +2054=Two Zero or Negative Values not allowed +2055=At least one Entity is not scalable +2056=Distance too big +2057=Curve not flat (in its plane) +// Controller : Draw +2101= +// Controller : Construct +2201= +// Controller : Modify +2301= +// Controller : Transform +2401=COPY +2402=MOVE +2403=Insert Base Point +2404=Insert Target Point +2406=ROTATE +2407=Insert Center +2408=Insert Base Point +2409=Insert Angle or Rotation Point +2411=ROTATE 3D +2412=Insert First Point on Axis +2413=Insert Second Point on Axis +2414=Insert Base Point +2415=Insert Angle or Rotation Point +2416=MIRROR +2417=Insert First Point +2418=Insert Second Point +2421=MIRROR 3D +2422=Insert First Point +2423=Insert Second Point +2424=Insert Third Point +2426=SCALE +2427=Insert Center +2428=Insert Factor +2431=SCALE 3D +2432=Insert Center +2433=Insert Factors +2436=OFFSET +2437=Insert Distance +2438=Fillet +2439=Chamfer +2440=Extend +// ----- EgtCAM5 ----- +5001=DRAW +5002=MACHINING +5003=Tool Db +5004=Machining Db +5005=Options +5006=Tool Db +5007=Mach Db +5008=Machine Options +5009=SetUp Db +5010=SetUp Db +5020=Machining Table Db +//Top CommandBar +5101=New +5102=Open
Open recent File (Right button) +5103=Save +5104=Save as +5105=Insert +5106=Import +5107=Export +5108=Exec Script
Exec recent Script (Right button) +5109=Options +5110=Can't find support address. +5111=Save current file before sending feedback? +5112=Send a feedback to {0} with the {1} directory attached. +5113=Feedback +5114=Feedback mail ready. +// Draw Panel +5150=Extract Free Edges of Surfaces and Flat Regions +5151=Join Surfaces and Flat Regions +5152=Subtract Surfaces and Flat Regions
Cut Surface with Reverse Surface (Shift) +5153=Intersect Surfaces and Flat Regions
Cut Surface with Surface (Shift) +5154=Points, Curves and Faces from Surfaces Intersection +5155=Linear Dimension
Aligned Dimension (Shift) +5156=Circle 3 Points +5157=Extract Edges of Surface Faces and Flat Regions Parts +5158=Extract Face from Surface +5159=Arc Flip
Arc Explementary (Shift) +5160=Modify Shape +5161=Add Point
Modify in Arc (Shift)
Close Curve Composite (Ctrl) +5162=Remove Point
Modify in Line (Shift)
Open Curve Composite (Ctrl) +5163=Approx Curve
Approx Curve with Lines (Shift) +5201=Point
Vector (Shift)
Frame (Ctrl) +5202=Line 2 Points
Line 2 Points with Continue (Ctrl) +5203=Line Point Direction Length
Line Point Direction vector Length (Shift) +5204=Circle Center Point +5205=Circle Center Diameter +5206=Arc Center Start End points +5207=Arc 3 Points +5208=Arc Start point Direction End point
Arc Start point Direction vector End point (Shift)
Arc Start point Direction End point with Continue (Ctrl) +5209=Fillet +5210=Chamfer +5211=Rectangle 2 Points +5212=Polygon +5213=Polygon Side +5214=Text
Advanced Text (Shift) +5215=Plane from boundary curves
Flat Region (Shift) +5216=Extrude +5217=Revolve +5218=Screw +5219=Ruled +5220=Merge Surfaces +5221=Explode Surfaces and Flat Regions +5222=Invert Surface and Flat Regions +5223=Delete +5224=Change Layer
Change Layer with Transformations (Shift) +5225=Change Transparency +5226=Reset Color +5227=Change Color +5228=Invert Curve +5229=Change closed Curve Start point +5230=Trim or Extend Curve +5231=Break Curve +5232=Split Curve +5233=Join Curves
Join Curves making a Copy (Shift)
Merge Curves in Composite (Ctrl) +5234=Explode Curves and Texts +5235=Thick and Extrusion Curve +5236=Move +5237=Rotate +5238=Rotate 3D +5239=Mirror +5240=Mirror 3D +5241=Scale +5242=Scale 3D +5243=Offset +5244=2D Draw +5245=3D Draw +5246=Modify +5247=Transform +5248=Swept (Section, Guide) +5249=Edit Text +// Grid View Panel +5251=Wireframe +5252=Hidden Lines +5253=Shading +5254=Zoom All +5255=Zoom In +5256=Zoom Out +5257=Top View +5258=Front View +5259=Left View +5260=Back View +5261=Right View +5262=SW Isometric View +5263=SE Isometric View +5264=NE Isometric View +5265=NW Isometric View +5266=Show Curve Direction +5267=Analyze +5268=Distance +5269=Top Grid +5270=Front Grid +5271=Right Grid +5272=Back Grid +5273=Left Grid +5274=Bottom Grid +5275=Grid From View +5276=Grid Elevation +5277=Grid Origin +5278=Grid Rotation
Grid 3D Rotation (Shift) +5279=Grid From 3 Points +5280=Grid Perpendicular to Curve +5281=Grid From Object +5282=View From Grid +5283=Zoom Selection +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=END +5302=Outstroke +5303=Tool direction unreachable +5304=Error +5305=ERROR +5306=Error in generation! +5307=Simulation +5308=One step +5309=Play/Pause +5310=Stop/Home +5311=PAUSE +5312=STOP +5313=Can't exit now. Stop the Simulation or wait until the end of it! +5314=HOME +5315=WARNING +5316=Virtual Milling +5317=Error in estimates calculation! +5318=Estimation file missing +5319=Collision! +5320=INFORMATION +5330=GENERATE +5331=The project must be saved before generated. Save it ? +5332=Generation completed successfully +5333=The license does not allow NC Generation +5340=Estimations +5341=Total time +5342=Total length +5343=Details +5344=Estimations details +// Draw Option +5351=Properties +5352=New Part +5353=New Layer +5354=Color +5355=Drawings Parameters +5356=Select +5357=Deselect +5358=Name +5359=Info +5360=Relocate +5361=Copy +5362=Delete +5363=Save +5364=Show +5365=Ok +5366=Delete Confirm +5367=Workpiece, do you want to delete it? +// Operation +5401=Operations +5402=Operation Parameters +5403=Apply Machining +5404=New Mach +5405=New Disp +5406=Delete +5407=Generic +5408=Move Up +5409=Move Down +5410=Update +5411=Update completed successfully +5412=New Machinings +5413=Tool Preview +5414=Next +5415=Prev +5416=Duplicate +5417=Copy to Db +5418=Machining name in Db +5419=Machining adding failed +5420=Rename +5421=Name can not start with "Disp" +5422=Name already used. +5423=Machining cannot be applied due to the following reasons: +// Disposition +5431=Ok +5432= +5433=New +5434=Remove +5435=Length +5436=Width +5437=Height +5438=Position +// Disposition Errors +5461=SCRIPT EXECUTION ERROR +5462=Error executing automatic disposition script +5463=Error executing machining init script +5464=Error executing machining exit script +// Mach Group +5501=Are you sure you want to reset the Machining Group ? +5502=Are you sure you want to delete the Machining Group ? +5551=There are no Machining Groups :
select the parts to insert and
repeat the command to create the first one. +5552=Do you want to create a new Machining Group
with the selected parts? +// Tools Db Page +6001=Drillbit +6002=Sawblade +6003=Mill +6004=Mortise +6005=Compo +6006=Long drill +6007=Flat saw +6008=No tip mill +6009=Chisel +6010=WaterJet +6051=Compensation +6052=Exit +6053=Type +6054=Coolant +6055=Corner Radius +6056=Diameter +6057=Total Diameter +6058=Feed +6059=End Feed +6060=Start Feed +6061=Tip Feed +6062=Length +6063=Total Length +6064=Max Material +6065=Longitudinal Offset +6066=Radial Offset +6067=RPM +6068=Side Angle +6069=Max RPM +6070=Thick +6071=Max Absorption +6072=Min Feed +6073=Draw +6074=Head +6075=Name +6076=Notes +6077=Tool Changer Position +6078=Position +6079=Distance +6080=Overtable +// Tools Errors +6100=Save the modified tool? +6101=SAVE +6102=File has to be .nge +6103=File does not exist or is not Nge type +6104=ToolMaker does not exist for this kind of tool +6105=Impossible creating tool with this parameter +6106=MaxMat value must be greater than 0 +6107=MaxMat value must be less than Len +6108=Thick value must be greater than 0 +6109=Diam value must be greater than 0 +6110=Len value must be greater than 0 +6111=RPM value must be less than MaxRPM +6112=Invalid Name +6113=Length value must be less than Total Length +6114=Length value must be greater than Max Material +6115=Total Length must be greater than 0 +6116=Total Length must be greater than Length +6117=Max Material must be less than 1/3 Diameter +6118=Diameter must be less than Total Diameter +6119=Diameter must be greater than 3 times Max Material +6120=Total Diameter must be greater than 0 +6121=Length too small with toolholder +6122=Are you sure you want to delete +6123=? +6124=DELETE +6125=SetUp configuration file not found! +6126=Error +6127=Head value must be set +6128=Exit value must be set +6129=Invalid tool, correct or delete it before exit Tool Db. +6130=Impossible reloading Tool database. If the machine dir is on a server, verify the connection is active. +6131=Thick value must be different than 0 +6132=Side Angle value must be smaller than 90 +6133=Side Angle value must be bigger than -90 +6134=Total Length must be greater than Length + Thick +6135=Corner Radius value is too big +6136=Thick value is too small for insert radius +6137=Calculated Diameter must be less than Total Diameter +6138=Calculated Diameter is less than 0 +6139=Calculated Diameter is less or equal than 0 +6140=MaxMat value must be greater than Corner Radius +6141=Calculated MaxMat must be >= 0 +6142=Corner Radius must not exceed half Thick +6143=Save tool +6144=Tool modified! All tools must be saved before changing activations. Save tool {0}? +6145=Position already occupied! +6146=Position not defined! +// Machinings Db Page +6201=Drilling +6202=Sawing +6203=Milling +6204=Pocketing +6205=Mortising +6206=Sawroughing +6207=Sawfinishing +6208=Gen Machining +6209=Chiseling +6210=Surface Roughing +6211=Surface Finishing +6212=WaterJet +6251=Invert +6252=Leave Tab +6253=Type +6254=Work Side +6255=Head Side +6256=Lead In +6257=Link +6258=Lead Out +6259=Curve Use +6260=Step Type +6261=Sub Type +6262=Lead Link Type +6263=RPM +6264=Feed +6265=Start Feed +6266=End Feed +6267=Tip Feed +6268=Radial Offset +6269=Longitudinal Offset +6270=Depth +6271=Side Angle +6272=Approximation +6273=Start Safety Length +6274=Start Slow Length +6275=End Slow Length +6276=Throu Add Length +6277=Step +6278=Return Position +6279=Length +6280=Distance +6281=Height +6282=Angle +6283=L.In Tangent Distance +6284=L.In Perp. Distance +6285=L.In Elevation +6286=L.In Comp. Length +6287=L.Out Tangent Distance +6288=L.Out Perp. Distance +6289=L.Out Elevation +6290=L.Out Comp. Length +6291=Start Add. Length +6292=End Add. Length +6293=Step External Arc +6294=Step Internal Arc +6295=Side Step +6296=Vertical Feed +6297=Name +6298=Tool +6299=Depth +6300=Notes +6301=Overlap +6302=Offset +6303=Sub Type +6304=SCC +6305=None +6306=Standard +6307=Opposite +6308=AuxDir X+ +6309=AuxDir X- +6310=AuxDir Y+ +6311=AuxDir Y- +6312=AuxDir Z+ +6313=AuxDir Z- +6314=Nearest AuxDir +6315=Farthest AuxDir +6320=Center +6321=Left +6322=Right +6323=Extend +6324=Standard +6325=Strict +6326=Out +6327=Extend Central +6328=Extend Out +6329=None +6330=Linear +6331=Tangent +6332=Glide +6333=Helix +6334=Extend Prev +6335=Extend Next +6336=Extend Both +6337=As Lead In +6338=Skip +6339=Approx +6340=Convex +6341=Keep +6342=ZigZag +6343=Oneway +6344=Spiral +6345=To And From +6346=Along +6347=Across +6348=Spiral In +6349=Spiral Out +6350=Advanced +6351=Invert tool direction +6352=Face machining +6353=Not defined +6354= Parallel +6355= Orthogonal +6356= Orthog. Up +6357=Down +6358=Top +6359=Front +6360=Back +6361=Left +6362=Right +6363=Contour +6364=Suggested Angles +6365=Blocked Axis +6366=Max count +6367=Min count +// Machining errors +6370=Save the modified machining? +6371=SAVE +6372=Invalid name +6373=Characters \ / : * ? " < > | are not allowed +6374=Are you sure you want to delete +6375=? +6376=DELETE +6377=Impossible reloading Machining database. If the machine dir is on a server, verify the connection is active. +6378=Oscillation +6379=Amplitude +6380=Ramp Length +6381=Flat Length +// Machining Option Page +6401=Safe Z +6402=Split Arcs +6403=Never +6404=Gen plane +6405=No XY plane +6406=Always +6407=Default Setup +6408=Safe Z bottom aggregate +6409=Holes tolerance +// SetUp Window +6451=SetUp +6452=Apply +6453=Save +6454=Retrieves +6455=Auto +6456=Apply current setup before exit? +6457=New +// SetUp Errors +6471=Error +6472=Warning +6473=Can't find tool +6474=in Tool Database. +6475=The tool's default position is not valid. +6476=Tools not setup because their default position is alredy occupied: +6477=SetUp configuration file doesn't exist! +6478=SetUp configuration use a head that doesn't exist on the machine! +6479=Error loading default setup +// Option Page +6501=Current language +6502=The new language will take effect after restart. +6503=Curves +6504=Surfaces +6505=Curves & Surfaces +6506=Selecting geometry +6507=New machining is the last one +6508=Use disposition script +6509=Measure Unit +6510=View top color +6511=View bottom color +6512=Default color +6513=Geometric tolerance +6514=Generic +6515=CAD +6516=CAM +6517=Grid color +6518=Smoothed surfaces +6519=Import +6520=DXF +6521=STL +6522=Images +6523=Export +6524=Image +6525=Width (pixel) +6526=Height (pixel) +6527=Update Machine +6528="{0}" machine already exists,
what do you want to do ? +6529=File {0} does not contain a machine. +6530=The machine "{0}" has been successfully updated. +6531=Replace +6532=Update +6533=Cancel +6534=Warning +6535=The update of the "{0}" machine failed. +6536=Thick lines +6537=Extra line length +6538=Arrow length +6539=Text distance +6540=Measuring unit +6541=Decimal +6542=Font +6543=Text height +6544=Dimension +6545=Current unit +6546=Other +6547=Measuring unit +6548=Scale factor +6549=Export Current Machine +6550=Select the folder where you want to save the machine +6551=The export of the "{0}" machine failed. +6552=The machine "{0}" has been successfully exported. +6553=Update Licence +// Heads +6601=Vertical +6602=Horizontal +6603=2 exit aggr. +6604=3 exit aggr. +6605=4 exit aggr. +6606=3 axis head +6607=4 axis head +6608=5 axis head +6609=Shuttle 1 +6610=Shuttle 2 +6611=Carousel +6612=Gang drill +6613=Multi chisel +6614=Bottom aggr. +6615=5 axis saw +6616=Chainsaw +6617=1 exit aggr. +6618=Probe head +6619=Floating 360deg +6620=2nd 5 axis head +6621=Horizontal drill +6622=Mortiser +6623=2nd 5 axis saw +6624=1 exit tilt. aggr. +6625=Extruder +6799= +// StatusBar +6801=Machines dir not found. EgtCAM5 wil be run in CAD-ONLY mode. +// Doors +8001=Create new MTable +8002=Save MTable +8003=Save MTable As +8004=Delete MTable +8005=Save MTable file +8006=Are you sure to delete this MTable? +8007=Save the modified MTable? +8008=Active Machines List +8009=Machine Name +8010=Nc Generate +8011=Make Raw +8012=On +8013=Geometry Name +8014=Operation +8015=MId +8016=Shift +8017=Machining Type +8018=Machining 1 +8019=Machining 2 +8020=Machining 3 +8021=Add Machine +8022=Remove Machine +8023=Add Machining +8024=Remove Machining +8025=CURR +8026=Set active MTable +8027=GId +8028=Property +8029=Machining +8030=Join +// Door errors +8101=Error +8102=Error running Ddf file +8103=Warning +8104=MTable dir path not found +8105=MTable dir not exist +8106=Missing configuration files in MTable dir +8107=Unknown error +8108=This MTable is currently the active one. +8109=You can't delete it. +8110=Are you sure you want to delete the selected machining? +8111=DELETE +8112=Are you sure you want to delete the selected machine? +8113=Can't find {0} machine dir. If the machine dir is on a server, verify the connection is active. +8114=Try to reload the machine? +8115=Can't find {0} dir. If the Doors dir is on a server, verify the connection is active. +8116=Try to reload Doors dir? +8117=Execution error (see log file) +// GunStock +8201=New Part +8202=Gunstock new part +8203=Modify Part +8204=Gunstock modify part +8205=Gunstock parameters +8206=File name +8207=Description +8208=Ok +8209=Cancel +8210=must have a value. +8211=The value has to be between +8212=and +8213=Rawpart dimensions +// GunStock errors +8251=Error +8252=Error running Gunstock environment +8253=Error reading model file +8254=Error writing part file +// ----- Beams & Walls ----- +9000=Beam machining tables +9001=On +9002=Name +9003=Type +9004=Add +9005=Delete +9006=Save +9007=Save modifications? +9008=Error +9009=Impossible to open Beam Machining Editor.
Can't find config files. +9010=Wall machining tables +9011=Impossible to open Wall Machining Editor.
Can't find config files. +// ----- Errors ----- +10001=Error +10002=Error on new file +10003=Error opening file +10004=Error saving file +10005=File type unknown +10006=Error importing file +10007=Error exporting file +10008=Error loading or creating Machining Group +10009=Missing file +// Missing Key Window +10101=Error +10102=Missing Protection Key. +10103=Insert Dongle and restart the program. +10104=Ok +10105=Program without licence. +10106=Load Licence and restart the program. +10107=Run GetMachineId and send results to supplier. +// Numeric virtual keyboard +10201=Wrong Expression +// ----- MessageBox ----- +15001=Error +15002=Warning +15003=Information +15010=Internal error (see log file) +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Wrong Expression +// EgtCalculatorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Canc +20043=YES +20044=NO +// ----- EgtWPFLib5 ----- +// EgtFileDialog +30001=Save +30002=Cancel +30003=alredy exists. +30004=Do you want to replace it? +30005=File name: +30006=Open +30007=ERROR +30008=Name can't be empty! +30009=WARNING +30010=File Name +30011=Folder Name +// Top CommandBar +30501=New +30502=Open +30503=Save +30504=Save as +30505=Insert +30506=Import +30507=Export +30508=Exec +30509=Options +30510=Can't find support address. +30511=Save current file before sending feedback? +30512=Send a feedback to {0} with the {1} directory attached. +30513=Feedback +30514=Feedback mail ready. +// Grid View Panel +30801=Wireframe +30802=Hidden Lines +30803=Shading +30804=Zoom All +30805=Zoom In +30806=Zoom Out +30807=Top View +30808=Front View +30809=Left View +30810=Back View +30811=Right View +30812=SW Isometric View +30813=SE Isometric View +30814=NE Isometric View +30815=NW Isometric View +30816=Show Curve Direction +30817=Analyze +30818=Distance +30819=Top Grid +30820=Front Grid +30821=Right Grid +30822=Back Grid +30823=Left Grid +30824=Bottom Grid +30825=Grid From View +30826=Grid Elevation +30827=Grid Origin +30828=Grid Rotation +30829=Grid From 3 Points +30830=Grid Perpendicular to Curve +30831=Grid From Object +30832=View From Grid +// MachGroupPanel +30901=New Mach Group +30902=Name: +30903=Machine: +// ToolDbWindow +31001=Drillbit +31002=Sawblade +31003=Mill +31004=Mortise +31005=Compo +31006=Long drill +31007=Flat saw +31008=No tip mill +31009=Chisel +31010=Waterjet +31051=Compensation +31052=Exit +31053=Type +31054=Coolant +31055=Corner Radius +31056=Diameter +31057=Total Diameter +31058=Feed +31059=End Feed +31060=Start Feed +31061=Tip Feed +31062=Length +31063=Total Length +31064=Max Material +31065=Longitudinal Offset +31066=Radial Offset +31067=RPM +31068=Side Angle +31069=Max RPM +31070=Thick +31071=Max Absorption +31072=Min Feed +31073=Draw +31074=Head +31075=Name +31076=Notes +31077=Tool Changer Position +31078=Position +31079=Drilling +31080=Cutting edge +// ToolDb Errors +31100=Save the modified tool? +31101=SAVE +31102=File has to be .nge +31103=File does not exist or is not Nge type +31104=ToolMaker does not exist for this kind of tool +31105=Impossible creating tool with this parameter +31106=MaxMat value must be greater than 0 +31107=MaxMat value must be less than Len +31108=Thick value must be greater than 0 +31109=Diam value must be greater than 0 +31110=Len value must be greater than 0 +31111=RPM value must be less than MaxRPM +31112=Invalid Name +31113=Length value must be less than Total Length +31114=Length value must be greater than Max Material +31115=Total Length must be greater than 0 +31116=Total Length must be greater than Length +31117=Max Material must be less than {0} +31118=Diameter must be less than Total Diameter +31119=Diameter must be greater than 3 times Max Material +31120=Total Diameter must be greater than 0 +31121=Length too small with toolholder +31122=Are you sure you want to delete +31123=? +31124=DELETE +31125=SetUp configuration file not found! +31126=Error +31127=Head value must be set +31128=Exit value must be set +31129=Invalid tool, correct or delete it before exit Tool Db. +31130=Impossible reloading Tool database. If the machine dir is on a server, verify the connection is active. +31131=Thick value must be different than 0 +31132=Side Angle value must be smaller than 90 +31133=Side Angle value must be bigger than -90 +31134=Total Length must be greater than Length + Thick +31135=Corner Radius value is too big +31136=Thick value is too small for insert radius +31137=Calculated Diameter must be less than Total Diameter +31138=Calculated Diameter is less than 0 +31139=Calculated Diameter is less or equal than 0 +31140=MaxMat value must be greater than Corner Radius +31141=Calculated MaxMat must be >= than 0 +31142=Cutting edge must be greater than 0 +31143=Cutting edge must be less than Len +// ImportExportToolWindow +31161=Import +31162=Export +31163=Tools +31164=Tool already existing in DB. Overwrite? +31165=Tool will be imported with the name followed by "_imp" +31166=The following Tools have been imported succesfully: +31167=Reset +// MachiningDbWindow +31201=Drilling +31202=Sawing +31203=Milling +31204=Pocketing +31205=Mortising +31206=Sawroughing +31207=Sawfinishing +31208=Gen Machining +31209=Chiseling +31210=Waterjetting +31211=Surffinishing +31251=Invert +31252=Leave Tab +31253=Type +31254=Work Side +31255=Head Side +31256=Lead In +31257=Link +31258=Lead Out +31259=Curve Use +31260=Step Type +31261=Sub Type +31262=Lead Link Type +31263=RPM +31264=Feed +31265=Start Feed +31266=End Feed +31267=Tip Feed +31268=Radial Offset +31269=Longitudinal Offset +31270=Depth +31271=Side Angle +31272=Approximation +31273=Start Safety Length +31274=Start Slow Length +31275=End Slow Length +31276=Throu Add Length +31277=Step +31278=Return Position +31279=Length +31280=Height +31281=Angle +31282=Distance +31283=Tangent Distance +31284=Perp. Distance +31285=Elevation +31286=Comp. Length +31287=Min count +31288=Max count +31291=Add. Length +31293=Step External Arc +31294=Step Internal Arc +31295=Side Step +31296=Vertical Feed +31297=Name +31298=Tool +31299=Depth +31300=Notes +31301=Overlap +31302=Offset +31303=Sub Type +31304=SCC +31305=None +31306=Standard +31307=Opposite +31308=AuxDir X+ +31309=AuxDir X- +31310=AuxDir Y+ +31311=AuxDir Y- +31312=AuxDir Z+ +31313=AuxDir Z- +31314=Nearest AuxDir +31315=Farthest AuxDir +31320=Center +31321=Left +31322=Right +31323=Extend +31324=Standard +31325=Strict +31326=Out +31327=Extend Central +31328=Extend Out +31329=None +31330=Linear +31331=Tangent +31332=Glide +31333=Helix +31334=Extend Prev +31335=Extend Next +31336=Extend Both +31337=As Lead In +31338=Skip +31339=Approx +31340=Convex +31341=Keep +31342=ZigZag +31343=Oneway +31344=Spiral +31345=To And From +31346=Along +31347=Across +31348=Spiral In +31349=Spiral Out +31350=Advanced +31351=Invert tool direction +31352=Face machining +31353=Not defined +31354= Parallel +31355= Orthogonal +31356= Orthog. Up +31357=Down +31358=Top +31359=Front +31360=Back +31361=Left +31362=Right +31363=Contour +31364=Suggested Angles +31365=Blocked Axis +31366=Last backward feed +31367=Backward step +31368=Tilted step +31369=Tilted back step +31370=Forward angle +31371=Probing +31372=Min dist. points +31373=Max dist. points +31374=External +31375=Internal +31376=Slowdown len. +31377=Slowdown % +31378=Lead in hole +31379=Radius +31380=LP turns +31381=HP turns +31382=Oscillation +31383=Amplitude +31384=Ramp Length +31385=Flat Length +31386=Generic +31387=Advanced +31388=Tang+Perp +31389=Perp+Tang +//MachiningTreeView +31391=Standard +31392=Slowdown +31393=Loop +31394=Enable +31395=Add Length +31396=Start +31397=End +31398=System notes +31399=Epicycles radius +31400=Epicycles distance +// MachiningDb Errors +31401=Save the modified machining? +31402=SAVE +31403=Invalid name +31404=Characters \ / : * ? " < > | are not allowed +31405=Are you sure you want to delete +31406=? +31407=DELETE +31408=Impossible reloading Machining database. If the machine dir is on a server, verify the connection is active. +31409=Machine material not recognized +31410=Invalid machining, correct or delete it before exiting. +31411=Length must be positive +31412=Distance must be positive +31413=Height must be positive +31414=Angle must be between {0}° and {1}° +31415=Max count must be null or positive +31416=Max count must be equal or greater than Min +31417=Min count must be null or positive +31418=Min count must be equal or less than Max +31419=Enabling {0} will disable {1}. Continue? +// ImportExportMachiningWindow +31450=Import +31451=Export +31452=Machinings +31453=Machining already existing in DB. Overwrite? +31454=Machining will be imported with the name followed by "_imp" +31455=The following Machinings have been imported succesfully: +31456=Reset +// SetUp Window +31501=SetUp +31502=Apply +31503=Archive +31504=Retrieves +31505=Auto +31506=Apply current setup before exit? +// SetUp Errors +31551=Error +31552=Warning +31553=Can't find tool +31554=in Tool Database. +31555=The tool's default position is not valid. +31556=Tools not setup because their default position is alredy occupied: +31557=SetUp configuration file doesn't exist! +31558=SetUp configuration use a head that doesn't exist on the machine! +31559=Error loading default setup +// Simulation +31601=Complete simulation +31602=Outstroke +31603=Tool direction unreachable +31604=Error +31605=ERROR +31606=Error in generation! +31607=Simulation +31608=One step at a time +31609=Play/Pause +31610=Stop/Home +31611=Pause +31612=Stopped simulation +31613=Can't exit now. Stop the Simulation or wait until the end of it! +31614=WARNING +31615=Estimation file missing +31616=Estimation details +//MachiningDbWindow/ToolDbWindow buttons +31701=New +31702=Save +31703=Remove +31704=Edit +//Db Waterjet +31751=Waterjet Db +31752=Thickness +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=Do you want to save edits? +// ----- EgtDOORCreator ----- +//General +50001=Width +50002=Height +50003=Thickness +50004=Swing +50005=Lock edge +50006=Hinge edge +50007=Top +50008=Bottom +50009=Type +50010=Corner +50011=Extension +50012=Side +50013=Offset wide side +50014=Back set +50015=Top to center +50016=Bottom rail +50017=Lock stile +50018=Offset from center +50019=Point to pocket +50020=Pocket length +50021=Pocket offset narrow side +50022=Point to arm +50023=Arm length +50024=CenterHung +50025=Offset +50026=Offset intermediate +50027=Radius +50028=Top rail +50029=Position +50030=Length +50031=Template +50032=Up +50033=Down +50034=Shape +50035=Hinge +50036=Top to top application +50037=Center from top application +50038=Center from top lock +50039=Depth +50040=General +50041=Center +50042=Thru +50043=Face to center line application +50044=Edge Type +50045=Over Material +50046=Send Feedback +50047=Weight +50048=Angle +50049=Face +50050=Secure +50051=Keyway +50052=Brand +50053=Folder +50054=Main Folder +50055=Jamb +50056=Light Up +50057=Light Lock +50058=Light Bottom +50059=Light Hinge +50060=Thickness Head +50061=Overlap Hinge +50062=Overlap Lock +50063=Overlap Top +50064=Delta T +50065=Exterior +50066=Number of Doors +50067=Jambs and Doors +50068=Order +50069=Disposition +50070=Customer +50071=Inv. Lock prof. +//Compo Name +50072=Flush Bolt +50073=Flush Pull +50074=Hinge +50075=Lock +50076=Louver Cut Out +50077=Mail Slot +50078=Over Head +50079=Pivot +50080=Roller Latch +50081=Stops And Closer +50082=Strike +50083=Edge pull +50084=Peep hole +50085=Light cut out +50086=Groove +50087=Rabbet +50088=EPT +50089=Raceway +50090=Face Decoration +//error messages +50100=Directory not founded +50101=Error +50102=Failed reading DDF file. Missing needed parameter {0}. +50103=Failed reading value +50104=Failed reading DDF file row # +50105=Row +50106=Invalid value in +50107=Empty file. +50108=You can not add a compo if there is not a door! +50109=Do you want to save this file ({0}) ? +50110=Question +50111=Add new door +50112=Remove door +50113=New Door +50114=File name already exists in the current directory ({0}). +50115=Caution +50116=Do you want to delete this file ({0}.ddf)? +50117=Confirm deleting ({0})?. +50118=Information +50119=Error in reading messages. There is no match with the number {0}. +50120=Error reading name {0} in {1}. Expected numeric match. +50121=Error reading {0} param in {1} compo: do not exist. +50122=Error in {0} param in {1} compo. +50123=Error reading {0} param in {1} compo: do not exist list. +50124=Error reading {0} param in {1} compo: {2}. +50125=Error in {0} param in {1} compo: do not exist value. +50126=Delete +50127=Error in EgtLoadMessages +50128=You can not save a file if there is not a door! +50129=Error in Project scene creation +50130=Error in reading: line {0}. +50131=Error in reading {0}: line {1}. Expected ':' after the name. +50132=Error in reading {0}: line {1}. Expected 'template' or 'shape'. +50133={0} has not been created. +50134=Error reading 'Template' in file {0}\{1}. Expetcted name. +50135=Error reading 'Template' in file {0}\{1}. File {0}\{2} .lua does not exist. +50136=Error in reading {0}: line {1}. It does not exist in the list of components in file 'Default.ini'. +50137=Error in reading {0}: line {1}. It is not a member of the list. +50138=This param will be initialized by default. +50139=Error in reading: line {0}. Expected {1}. +50140=All missing params will be initialized by default. +50141=Invalid expression in {0}. +50142=Remove compo +50143=Invalid expression. +50144=Warning +50145=Impossible to create the current door. +50146=Do you want to open a template? +50147=Error expression in {0}. {1} does not match anything. +50148=Invalid value. +50149=Caution: Weight is setted in OptionPage. Do you want to remove? +50150=Caution: Weight is setted in DDF. Do you want to add? +50151={0} is not a member of the current list of EdgeType. Check Bevel in option page. +50152=Do you want to save this file ({0})? +50153=Caution. Weight is setted in the current door. Do you want to remove? +50154=It is the bevel of the current door. Do You want to proced? +50155=Impossible to create a template if there is not a door! +50156=Error in reading ddf: door is not completed or ddf has been slpitted by '---' bad. +50157=Script Lua ( {0}\{1} )has not been found. +50158=Bevel {0} can not be acceptable in Jamb. +50159=Missing parameter in ddf! +50160=File {0} in directory {1} has not been found. +50161=parameter +50162=In file {0} param 'Default' must be numeric. +50163=Error in reading General Assembly in DDF +50164=In General Assembly: +50165=CompoDir not found : +50166=Jamb compo does not exist +50167=Empty Line +50168=No matching param +50169=Door disposition has been modify. +50170=Incongruity between the bevel, it has been resolved by default. +50171=In file StdTempate.ini is missing numeric param in [Type]. +50172=File does not exist. +50173=Definition type is not correct: +50174=Missing name of the new template! +50175=The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=Error in copying: {0} +50177=Do you want to save the current changes? +50179=Doors Compo Default.ini not found in {0} . +50180=Warning : {0} does not exist. +50181=Error in creating the print image +50182=Error executing print +50183=Some Doors could use this hardware, do you want to proceed deleting? +50184=Impossible to delete Hardware if there is no Hardware selected! +50185=Impossible to duplicate Hardware if there is no Hardware selected! +50186=Project must be saved before copying +50187=Do you want to copy all files ? {0} (No to copy only the current file) +50188=Export to machine +50189=Machine Directory not found +50190=Error in copying: {0} +50191=Impossible to copy a door if there is not a door! +50192=Impossible to export to machine a door if there is not a door! +50193=Impossible to print a door if there is not a door! +50194=Properties has been deleted +50195=The current ddf configuration ({0}) is different from the current program configuration ({1}).{2}To load the current ddf configuration you have to restart the program, do you want it? +50196=Configuration ddf ({0}) does not exist! +50197=Top Arch has been modified because of configuration. +50198=Bevel on lock edge would be inverted. +//Option +50200=Unit measure +50201=General +50202=LockEdgeOverMaterial +50203=HingeEdgeOverMaterial +50204=TopOverMaterial +50205=BottomOverMaterial +50206=Open Window +50207=Last Project +50208=Empty +50209=Option Page +50210=StartUp +50211=Unit measure new door. +50212=Directory Project +50213=Option Start +50214=Current Directory +50215=Edge Type +50216=Over Material +50217=Browse +50218=Close +50219=Bevel +50220=Bevel Up +50221=Bevel Down +50222=Door disposition in machining +50223=Save as template +50224=Matching +50225=Brand +50226=File +50227=Template +50228=Enable template +50229=Enable Order +50230=Open template door. +50231=Open window order. +50232=Directory Template +//Scene +50301=Refresh +50302=Add New Door +50303=Remove Door +50304=New Project +50305=Help +50306=Directory Machine +50307=Machine +50308=Door +50309=Wide Side Down (BU) +50310=Wide Side Up (BD) +50311=Resize +50312=Design +50313=Save as pdf +//Launcher +50400=Launcher +50401=New Project +50402=Open Project +50403=Open Last Project +50404=New Project +50405=New Hardware +50406=Elevation +50407=Project +50408=PO +50409=Line +50410=Save +50411=Print +50412=Cancel +50413=Hardware +50414=Dimensioning +50415=Duplicate +50416=Export to machine +50417=New Template +50418=Dimension +50419=New Directory +50420=Create Assembly +50421=Reload Directories +50422=Save As +50423=Reload Compo on Jamb +//Error messages +50501=Error reading {0} param in {1} compo: incomplete definition (look at StdTemplate.ini). +50502=Error reading {0} param in {1} compo: no matching (look at StdTemplate.ini and GeometryNameList.ini). +50503=Do you want to save? +50504=File name contains empty spaces, do you want to rename file deleting empty spaces? +50505=DDF is not an assembly, there are only: {0}, do you want to save? +50506=Impossible to find the first door (DO_1)! +50507=The swing is not a member of the swing list of single door. +50508=The swing of left door is not a member of the swing list of left door. +50509=The swing of right door is not a member of the swing list of right door. +50510=The swing of left door is on the right door and viceverse. +50511=The swing of left door is not a member of the swing list of left door. +50512=The swing of right door is not a member of the swing list of right door. +50513=Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=The swing are absolutly wrong! +50515=The first door is not realy the first, check the ddf. +50516=The current ddf contains {0} jambs. +50517=The current ddf does not contains doors! +50518=The current ddf is not an assembly. +50519=Impossible to open a ddf with no doors. +50520=The current ddf is an assembly. +50521=The current ddf is a jamb: {0}. +50522=The profile {0} is not a member of the {1} profile list. +50523=Missing profile on {0}. +50524={0} file open by another EgtDOORCreator {1}. +50525={0} file open by another EgtDOORCreator {1}. +50526=Directory {0} already exists! Do you want to overwrite it? +50527=Impossible to overwrite {0} +50528=Impossible to save the door out of the project! +50530=Property {0} does not exist in the list of {1}. Look at file "../Compo/Default.ini". +50531=The current material {0} does not exist in the list of material. Look at file "../Compo/Default.ini". +50532=Missing list of material at file "../Compo/Default.ini". +50533=Impossible to load more than one property at time. +50534=Property {0} does not exist in the list. Look at file "../Compo/Default.ini". +50535=Impossible to delete a project if there is not a project! +50536=Do you want to delete entire project? ( All doors will be deleted!) +50537=Do you want to delete subdirectory {0} ? ( All doors will be deleted!) +50538=Impossible to vreate a template door if there is not a door! +50539=Do you want to change project? +50540=The current ddf is a part of a frame, do you want to save? +50541={0} in reading {1}. +50542={0}: Directory does not exist! +50543=It has been renamed file: {0}, {1}. +50544=It has been created new file: {0}, {1}. +50545=It has been deleted file: {0}, {1}. +50546=Enable single door. +50547=Project +50548=The new configuration will take effect after restart. +50549=File {0} exist, but it is not in the correct Directory! +50550=Every componente on jambs will be relocated, do you want to continue +50551=The current parameters have been modified: +50552=Do you want to overwrite? +50553= has not been created. +50554=Parameter {0} is already deinfed in geometry {1}. +50555=Impossible to save. +50556=File has nge extension. +50557=Error in deleting file: {0} +50558=Impossible to import a different hardware! +50559=Open File Dialog +50560=The hardware part has not been generated correctly. +50561=Directory already exists +50562=Folder {0} does not exist. Check in OptionPage. +50563=Compo {0} does not exist. +50564=In group {0} at paramater {1} does not exist: {2} +50565=Brand {0} has not been found in HardwareManager. +50566=Template {0} has not been found in HardwareManager. +50567=Error in executing EgtCam5. +50568=Error in definition {0} in file GeometryNameList.ini . +50569=Error in definition {0} in file StdTemplate.ini . +50570=Nothing has been selected. +//Added General messages +50701=Lines +50702=Rectangle +50703=None +50704=Radius +50705=Angle +50706=Pos_x +50707=Top Arc +50708=Top Angle +50709=Properties +50710=Material +50711=Mach. +50712=HardwarePart +50713=Assemby +50714=Total Dimension +50715=Depth +50716=Overlap Bottom +50717=Thickness Bottom +50718=Depth Bottom +50719=Delta Bottom +50720=GoToAssembly +50721=New Geometry +50722=Geometry Name +50723=Type Hardware +50724=Parameter +50725=Part Dimension +50726=Apply +50727=Frame +50728=Refresh Directory +50729=General +50730=Report +50731=Opposite face +// ----- EgtBEAMEditor ------ +60951=Cut +60952=Longitudinal Cut +60953=Double Cut +60954=Ridge or Valley Cut +60955=Saw Cut +60956=Slot +60957=Front Slot +60958=Birds Mouth +60959=Hip or Valley Rafter Notch +60960=Ridge Lap +60961=Lap Joint +60962=Notch/Rabbet +60963=Block House Half Lap, Stairs Riser Dado +60964=Seathing Cut +60965=French Ridge Lap +60966=Chamfer +60967=Block House Half Lap +60968=Block House Front +60969=Pocket +60970=Drilling +60971=Tenon +60972=Mortise +60973=Mortise Front +60974=House +60975=House Mortise +60976=Dovetail Tenon +60977=Dovetail Mortise +60978=Dovetail Mortise Front +60979=Marking/Labeling +60980=Text +60981=Simple Scarf +60982=Scarf Joint +60983=Step Joint +60984=Step Joint Notch +60985=Planing +60986=Profile Front +60987=Profile Head concave +60988=Profile Head convex +60989=Profile Head cambered +60990=Round Arch +60991=Profile Head +60992=Sphere +60993=Triangle Cut +60994=Tyrolean Dovetail +60995=Dovetail +60996=Free Contour +60997=Outline +60998=Aperture +61001=Distance from beam start to the reference point +61002=Distance from the reference edge to the reference point +61003=Distance from the reference side to the reference point (orthogonal) +61004=Angle between cut edge and reference edge +61005=Inclination between face and reference side +61008=Limit of the 2 ends, binary code +61009=Inclination to the reference side +61010=Depth: If P11 is zero, then the face of the cut dispreads to the neigbour-sides or opposite-side to referenceside +61011=Length: If P12 and P04 equal to zero, the processing is performed along the whole component length +61012=Angle in face at start +61013=Angle in face at end +61015=Distance from the reference point to the reference edge +61016=Angle between the first cutting edge and the reference edge +61017=Inclination of the first cutting towards the reference side +61018=Angle between the second cutting edge and the reference edge +61019=Inclination of the second cutting towards the reference side +61023=Inclination between the first face and the reference side +61024=Inclination between the second face and the reference side +61025=Depth +61027=Angle in face at reference edge at start +61028=Angle in face at reference edge at end +61029=Angle in face in opposite to reference edge at start +61030=Angle in face in opposite to reference edge at end +61033=Displacement to the reference side +61036=Angle to the reference edge in the cut face +61037=Depth, orthogonal to the reference side +61038=Length +61041=Distance to the reference point orthogonal to the reference side P03 = 0: Slot on one of the 4 sides of the component. P03 > 0: Slot on one of the 2 front sides of the component +61042=Limit of the 6 faces of the slot, binary code +61043=Angle to the reference edge in the reference side +61045=Interior angle at reference point +61046=Interior angle at opposite of reference point +61047=Addition to P09 +61048=Depth orthogonal to the reference side +61049=Length +61050=Thickness +61051=Displacement of the entrance edge at reference point +61052=Displacement of the entrance edge at opposite of reference point +61055=Distance to the reference point orthogonal to the reference side +61056=Limit of the 6 faces of the Frotn Slot, binary code +61059=Angle between the longitudinal axis of the slot and the reference side +61060=Depth +61061=Length +61062=Width +61065=Location of P09/P10, if P09>0 and P10>0. If P04=-1, then the location must be defined on the machineside +61066=P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole. +61067=Angle to the reference edge in the reference area +61068=Inclination between face 1 and reference side +61069=Inclination between face 2 and reference side +61070=First cut angle of the counterpart. If P09 is zero, the limit face beside face 1 is parallel to component side. +61071=First cut inclination of the counterpart. If P10 is zero, the limit face beside face 1 is parallel to component side. +61072=Depth 1 orthogonal to reference side +61073=Depth 2 orthogonal to reference side +61074=Grooving depth in the transverse direction of the component. If P13 is zero, then its value must be calculated:P13=WRS-P02 +61075=Height Counterpart. Zero means: no limit. Measurement orthogonal to face 1 (P07). +61076=Width Counterpart. Zero means: no limit. Measurement orthogonal to face 2 (P08). +61079=P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole +61080=Angle notch 1 to the reference edge in the reference area +61081=Angle notch 2 to the opposite reference edge in the reference area +61082=Inclination between base area of notches and reference side +61083=Depth orthogonal to reference side +61084=Width of notch 1. If this value is equal 0, then the notch is not limited. +61085=Width of notch 2. If this value is equal 0, then the notch is not limited. +61087=0: Reference point on referene edge. 1: Reference point on the opposite edge +61088=Angle to the reference edge in the reference side +61089=Depth of Half Lap +61090=Width of Half Lap +61091=Drill hole diameter +61094=Displacement to the reference side +61095=Limit of the 6 faces of the lap, binary code +61096=Angle to the reference edge in the reference side +61098=Angle between edge and reference side in face +61099=Angle in the floor face +61100=Angle between base face and one face of lap +61101=Distance (orthogonal) from reference side to point below reference point +61102=Length +61103=Chamfer angle +61104=Grooving depth (length of the lapped scarf in transverse direction). If P14 is zero, then its value must be calculated: P14=WRS-P02 +61107=Limit of the 6 faces of the notch/rabbet, binary code +61108=Notch/Rabbet depth +61109=Notch/Rabbet length +61110=Notch/Rabbet width +61113=Depth of the Half Lap on the reference side +61114=Depth of the Half Lap opposite of the reference side +61115=Length of the Half Lap / Dado +61117=Depth of Seathing Cut +61118=Length of Seathing Cut +61120=0: Reference point on reference edge; 1: Reference point on the opposite edge +61121=Angle to the reference edge in the reference side +61122=Drill hole diameter +61124=Input of edge(s) to be beveled, binary code: Bit 0=edge 1 ; Bit 1=edge 2; Bit 2=edge 3; Bit 3=edge 4. Example: P04=9: edge 1+4; P04=3: edge 1+2 +61125=Depth +61126=Length: If P12 is equal to zero, the processing is performed along the whole component length. +61127=Shape for bevel exit: 0 = orthogonal, 1 = at 45 deg, 2 = round; +61129=Depth orthogonal to reference side of the lap 2 and 4. If P03 is zero, then its value must be calculated: P03=HRS +61130=0:all laps are symmetric to each other; 1:lap on reference edge moved to start beam, lap in opposite of reference edge moved to end beam; 2: lap on reference edge moved to end beam, lap in opposite of reference edge moved to start beam; +61131=P05=1: drilhole for drop rod, P05=0: no drillhole. The machines defines place and direction of the drillhole. +61132=lap 1: Depth +61133=lap 1: Length +61134=lap 2: Depth +61135=lap 2: Length +61136=lap 3: Depth +61137=lap 3: Length +61138=lap 4: Depth +61139=lap 4: Length +61140=Distance from end of arc orthogonal to the reference side +61141=Radius of arc +61142=Distance reference point to center of arc +61143=Which arc (A, B,C or D) is to produced, binary code +61145=0:only one lap on reference side; 1:one lap on reference side and one on the opposite side +61146=Angle to the reference edge in the reference side +61147=Depth at reference point +61148=Depth opposite to the reference point +61149=Depth at reference edge +61150=Length +61153=Limit of the 6 faces of the pocket, binary code +61154=Rotation angle around the local z-axis of the cuboid +61155=Rotation angle around the local y-axis of the cuboid, rotated with P06 +61156=Rotation angle around the local x-axis of the cuboid, rotated with P06 and P07 +61157=Internal angle at the reference point +61158=Depth of reference point orthogonal to reference side +61159=Length of Half Lap +61160=Width of Half Lap +61163=Distance from the reference face to the reference point. P03 = 0:Drilling on one of the 4 sides of the component. P03 <> 0:Drilling on one of the 2 front sides of the component. +61164=P03 = 0:Angle to the reference edge in the reference side. P03 <> 0:Angle in the front side. +61165=Inclination between drilling and reference side. P03 = 0: Inclination between drilling and reference side. P03 > 0: Inclination between drilling and front side +61166=Depth, orthogonal to reference side or front side. +61167=Drill hole diameter +61170=Rounding +61171=Chamfer +61174=Angle between axis of the tenon and reference side +61175=Radius for P04=4 +61176=Tenon height +61177=Tenon width +61178=Margin on the reference side +61179=Margin opposite the reference side +61182=Displacement to the reference side +61183=Rounding +61184=Angle between axis and reference edge +61185=Inclination between strut and reference side +61186=Inclination of hole side walls towards reference side +61187=Radius for P04=4 +61188=Mortise depth +61189=Mortise width +61190=Height of strut +61191=Margin on the reference point +61192=Margin opposite the reference point +61193=Inclination of hole front side towards reference side +61196=Rounding +61199=Angle between axis of the tenon and reference side +61200=Radius for P04=4 +61201=Mortise depth +61202=Mortise width +61203=Margin on the reference side +61204=Margin opposite the reference side +61205=Processident of the associated tenon or dovetail tenon +61206=Processident of the associated mortise or dovetail mortise +61209=0:with rounding at the bottom; 1:without rounding, unbounded +61210=Angle between edge and reference edge +61212=Angle between axis of the tenon and reference side +61213=Middle flattening +61214=Angle of cone +61215=Tenon height +61216=Diameter of the curve: If P12 < 0, then the radius must be defined on the machineside. +61217=Margin on the reference side +61218=Margin opposite the reference side +61221=Displacement to the reference side +61222=0:with rounding at the bottom; 1:without rounding, unbounded +61223=0:with elongation; 1:with pocket +61224=Angle between axis and reference edge +61225=Inclination between strut and reference side +61226=Middle flattening +61227=Angle of cone +61228=Mortise depth +61229=Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61230=Height of strut +61231=Margin on the reference point +61232=Margin opposite the reference point +61235=Displacement to the front side +61236=0=with rounding at the bottom; 1=without rounding, unbounded +61237=0=with elongation; 1=with pocket +61240=Angle between axis of the tenon and reference side +61241=Middle flattening +61242=Angle of cone +61243=Mortise depth +61244=Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61245=Margin on the reference side +61246=Margin opposite the reference side +61249=Position and alignment of the text. P04 = 0 if there is no text. +61250=Angle between axis and reference edge. If P06 equals 180°, then a horizontal line is defined, P12 defines the length of the line. +61251=Interior angle. If P07 equals zero, 2 single markings have to be produced. +61252=Width of quadrangle. If P11 equals zero, there is only a single marking. +61253=Height of quadrangle. If P12 equals zero, marking is limited by the edge opposite to the reference edge. +61254=Height of text. If P13 equals zero, the machine determines the text height. +61255=Text (String max. 256 characters) +61258=Angle between axis and reference edge +61259=Alignment vertical. 0 = bottom, 1=middle, 2=top +61260=Alignment horizontal. 0 = left, 1=middle, 2=right +61261=Alignment in case of a multiline text. 0 = left-aligned, 1=centered, 2=right-aligned. A new line must be defined with this 2 letters: \n +61262=Letters standard or horizontal placed. 0 = standard, 1=letters horizontal placed +61263=Height of text. If P13 equals zero, the machine determines the text height. +61266=Depth at the reference side +61267=Depth at the opposite of reference side +61268=Length of the overlap +61269=Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61270=Drilling 2 diameter. Placed at 2/3 P13 +61272=Angle of inclination of the lapped scarf base +61273=Shape of the lapped scarf or classic data identification: 1:when cutting orthogonal to reference side; -1:when cutting orthogonal to base side; 0:classic definition, P10 and P12 are not used +61274=Length of the lapped scarf base +61275=Depth of the lapped scarf base +61276=Depth of the lapped scarf base orthogonal to reference side +61277=Length +61278=Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61279=Drilling 2 diameter. Placed at 2/3 P13 +61281=Type of heel notch:0=normal; 1=tapered +61282=Inclination strut +61283=Depth step joint +61284=Depth heel notch +61285=Height tenon. Which implementation (A or B) is used depends on the machine +61286=Width tenon +61289=Type of heel notch: 0=normal; 1=tapered +61290=Inclination between strut and reference side +61291=Width of the notch +61292=Depth step joint +61293=Depth heel notch +61294=Height of strut +61295=Depth of mortise. Which implementation (A or B) is used depends on the machine +61296=Width of mortise +61298=Specification of side(s) to be planed; binary coded +61299=Planing depth +61300=Length of the area to be planed +61303=Rotation angle of the first curve of the profile +61304=Rotation angle of the profile towards the reference edge +61305=Offset angle +61306=Radius of the first curve +61307=Radius of the second curve +61309=Radius +61310=Depth +61311=Displacement +61312=Depth +61313=Displacement +61315=Radius +61316=Depth +61317=Displacement +61318=Depth +61319=Displacement +61321=Profile length +61322=Depth at the reference point +61323=Maximum depth of profile +61324=Minimum depth of profile +61325=Depth at the profile end +61326=Premill: 0=round; 1=angular +61328=Depth of the arch segment +61329=Length of the arch segment +61331=Type of arc (convex, concave), binary coded. See table below. +61332=Length of lap 1 +61333=Depth of lap 1 +61334=Displacement arc 1 +61335=Horizontal length arc 1 +61336=Vertical length arc 1 +61337=Camber arc 2 +61338=Length of lap 2 +61339=Depth of lap 2 +61340=Displacement arc 2 +61341=Horizontal length arc 2 +61342=Vertical length arc 2 +61343=Camber arc 2 +61344=Length of lap 3 +61345=Depth of lap 3 +61348=Distance from the reference side to the reference point +61349=Radius +61350=Start offset +61351=Length +61354=Distance from the reference side to the reference point +61355=Normal vector 1: Length of X-component +61356=Normal vector 1: Length of Y-component +61357=Normal vector 1: Length of Z-component +61358=Normal vector 2: Length of X-component +61359=Normal vector 2: Length of Y-component +61360=Normal vector 2: Length of Z-component +61362=Distance between "inside" an side of part +61363=Distance orthogonal to the reference side +61364=0:"inside" at reference edge, 1:"inside" at opposite of reference edge +61365=0:Without rebate or mitre, -1:With mitre, >0:With rebate +61366=Angle to the reference edge in the reference side +61367=Width +61368=Depth +61369=Inclination +61370=Height +61371=Radius +61372=Length of tool (part of arc) +61373=0:Angular corner joint, 1:Straight T-wall connection +61374=Length +61375=0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61377=Distance between "inside" an side of part +61378=Distance orthogonal to the reference side +61379=0:"inside" at reference edge, 1:"inside" at oppostite of reference edge +61380=0:Without rebate or mitre, -1:with mitre, >0:with rebate +61381=Inclination +61382=Depth 1 +61383=Depth 2 +61384=0:European Dovetail, 1:American Dovetail +61385=Length +61386=0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61387=Depth +61388=Mode: 0=contour only, 1=countersink completely. Only for closed contours. +61389=Contour type +61390=Parameter depends on contour type(P13) +61391=Parameter depends on the contour type(P13) +61400=Reference point on referene edge +61401=Reference point on the opposite edge +61402=Reference point on referene edge +61403=Reference point on the opposite edge +61404=orthogonal +61405=at 45 deg +61406=round +61407=all laps are symmetric to each other +61408=lap on reference edge moved to end beam. lap in opposite of reference edge moved to start beam +61409=lap on reference edge moved to start beam. lap in opposite of reference edge moved to end beam +61410=only one lap on reference side +61411=one lap on reference side and one on the opposite side +61412=with rounding at the bottom +61413=without rounding, unbounded +61414=with elongation +61415=with pocket +61416=bottom +61417=middle +61418=top +61419=left +61420=right +61421=left-aligned +61422=centered +61423=right-aligned +61424=standard +61425=letters horizontal placed +61426=when cutting orthogonal to reference side +61427=when cutting orthogonal to base side +61428=classic definition, P10 and P12 are not used +61429=normal +61430=tapered +61431=round +61432=angular +61433="inside" at reference edge +61434="inside" at opposite of reference edge +61435=Angular corner joint +61436=Straight T-wall connection +61437=Processing on the reference side and opposite the reference side +61438=Processing only on the reference side +61439=Processing only opposite the reference side +61440=European Dovetail +61441=American Dovetail +// ---Custom Parameter (Q) +61451=Chamfer depth +61452=0=Default; 1=Longitudinal machining with saw blade +61453=Wood thickness for processing support with Q02 +61454=0=Centered Leadin 1=Inside Leadin +61455=0=Default; 1=Machine with mill side +61456=0=Default; 1=Use saw blade +61457=0=Default; 1=Only chamfer +61458=0=Default; 1=Max depth +61459=0=Default; 1=Chipper; 2=Chipper side; 3=Mill; 4=Mill side +61460=0=Default; 1=Machine outline with smallest diameter mill; 2=Corner cleaning +61461=0=Default; 1=Max radius permitted on closed pockets +61462=Tool diameter for Q05 +61463=Tool diameter for Q07 +61464=0=Rounded corner; 1=Drill on corner; 2=Sharp corner +61465=Drill diameter when P05=1 +61466=0=Default; 1=Roughing with saw blade +61467=Anti-splint: 0=No; 1=With saw blade; 2=With mill +61468=Increase pocket size +61469=Clean corners: 0=No; 1=With conical mill after manual removal of scraps; 2=With small conical mill; 3=With groove +61470=0=Default; 1=Outline only ; 2=Drill or Pocket +61471=0=Default; 1=Machine from only one side +61472=Increase/decrease P01 value for drills in tenons +61473=0=Chip breaker drilling; 1=Chip discharge drilling +61474=Chamfer depth when P05=1 +61475=Decrease tenon depth +61476=Decrease tenon width +61477=Decrease tenon height +61478=Decrease tenon depth +61479=Increase/decrease tenon shape +61480=Increase/decrease tenon height +61481=Increase mortise depth +61483=Machining depth +61484=Increase P10 dimensions +61485=0=Default; 1=Chipper +61486=Decrease P14 length +61487=Decrease P15 width +61488=Overmaterial for finishing +61489=Number of chamfer corrugation parts on the length +61490=0=Default; 1=Disable step milling +61491=0=Default; 1=Enable top chamfer +61492=0=Default; 1=Top chamfer with blade +61493=Wood thickness for processing support +61494=Enable anti-splint +61495=Anti-splint depth +61496=Max elevation (0=Default, >10=By value) +61497=0=Default; 1=Saw blade +61498=0=Default; 1=Disable tool length check +61499=0=Default; 1=Saw on top face 2=Saw on sides and below; 3=Saw on closed faces; 4=Saw on sides and below on closed faces +61500=0=Default; 1=Saw on top face 2=Saw on sides and below; 3=Saw on closed faces; 4=Saw on sides and below on closed faces +61501=0=Default; 1=Machining with horizontal mill if above or below (disable blade) +61502=0=Default; 1=Use chipper if below +61503=0=Centered Leadin and Leadout 1=Inside Leadin and leadout +61504=0=Default; 1=Machine with mill side like blade; 2=Machine with mill side like blade only on top faces +61505=0=Default; 1=Machine like LongCut +61506=0=Default; 1=Machine with mill +// ----- EgtBEAMWALL - BTLParam ----- +61601=???SN +61602=Enable +61603=Description +61604=L +61605=W +61606=H +61607=Material +61608=Required +61609=In production +61610=Done +61611=Rotate +61612=Group +61613=Unit Time +61614=Parameter +61615=Value +61616=Min +61617=Max +61618=Single member number +61619=Assembly number +61620=Order number +61621=Designation +61622=Annotation +61623=Subgroup/Storey +61624=Group +61625=Package +61626=Material +61627=Timber grade +61628=Quality grade +61629=Count +61630=Colour +61631=Transparency +61632=Planing length +61633=Start offset +61634=End offset +61635=Transformation: Origin +61636=Transformation: X-axis dir. vect. +61637=Transformation: Y-axis dir. vect. +61638=Camber: Reference side +61639=Camber: P01,P02,P03,P04 +61640=Part offset: ref. side fix clamp +61641=Part offset: P11,P12,P13,P14 +61642=Processing quality +61643=Recess +61644=Storey type +61645=Element number +61646=Layer +61647=Module number +61648=USERATTRIBUTE +61649=Comment +61650=Grain direction: X,Y,Z +61651=Grain direction: Align +61652=Reference side +61653=Reference side: Align +61654=Alignment: Location +61655=Alignment: Endtype +61656=Material type: Group +61657=Material type: Specification +61658=AUTOMATIC +61659=VISIBLE +61660=FAST +61661=MANUAL +61662=CEILING +61663=ROOF +61664=WALL +61665=inactiv +61666=BR +61667=TR +61668=BA +61669=TA +61670=HC +61671=VC +61672=AC +61673=R +61674=A +61675=D +61676=Batten +61677=Cladding +61678=Massive timber +61679=Membrane +61680=Gypsum Board +61681=Gypsum Fibre +61682=Insulation +61683=Sheet Component +61684=Facade Panel +61685=Profiled Panel +61686=Plaster +61687=Reference side 1 +61688=Reference side 2 +61689=Reference side 3 +61690=Reference side 4 +61691=UID +61692=Project number +61693=Project name +61694=Project part +61695=GUID +61696=Listname +61697=Customer +61698=Architect +61699=Editor name +61700=Delivery date +61701=Export date +61702=Export time +61703=Export release +61704=Language +61705=Range +61706=Computername +61707=User name +61708=Path & name of CAD-File +61709=Path & name of BTL-File +61710=STANDARD +61711=EXTENDED +61712=Vol unit +61713=Vol tot +61714=Time unit +61715=Time tot +61716=Total parts number +61717=Total volume +61718=Total time +61719=Total estimed time +61720=Remaining time +61721=Rawpart counter +61722=BTL part counter +61723=Added part counter +61724=Part in rawpart counter +61725=Done part counter +61726=Quantity +61727=Print PDF +//Warehouse +61751=Current S +61752=Current L +61753=StartOffset +61754=Kerf +61755=Offset +61756=S Parameters +61757=L Parameters +61758=New Value: +61759=W +61760=L +61761=Confirm +61762=Save +61763=Cancel +61764=Error +61765=Input value already present +61766=Input value not correct +61767=Input pair already present +61768=One or more input values not correct +61769=Attention +61770=Selected parameter is equivalent to current L/S. Are you sure you want to remove it? +61771=SectionXMaterial +61772=Alias +61773=Values +61774=Quantity +61775=Min thickness +61776=Max thickness +61777=Increment Max thickness of the last range before adding a new range +// +61801=Custom +61802=Default +61803=L +61804=T +61805=Process +61806=Section time +61807=Part time +61808=Name +61809=PDN +61810=DO +61811=X position +61812=Y position +61813=Added +61814=Done +61815=ID +61816=Start offset +61817=% Used +61818=Waste +61819=BTL File Name +61820=List Name +61821=Export Date +61822=Creation Date +61823=Delete +61824=Face +61825=Group +61826=Modify +61827=Save +61828=Cancel +61829=Nesting +61830=Viewer +61831=Optimizer +61832=Configuration +61833=Optimize +61834=Update BTL +61835=Go to optimization +61836=Filter type +61837=Search +61838=Export project +61839=Import project +61840=Import BTL +61841=Copy to Clipboard +61842=DisplayIndex +61843=Column name +61844=CanUserReorder +61845=CanUserResize +61846=CanUserSort +61847=IsReadOnly +61848=Visible +61849=Variable Path +61850=Type +// +61851=This part modification will cause the removal of the part from {0} raw parts. Do you want to proceed anyway? +61852=Impossible create feature with this values +61853=Impossible create part with this values +61854=Impossible create bar with this values +61855=Impossible create wall with this values +61856=Value outside minimum and maximum +61857=Impossible to insert a quantity inferior to the number of parts already in rawparts! +61858=Impossible to modify these values +61859=Error in machine parameter writing +61860=Save machine parameters modification? +61861=Save default values modification? +61862=Changing type second path will be deleted. Do you want to proceed? +61863=To produce part number reached: +61864= from BTL; +61865= added. Do you want to add another one? +61866=Selected part has different section from selected bar. Impossible to add. +61867=Selected part lenght is more then the selected bar lenght. Impossible to add. +61868=Selected part has different height from selected wall. Impossibl to add. +61869=Error in macro file execution! +61870=Impossible create a Macro without selecting a Feature or with empty name +61871=File not found! +61872=Impossibie deleting current project +61873=Impossibile deleting the project because already linked to an optimization +61874=Impossibile deleting the project because some parts are already sent to production +61875=Do you want to save the project modifications? +61876=Impossible creating a new file! +61877=Save project modification before continuing? +61878=Impossible proceding with a new unsaved project! +61879=Type of current machine is both Beam and Wall. Select the type you want to set the project to: +61880=Select one of the available machines and/or types. Otherwise cancel the project import. +61881=The opened project type is not compatible with the current machine type +61882=Do you want to save the modifications to the DataGrid columns? +61883=The columnn specified as "{0}" in the "{1}" table in the datagrid columns ini file was not found in the program +61884=Select the machine you want to associate to the project: +61885=The machine linked to the opening project cannot be found among the available machines +61886=Machine +61887=Impossible creating the inserted rawparts quantity +61888=How many copies of the rawpart do you want to create? +61889=Long Drill Area +61890=Min Rule +61891=Can't send feedback from Optimizer if there is no open Prod +// +61900=Change paramter +61901=Verify +61902=Simulate +61903=New raw part +61904=Add to raw part +61905=Copy part +61906=Add part +61907=Remove part +61908=Copy feature +61909=Create macro +61910=Add feature +61911=Remove feature +61912=Produce rawpart +61913=Produce all rawpart +61914=Copy rawpart +61915=Remove rawpart +61916=Reorder parts +61917=Move up part +61918=Move down part +61919=Remove part +61920=Warehouse +61921=Add project to optimization +61922=Go to project +61923=Statistics +61924=Reset +61925=Show all parts +61926=Show solid +61927=Show building +61928=Verify all +61929=Can't change machine because the Proj is already linked to a Prod +61930=Inputs +61931=Outputs +61932=Calculate Flip & Rotation +61933=Unlock Flip +61934=Unlock Rotation +61935=Length +61936=Width +61937=Offset +61938=Kerf +61939=Edit +61940=Reset +61941=Choose machine +61942=BTL file already imported and optimized. Do you want to import it again? +61943=BTL file already imported. Do you want to overwrite it? +61944=Shift parts +61945=Shift direction +61946=Shift length +61947=Parts can't be shifted outside the raw part +61948=The inserted shift value is not valid +61949=Search & Filter +61950=Parameter Type +61951=Parameter Value +61952=R +61953=A +61954=P +61955=D +61956=All +61957=Filtered +61958=Update +61959=Append +61960=Check the parts you would like to add to update BTL +61961=Change material +61962=Project material +61963=Warehouse material +61964=Standard +61965=From BTL +61966=Save +61967=Do NOT save +61968=Waiting for optimizer save +61969=Cancel +// +62500=Supervisor +62501=Channel +62502=OPMode +62503=Produce All +62504=Done RawPart +62505=Reset RawPart +62506=Delete RawPart +62507=Print Label +62508=Done Part +62509=Resume started processing? +// Loading +63000=Project opening +63001=Loading project geometries +63002=Loading machining groups +63003=Loading production data +63004=Optimization opening +63005=Loading parts +63006=Loading graphics +63007=Project saving +63008=BTL file importing +63009=Reading BTL file +63010=Project exporting +63011=Loading environment +63012=Saving geometry +63013=Saving data on Db +63014=Modifying parameters +63015=Part viewer opening +63016=Adding export info +63017=Exporting... +63018=Project importing +63019=Loading project +63020=Creating imported project +63021=Modifying materials +// ----- FromLua ----- +65001=Rawpart ({0} x {1} x {2}) bigger then machine maximum rawpart ({3} x {4} x {5}) +// ----- OmagCUT ----- +// General +90001=CURRENT MACHINING +90002=DIRECT CUTS +90003=CAD CUTS +90004=FRAMES +90005=MACHINE +90006=OPTIONS +// Current Machining +90101= +// Direct Cuts +90201=Manual move +90202=Single cut +90203=Multiple cuts +90204=Grid cuts +90205=MTH +90206=Leveling cuts +90207=Saw test +90208=Saw probe +90209=Copy template +90210=Acquire P1 +90211=Acquire P2 +90212=Laser +90213=Depth +90214=Length +90215=Direction +90216=Side angle +90217=Number +90218=Dimension +90219=Number X +90220=Dimension X +90221=Number Y +90222=Dimension Y +90223=Spindle side cut +90224=Saw +90225=Draw +90226=Width +90227=Overlap +90228=Offset +90229=C Axis Lock +90230=Execute +90231=Polishing +90232=Saw thickness +90241=Saw probing +90242=Probing in progress... +90243=Probing succesfully completed +90244=Error in saw probing +90245=New template name +90246=Probing canceled by user +90250=Line +90251=Arc +90252=Remove +90253=Close +90254=Save +90255=Test +90256=Test work position +90257=Testing work position... +90258=Single drill +// Cad Cuts +90301=Simulate +90302=Execute +90303=New +90304=Load +90305=Save +90306=Save as +90307=New project name +90308=CSV +90309=Vein Match +90310=Export +90311=Tool +90312=Machining +90313=Photo camera failed +90314=Error in NC program generation +90315=Error in NC program transmission +90316=Not connected to the machine +90317=NC program transmitted +90318=NC program refused by machine +90319=NC program already sent, resend ? +90320=Different machine +90321=Reduced some machinings to avoid interference +90322=Missing tools : +90323=Background photo taken +90324=Contour recognition failed +90325=Error saving statistics +90326=Confirm restart from phase {0} ? +90327=New Ruined Parts +90328=Parts Area : +90329=To be Produced : +90330=NC program already sent, new slab ? +// NestPage +90331=Insert part +90332=Park part +90333=Remove part +90334=Select all +90335=Deselect all +90336=Reset +90337=One or more parts with non-compatible thickness, material or finish +90338=Rotation beyond the limits +90339=Rotation impossible +90340=Automatic nesting in progress +// SplitPage +90341=On/Off +90342=All On +90343=All Off +90344=Extend/Reduce +90345=Start Ext/Red +90346=End Ext/Red +90347=Start Cnt/Out +90348=All Starts Out +90349=All Starts Center +90350=Automatic computation failed +90351=Saw too big for vacuum use +90352=End Cnt/Out +90353=All End Out +90354=All End Center +90355=All Extend +90356=All Reduce +90357=Modify +90358=Auto +90359=Restart +// MoveRawPart +90361=Remove +90362=Part too small : can not be moved +90363=Selected position already occupied +90364=Part too havy : can not be moved +90365=Part beyond strokes : can not be moved +// SplitPage 2 +90371=Pause On/Off +90372=Pause +90373=Start Modif. +90374=End Modif. +90375=Elongation +90376=Invert +// DrawPage +90381=Part Count +90382=Measure +90383=Side angles +90384=Mark Top +90385=Parametric Draw +90386=Select a contour +90387=No editable sides +90388=Name +90389=Trf Data +90390=Order Code +90391=Order Description +90392=Material Code +90393=Surface Code +90394=Thickness +90395=Select one or more holes +90396=Part Code +90397=Engrave +90398=Csv Data +90399=All machinings updated +90400=Top Edge +// Component +// Massimo 17 caratteri senza immagine e massimo 12 con l'immagine +90401=Triangle +90402=Rectangle +90403=Trapezium +90404=Quadrilateral +90405=Winder +90406=Sill +90407=Kitchen top +90408=Vanity top +90409=Others +90410=2Sides 1Ang +90411=3Sides +90412=Isosceles +90413=Right +90414=Scalene +90415=Scalene +90416=4Sides 1Ang +90417=3Sides 2Ang +90418=3Sides 2Diag +90419=4Sides 1Diag +90420=4Sides 3Diag +90421=4Sides 3Ang +90422=4Sides 3Ang +90423=Right Angle +90424=Chamfered Right Angle +90425=Aligned Angle +90426=Chamfered Aligned Angle +90427=Part A +90428=Part B +90429=Angle +90430=Chamfered Angle +90431=Ellipse +90432=Oval +90433=Arc +90434=Arc LHF +90435=Arc LLH +90436=Arc LLF +90437=Rounded Rectangle +90438=Convex +90439=Hole +90440=2 Holes +90441=3 Holes +90442=Arc RHa +90443=Polygon +90444=Bottom Hole +90445=Dxf +90446=Recess +90447=Internal Features +90448=Add +90449=Remove +90450=Confirm +// Import +90451=Use layers +90452=Use regions +90453=Reset +90454=mm +90455=inch +90456=Use closed curves +90457=Side angle +90458=Drip +90459=Angle +90460=Offset +90461=Depth +90462=Shortening +90463=DXF import +90464=Drill bottom +90465=Number +90466=Offset2 +90467=Order +90468=List +90469=Name +// Component 2 +90470=Recess engravings +90471=Engravings +90472=TriangleCH +90473=TriangleRT +90474=TrapeziumRtA +90475=3Sides 2Ang +90476=Nuova soglia +// FastGrid +90480=Order name +90481=N. slab +90482=Last slab +90483=Piece type +90484=Insert pieces +90485=Confirm order +// Open +90491=Invalid project +90492=Project with collisions. To load disable whole cuts guard. +// RawPart +90499=Undefined Raw part +90500=Rotation +90501=Rectangle +90502=By points +90503=Length +90504=Width +90505=Thickness +90506=Offset X +90507=Offset Y +90508=Kerf +90509=Material +90510=Damaged area +90511=New +90512=Erase +90513=Points +90514=Add +90515=Remove +90516=Max length = +90517=Max width = +90518=Negative thickness not allowed +90519=Min X offset = +90520=Min Y offset = +90521=Min kerf = +90522=Max kerf = +90523=Raw probe +90524=Ok +90525=Raw probing +90526=Probing in progress... +90527=Probing succesfully completed +90528=Error in raw probing +90529=From draw +90530=From laser +90531=Close +90532=Error in laser point acquisition +90533=Outline +90534=Saw too big for probing +90535=From photo +//ChooseMachining +90536=Choose sawing +90537=Choose auxiliary machining +90538=Choose drilling +90539=Choose milling +90540=None +90541=Drilling +90542=Milling +90543=Both +90544=Choose Current Machining +90545=Choose waterjet +90546=Waterjet Cut +90547=Error in the position or size of the raw +90548=Max X offset = +90549=Max Y offset = +90550=Choose pocketoing +// Simulation +90551=Complete simulation +90552=Outstroke +90553=Tool direction unreachable +90554=Error +90555=ERROR +90556=Error in generation! +90557=Simulation +90558=One step at a time +90559=Play/Pause +90560=Stop/Home +90561=Pause +90562=Stopped simulation +90563=Mach view +90564=Home +90565=Time +90566=Length +90567=Parts Area +90568=Usage +90569=Estimations +90570=Details +// FrameCut +90601=Along X +90602=Along Y +90603=Remove +90604=Roughing +90605=Finishing +90606=Side finishing +90607=Mirror +90608=Top clearance +90609=Side clearance +90610=Trim start +90611=Trim end +90612=Single cut +90613=Arc +90614=Guide +90615=Section +90616=Guide +90617=Rad +90618=Ang +90619=Error : radius smaller then section width +90620=Error : frame creation failed +90621=X clearance +90622=Y clearance +90623=Opposite Side +// Machine +90701=Msg_Ita.xpi +90705=Machine data +90706=Tool DB +90707=Machining DB +90708=Machine +90709=Statistics +90715=New +90716=New +90717=Save +90718=Delete +//ToolsDb +//param +90719=Tool holder length +90720=Core +90721=Name +90722=Position +90723=Head +90724=Exit +90725=Speed +90726=Standard +90727=Maximum +90728=Feed +90729=Standard +90730=Tip +90731=Lead in +90732=Lead out +90733=Coolant +90734=Compensation +90735=Over material +90736=Longitudinal +90737=Radial +90738=Max power +90739=Min feed +90740=Max depth +90741=Length +90742=Diameter +90743=Thickness +90744=Cutter +90745=Notes +90746=Serial Number +90747=Code +90748=Supplier +90749=End Life +//tools families +90751=Sawblade +90752=Drillbit +90753=Mill +90754=Cupwheel +90755=Waterjet +90756=Polishingwheel +//Tool Setup +90759=Default tool position already occupied +//MachiningsDb +//param +90761=Name +90762=Depth +90763=Side angle +90764=Invert +90765=Step type +90766=Mach. side +90767=Head side +90768=Start position +90769=Lead in +90770=Link +90771=Lead out +90772=Use curve +90773=Tolerance +90774=Depth step +90775=Standard +90776=Depth step +90777=Inner arc +90778=Outer arc +90779=Slowing length +90780=Starting +90781=Ending +90782=Additional depth +90783=Return position +90784=Tool +90785=Min thickness +90786=Max thickness +90787=Step +90788=Down +90789=Side +90790=Vertical +//machinings families +90791=Sawing +90792=Drilling +90793=Milling +90794=Saw Roughing +90795=Saw Finishing +90796=Pocketing +90797=Waterjet +//ComboBox Param +90801=No +90802=Inner +90803=Outer +90804=Both +90821=Center +90822=Left +90823=Right +90824=Centered +90825=Inner +90826=Outer +90827=Cent. Extended +90828=Outer Extended +90829=Prev Extended +90830=Next Extended +90831=Booth Extended +90832=Centered +90833=Inner +90834=Outer +90835=Skip +90836=Approximate +90837=Convex +90838=Zig Zag +90839=One way +90840=Back and forth +90841=Keep +90842=None +90843=Standard +90844=Slowdown +90845=Loop +90846=Linear +90847=Tangent +90848=Glide +90849=Helix +90850=As lead in +// param2 +90861=Side +90862=Tilted +90863=Tilted back +90864=Forward +90865=Backward +90866=Last backward +90867=Forward angle +90868=Probing +90869=Min dist. points +90870=Max dist. points +90871=External +90872=Internal +90873=Slowdown len. +90874=Slowdown % +90875=Lead in hole +90876=Radius +90877=LP turns +90878=HP turns +90879=Enable +90880=Corners +// Barcode +90881=Barcode +90882=Block +90883=Number +90884=Slab data +// param3 +90890=Dist. tang. +90891=Dist. perp. +90892=Dist. tang. +90893=Dist. perp. +90894=Leadin ceramic +90895=Length +90896=Step +90897=Last cut +90898=Side angle cuts +// Alarms +90900=Current Waterjet +90901=Current sawblade +90902=Auxiliary tool +90903=Current drillbit +90904=Current mill +90905=Safe Z +90906=Cut safety +90907=Corner safety +90908=Whole cuts guard +90909=Holes offset +90910=Holes overlap +90911=Holes toler. +90912=NC Errors List +90913=Materials +90914=Add +90915=Remove +90916=Current tools +90917=Holes parameters +90918=Ext arc min R +90919=Machine parameters +90920=None +90921=Drillbit +90922=Mill +90923=Both +90924=Int arc max A +90925=Saw parameter +90926=Single hole in corner +90927=Direct cuts +90928=Final home +90929=Millings parameters +90930=Always on sinks +90931=Nesting +90932=Aligned +90933=Setup +90934=New +90935=Delete +90936=Overtable height +90937=Camera +90938=Background +90939=Threshold +90940=Tolerance +90941=Washing +90942=Confirm deletion of selected material ? +90943=Default Setup +90944=Always on corners +90945=Select tool to probe +90946=Cuts Feed start/end +90947=Length +90948=Slowdown% +90949=Shortening +90950=Probing +//Machine +90951=Start +90952=Stop +90953=Reset +90954=Auto +90955=Single +90956=MDI +90957=Manual +90958=Home +90959=Download +90960=Upload +90961=Activate +90962=Delete +90963=MDI Confirm +90964=CN Mode +90965=Machine Commands +90966=MDI string +90967=Part program transfer +90968=Do you want to change table? +// Options +90981=Language +90982=The new language will take effect after restart. +90983=Units of measure +90984=View rotation +90985=Side angle +90986=Same value +90987=Multiple values +90988=Direct insertion of parts +90989=Parametrics and DXF +90990=CSV +90991=Fast grid +90992=Enable standard pieces creation +90993=Text color +90994=Slab Dxf +90995=Slab Layer +90996=Parts Layer +90997=Scrap Layer +90998=Std Thick +90999=ColorToSideAng +91000=Enable +91001=Tolerance +91002=Heel +91003=Side angle +91004=Feedback +91005=Themes +91006=Engrave from color +91007=Depth +91008=Width +91009=Start program +91010=Select start mode +91011=Recent project +91012=Last opening +91013=Last project +91014=New project +91015=Open folder +91016=Show window +//Alarms2 +91051=Machinings +91052=Sawing +91053=Drilling +91054=Milling +91055=DripSawing +91056=DripDrilling +91057=WaterJet +91058=Waterjet parameters +91059=Automatic +91060=Aligned and Guillotine +91061=Engraving parameters +91062=Use Mill +91063=Depth +91064=Width +91065=Precut exit +91066=Guillotine +91067=Add pause +91068=Frame +91069=Pocketing +91070=Current cupwheel +//Statistics +91071=Day Production +91072=Week Production +91073=Project +91074=Parts Area +91075=Cuts Area +91076=Day +91077=Week +91078=Reset +91079=To Produce Area +//Lucidature +91089=Offset +91090=Polishing DB +91091=Polishings +91092=Move +91093=Count +91094=LeadIn/LeadOut +91095=Height +91096=Tools +91097=Length +91098=Up +91099=Down +91100=Load +//EgtMsgBox +91101=Save changes to current project ? +91102=Save changes to current tool ? +91103=Save changes to current machining ? +91104=Already used name +91105=There are collisions, some pieces will be parked. Continue ? +91106=Another file with same name alredy exists? Overwrite it? +91107=NC CONNECTION +91108=Try to connect... +91109=Connection failed +91110=Succesfully connected +91111=Table to use ? +91112=Also delete parts from CSV list ? +91113=Parts not removed because free +91114= or from other Csv lists +91115=Error +91116=Option Production line not enabled +91117=Error copying file for OmagVIEW +91118=Retain parked parts ? +91119=Error in ruined parts management +91120=Characters \ / : * ? " < > | are not allowed +91121=Are you sure you want to delete selected pieces? +91122=Warning +91123=Table +91124=???Salvare la lucidatura corrente? +91125=Do you want to save current modified? +91126=Export +91127=Import +91128=DB WaterJet +91129=Origin from laser +91130=Start program? +// CSV +91201=Open +91202=Insert +91203=New +91204=Remove +91205=Error saving CSV file, continue anyway ? +91206=Error reading CSV file +// OmagVIEW +91301=All Good +91302=Good Part +91303=Ruined Part +91304=Print Label +91305=Confirm +91306=Print +// OmagOFFICE +// OptionPanel +91401=RawPart +91402=Disposition +91403=Work +91404=Simulation +// MachiningDbWindow +91451=Material +91452=Min Thickness +91453=MaxThickness +// TopCommandBar +91501=Save project is mandatory before export +91502=Select export directory +91503=Error in export +91504=Export completed successfully +91505=Export to machine +91506=DXF export +// Rawpart +91551=Error loading photo +91552=Import photo +// VeinMatching +91601=Export +91602=Show Info +91603=Edit +91604=Verify +91605=Magnetic +91606=Part not selectable in this situation +91607=Part not selectable because belonging to non-current workgroup : +91608=Dxf parts BoundingBox too big for VeinMatching +// Generic +91651=Ok +91652=Cancel +91653=A° +91654=H +91655=Start +91656=End +// ----- OmagPHOTO ----- +// General +92001=Db not found! +92002=Unable starting the program +// OptionPanel +92051=Save +92052=Add +92053=Cancel +92054=Remove +92055=Are you sure you want to delete current slab? +92056=Label +92057=Label Arrow +92058=Browse +92059=Print +92060=Select +// Slab +92071=Id +92072=Image name +92073=State +92074=Project assigned to +92075=Warehouse position +92076=Date +92101=Name already used +92102=Name is mandatory +92103=Image is mandatory +// SearchPanel +92151=Search +92152=Thickness tolerance +92153=Start date +92154=End date +92155=Reset +//Messaggi +92200=???Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=Warning +92202=???Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=???Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=???Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// General +101001=Import BTL +101002=Draw +101003=Place +101004=Options +// ImportPage +101101 +// DrawPage +101201=Wall +101202=Door +101203=Window +101204=Add +101205=Cancel +101206=Apply +101207=Remove +101208=Spacer +// PlacePage +101301=Generate +101302=Trasmit +101303=Place wall +101304=Add +101305=Park +101306=Remove +101307=Layer thickness +101308=Table count on top +101309=Add failed +101310=Generation successful +101311=Generation error +101312=Transmission exec successful +101313=Transmission exec error +101314=Transmission successfully completed +101315=Transmission failed +101316=All gantries disabled +101317=Generation file missing +// OptionsPage +101401=Machine options +101402=Glueing parameters +101403=X Extra Raw +101404=Y Extra Raw +101405=Extra glue +101406=Plank parameters +101407=Plank width +101408=Table count in a layer +101409=Gantries activation +101410=Glue gantry +101411=Plank gantry +101421=Software options +101422=Language selection +101423=The new language will take effect after restart +101424=Saved project number +101425=Place planks on doors and windows +101426=Advance opening glue +101427=Advance closing glue +// OpenPage +101501=Invalid project +// ----- End ----- diff --git a/ProgramData/EgtCAM5/Config/EgalTechEsp.txt b/ProgramData/EgtCAM5/Config/EgalTechEsp.txt new file mode 100644 index 0000000..00d9080 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgalTechEsp.txt @@ -0,0 +1,3313 @@ +// File dei messaggi EgalTech Spagnolo 2022/04/11 +0=ESP +// File +1=File +3=Nuovo +5=Apri +6=Apri
File recenti (Shift) +7=Inserisci +9=Salva +11=Copia +13=Importa +15=Esporta +17=Esegui +19=File Recenti +20=Script Recenti +// Vista +101=Vista +103=Linee +105=Bordi +107=Solidi +109=ZoomAll +111=ZoomIn +113=ZoomOut +115=Sopra +117=Fronte +119=Destra +121=Dietro +123=Sinistra +125=Sotto +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Griglia +136=Imposta Vista perpendicolare alla Griglia corrente +137=DirCurve +139=Analisi +141=Distanza +// Griglia +201=Griglia +203=Sopra +205=Fronte +207=Destra +209=Dietro +211=Sinistra +213=Sotto +215=Vista +216=Imposta Griglia perpendicolare alla direzione di Vista +217=Elevaz +218=Imposta Elevazione della Griglia +219=Origine +220=Imposta Origine della Griglia +221=Ruota +222=Ruota Griglia
Ruota Griglia in 3d (Shift) +223=3 Punti +224=Imposta Griglia da 3 Punti +225=Perp +226=Imposta Griglia Perpendicolare a Oggetto +227=Oggetto +228=Imposta Griglia da Oggetto +// Disegna +301=Disegna +303=Punto +304=Punto
Vettore (Shift)
Riferimento (Ctrl) +305=Lin 2P +306=Linea : 2 Punti
Linea : 2 punti con Continuazione (Ctrl) +307=Lin PDL +308=Linea : Punto iniziale, Direzione, Lunghezza
Linea : Punto iniziale, Vettore direzione, Lunghezza (Shift) +309=Circ +310=Circonferenza : Centro, Punto
Circonferenza : Centro, Diametro (Shift) +311=Racc +312=Raccordo : Raggio
Smusso : Dist (Shift) +313=Arco CIF +314=Arco : Centro, Punto iniziale, Punto finale +315=Arco 3P +316=Arco : 3 Punti +317=Arc IDF +318=Arco : Punto iniziale, Direzione, Punto finale
Arco : Punto iniziale, Vettore direzione, Punto finale (Shift)
Arco : Punto iniziale, Direzione, Punto finale con Continuazione (Ctrl) +319=Rett 2P +320=Rettangolo : 2 Punti +321=Poligono +322=Poligono : Raggio o Apotema
Poligono : Lato con 2 Punti (Shift) +323=Testo +324=Testo
Testo Avanzato (Shift) +399=Continuazione : 'L' con linea, 'A' con arco +// Costruisci +401=Costruisci +403=Piano +404=Superficie : piano contornato da una o più curve
Regione piana (Shift) +405=Estrudi +406=Superficie : da estrusione di una o più curve +407=Ruota +408=Superficie : da rotazione di una curva +409=Avvita +410=Superficie : da rototraslazione di una curva +411=Rigata +412=Superficie : rigata tra 2 curve +413=Combina +414=Combina una o più Superfici +415=Inverti +416=Inverte l'esterno di una o più Superfici +417=Esplodi +418=Esplodi Superfici o Regioni Piane +419=Swept +420=Superficie : da spostamento di una curva lungo un'altra +// Modifica +501=Modifica +503=Cancella +504=Cancella gli Oggetti +505=Layer +506=Porta gli Oggetti nel Layer corrente +507=Colore +508=Cambia Colore
Rimuovi Colore specifico (Shift)
Cambia Trasparenza (Ctrl) +509=Inverti +510=Inverti Curva +511=Trim/Est +512=Taglia o Estendi Curva +513=Spezza +514=Spezza Curva
Dividi Curva in Parti (Shift) +515=Unisci +516=Unisci Curve
Unisci Curve creando una Copia (Shift)
Fondi Curve nella Composita (Ctrl) +517=Esplodi +518=Explodi Testi o Curve in Componenti +519=Spess +520=Imposta Spessore e direzione di Estrusione su una o più Curve +521=Inizio +522=Cambia Inizio di Curva Chiusa +// Trasforma +601=Trasforma +603=Muovi +604=Muovi uno o più Oggetti +605=Ruota +606=Ruota uno o più Oggetti
Ruota uno o più Oggetti in 3D (Shift) +607=Specch +608=Specchia uno o più Oggetti
Specchia uno o più Oggetti in 3D (Shift) +609=Scala +610=Scala uno o più Oggetti
Scala uno o più Oggetti in 3D (Shift) +611=Offset +612=Offset di una Curva +// Special +701=Special +703=Pezzi 2d +704=Inserisci Pezzi Piani da DXF o NGE +705=Compo +706=Inserisci Componenti Parametrici +// Scene : Menù Selezione Entità +1001=Seleccionar todo +1003=Deseleccionar todo +1005=Seleccionar con ventana +1007=Seleccionar pieza +1009=Seleccionar capa +1011=Seleccionar ruta +1013=Seleccionar ruta completa +1015=Seleccionar entidad +1016=Seleccionar todo visible +// Scene : Menù Punto notevole +1101=Punto Sketch +1102=Punto Sketch +1103=Punto Rejilla +1104=Punto de cuadrícula +1105=Punto Final +1106=Punto Final +1107=Punto Medio +1108=Punto Medio +1109=Centro +1110=Centro +1111=Centro de Gravedad +1112=Centro de Gravedad +1113=Punto Cercano +1114=Punto Cercano +1115=Intersección +1116=Intersección +1117=Punto de Tangencia +1118=Punto Tang +1119=Punto Perpendicular +1120=Punto Perp +1121=Punto a Distancia Mínima +1122=Punto MinDist +1123=Excluir Superficies +// Scene : Menù Varie +1201=Disattiva Trascinamento +1203=Attiva Trascinamento +// Scene : Varie +1301=Dist= +// Controller +2001=Copia (V) +2002=Errore +2003=Allarme +2051=Il Punto deve essere diverso dal precedente +2052=I Punti devono essere non allineati +2053=Valori Nulli o Negativi non sono ammessi +2054=Valori Negativi o Due Valori Nulli non sono ammessi +2055=Almeno una Entità non è scalabile +2056=Distanza troppo grande +2057=Curva non piatta (nel suo piano) +// Controller : Disegna +2101= +// Controller : Costruisci +2201= +// Controller : Modifica +2301= +// Controller : Trasforma +2401=COPIA +2402=MUOVI +2403=Inserisci Punto Base +2404=Inserisci Punto Destinazione +2406=RUOTA +2407=Inserisci Centro +2408=Inserisci Punto Base +2409=Inserisci Angolo o Punto +2411=RUOTA 3D +2412=Inserisci Primo Punto Asse +2413=Inserisci Secondo Punto Asse +2414=Inserisci Punto Base +2415=Inserisci Angolo o Punto +2416=SPECCHIA +2417=Inserisci Primo Punto +2418=Inserisci Secondo Punto +2421=SPECCHIA 3D +2422=Inserisci Primo Punto +2423=Inserisci Secondo Punto +2424=Inserisci Terzo Punto +2426=SCALA +2427=Inserisci Centro +2428=Inserisci Coefficiente +2431=SCALA 3D +2432=Inserisci Centro +2433=Inserisci Coefficienti +2436=OFFSET +2437=Inserisci Distanza +2438=Raccordo +2439=Smusso +2440=Estendi +// ----- EgtCAM5 ----- +5001=DIBUJA +5002=TRABAJA +5003=Db Herramientas +5004=Db Trabajos +5005=Opciones +5006=Db Herr. +5007=Db Trab. +5008=Opciones Maquina +5009=Db Equip. +5010=Db Equipado +5020=Tablas Trabajos +//Top CommandBar +5101=Nuevo +5102=Abrir
Abrir archivos recientes (clic derecho) +5103=Gravar +5104=Gravar como +5105=Insertar +5106=Importar +5107=Exportar +5108=Ejecutar guión
Ejecutar guión reciente (tecla derecha) +5109=Opciones +5110=Dirección de correo electrónico de soporte no encontrada. +5111=¿Guardar el proyecto actual antes de enviar comentarios? +5112=Enviar comentarios a {0} con la carpeta {1} adjunta. +5113=Comentarios (Feedback) +5114=Correo de comentarios listo. +//Draw Panel +5150=Extraer bordes libres de superficies y regiones planas +5151=Combinar superficies y regiones planas +5152=Restar superficies y regiones planas
Taglia Superficie con Superficie Inversa (Shift) +5153=Intersecar superficies y regiones planas
Taglia Superficie con Superficie (Shift) +5154=Puntos, curvas y caras de intersección entre superficies +5155=Dimensión lineal
Dimensión alineada (Shift) +5156=Círculo 3 Puntos +5157=Extraer bordes de caras de superficies y partes de regiones planas +5158=Extraer cara de superficie +5159=Arco Invertido
Arco Esplementare (Shift) +5160=???Modifica forma +5161=???Aggiungi Punto
Trasforma in Arco (Shift)
Chiudi Curva Composita (Ctrl) +5162=???Rimuovi Punto
Trasforma in Retta (Shift)
Apri Curva Composita (Ctrl) +5163=???Approssima Curva
Approssima Curva con Linee (Shift) +5201=Punto
Vector (Shift)
Referencia (Ctrl) +5202=Línea de 2 puntos
Línea de 2 puntos con continuación (Ctrl) +5203=Línea Punto, Dirección y Longitud
Línea Punto, Dirección Vectorial y Longitud (Shift) +5204=Círculo Centro Punto +5205=Círculo Centro Diámetro +5206=Arco Centro Puntos de inicio y fin +5207=Arco 3 Puntos +5208=Arco Punto y Dirección de Inicio, Punto de Fin
Arco Punto y Dirección Vectorial de inicio, Punto de Fin (Shift)
Arco Punto y Dirección de Inicio, Punto de Fin con continuación (Ctrl) +5209=Conexión +5210=Bisel +5211=Rectángulo de 2 puntos +5212=Polígono +5213=Polígono desde el lado +5214=Texto
Texto avanzado (Shift) +5215=Plano delineado
Región plana (Shift) +5216=Extrusión +5217=Revolución +5218=Atornillar +5219=Rigata +5220=Fusionar superficies +5221=Explotar superficies y regiones planas +5222=Invertir superficies y regiones planas +5223=Eliminar +5224=Cambiar capa
Cambiar capa con transformaciones (Shift) +5225=Cambiar transparencia +5226=Cancelar color +5227=Cambiar color +5228=Curva inversa +5229=Cambiar el punto inicial de la curva cerrada +5230=Extender o acortar curva +5231=Interruptor de curva +5232=Curva de división +5233=Combinar curvas
Combinar curvas creando una copia (Shift)
Fusionar curvas en Composita (Ctrl) +5234=Explotar curvas y textos +5235=Espesor y extrusión curva +5236=Moverse +5237=Rotar +5238=Rueda 3D +5239=Espejo +5240=Espejo 3D +5241=Escalera +5242=Escala 3D +5243=Offset +5244=Dibujo 2D +5245=Dibujo 3D +5246=Cambiar +5247=Transformar +5248=Barrido (Sección, Guía) +5249=Editar texto +// Grid View Panel +5251=Wireframe +5252=Líneas ocultas +5253=Sombra +5254=Zoom todo +5255=Acercar +5256=Alejar +5257=Vista desde arriba +5258=Vista frontal +5259=Vista desde la izquierda +5260=Vista desde atrás +5261=Vista desde la derecha +5262=Vista isométrica desde SW +5263=Vista isométrica desde el SE +5264=Vista isométrica desde NE +5265=Vista isométrica desde el NO +5266=Mostrar dirección de curva +5267=Analizar +5268=Distancia +5269=Cuadrícula desde arriba +5270=Cuadrícula frontal +5271=cuadrícula derecha +5272=Cuadrícula desde atrás +5273=Cuadrícula izquierda +5274=Cuadrícula desde abajo +5275=Ver cuadrícula +5276=Elevación de la cuadrícula +5277=Origen de cuadrícula +5278=Rueda de Cuadrícula
Rueda de Cuadrícula 3d (Shift) +5279=Cuadrícula de 3 puntos +5280=Cuadrícula perpendicular curvada +5281=Cuadrícula de objeto +5282=Vista desde la cuadrícula +5283=Selección de zoom +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=FIN +5302=Extra corsa +5303=Dirección de herramienta inalcanzable +5304=Error +5305=ERROR +5306=¡Error en la generación! +5307=Simulación +5308=Un paso a la vez +5309=Reproducir / Pausa +5310=Parar / Inicio +5311=PAUSA +5312=PARAR +5313=Imposible salir ahora. ¡Primero pare la simulación o espere a que termine! +5314=INICIO +5315=ADVERTENCIA +5316=Fresado virtual +5317=¡Error al calcular las estimaciones! +5318=Archivo de estimación no encontrado +5319=¡Colisión! +5320=INFORMACIÓN +5330=GENERAR +5331=El proyecto debe guardarse antes de la generación NC. ¿Desea hacerlo? +5332=Generado con éxito +5333=La licencia no permite la generación CN +5340=Estimado +5341=Tiempo total +5342=longitud total +5343=Detalles +5344=Estimaciones detalladas +// Draw Option +5351=Propiedades +5352=Nueva pieza +5353=Nueva capa +5354=Color +5355=Parámetros de dibujo +5356=Seleccionar +5357=Desmarcar +5358=Nombre +5359=Información +5360=Mover +5361=Copiar +5362=Eliminar +5363=Guardar +5364=Mostrar +5365=Confirmación +5366=Cancelación de confirmación +5367=Pieza de trabajo, ¿quieres eliminarla de todos modos? +// Operation +5401=Operaciones +5402=Parámetros de operación +5403=Aplicar procesamiento +5404=Nuevo Trab +5405=Nueva Disp +5406=Eliminar +5407=Genérico +5408=ascender +5409=abajo +5410=Actualizar +5411=Actualización completada con éxito +5412=Nuevo procesamiento +5413=Vista herramienta +5414=adelante +5415=Atrás +5416=Duplicado +5417=Copiar a Db +5418=Procesando nombre en el Db +5419=Error en la inserción del trabajo +5420=Cambiar nombre +5421=El nombre no puede comenzar con "Disp" +5422=Nombre ya usado +5423=???La lavorazione non può essere applicata per i seguenti motivi: +// Disposition +5431=Ok +5432= +5433=Nuevo +5434=Eliminar +5435=Longitud +5436=Ancho +5437=Altura +5438=Posición +// Mach & Disposition Errors +5461=ERROR DE EJECUCIÓN DE SCRIPT +5462=Error al ejecutar el script de disposición automática +5463=Error al ejecutar el script de inicio de mecanizado +5464=Error al ejecutar el script de mecanizado final +// Mach Group +5501=¿Está seguro de que desea limpiar el grupo de procesamiento? +5502=¿Está seguro de que desea cancelar el Grupo de procesamiento? +5551=No hay grupos de mecanizado:
seleccione las piezas a insertar y
repita el comando para crear el primero +5552=¿Desea crear un nuevo grupo de trabajo
con las piezas seleccionadas? +// Tools Db Page +6001=Broca +6002=Cuchilla +6003=Cortador +6004=Mortaja +6005=Compuesto +6006=Broca larga +6007=Cuchilla plana +6008=Cortador sin punta +6009=Cincel +6010=WaterJet +6051=Corrección +6052=Salida +6053=Tipo +6054=Refrigerante +6055=Radio de la esquina +6056=Diámetro +6057=Diámetro total +6058=Progreso +6059=Progreso final +6060=Progreso inicial +6061=Progreso de pico +6062=Longitud +6063=Longitud total +6064=Agudo +6065=Desplaz. longitudinal +6066=Desplaz. radial +6067=Rotación +6068=ángulo lateral +6069=Rotación máxima +6070=Espesor +6071=Absorción máxima +6072=Avance mínima +6073=Diseño +6074=Motor +6075=Nombre +6076=Notas +6077=Pos.herramienta +6078=Posición +6079=Distancia +6080=???Overtable +// Tools Errors +6100=¿Guardar la herramienta modificada? +6101=GUARDAR +6102=El archivo debe ser .nge +6103=El archivo no existe o no es del tipo Nge +6104=No hay ToolMaker para este tipo de herramienta +6105=La herramienta no se puede crear con estos parámetros +6106=El agudo debe ser mayor que 0 +6107=El agudo debe ser menor que el pulmón +6108=El grosor debe ser mayor que 0 +6109=El diámetro debe ser mayor que 0 +6110=La longitud debe ser mayor que 0 +6111=La rotación debe ser menor que la rotación máxima +6112=Nombre inválido +6113=La longitud debe ser menor que la Longitud total +6114=La longitud debe ser mayor que el Agudo +6115=La longitud total debe ser mayor que 0 +6116=La longitud total debe ser mayor que la longitud +6117=El agudo debe ser inferior a 1/3 del diámetro +6118=El diámetro debe ser menor que el diámetro total +6119=El diámetro debe ser mayor que 3 veces el agudo +6120=El diámetro total debe ser mayor que 0 +6121=Longitud demasiado pequeña con el portaherramientas +6122=¿Está seguro de que desea eliminar la herramienta? +6123=? +6124=CLARO +6125=¡No se encontró el archivo de configuración de instalación! +6126=Error +6127=Establecer el tipo de cabeza. +6128=Establecer el tipo de salida. +6129=Herramienta no válida, corríjala o elimínela antes de salir de la base de datos de herramientas. +6130=No se puede volver a cargar la base de datos de herramientas. Si la carpeta de máquinas está en un servidor, verifique que la conexión esté activa. +6131=El grosor debe ser diferente de 0 +6132=El ángulo lateral debe ser inferior a 90 +6133=El ángulo lateral debe ser mayor que -90 +6134=La longitud total debe ser mayor que la longitud + grosor +6135=El radio de la esquina es demasiado grande. +6136=El grosor es demasiado pequeño en comparación con el radio de la esquina +6137=El diámetro resultante excede el diámetro total +6138=El diámetro resultante es menor que 0 +6139=El diámetro de la varilla resultante es menor o igual a 0 +6140=El agudo debe ser mayor que el radio de la esquina +6141=El agudo resultante debe ser> = 0 +6142=El radio de la esquina no debe exceder la mitad del grosor +6143=Guardar herramienta +6144=¡Herramienta modificada! Todas las herramientas deben guardarse antes de cambiar las activaciones. ¿Guardar herramienta {0}? +6145=¡Posición ya ocupada! +6146=¡Posición no definida! +// Machinings Db Page +6201=Taladrar +6202=Corte con disco +6203=Mecanizado +6204=Vaciar +6205=Ranurado +6206=Desbaste con disco +6207=Acabado con disco +6208=Trab.generico +6209=Cincelado +6210=Desbaste de superficies +6211=Acabado superficial +6212=WaterJet +6251=Invertir +6252=TAB +6253=Tipo +6254=Lado de trabajo +6255=Lado de la cabeza +6256=Ataque +6257=Conexión +6258=Salir +6259=Usando curvas +6260=Tipo de paso +6261=Subtipo +6262=Tipo de aproximación +6263=Velocidad +6264=Progreso +6265=Alimentación inicial +6266=Alimentación final +6267=Avance del cabezal +6268=Desplaz. radial +6269=Desplaz. longitud. +6270=Hundimiento +6271=Ángulo de flanco +6272=Aproximación +6273=Dist. la seguridad +6274=Longitud ralentizado inicial +6275=Longitud ralentizado el final +6276=Longitud passante adj. +6277=Paso +6278=Posición de retorno +6279=Longitud +6280=Distancia +6281=Altura +6282=Esquina +6283=Dist. ataque tangente +6284=Dist. para p. ataque +6285=Elevación del ataque +6286=Long. corre. ataque +6287=Dist. salida tangente +6288=Dist. para p. salida +6289=Elevación de salida +6290=Long. correg. salida +6291=Long. añadir. ataque +6292=Long. añadir. salida +6293=Paso en arco exterior +6294=Paso en arco interior +6295=Paso lateral +6296=Progreso vertical +6297=Nombre +6298=Herramienta +6299=Hundimiento +6300=Notas +6301=Superposición +6302=Desplazamiento +6303=Subtipo +6304=SCC +6305=Ninguno +6306=Estándar +6307=Opuesto +6308=AuxDir derecha +6309=AuxDir Izquierda +6310=AuxDir detrás +6311=AuxDir delantero +6312=AuxDir arriba +6313=AuxDir abajo +6314=AuxDir más cercano +6315=AuxDir más lejos +6320=Centro +6321=Izquierda +6322=Derecha +6323=Ampliar +6324=Estándar +6325=Interna +6326=Externo +6327=Extendido centrado +6328=externo extendido +6329=Ninguno +6330=Lineal +6331=Tangente +6332=Persecución +6333=Hélice +6334=Ampliar anterior +6335=Ampliar siguiente +6336=Extender ambos +6337=Como ataque +6338=Saltar +6339=Aproximado +6340=convexo +6341=Mantener +6342=ZigZag +6343=Unidireccional +6344=Espiral +6345=Ir y volver +6346=Longitudinal +6347=transversal +6348=Espiral en +6349=Espiral hacia fuera +6350=Avanzado +6351=Dir. inversa herr. +6352=Mecanizado de caras +6353=Indefinido +6354=Paralelo +6355=Ortogonal +6356=Orthog. Arriba +6357=Abajo +6358=Arriba +6359=Frente +6360=Detrás +6361=Izquierda +6362=Derecha +6363=Esquema +6364=Ángulos sugeridos +6365=Eje bloqueado +6366=Máximo no +6367=Número mínimo +// Machining errors +6370=¿Guardar el mecanizado modificado? +6371=GUARDAR +6372=Nombre inválido +6373=Los personajes \ /: *? "<> | no están permitidos +6374=¿Está seguro de que desea eliminar? +6375=? +6376=BORRAR +6377=No se puede volver a cargar la base de datos del trabajo. Si la carpeta de máquinas está en un servidor, verifique que la conexión esté activa. +6378=Oscilación +6379=Ancho +6380=Longitud rampa +6381=Longitud. cresta +// Machining Option Page +6401=Z de Seguridad +6402=División del arco +6403=Nunca +6404=Plan genérico +6405=Plano distinto de XY +6406=Siempre +6407=Configuración predeterminada +6408=Retorno de seguridad desde abajo +6409=Tolerancia del agujero +// SetUp Window +6451=Config. +6452=Aplicar +6453=Guardar +6454=Recuperar +6455=Automático +6456=¿Aplicar las herramientas actuales antes de salir? +6457=???New +// SetUp Errors +6471=Error +6472=Advertencia +6473=No se pudo encontrar la herramienta +6474=en el DB de herramientas. +6475=La posición predeterminada de la herramienta no es válida. +6476=La posición de herramienta predeterminada ya está ocupada. +6477=¡El archivo de configuración no existe! +6478=¡La herramienta utiliza un cabezal que no existe en la máquina! +6479=Error al cargar la configuración +// Option Page +6501=Idioma actual +6502=El nuevo idioma serà actualizado desde el pròximo inicio del programa. +6503=Curvas +6504=Superficies +6505=Curvas y superficies +6506=Geometría seleccionable +6507=Agregar el nuevo mecanizado al final +6508=Usar script de disposición +6509=Unidad de medida +6510=Color de la vista de arriba +6511=Color de la vista inferior +6512=Color predeterminado +6513=Tolerancia geométrica +6514=General +6515=CAD +6516=CAM +6517=Color de la cuadrícula +6518=Superficie biselada +6519=Importar +6520=DXF +6521=STL +6522=Imágenes +6523=Exportar +6524=Imagen +6525=Ancho (píxeles) +6526=Altura (píxeles) +6527=Actualización de la máquina +6528=La máquina "{0}" ya está, ¿qué quieres hacer? +6529=El archivo {0} no contiene una máquina. +6530=La máquina "{0}" se ha actualizado correctamente. +6531=Soporte +6532=Actualización +6533=Cancelar +6534=Aviso +6535=El usuario de la máquina "{0}" ha fallado. +6536=Líneas gruesas +6537=Longitud extra de referencia +6538=Longitud de la flecha +6539=Distancia de texto +6540=Unidad de medida +6541=Decimales +6542=Fuente +6543=Altura del texto +6544=Dimensionamiento +6545=Unidad actual +6546=Otro +6547=Unidad de medida +6548=Factor de escala +6549=Exportar máquina actual +6550=???Select the folder where you want to save the machine +6551=???The exportation of the "{0}" machine failed. +6552=???The machine "{0}" has been successfully exported. +6553=???Update Licence +// Heads +6601=???Verticale +6602=???Orizzontale +6603=???Aggr. 2 uscite +6604=???Aggr. 3 uscite +6605=???Aggr. 4 uscite +6606=???Testa 3 assi +6607=???Testa 4 assi +6608=???Testa 5 assi +6609=???Navetta 1 +6610=???Navetta 2 +6611=???Multi rotante +6612=???Gr. a forare +6613=???Multi scalp. +6614=???Rinvio sotto +6615=???Lama 5 assi +6616=???Sega a catena +6617=???Aggr. 1 uscite +6618=???Testa tastatura +6619=???Flottante 360° +6620=???Seconda Testa 5 assi +6621=???Foratore orizzontale +6622=???Mortasatrice +6623=???Seconda Lama 5 assi +6624=???Aggr. 1 uscita tilt. +6625=???Estrusore +6799= +// StatusBar +6801=Direttorio Machines non trovato. EgtCAM5 funzionerà in modo solo CAD. +// Doors +8001=Crea nuova MTable +8002=Salva MTable +8003=Salva MTable Come +8004=Elimina MTable +8005=Salva file MTable +8006=Sei sicuro di voler cancellare questa MTable? +8007=Salva la MTable modificata? +8008=Lista delle macchine attive +8009=Nome della macchina +8010=Genera Cn +8011=Aggiorna grezzo +8012=On +8013=Nome Geometria +8014=Operazione +8015=MId +8016=Spost. +8017=Tipo Lavorazione +8018=Lavorazione 1 +8019=Lavorazione 2 +8020=Lavorazione 3 +8021=Aggiungi Macchina +8022=Elimina Macchina +8023=Aggiungi Lavorazione +8024=Elimina Lavorazione +8025=CORR +8026=Imposta MTable corrente +8027=GId +8028=Proprietà +8029=Lavorazione +8030=Unisci +// Door errors +8101=Errore +8102=Errore nell'esecuzione del file Ddf +8103=Avvertimento +8104=Path della cartella MTable non trovata +8105=La cartella MTable non esiste +8106=Mancano i file di configurazione nella cartella MTable +8107=Errore sconosciuto +8108=Questa è la MTable correntemente attiva. +8109=Non può essere cancellata. +8110=Sei sicuro di voler cancellare la lavorazione selezionata? +8111=CANCELLA +8112=Sei sicuro di voler cancellare la macchina selezionata? +8113=Impossibile trovare la cartella delle macchine {0}. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +8114=Provare a ricaricare la macchina? +8115=Impossibile trovare la cartella {0}. Se la cartella Doors è su un server, verificare che la connessione sia attiva. +8116=Provare a ricaricare la cartella Doors? +8117=Errore di esecuzione (guarda il file di log) +// GunStock +8201=Nuovo pezzo +8202=Gunstock Nuovo Pezzo +8203=Mod pezzo +8204=Gunstock Modifica Pezzo +8205=Parametri calcio +8206=Nome file +8207=Descrizione +8208=Ok +8209=Cancella +8210=deve avere un valore. +8211=Il valore deve essere compreso tra +8212=e +8213=Dimensioni del grezzo +// GunStock errors +8251=Errore +8252=Errore nel lancio dell'ambiente Gunstock +8253=Errore nella lettura del file Modello +8254=Errore nella scrittura del file Pezzo +// ----- Beams ----- +9000=Tabla de mecanizado de vigas +9001=Activado +9002=Nombre +9003=Tipo +9004=Agregar +9005=Eliminar +9006=Guardar +9007=¿Quiere guardar sus cambios? +9008=Error +9009=No se puede abrir el editor de características de la viga.
Faltan archivos de configuración. +9010=Tablas de procesamiento de paredes +9011=No se pudo abrir el Editor de características del muro.
Faltan archivos de configuración. +// ----- Errori ----- +10001=Error +10002=Error enla creaciòn de un nuevo file +10003=Error en el abrir el file +10004=Error en el salvar el file +10005=Tipo de file desconocido +10006=Error en importar el file +10007=Error en exportar el file +10008=Error cargando o creando el Grupo de trabajo +10009=No existe el file +// Missing Key Window +10101=Error ! +10102=Llave no presente. +10103=Introducirla y reiniciar el programa. +10104=Ok +10105=Programa sin licencia. +10106=Cárgalo y reinicia el programa. +10107=Ejecuta GetMachineId y envia los resultados al proveedor.. +// Numeric virtual keyboard +10201=Expresión equivocada +// ----- MessageBox ----- +15001=???Errore +15002=???Avviso +15003=???Informazione +15010=???Errore interno (guarda log file) +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Expresiòn errada +// EgtCalculadorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Canc +20043=SI +20044=NO +// ----- EgtWPFLib5 ----- +// EgtSaveFileDialog +30001=Salvar +30002=Anular +30003=ya existe. +30004=reemplazarlo? +30005=Nombre file: +30006=Abrir +30007=ERROR +30008=El nombre no puede estar vacio! +30009=ATENCION +30010=Nombre File +30011=Nombre Carpeta +// Top CommandBar +30501=Nuevo +30502=Abrir +30503=Salvar +30504=Salva como +30505=Introducir +30506=Importar +30507=Exportar +30508=Ejecutar +30509=Opciones +30510=Direcciòn de correo electronico de soporte no encontrado +30511=Salvar el proyecto actual antes de enviar el feedback +30512=Enviar el feedback a {0} con adjunto la carpeta {1} +30513=Feedback +30514=Correo de feedback listo +// Grid View Panel +30801=Wireframe +30802=Lineas Escondidas +30803=Sombreado +30804=Zoom All +30805=Zoom In +30806=Zoom Out +30807=Vista desde arriba +30808=Vista de Frente +30809=Vista de izquierda +30810=Vista desde atràs +30811=Vista de Derecha +30812=Vista Isometrica de SW +30813=Vista Isometrica de SE +30814=Vista Isometrica de NE +30815=Vista Isometrica de NW +30816=Muestra Direcciòne Curvas +30817=Analiza +30818=Distancia +30819=Rejilla desde arriba +30820=Rejilla de Frente +30821=Rejilla de Derecha +30822=Rejilla desde Atràs +30823=Rejilla de Izquierda +30824=Rejilla desde Abajo +30825=Rejilla de Vista +30826=Elevaciòn Rejilla +30827=Origen Rejilla +30828=Girar Rejilla +30829=Rejilla de 3 Puntos +30830=Rejilla Perpenticular a Curva +30831=Rejilla de Objeto +30832=Vista de Rejilla +// MachGroupPanel +30901=Nuevo grupo de trabajo +30902=Nombre: +30903=Màquina: +// ToolDbWindow +31001=Broca +31002=Cuchilla +31003=Cortador +31004=Mortaja +31005=Compuesto +31006=Broca larga +31007=Cuchilla plana +31008=Taladro sin fin +31009=Cincel +31010=Chorro de agua +31051=Corrector +31052=Salida +31053=Tipo +31054=Refrigerante +31055=Radio de la esquina +31056=Diámetro +31057=Diámetro total +31058=Progreso +31059=Progreso Final +31060=Progreso Inicial +31061=Progreso de pico +31062=longitud +31063=longitud total +31064=Material máximo +31065=Desplaz. long. +31066=Desplaz. radial +31067=Rotación +31068=Angulo de Lado +31069=Rotaciòn Màxima +31070=Espesor +31071=Absorción máxima +31072=Progreso mínima +31073=Diseño +31074=Cabezal +31075=Nombre +31076=Notas +31077=Posic. Cambio Herramienta +31078=Posiciòn +31079=Perforación +31080=Agudo +// ToolDb Errors +31100=¿Guardar la herramienta modificada? +31101=GUARDAR +31102=El archivo debe ser .nge +31103=El archivo no existe o no es del tipo Nge +31104=No hay ToolMaker para este tipo de herramienta +31105=Imposible crear la herramienta con estos parametros +31106=El Agudo tiene que ser mayor de 0 +31107=El Agudo tiene que ser menor de Len +31108=El espesor tiene que ser mayor de 0 +31109=El Diàmetro tiene que ser mayor de 0 +31110=La longitud debe ser mayor que 0 +31111=La rotación debe ser menor que la rotación máxima +31112=Nombre no vàlido +31113=La longitud debe ser menor que la longitud total. +31114=La longitud debe ser mayor que el máximo del material. +31115=La longitud total debe ser mayor que 0 +31116=La longitud total debe ser mayor que la longitud +31117=El Agudo debe ser inferior a {0} +31118=El diámetro debe ser menor que el diámetro total. +31119=El diámetro debe ser superior a 3 veces el máximo del material. +31120=El diámetro total debe ser mayor que 0 +31121=Longitud demasiado pequeña con portaherramientas +31122=¿Estás seguro de que deseas eliminar la herramienta? +31123=? +31124=BORRAR +31125=Archivo de configuración de instalación no encontrado! +31126=Error +31127=Configurar el tipo de cabeza. +31128=Configurar el tipo de salida. +31129=Herramienta no vàlida, corrijala o eliminela antes de salir del Db Herramientas. +31130=Imposible recargar el database herramientas. Si la carpeta de máquinas está en un servidor, verifique que la conexión esté activa. +31131=El espesor debe ser diferente de 0 +31132=El ángulo lateral debe ser inferior a 90 +31133=El ángulo lateral debe ser mayor que -90 +31134=La longitud total debe ser mayor que longitud + espesor +31135=El radio corner tiene un valor demasiado grande. +31136=El grosor tiene un valor demasiado pequeño en comparación con el radio Corner +31137=El diámetro resultante excede el diámetro total +31138=El diámetro resultante es menor que 0 +31139=El diámetro del vástago resultante es menor o igual que 0 +31140=El Agudo debe ser mayor que el radio Corner +31141=El Agudo resultante debe ser >= 0 +31142=El agudo debe ser mayor que 0 +31143=El agudo debe ser menor que Len +// ImportExportToolWindow +31161=???Import +31162=???Export +31163=???Tools +31164=???Tool already existing in DB. Overwrite? +31165=???Tool will be imported with the name followed by "_imp" +31166=???The following Tools have been imported succesfully: +31167=Reset +// MachiningDbWindow +31201=perforación +31202=Corte de la cuchilla +31203=fresado +31204=Vaciar +31205=Ranurado +31206=Desbaste con cuchilla +31207=Terminar con cuchilla +31208=Procesamiento genérico +31209=cincelado +31210=Chorro de agua +31211=???Surffinishing +31251=invertido +31252=Salir de la pestaña +31253=Tipo +31254=Lado de trabajo +31255=Lado del cabezal +31256=Ataque +31257=Conexión +31258=Salida +31259=Usa curvas +31260=Tipo de paso +31261=subtipo +31262=Tipo de aproximación +31263=Rotación +31264=Progreso +31265=Progreso inicial +31266=Progreso final +31267=Progreso pico +31268=Despl. radial +31269=Despl. longit. +31270=Hundimiento +31271=Angulo de lado +31272=Aproximación +31273=Dist. de seguridad +31274=Long. ralent. inicial +31275=Long. ralent. final +31276=Long. pasador adic. +31277=Paso +31278=Posición de retorno +31279=Longitud +31280=Altura +31281=Ángulo +31282=Distancia +31283=Dist. tangente +31284=Dist. perp. +31285=Elevación +31286=Longitud. Corrección. +31287=Número mínimo +31288=Número máximo +31291=Longitud. Suplem. +31293=pisar el arco externo +31294=pisar el arco interno +31295=Paso a un lado +31296=Progreso vertical +31297=Nombre +31298=Herramienta +31299=Profundidad +31300=Notas +31301=Superposición +31302=OFFSET +31303=Subtipo +31304=SCC +31305=Ninguno +31306=Estándar +31307=Opuesto +31308=AuxDir derecha +31309=AuxDir izquierda +31310=AuxDir detrás +31311=AuxDir Delantero +31312=AuxDir arriba +31313=AuxDir debajo +31314=AuxDir màs cercano +31315=AuxDir màs lejano +31320=Centro +31321=Izquierda +31322=Derecha +31323=Extender +31324=Estándar +31325=Dentro +31326=Fuera +31327=Centrado extendido +31328=Extendido externo +31329=Ninguno +31330=Linear +31331=Tangente +31332=Persecución +31333=Hélice +31334=Extender anterior +31335=Extender siguiente +31336=Extender ambos +31337=Como ataque +31338=saltar +31339=aproximado +31340=Convexo +31341=Mantiene +31342=ZigZag +31343=Una via +31344=Espiral +31345=Va y regresa +31346=Longitudinal +31347=Transversal +31348=Espiral en +31349=Espiral fuera +31350=Avanzados +31351=Dirección inversa her. +31352=Mecanizado frontal +31353=No definido +31354=Paralelo +31355=Ortogonal +31356=Ortog. arriba +31357=Debajo +31358=Arriba +31359=Delante +31360=Atràz +31361=Izquierda +31362=Derecha +31363=Contorno +31364=Angulos Sugeridos +31365=Eje Blocado +31366=Retroalimentar último +31367=Retroceder +31368=Paso inclinado +31369=Paso hacia atrás inclinado +31370=inclinación hacia adelante +31371=Sondeo +31372=Min dist. puntos +31373=Dist. Máx. puntos +31374=Exterior +31375=Interior +31376=Longitud. rall. +31377=DECELERACIÓN. % +31378=Agujero de ataque +31379=Radio +31380=Número. vueltas en LP +31381=Número. revoluciones en HP +31382=Oscilación +31383=ancho +31384=Longitud. rampa +31385=Longitud. cresta +31386=Genérico +31387=Avanzado +31388=Tang+Perp +31389=Perp+Tang +//MachiningTreeView +31391=Normal +31392=Ralentiza +31393=Anillo +31394=Habilitar +31395=???Add Length +31396=???Start +31397=???End +31398=???System notes +31399=???Epicycles radius +31400=???Epicycles distance +// MachiningDb Errors +31401=¿Guardar el mecanizado modificado? +31402=GUARDAR +31403=Nombre inválido +31404=Los caracteres \ /: *? "<> | no están permitidos +31405=¿Está seguro de que desea eliminar? +31406=? +31407=BORRAR +31408=Imposible recargar database laboraciones. Si la carpeta de máquinas está en un servidor, verifique que la conexión esté activa. +31409=???Machine material not recognized +31410=???Lavorazione non valida, correggerla o cancellarla prima di uscire. +31411=???La Lunghezza deve essere positiva +31412=???La Distanza deve essere positiva +31413=???L'Altezza deve essere positiva +31414=???L'Angolo deve essere compreso tra {0}° e {1}° +31415=???N° massimo deve essere nullo o positivo +31416=???N° massimo deve essere maggiore o uguale al minimo +31417=???N° minimo deve essere nullo o positivo +31418=???N° minimo deve essere minore o uguale al massimo +31419=???L'abilitazione di {0} disabiliterà {1}. Procedere? +// ImportExportMachiningWindow +31450=???Import +31451=???Export +31452=???Machinings +31453=???Machining already existing in DB. Overwrite? +31454=???Machining will be imported with the name followed by "_imp" +31455=???The following Machinings have been imported succesfully: +31456=???Reset +// Ventana de configuración +31501=Configuración +31502=Aplicar +31503=Archivar +31504=Recuperar +31505=Auto +31506=¿Aplicar el equipo actual antes de partir? +// SetUp Errores +31551=Error +31552=Aviso +31553=No se pudo encontrar la herramienta +31554=en el DB herramientas. +31555=La posición predeterminada de la herramienta no es válida. +31556=La posición predeterminada de la herramienta ya está ocupada. +31557=¡El archivo de configuración no existe! +31558=¡Las herramientas utilizan un cabezal que no existe en la máquina! +31559=Error al cargar la configuración +// Simulaciòn +31601=Simulaciòn completada +31602=Carrera extra +31603=Dirección de herramienta inalcanzable +31604=Error +31605=ERROR +31606=¡Error en la generación! +31607=Simulaciòn +31608=Un paso a la vez +31609=Reproducir / Pausa +31610=Detener / Inicio +31611=Pausa +31612=Simulación detenida +31613=Imposible salir ahora. ¡Primero pare la simulación o espere a que termine! +31614=ADVERTENCIA +31615=Archivo de estimaciones no encontrado +31616=Estimaciones detalladas +//MachiningDbWindow/ToolDbWindow buttons +31701=Nuevo +31702=Guardar +31703=Eliminar +31704=???Edit +//Db Waterjet +31751=???Waterjet Db +31752=???Thickness +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=???Do you want to save edits? +// ----- EgtDOORCreator ----- +//General +50001=Larghezza +50002=Altezza +50003=Spessore +50004=???Swing +50005=Lato-serratura +50006=Lato-cerniera +50007=???Top +50008=Fondo +50009=Tipo +50010=Angolo +50011=???Extension +50012=Lato +50013=???Offset wide side +50014=Margine +50015=???Top to center application +50016=Traverso basso +50017=???Lock stile +50018=???Offset from center +50019=???Point to pocket +50020=???Pocket length +50021=???Pocket offset narrow side +50022=???Point to arm +50023=???Arm length +50024=???CenterHung +50025=Traslato +50026=Intermedio traslato +50027=Raggio +50028=Traverso alto +50029=Posizione +50030=Lunghezza +50031=Modello +50032=???Up +50033=???Down +50034=???Shape +50035=Cerniera +50036=???Top to top application +50037=???Center from top application +50038=???Center from top lock +50039=Profondità +50040=Generale +50041=Centro +50042=???Thru +50043=???Face to center line application +50044=Tipo di spigolo +50045=Sovramateriale +50046=Invia Feedback +50047=Peso +50048=???Angle +50049=???Face +50050=???Secure +50051=???Keyway +50052=???Brand +50053=???Folder +50054=???Main Folder +50055=???Jamb +50056=???Light Up +50057=???Light Lock +50058=???Light Bottom +50059=???Light Hinge +50060=???Thickness Head +50061=???Overlap Hinge +50062=???Overlap Lock +50063=???Overlap Top +50064=???Delta T +50065=???Exterior +50066=???Number of Doors +50067=???Jambs and Doors +50068=Ordine +50069=Disposizione +50070=Cliente +50071=Inverti profilo serratura +//Compo Name +50072=Catenaci +50073=Maniglia di superficie +50074=Cerniera +50075=Serratura +50076=Passaggio animali +50077=Buca delle lettere +50078=Ferramenta lato superiore +50079=Cerniera perno +50080=Fermo rullo +50081=???Stops And Closer +50082=Piastrina di battuta +50083=Maniglia incassata tirare +50084=Spioncino +50085=Sfinestratura +50086=Gole +50087=Ribassi +50088=???Ept +50089=???Raceway +50090=Decorazioni +//error messages +50100=Direttorio non trovato +50101=Errore +50102=Fallita lettura del file ddf. Manca un parametro fondamentale {0}. +50103=Fallita lettura valore. +50104=Fallita lettura nella riga del file ddf +50105=Riga +50106=Valore non accettabile in +50107=File vuoto. +50108=Impossibile aggiunegere la componente. Inserire una porta! +50109=Vuoi salvare questo file ({0}) ? +50110=Domanda +50111=Aggiungi nuova porta +50112=Rimuovi porta +50113=Nuova Porta +50114=Il nome del file già esiste nel direttorio corrente ({0}). +50115=Attenzione +50116=Vuoi cancellare questo file ({0}.ddf) ? +50117=Confermi la cancellazione ({0}.ddf) ? +50118=Informazione +50119=Errore nella lettura dei messaggi. Non esiste corrispondenza con il numero {0}. +50120=Errore nella lettura del nome {0} in {1}. Attesa una corrispondenza numerica. +50121=Errore nella lettura {0} nel parametro {1} della componente: non esiste. +50122=Errore nel parametro {0} della componente {1} della componente. +50123=Errore nella lettura {0} nel parametro {1} della componente: non esiste la lista. +50124=Errore nella lettura {0} nel parametro {1} della componente: {2}. +50125=Errore nel parametro {0} della componente {1} della componente: non esiste il valore. +50126=Elimina +50127=Errore in EgtLoadMessages +50128=Impossibile salvare un file se non esiste una porta! +50129=Errore nella creazione della scena. +50130=Errore nella lettura della riga {0}. +50131=Errore in lettura {0}: riga {1}. Atteso ':' dopo il nome. +50132=Errore in lettura {0}: riga {1}. Atteso 'template' o 'shape'. +50133={0} non è stato creato. +50134=Errore nella lettura di 'Template' nel file {0}\{1}. Atteso nome. +50135=Errore nella lettura di 'Template' nel file {0}\{1}. File {0}\{2} .lua non esiste. +50136=Errore nella lettura {0}: riga {1}. Non esite la componente nel file 'Default.ini'. +50137=Errore nella lettura {0}: riga {1}. Non è un memebro della lista. +50138=Questo parametro sarà inizializzato di default. +50139=Errore in lettura: riga {0}. Atteso {1}. +50140=Tutti i parametri mancanti saranno inizializzati di default. +50141=Espressione non valida in {0}. +50142=Rimuovi componente +50143=Espressione non valida +50144=Avvertenza +50145=Impossibile creare la porta corrente. +50146=Vuoi aprire un modello? +50147=Errore nell'espressione {0}. {1} non associa nulla. +50148=Valore non valido. +50149=Attenzione: il peso è selezionato nella pagine delle impostazioni. Vuoi disabilitarlo? +50150=Attenzione: il peso è un parametro del file .ddf. Vuoi aggiungerlo alle impostazioni? +50151={0} Non appartiene alla lista degli spigoli. Seleziona il Bevel nella pagina delle impostazioni. +50152=Vuoi salvare questo file ({0})? +50153=Attenzioni: il peso è un parametro della porta corrente. Vuoi rimuoverlo dalla porta? +50154=Questo bevel è selezionato nella porta corrente. Vuoi procedere? +50155=Impossibile creare un modello se non esite una porta! +50156=???Errore nella lettura ddf: la porta non è completa o il ddf è stato separato male da '---'. +50157=???Script Lua ( {0}\{1} )has not been found. +50158=???Bevel {0} can not be acceptable in Jamb. +50159=??? Missing parameter in ddf! +50160=Il file {0} nel direttorio {1} non esite. +50161=???parameter +50162=???In file {0} param 'Default' must be numeric. +50163=???Error in reading General Assembly in DDF +50164=???In General Assembly: +50165=???CompoDir not found : +50166=???Jamb compo does not exist +50167=???Empty Line +50168=???No matching param +50169=???Door disposition has been modify. +50170=???Incongruity between the bevel, it has been resolved by default. +50171=???In file StdTempate.ini is missing numeric param in [Type]. +50172=???File does not exist. +50173=???Definition type is not correct: +50174=???Missing name of the new template! +50175=???The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=???Error in copying: {0} +50177=???Do you want to save the current changes? +50179=Il file Default.ini non esiste nella cartella {0} . +50180=Attenzione : {0} non esiste. +50181=Errore nella stampa dell'immagine. +50182=Errore nell'esecuzione della stampa +50183=Alcune porte potrebbero usare questa ferramenta, confermi l'eliminazione? +50184=???Impossible to delete Hardware if there is no Hardware selected! +50185=???Impossible to duplicate Hardware if there is no Hardware selected! +50186=Il progetto deve essere salvato prima di essere copiato. +50187=Vuoi copiare tutti i files ? {0} (No: per copiare solo il file corrente) +50188=Esporta in macchina +50189=Direttorio macchina non trovato +50190=Errore durante la copia: {0} +50191=Non c'è alcuna porta, impossibile copiare +50192=Non c'è alcuna porta, impossibile esportare verso la macchina +50193=Non c'è alcuna porta, impossibile stampare +50194=Le proprietà sono state cancellate +50195=La configurazione del ddf corrente ({0}) è differente dalla configurazione del programma ({1}).{2}Per caricare la configurazione del ddf corrente devi rilanciare il programma, vuoi farlo? +50196=La configurazione del ddf ({0}) non esiste! +50197=Porta ad arco modificata perchè la configurazioe non la pravede. +50198=Il profilo sul lato serratura dovrebbe essere invertito. +//Option +50200=Unità di misura +50201=Generale +50202=???LockEdgeOverMaterial +50203=???HingeEdgeOverMaterial +50204=???TopOverMaterial +50205=???BottomOverMaterial +50206=Apri finestra +50207=Ultimo progetto +50208=Vuoto +50209=Pagina delle opzioni +50210=Avvio programma +50211=Unità di misura nuova porta. +50212=???Directory Project +50213=Impostazione di avvio +50214=???Current Directory +50215=???Edge Type +50216=???Over Material +50217=???Browse +50218=Chiudi +50219=???Bevel +50220=???Bevel Up +50221=???Bevel Down +50222=Posizionamento porta in lavorazione. +50223=Salva come modello +50224=Associazione +50225=Marca +50226=Modello +50227=???Template +50228=???Enable template +50229=???Enable Order +50230=???Open template door. +50231=???Open window order. +50232=???Directory Template +//Scene +50301=Aggiorna +50302=Aggiungi Nuova Porta +50303=Rimuovi Porta +50304=Nuovo Progetto +50305=???Help +50306=Direttorio Macchina +50307=Macchina +50308=Anta +50309=???Wide Side Down (BU) +50310=???Wide Side Up (BD) +50311=???Resize +50312=???Design +50313=???Save as pdf +//Launcher +50400=???Launcher +50401=Apri Nuovo Progetto +50402=Apri Progetto +50403=Apri Ultimo Progetto +50404=Nuovo Progetto +50405=Nuova Ferramenta +50406=???Elevation +50407=???Project +50408=???PO +50409=???Line +50410=Salva +50411=Stampa +50412=Annulla +50413=Ferramenta +50414=???Dimensioning +50415=???Duplica +50416=???Esporta in macchina +50417=???New Template +50418=???Dimension +50419=Nuovo Direttorio +50420=Ricalcola posizione Hardware +50421=Aggiorna +50422=???Save As +50423=???Reaload Compo on Jamb +//Error (continue) +50501=Errore nella lettura del parametro {0 nel componente {1} : definizione incompleta (controlla StdTemplate.ini). +50502=Errore nella lettura del parametro {0 nel componente {1} : nessuna associazione (controlla StdTemplate.ini e GeometryNameList.ini). +50503=Vuoi salvare? +50504=Il nome del file contiene spazi vuoti agli estremi, vuoi eliminarli ? +50505=Il DDF non è un assemblato, le parti resenti sono: {0}, vuoi salvare? +50506=Impossibile trovare la prima anta! +50507=???The swing is not a member of the swing list of single door. +50508=???The swing of left door is not a member of the swing list of left door. +50509=???The swing of right door is not a member of the swing list of right door. +50510=???The swing of left door is on the right door and viceverse. +50511=???The swing of left door is not a member of the swing list of left door. +50512=???The swing of right door is not a member of the swing list of right door. +50513=???Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=???The swing are absolutly wrong! +50515=???The first door is not realy the first, check the ddf. +50516=???The current ddf contains {0} jambs. +50517=???The current ddf does not contains doors! +50518=???The current ddf is not an assembly. +50519=???Impossible to open a ddf with no doors. +50520=???The current ddf is an assembly. +50521=???Il ddf corrente è un pezzo del telaio: {0}. +50522=???The profile {0} is not a member of the {1} profile list. +50523=???Manca il profile sul lato {0}. +50524=???{0} file aperto da un altro EgtDOORCreator {1}. +50525=???{0} file open by another EgtDOORCreator {1}. +50526=???Il direttorio {0} già esiste! Vuoi sovrascriverlo? +50527=???Impossibile sovrascrivere {0} +50528=???Impossibile salvare il file fuori dal progetto corrente! +50530=???Property {0} does not exist in the list of {1}. Look at file "../Compo/Default.ini". +50531=???The current material {0} does not exist in the list of material. Look at file "../Compo/Default.ini". +50532=???Missing list of material at file "../Compo/Default.ini". +50533=???Impossible to load more than one property at time. +50534=???Property {0} does not exist in the list. Look at file "../Compo/Default.ini". +50535=???Impossible to delete a project if there is not a project! +50536=???Do you want to delete entire project? +50537=???Do you want to delete subdirectory {0} ? +50538=???Impossible to vreate a template door if there is not a door! +50539=???Do you want to change project? ( All doors will be deleted!) +50540=???The current ddf is a part of a frame, do you want to save? +50541=???{0} in reading {1}. +50542=???{0}: Directory does not exist! +50543=???It has been renamed file: {0}, {1}. +50544=???It has been created new file: {0}, {1}. +50545=???It has been deleted file: {0}, {1}. +50546=???Enable single door. +50547=???Project +50548=???The new configuration will take effect after restart. +50549=???File {0} exist, but it is not in the correct Directory! +50550=???Every componente on jambs will be relocated, do you want to continue +50551=???The current parameters have been modified: +50552=???Do you want to overwrite? +50553=??? has not been created. +50554=???Parameter {0} is already deinfed in geometry {1}. +50555=???Impossible to save. +50556=???File has nge extension. +50557=???Error in deleting file: {0} +50558=???Impossible to import a different hardware! +50559=???Open File Dialog +50560=???The hardware part has not been generated correctly. +50561=???Directory already exists +50562=???Folder {0} does not exist. Check in OptionPage. +50563=???Compo {0} does not exist. +50564=???In group {0} at paramater {1} does not exist: {2} +50565=???Brand {0} has not been found in HardwareManager. +50566=???Template {0} has not been found in HardwareManager. +50567=???Error in executing EgtCam5. +50568=???Error in definition {0} in file GeometryNameList.ini . +50569=???Error in definition {0} in file StdTemplate.ini . +50570=???Nothing has been selected. +//Added General messages +50701=???Lines +50702=???Rectangle +50703=???None +50704=???Radius +50705=???Angle +50706=???Pos_x +50707=???Top Arc +50708=???Top Angle +50709=???Properties +50710=???Material +50711=???Mach. +50712=???HardwarePart +50713=???Assemby +50714=???Total Dimension +50715=???Depth +50716=???Overlap Bottom +50717=???Thickness Bottom +50718=???Depth Bottom +50719=???Delta Bottom +50720=???GoToAssembly +50721=???New Geometry +50722=???Geometry Name +50723=???Type Hardware +50724=???Parameter +50725=???Part Dimension +50726=???Apply +50727=???Frame +50728=???Refresh Directory +50729=???General +50730=???Report +50731=???Opposite face +// ----- EgtBEAMEditor ------ +60951=???Cut +60952=???Longitudinal Cut +60953=???Double Cut +60954=???Ridge or Valley Cut +60955=???Saw Cut +60956=???Slot +60957=???Front Slot +60958=???Birds Mouth +60959=???Hip or Valley Rafter Notch +60960=???Ridge Lap +60961=???Lap Joint +60962=???Notch/Rabbet +60963=???Block House Half Lap, Stairs Riser Dado +60964=???Seathing Cut +60965=???French Ridge Lap +60966=???Chamfer +60967=???Block House Half Lap +60968=???Block House Front +60969=???Pocket +60970=???Drilling +60971=???Tenon +60972=???Mortise +60973=???Mortise Front +60974=???House +60975=???House Mortise +60976=???Dovetail Tenon +60977=???Dovetail Mortise +60978=???Dovetail Mortise Front +60979=???Marking/Labeling +60980=???Text +60981=???Simple Scarf +60982=???Scarf Joint +60983=???Step Joint +60984=???Step Joint Notch +60985=???Planing +60986=???Profile Front +60987=???Profile Head concave +60988=???Profile Head convex +60989=???Profile Head cambered +60990=???Round Arch +60991=???Profile Head +60992=???Sphere +60993=???Triangle Cut +60994=???Tyrolean Dovetail +60995=???Dovetail +60996=???Free Contour +60997=???Outline +60998=???Aperture +61001=???Distance from beam start to the reference point +61002=???Distance from the reference edge to the reference point +61003=???Distance from the reference side to the reference point (orthogonal) +61004=???Angle between cut edge and reference edge +61005=???Inclination between face and reference side +61008=???Limit of the 2 ends, binary code +61009=???Inclination to the reference side +61010=???Depth: If P11 is zero, then the face of the cut dispreads to the neigbour-sides or opposite-side to referenceside +61011=???Length: If P12 and P04 equal to zero, the processing is performed along the whole component length +61012=???Angle in face at start +61013=???Angle in face at end +61015=???Distance from the reference point to the reference edge +61016=???Angle between the first cutting edge and the reference edge +61017=???Inclination of the first cutting towards the reference side +61018=???Angle between the second cutting edge and the reference edge +61019=???Inclination of the second cutting towards the reference side +61023=???Inclination between the first face and the reference side +61024=???Inclination between the second face and the reference side +61025=???Depth +61027=???Angle in face at reference edge at start +61028=???Angle in face at reference edge at end +61029=???Angle in face in opposite to reference edge at start +61030=???Angle in face in opposite to reference edge at end +61033=???Displacement to the reference side +61036=???Angle to the reference edge in the cut face +61037=???Depth, orthogonal to the reference side +61038=???Length +61041=???Distance to the reference point orthogonal to the reference side P03 = 0: Slot on one of the 4 sides of the component. P03 > 0: Slot on one of the 2 front sides of the component +61042=???Limit of the 6 faces of the slot, binary code +61043=???Angle to the reference edge in the reference side +61045=???Interior angle at reference point +61046=???Interior angle at opposite of reference point +61047=???Addition to P09 +61048=???Depth orthogonal to the reference side +61049=???Length +61050=???Thickness +61051=???Displacement of the entrance edge at reference point +61052=???Displacement of the entrance edge at opposite of reference point +61055=???Distance to the reference point orthogonal to the reference side +61056=???Limit of the 6 faces of the Frotn Slot, binary code +61059=???Angle between the longitudinal axis of the slot and the reference side +61060=???Depth +61061=???Length +61062=???Width +61065=???Location of P09/P10, if P09>0 and P10>0. If P04=-1, then the location must be defined on the machineside +61066=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole. +61067=???Angle to the reference edge in the reference area +61068=???Inclination between face 1 and reference side +61069=???Inclination between face 2 and reference side +61070=???First cut angle of the counterpart. If P09 is zero, the limit face beside face 1 is parallel to component side. +61071=???First cut inclination of the counterpart. If P10 is zero, the limit face beside face 1 is parallel to component side. +61072=???Depth 1 orthogonal to reference side +61073=???Depth 2 orthogonal to reference side +61074=???Grooving depth in the transverse direction of the component. If P13 is zero, then its value must be calculated:P13=WRS-P02 +61075=???Height Counterpart. Zero means: no limit. Measurement orthogonal to face 1 (P07). +61076=???Width Counterpart. Zero means: no limit. Measurement orthogonal to face 2 (P08). +61079=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole +61080=???Angle notch 1 to the reference edge in the reference area +61081=???Angle notch 2 to the opposite reference edge in the reference area +61082=???Inclination between base area of notches and reference side +61083=???Depth orthogonal to reference side +61084=???Width of notch 1. If this value is equal 0, then the notch is not limited. +61085=???Width of notch 2. If this value is equal 0, then the notch is not limited. +61087=???0: Reference point on referene edge. 1: Reference point on the opposite edge +61088=???Angle to the reference edge in the reference side +61089=???Depth of Half Lap +61090=???Width of Half Lap +61091=???Drill hole diameter +61094=???Displacement to the reference side +61095=???Limit of the 6 faces of the lap, binary code +61096=???Angle to the reference edge in the reference side +61098=???Angle between edge and reference side in face +61099=???Angle in the floor face +61100=???Angle between base face and one face of lap +61101=???Distance (orthogonal) from reference side to point below reference point +61102=???Length +61103=???Chamfer angle +61104=???Grooving depth (length of the lapped scarf in transverse direction). If P14 is zero, then its value must be calculated: P14=WRS-P02 +61107=???Limit of the 6 faces of the notch/rabbet, binary code +61108=???Notch/Rabbet depth +61109=???Notch/Rabbet length +61110=???Notch/Rabbet width +61113=???Depth of the Half Lap on the reference side +61114=???Depth of the Half Lap opposite of the reference side +61115=???Length of the Half Lap / Dado +61117=???Depth of Seathing Cut +61118=???Length of Seathing Cut +61120=???0: Reference point on reference edge; 1: Reference point on the opposite edge +61121=???Angle to the reference edge in the reference side +61122=???Drill hole diameter +61124=???Input of edge(s) to be beveled, binary code: Bit 0=edge 1 ; Bit 1=edge 2; Bit 2=edge 3; Bit 3=edge 4. Example: P04=9: edge 1+4; P04=3: edge 1+2 +61125=???Depth +61126=???Length: If P12 is equal to zero, the processing is performed along the whole component length. +61127=???Shape for bevel exit: 0 = orthogonal, 1 = at 45 deg, 2 = round; +61129=???Depth orthogonal to reference side of the lap 2 and 4. If P03 is zero, then its value must be calculated: P03=HRS +61130=???0:all laps are symmetric to each other; 1:lap on reference edge moved to start beam, lap in opposite of reference edge moved to end beam; 2: lap on reference edge moved to end beam, lap in opposite of reference edge moved to start beam; +61131=???P05=1: drilhole for drop rod, P05=0: no drillhole. The machines defines place and direction of the drillhole. +61132=???lap 1: Depth +61133=???lap 1: Length +61134=???lap 2: Depth +61135=???lap 2: Length +61136=???lap 3: Depth +61137=???lap 3: Length +61138=???lap 4: Depth +61139=???lap 4: Length +61140=???Distance from end of arc orthogonal to the reference side +61141=???Radius of arc +61142=???Distance reference point to center of arc +61143=???Which arc (A, B,C or D) is to produced, binary code +61145=???0:only one lap on reference side; 1:one lap on reference side and one on the opposite side +61146=???Angle to the reference edge in the reference side +61147=???Depth at reference point +61148=???Depth opposite to the reference point +61149=???Depth at reference edge +61150=???Length +61153=???Limit of the 6 faces of the pocket, binary code +61154=???Rotation angle around the local z-axis of the cuboid +61155=???Rotation angle around the local y-axis of the cuboid, rotated with P06 +61156=???Rotation angle around the local x-axis of the cuboid, rotated with P06 and P07 +61157=???Internal angle at the reference point +61158=???Depth of reference point orthogonal to reference side +61159=???Length of Half Lap +61160=???Width of Half Lap +61163=???Distance from the reference face to the reference point. P03 = 0:Drilling on one of the 4 sides of the component. P03 <> 0:Drilling on one of the 2 front sides of the component. +61164=???P03 = 0:Angle to the reference edge in the reference side. P03 <> 0:Angle in the front side. +61165=???Inclination between drilling and reference side. P03 = 0: Inclination between drilling and reference side. P03 > 0: Inclination between drilling and front side +61166=???Depth, orthogonal to reference side or front side. +61167=???Drill hole diameter +61170=???Rounding +61171=???Chamfer +61174=???Angle between axis of the tenon and reference side +61175=???Radius for P04=4 +61176=???Tenon height +61177=???Tenon width +61178=???Margin on the reference side +61179=???Margin opposite the reference side +61182=???Displacement to the reference side +61183=???Rounding +61184=???Angle between axis and reference edge +61185=???Inclination between strut and reference side +61186=???Inclination of hole side walls towards reference side +61187=???Radius for P04=4 +61188=???Mortise depth +61189=???Mortise width +61190=???Height of strut +61191=???Margin on the reference point +61192=???Margin opposite the reference point +61193=???Inclination of hole front side towards reference side +61196=???Rounding +61199=???Angle between axis of the tenon and reference side +61200=???Radius for P04=4 +61201=???Mortise depth +61202=???Mortise width +61203=???Margin on the reference side +61204=???Margin opposite the reference side +61205=???Processident of the associated tenon or dovetail tenon +61206=???Processident of the associated mortise or dovetail mortise +61209=???0:with rounding at the bottom; 1:without rounding, unbounded +61210=???Angle between edge and reference edge +61212=???Angle between axis of the tenon and reference side +61213=???Middle flattening +61214=???Angle of cone +61215=???Tenon height +61216=???Diameter of the curve: If P12 < 0, then the radius must be defined on the machineside. +61217=???Margin on the reference side +61218=???Margin opposite the reference side +61221=???Displacement to the reference side +61222=???0:with rounding at the bottom; 1:without rounding, unbounded +61223=???0:with elongation; 1:with pocket +61224=???Angle between axis and reference edge +61225=???Inclination between strut and reference side +61226=???Middle flattening +61227=???Angle of cone +61228=???Mortise depth +61229=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61230=???Height of strut +61231=???Margin on the reference point +61232=???Margin opposite the reference point +61235=???Displacement to the front side +61236=???0=with rounding at the bottom; 1=without rounding, unbounded +61237=???0=with elongation; 1=with pocket +61240=???Angle between axis of the tenon and reference side +61241=???Middle flattening +61242=???Angle of cone +61243=???Mortise depth +61244=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61245=???Margin on the reference side +61246=???Margin opposite the reference side +61249=???Position and alignment of the text. P04 = 0 if there is no text. +61250=???Angle between axis and reference edge. If P06 equals 180°, then a horizontal line is defined, P12 defines the length of the line. +61251=???Interior angle. If P07 equals zero, 2 single markings have to be produced. +61252=???Width of quadrangle. If P11 equals zero, there is only a single marking. +61253=???Height of quadrangle. If P12 equals zero, marking is limited by the edge opposite to the reference edge. +61254=???Height of text. If P13 equals zero, the machine determines the text height. +61255=???Text (String max. 256 characters) +61258=???Angle between axis and reference edge +61259=???Alignment vertical. 0 = bottom, 1=middle, 2=top +61260=???Alignment horizontal. 0 = left, 1=middle, 2=right +61261=???Alignment in case of a multiline text. 0 = left-aligned, 1=centered, 2=right-aligned. A new line must be defined with this 2 letters: \n +61262=???Letters standard or horizontal placed. 0 = standard, 1=letters horizontal placed +61263=???Height of text. If P13 equals zero, the machine determines the text height. +61266=???Depth at the reference side +61267=???Depth at the opposite of reference side +61268=???Length of the overlap +61269=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61270=???Drilling 2 diameter. Placed at 2/3 P13 +61272=???Angle of inclination of the lapped scarf base +61273=???Shape of the lapped scarf or classic data identification: 1:when cutting orthogonal to reference side; -1:when cutting orthogonal to base side; 0:classic definition, P10 and P12 are not used +61274=???Length of the lapped scarf base +61275=???Depth of the lapped scarf base +61276=???Depth of the lapped scarf base orthogonal to reference side +61277=???Length +61278=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61279=???Drilling 2 diameter. Placed at 2/3 P13 +61281=???Type of heel notch:0=normal; 1=tapered +61282=???Inclination strut +61283=???Depth step joint +61284=???Depth heel notch +61285=???Height tenon. Which implementation (A or B) is used depends on the machine +61286=???Width tenon +61289=???Type of heel notch: 0=normal; 1=tapered +61290=???Inclination between strut and reference side +61291=???Width of the notch +61292=???Depth step joint +61293=???Depth heel notch +61294=???Height of strut +61295=???Depth of mortise. Which implementation (A or B) is used depends on the machine +61296=???Width of mortise +61298=???Specification of side(s) to be planed; binary coded +61299=???Planing depth +61300=???Length of the area to be planed +61303=???Rotation angle of the first curve of the profile +61304=???Rotation angle of the profile towards the reference edge +61305=???Offset angle +61306=???Radius of the first curve +61307=???Radius of the second curve +61309=???Radius +61310=???Depth +61311=???Displacement +61312=???Depth +61313=???Displacement +61315=???Radius +61316=???Depth +61317=???Displacement +61318=???Depth +61319=???Displacement +61321=???Profile length +61322=???Depth at the reference point +61323=???Maximum depth of profile +61324=???Minimum depth of profile +61325=???Depth at the profile end +61326=???Premill: 0=round; 1=angular +61328=???Depth of the arch segment +61329=???Length of the arch segment +61331=???Type of arc (convex, concave), binary coded. See table below. +61332=???Length of lap 1 +61333=???Depth of lap 1 +61334=???Displacement arc 1 +61335=???Horizontal length arc 1 +61336=???Vertical length arc 1 +61337=???Camber arc 2 +61338=???Length of lap 2 +61339=???Depth of lap 2 +61340=???Displacement arc 2 +61341=???Horizontal length arc 2 +61342=???Vertical length arc 2 +61343=???Camber arc 2 +61344=???Length of lap 3 +61345=???Depth of lap 3 +61348=???Distance from the reference side to the reference point +61349=???Radius +61350=???Start offset +61351=???Length +61354=???Distance from the reference side to the reference point +61355=???Normal vector 1: Length of X-component +61356=???Normal vector 1: Length of Y-component +61357=???Normal vector 1: Length of Z-component +61358=???Normal vector 2: Length of X-component +61359=???Normal vector 2: Length of Y-component +61360=???Normal vector 2: Length of Z-component +61362=???Distance between "inside" an side of part +61363=???Distance orthogonal to the reference side +61364=???0:"inside" at reference edge, 1:"inside" at opposite of reference edge +61365=???0:Without rebate or mitre, -1:With mitre, >0:With rebate +61366=???Angle to the reference edge in the reference side +61367=???Width +61368=???Depth +61369=???Inclination +61370=???Height +61371=???Radius +61372=???Length of tool (part of arc) +61373=???0:Angular corner joint, 1:Straight T-wall connection +61374=???Length +61375=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61377=???Distance between "inside" an side of part +61378=???Distance orthogonal to the reference side +61379=???0:"inside" at reference edge, 1:"inside" at oppostite of reference edge +61380=???0:Without rebate or mitre, -1:with mitre, >0:with rebate +61381=???Inclination +61382=???Depth 1 +61383=???Depth 2 +61384=???0:European Dovetail, 1:American Dovetail +61385=???Length +61386=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61387=???Depth +61388=???Mode: 0=contour only, 1=countersink completely. Only for closed contours. +61389=???Contour type +61390=???Parameter depends on contour type(P13) +61391=???Parameter depends on the contour type(P13) +61400=???Reference point on referene edge +61401=???Reference point on the opposite edge +61402=???Reference point on referene edge +61403=???Reference point on the opposite edge +61404=???orthogonal +61405=???at 45 deg +61406=???round +61407=???all laps are symmetric to each other +61408=???lap on reference edge moved to end beam. lap in opposite of reference edge moved to start beam +61409=???lap on reference edge moved to start beam. lap in opposite of reference edge moved to end beam +61410=???only one lap on reference side +61411=???one lap on reference side and one on the opposite side +61412=???with rounding at the bottom +61413=???without rounding, unbounded +61414=???with elongation +61415=???with pocket +61416=???bottom +61417=???middle +61418=???top +61419=???left +61420=???right +61421=???left-aligned +61422=???centered +61423=???right-aligned +61424=???standard +61425=???letters horizontal placed +61426=???when cutting orthogonal to reference side +61427=???when cutting orthogonal to base side +61428=???classic definition, P10 and P12 are not used +61429=???normal +61430=???tapered +61431=???round +61432=???angular +61433=???"inside" at reference edge +61434=???"inside" at opposite of reference edge +61435=???Angular corner joint +61436=???Straight T-wall connection +61437=???Processing on the reference side and opposite the reference side +61438=???Processing only on the reference side +61439=???Processing only opposite the reference side +61440=???European Dovetail +61441=???American Dovetail +// ---Custom Parameter (Q) +61451=???Profondità smusso +61452=???0=Automatico; 1=Ciclo longitudinale con lama +61453=???Spessore testimone centrale per ciclo Q02 +61454=???0=Attacco centrato; 1=Attacco interno +61455=???0=Automatico; 1=Lavorazione con fresa di lato +61456=???1=Forza Lama; 0=Automatico +61457=???1=Solo smusso +61458=???0=Automatico; 1=Massima profondità +61459=???0=Automatico; 1=Truciolatore; 2=Truciolatore di lato; 3=Fresa; 4=Fresa di lato +61460=???0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +61461=???0=Automatico; 1=Massimo raggio ammesso su tasche non passanti +61462=???Diametro utensile per Q05 +61463=???Diametro utensile per Q07 +61464=???0=Raggio su spigolo; 1=Foro su spigolo; 2=Spigolo vivo +61465=???Diametro foro quando P05=1 +61466=???0=Automatico; 1=Sgrossatura con lama +61467=???Antischeggia: 0=No; 1=Con lama; 2=Con fresa +61468=???Aumenta dimensioni tasca +61469=???Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico +61470=???0=Automatico; 1=Solo contorno ; 2=Drill or Pocket +61471=???0=Automatico; 1=Lavoro da un lato solo +61472=???Incrementare/decrementare valore P01 per fori nei tenoni +61473=???0=Foratura rompi truciolo; 1=Foratura scarico truciolo +61474=???Profondità smusso quando P05=1 +61475=???Riduzione profondità tenone +61476=???Riduzione larghezza tenone +61477=???Riduzione altezza tenone +61478=???Riduzione profondità tenone +61479=???Ridurre/Allargare sagoma tenone +61480=???Ridurre/Allargare altezza tenone +61481=???aumenta profondità mortasa +61483=???Profondità di lavoro +61484=???Aumenta dimensioni P10 +61485=???0=Automatico; 1=Truciolatore +61486=???Riduzione lunghezza P14 +61487=???Riduzione larghezza P15 +61488=???Sovramateriale finitura +61489=???Numero divisioni ondulazioni dello smusso sulla lunghezza +61490=???1=Disabilita fresatura gradini +61491=???1=Attiva smusso superiore +61492=???1=Smusso superiore con lama +61493=???Spessore legno per supporto lavorazione +61494=???Attiva antischeggia +61495=???Profondità antischeggia +61496=???Massima elevazione (0=Automatico, >10=Manuale) +61497=???0=Automatico; 1=Lama +61498=???0=Automatico; 1=Disabilita controllo lunghezza fresa +61499=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61500=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61501=???0=Automatico 1=Lavorazione con fresa orizzontale se sopra o sotto (disabilita lama) +61502=???0=Automatico 1=Usa truciolatore se sotto +61503=???0=Attacco e uscita centrati 1=Attacco e uscita interni +61504=???0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +61505=???0=Automatico; 1=Lavora come Taglio Longitudinale +61506=???0=Automatico; 1=Lavorazione con fresa +// ----- EgtBEAMWALL - BTLParam ----- +61601=???SN +61602=???Abilita +61603=???Descrizione +61604=L +61605=W +61606=H +61607=???Material +61608=???Richiesti +61609=???In produzione +61610=???Prodotti +61611=???Ruotare +61612=???Group +61613=???Unit Time +61614=???Parametro +61615=???Valore +61616=???Minimo +61617=???Massimo +61618=???Single member number +61619=???Assembly number +61620=???Order number +61621=???Designation +61622=???Annotation +61623=???Subgroup/Storey +61624=???Group +61625=???Package +61626=???Material +61627=???Timber grade +61628=???Quality grade +61629=???Count +61630=???Colour +61631=???Transparency +61632=???Planing length +61633=???Start offset +61634=???End offset +61635=???Transformation: Origin +61636=???Transformation: X-axis dir. vect. +61637=???Transformation: Y-axis dir. vect. +61638=???Camber: Reference side +61639=???Camber: P01,P02,P03,P04 +61640=???Part offset: ref. side fix clamp +61641=???Part offset: P11,P12,P13,P14 +61642=???Processing quality +61643=???Recess +61644=???Storey type +61645=???Element number +61646=???Layer +61647=???Module number +61648=???USERATTRIBUTE +61649=???Comment +61650=???Grain direction: X,Y,Z +61651=???Grain direction: Align +61652=???Reference side +61653=???Reference side: Align +61654=???Alignment: Location +61655=???Alignment: Endtype +61656=???Material type: Group +61657=???Material type: Specification +61658=???AUTOMATIC +61659=???VISIBLE +61660=???FAST +61661=???MANUAL +61662=???CEILING +61663=???ROOF +61664=???WALL +61665=???inactiv +61666=???BR +61667=???TR +61668=???BA +61669=???TA +61670=???HC +61671=???VC +61672=???AC +61673=???R +61674=???A +61675=???D +61676=???Batten +61677=???Cladding +61678=???Massive timber +61679=???Membrane +61680=???Gypsum Board +61681=???Gypsum Fibre +61682=???Insulation +61683=???Sheet Component +61684=???Facade Panel +61685=???Profiled Panel +61686=???Plaster +61687=???Reference side 1 +61688=???Reference side 2 +61689=???Reference side 3 +61690=???Reference side 4 +61691=???UID +61692=???Project number +61693=???Project name +61694=???Project part +61695=???GUID +61696=???Listname +61697=???Customer +61698=???Architect +61699=???Editor name +61700=???Delivery date +61701=???Export date +61702=???Export time +61703=???Export release +61704=???Language +61705=???Range +61706=???Computername +61707=???User name +61708=???Path & name of CAD-File +61709=???Path & name of BTL-File +61710=???STANDARD +61711=???EXTENDED +61712=???Vol unit +61713=???Vol tot +61714=???Time unit +61715=???Time tot +61716=???Total parts number +61717=???Total volume +61718=???Total time +61719=???Total estimed time +61720=???Remaining time +61721=???Rawpart counter +61722=???BTL part counter +61723=???Added part counter +61724=???Part in rawpart counter +61725=???Done part counter +61726=???Quantity +61727=???Print PDF +//Ware???house +61751=???Current S +61752=???Current L +61753=???StartOffset +61754=???Kerf +61755=???Offset +61756=???S Parameters +61757=???L Parameters +61758=???New Value: +61759=???W +61760=???L +61761=???Confirm +61762=???Save +61763=???Cancel +61764=???Error +61765=???Input value already present +61766=???Input value not correct +61767=???Input pair already present +61768=???One or more input values not correct +61769=???Attention +61770=???Selected parameter is equivalent to current L/S. Are you sure you want to remove it? +61771=???SectionXMaterial +61772=???Alias +61773=???Values +61774=???Quantity +61775=???Min thickness +61776=???Max thickness +61777=???Increment Max thickness of the last range before adding a new range +// +61801=???Custom +61802=???Default +61803=???L +61804=???T +61805=???Process +61806=???Section time +61807=???Part time +61808=???Name +61809=???PDN +61810=???DO +61811=???X position +61812=???Y position +61813=???Added +61814=???Done +61815=???ID +61816=???Start offset +61817=???% Used +61818=???Waste +61819=???BTL File Name +61820=???List Name +61821=???Export Date +61822=???Creation Date +61823=???Delete +61824=???Face +61825=???Group +61826=???Modify +61827=???Save +61828=???Cancel +61829=???Nesting +61830=???Viewer +61831=???Optimizer +61832=???Configuration +61833=???Optimize +61834=???Update BTL +61835=???Go to optimization +61836=???Filter type +61837=???Search +61838=???Export project +61839=???Import project +61840=???Import BTL +61841=???Copy to Clipboard +61842=???DisplayIndex +61843=???Column name +61844=???CanUserReorder +61845=???CanUserResize +61846=???CanUserSort +61847=???IsReadOnly +61848=???Visible +61849=???Variable Path +61850=???Type +// +61851=???This part modification will cause the removal of the part from {0} raw parts. Do you want to proceed anyway? +61852=???Impossible create feature with this values +61853=???Impossible create part with this values +61854=???Impossible create bar with this values +61855=???Impossible create wall with this values +61856=???Value outside minimum and maximum +61857=???Impossible to insert a quantity inferior to the number of parts already in rawparts! +61858=???Impossible to modify these values +61859=???Error in machine parameter writing +61860=???Save machine parameters modification? +61861=???Save default values modification? +61862=???Changing type second path will be deleted. Do you want to proceed? +61863=???To produce part number reached: +61864=??? from BTL; +61865=??? added. Do you want to add another one? +61866=???Selected part has different section from selected bar. Impossible to add. +61867=???Selected part lenght is more then the selected bar lenght. Impossible to add. +61868=???Selected part has different height from selected wall. Impossibl to add. +61869=???Error in macro file execution! +61870=???Impossible create a Macro without selecting a Feature or with empty name +61871=???File not found! +61872=???Impossibie deleting current project +61873=???Impossibile deleting the project because already linked to an optimization +61874=???Impossibile deleting the project because some parts are already sent to production +61875=???Do you want to save the project modifications? +61876=???Impossible creating a new file! +61877=???Save project modification before continuing? +61878=???Impossible proceding with a new unsaved project! +61879=???Type of current machine is both Beam and Wall. Select the type you want to set the project to: +61880=???Select one of the available machines and/or types. Otherwise cancel the project import. +61881=???The opened project type is not compatible with the current machine type +61882=???Do you want to save the modifications to the DataGrid columns? +61883=???The columnn specified as "{0}" in the "{1}" table in the datagrid columns ini file was not found in the program +61884=???Select the machine you want to associate to the project: +61885=???The machine linked to the opening project cannot be found among the available machines +61886=???Machine +61887=???Impossible creating the inserted rawparts quantity +61888=???How many copies of the rawpart do you want to create? +61889=???Long Drill Area +61890=???Min Rule +61891=???Can't send feedback from Optimizer if there is no open Prod +// +61900=???Change paramter +61901=???Verify +61902=???Simulate +61903=???New raw part +61904=???Add to raw part +61905=???Copy part +61906=???Add part +61907=???Remove part +61908=???Copy feature +61909=???Create macro +61910=???Add feature +61911=???Remove feature +61912=???Produce rawpart +61913=???Produce all rawpart +61914=???Copy rawpart +61915=???Remove rawpart +61916=???Reorder parts +61917=???Move up part +61918=???Move down part +61919=???Remove part +61920=???Warehouse +61921=???Add project to optimization +61922=???Go to project +61923=???Statistics +61924=???Reset +61925=???Show all parts +61926=???Show solid +61927=???Show building +61928=???Verify all +61929=???Can't change machine because the Proj is already linked to a Prod +61930=???Inputs +61931=???Outputs +61932=???Calculate Flip & Rotation +61933=???Unlock Flip +61934=???Unlock Rotation +61935=???Length +61936=???Width +61937=???Offset +61938=???Kerf +61939=???Edit +61940=???Reset +61941=???Choose machine +61942=???BTL file already imported and optimized. Do you want to import it again? +61943=???BTL file already imported. Do you want to overwrite it? +61944=???Shift parts +61945=???Shift direction +61946=???Shift length +61947=???Parts can't be shifted outside the raw part +61948=???The inserted shift value is not valid +61949=???Search & Filter +61950=???Parameter Type +61951=???Parameter Value +61952=???R +61953=???A +61954=???P +61955=???D +61956=???All +61957=???Filtered +61958=???Update +61959=???Append +61960=???Check the parts you would like to add to update BTL +61961=???Change material +61962=???Project material +61963=???Warehouse material +61964=???Standard +61965=???From BTL +61966=???Save +61967=???Do NOT save +61968=???Waiting for optimizer save +61969=???Cancel + +// +62500=???Supervisor +62501=???Channel +62502=???OPMode +62503=???Produce All +62504=???Done RawPart +62505=???Reset RawPart +62506=???Delete RawPart +62507=???Print Label +62508=???Done Part +62509=???Resume started processing? +// Loading +63000=???Project opening +63001=???Loading project geometries +63002=???Loading machining groups +63003=???Loading production data +63004=???Optimization opening +63005=???Loading parts +63006=???Loading graphics +63007=???Project saving +63008=???BTL file importing +63009=???Reading BTL file +63010=???Project exporting +63011=???Loading environment +63012=???Saving geometry +63013=???Saving data on Db +63014=???Modifying parameters +63015=???Part viewer opening +63016=???Adding export info +63017=???Exporting... +63018=???Project importing +63019=???Loading project +63020=???Creating imported project +63021=???Modifying materials +// ----- FromLua ----- +65001= +// ----- OmagCUT ----- +// General +90001=TRABAJO EN CURSO +90002=CORTES LINEALES +90003=CORTES CAD +90004=MARCOS +90005=MAQUINA +90006=OPCIONES +//Trabajo en progreso +90101= +// DirectCut +90201=Movimiento manual +90202=Corte singolo +90203=Corte multiple +90204=Corte rejilla +90205=MTH +90206=Alisado +90207=Test disco +90208=Palpador disco +90209=Copia molde +90210=Adquirir P1 +90211=Adquirir P2 +90212=Laser +90213=Profundidad +90214=Longitud +90215=Direcciòn +90216=Inclinaciòn +90217=Nùmero +90218=Dimensiones +90219=Nùmero X +90220=Dimensiones X +90221=Nùmero Y +90222=Dimensiones Y +90223=Corte lado motor +90224=Disco +90225=Diseño +90226=Ancho +90227=Superposiciòn +90228=Offset +90229=Bloquea el eje C +90230=Ejecuta +90231=???Lucidatura +90232=Espesor disco +90241=Palpaciòn disco +90242=Palpaciòn en curso... +90243=Palpaciòn completada con èxito +90244=Errore en tastatura disco +90245=Nuevo nombre del molde +90246=???Tastatura interrotta dall'utente +90250=Linea +90251=Arco +90252=Remueve +90253=Cierra +90254=Guardar +90255=???Test +90256=???Verifica posizione taglio +90257=???Verifica posizione in corso... +90258=???Single drill +// CadCut +90301=Simula +90302=Ejecuta +90303=Nuevo +90304=Carga +90305=Guardar +90306=Guardar como +90307=Nuevo nombre del proyecto +90308=CSV +90309=Vein Match +90310=Exporta +90311=Herramienta +90312=Elaboraciòn +90313=Fotografia no lograda +90314=Error en la generaciòn del programa CN +90315=Error en la transmisiòn del programa CN +90316=No conectado a la màquina +90317=Programa CN transmitido +90318=La màquina no acepta el programa CN +90319=Programa ya transmitido, quieres retransmitirlo ? +90320=Màquina diferente +90321=Reducidas algunas elaboraciones para evitar interferencias +90322=Faltan las herramientas : +90323=???Fotografia di sfondo eseguita +90324=???Riconoscimento contorno non riuscito +90325=???Errore nel salvataggio delle statistiche +90326=Confirmas Restart desde fase {0} ? +90327=Nuevas Piezas dañadas +90328=Area pezas : +90329=???Da Produrre : +90330=Programa ya transmitido, nueva losa ? +// NestPage +90331=Introducir pieza +90332=Aparcar pieza +90333=Eliminar pieza +90334=Selecionar todo +90335=Deselecionar todo +90336=Reset +90337=???Uno o più pezzi con spessore, materiale o finitura non compatibili +90338=???Rotazione oltre i limiti +90339=???Rotazione impossibile +90340=???Nesting Automatico in corso +// Pagina Dividida +90341=On/Off +90342=Todos On +90343=Todos Off +90344=Alarga/Acorta +90345=Inicio Alar/Acor +90346=Final Alar/Acor +90347=Inicio Centro/Fuera +90348=Inicio Todos Fuera +90349=Inicio Todos Centro +90350=Càlculo automàtico no exitoso +90351=Disco demasiado grande para utilizar ventosa +90352=Fin Centro/Afuera +90353=Fin Todos Afuera +90354=Fin Todos Centro +90355=Estira Todos +90356=Acorta Todos +90357=Modif. +90358=Auto +90359=Restart +// MoveRawPart +90361=Remueve +90362=Pieza demasiado pequeña : no se puede mover +90363=Posición seleccionada ya ocupada +90364=???Part too havy : can not be moved +90365=???Part beyond strokes : can not be moved +// SplitPage 2 +90371=Pausa On/Off +90372=Pausa +90373=Modif inicio +90374=Modif fine +90375=Elongación +90376=Revertir +// DrawPage +90381=Nùmero piezas +90382=Medidas +90383=Inclinaciones +90384=Indica Lado Arriba +90385=???Disegno Parametrico +90386=Seleccionar un contorno +90387=No hay lados editables +90388=Nombre +90389=???Dati Trf +90390=???Codice ordine +90391=???Descrizione ordine +90392=???Codice materiale +90393=???Codice superficie +90394=???Spessore +90395=???Seleziona uno o più fori +90396=???Codice pezzo +90397=Tallar +90398=???Dati Csv +90399=Todos los mecanizados actualizados +90400=???Filo Top +// Component +// Màximo 30 caracteres sin imagenes y màximo 20 con la imagen +90401=Triangulo +90402=Rectangulo +90403=Trapecio +90404=Cuadrilatero +90405=Piedoca +90406=Limite +90407=Piano Cocina +90408=Piano Baño +90409=Otros +90410=Triangulo2L +90411=Triangulo3L +90412=Isòsceles +90413=Rectangulo +90414=Escaleno +90415=Escaleno +90416=4Lados 1Ang +90417=3Lados 2Ang +90418=3Lados 2Diag +90419=4Lados 1Diag +90420=4Lados 3Diag +90421=4Lados 3Ang +90422=4Lados 3Ang +90423=Angulo Recto +90424=Angulo Recto Desafilado +90425=Angulo Alineado +90426=Angulo Alin. Desafilado +90427=Parte A +90428=Parte B +90429=Angulo +90430=Angulo Desafilado +90431=Elipse +90432=Oval +90433=Arco +90434=Arco LHF +90435=Arco LLH +90436=Arco LLF +90437=Rectangolo redondeado +90438=Convexo +90439=Agujero +90440=???2 Fori +90441=3 Agujeros +90442=Arco RHa +90443=Polygon +90444=???Foro da sotto +90445=Dxf +90446=Rebaje +90447=Componentes interiores +90448=Agrega +90449=Remueve +90450=Confirmación +// Import +90451=Usa layer +90452=Usa regiones +90453=Reset +90454=mm +90455=inch +90456=Usa curvas cerradas +90457=Inclinaciòn +90458=Tallar de debajo +90459=Ángulo +90460=Compensar +90461=Hundimiento +90462=Acortamiento +90463=Importa DXF +90464=Fora de debajo +90465=???Numero +90466=Compensar2 +90467=???Ordine +90468=???Distinta +90469=???Nome +// Component 2 +90470=Grabados Rebaje +90471=Grabados +90472=TriánguloCH +90473=TriánguloRT +90474=TrapecioRtA +90475=3Lados 2Ang +90476=???Nuova soglia +// FastGrid +90480=???Nome ordine +90481=???N° Lastra +90482=???Ultima lastra +90483=???Tipo pezzo +90484=???Inserisci pezzi +90485=???Conferma ordine +// Abierto +90491=Proyecto no vàlido +90492=Proyecto con interferencias. Para cargarlo desactiva respecto cortes completos. +// RawPart +90499=Bruto indefinido +90500=Rotación +90501=Rectangulo +90502=Para puntos +90503=Longitud +90504=Ancho +90505=Espesor +90506=Offset X +90507=Offset Y +90508=Kerf +90509=Material +90510=Zona aruinada +90511=Nuevo +90512=Borrar +90513=Puntos +90514=Agregar +90515=Borrar +90516=Màxima longitud = +90517=Màximo Ancho = +90518=No se admiten alturas negativas +90519=Minimo offset X = +90520=Minimo offset Y = +90521=Minimo kerf = +90522=Màximo kerf = +90523=Sondeo en bruto +90524=???Conferma +90525=Sondear en bruto +90526=Sondeo en curso... +90527=Sondeo completado con èxito +90528=Error en el sondeo en bruto +90529=Del diseño +90530=Del laser +90531=Cierra +90532=Error en la adquisiciòn del punto +90533=Contorno +90534=Disco demasiado grande para sondeo +90535=Da fotografia +//ChooseMachining +90536=Seleccionar el mecanizado de la disco +90537=Seleccionar el mecanizado secundario +90538=Seleccionar la perforaciòn +90539=Seleccionar el fresado +90540=Ninguna +90541=Taladrar +90542=Fresado +90543=Ambas +90544=Elegir trabajos +90545=Seleccionar el chorro de agua +90546=Corte por chorro de agua +90547=Error en la psicion o dimenson del material +90548=Maximo offset X = +90549=Maximo offset Y = +90550=???Scegliere la svuotatura +// Simulaciòn +90551=Simulaciòn completada +90552=Extracarrera +90553=Dirección de la herramienta inalcanzable +90554=Error +90555=ERROR +90556=Error al generar! +90557=Simulacion +90558=Un paso a la vez +90559=Play/Pausa +90560=Stop/Home +90561=Pausa +90562=Simulacion interumpida +90563=Vista maquina +90564=Home +90565=Tiempo +90566=Longitud +90567=Area pezas +90568=Utilizo +90569=Estimado +90570=Detalle +// FrameCut +90601=Largo X +90602=Largo Y +90603=Remueve +90604=Desbaste +90605=Acabado +90606=Espatulatur +90607=Espeja +90608=Dist.desde arriba +90609=Dist.desde princ. +90610=Acorta el inicio +90611=Acorta el final +90612=Corte único +90613=Arco +90614=Guia +90615=Sección +90616=Guia +90617=Rad +90618=Ang +90619=Error : radio más pequeño que el ancho de la sección. +90620=Error : la creación del marco falló +90621=Distancia X +90622=Distancia Y +90623=Lado contrario +// Màquinas +90701=Msg_Ita.xpi +90705=Datos màquina +90706=DB herramientas +90707=DB trabajos +90708=Màquina +90709=???Statistics +90715=Nuevo +90716=Nueva +90717=Salva +90718=Elimina +//ToolsDb +//param +90719=???Lunghezza portautensili +90720=???Anima +90721=Nombre +90722=Posiciòn +90723=Cabezal +90724=Salida +90725=Rotaciòn +90726=Normal +90727=Màxima +90728=Progreso +90729=Progreso +90730=Cabezal +90731=Entrada +90732=Salida +90733=Agua +90734=Corrector +90735=Supramaterial +90736=Longitudinal +90737=Radial +90738=Max absorciòn. +90739=Feed minima +90740=Max affond. +90741=Longitud +90742=Diàmetro +90743=Espesor +90744=Filo cortante +90745=Notas +90746=Numero de Serie +90747=Código +90748=Proveedor +90749=Fin de servicio +//tools families +90751=Disco +90752=Agujero +90753=Cortador +90754=???Mola da scasso +90755=Chorro de agua +90756=???Mola lucidante +//Tool Setup +90759=???Posizione utensile predefinita già occupata +//MachiningsDb +//param +90761=Nombre +90762=Profundidad +90763=Angulo de deslizamiento +90764=Invertir +90765=Tipo de paso +90766=Lado de trabajo +90767=Lado cabezal +90768=Posiciòn inicio +90769=Ataque +90770=Entrada +90771=Salida +90772=Utiliza curvas +90773=Tolerancia +90774=Paso de hundimiento +90775=Normal +90776=Paso de hundimiento +90777=Interno arcos +90778=Externo arcos +90779=Longitud de desaceleración +90780=Inicial +90781=Final +90782=Profundidad adicional +90783=Posiciòn de retorno +90784=Herramienta +90785=Espesor minimo +90786=Espesor màximo +90787=Paso +90788=En hundida +90789=De lado +90790=En vertical +//machinings families +90791=Corte +90792=Perforar +90793=Fresado +90794=Desbaste con disco +90795=Acabado con disco +90796=???Svuotatura +90797=???Waterjet +//ComboBox Param +90801=No +90802=Interior +90803=Exterior +90804=Ambas +90821=Centro +90822=Izquierda +90823=Derecha +90824=Centrado +90825=Interior +90826=Exterior +90827=Extendido centrado +90828=Extendido exterior +90829=Extendido anterior +90830=Extendido siguiente +90831=Extendido ambos +90832=Centrada +90833=Interior +90834=Exterior +90835=Salta +90836=Aproximar +90837=Convexo +90838=Zig Zag +90839=Una via +90840=Adelante y atràs +90841=Trabaja +90842=Ninguno +90843=???Normale +90844=???Rallenta +90845=???Anello +90846=???Lineare +90847=???Tangente +90848=???Inseguimento +90849=???Elica +90850=???Come attacco +// param2 +90861=Espatular +90862=Inclinado +90863=Incl. retorno +90864=Ida +90865=Retorno +90866=Último retorno +90867=???Inclinazione in avanti +90868=???Tastatura +90869=???Min dist. punti +90870=???Max dist. punti +90871=???Esterni +90872=???Interni +90873=???Lungh. rall. +90874=???Rallentam. % +90875=???Foro di attacco +90876=???Raggio +90877=???Num. giri in LP +90878=???Num. giri in HP +90879=???Abilitazione +90880=???Angoli +// Barcode +90881=Código de barras +90882=???Blocco +90883=???Numero +90884=???Dati lastra +// param3 +90890=???Dist. tang. +90891=???Dist. perp. +90892=???Dist. tang. +90893=???Dist. perp. +90894=???Ataque cerámico +90895=???Longitud +90896=???Paso +90897=???Last cut +90898=???Side angle cuts +// Alarms +90900=Chorro de agua actual +90901=Disco actual +90902=Herramienta auxiliar +90903=Agujero actual +90904=Fresa actual +90905=Z seguridad +90906=Seguridad cortes +90907=Seguridad esquinas +90908=Cumple con los cortes completos +90909=Offset agujeros +90910=Superposición agujeros +90911=Tolerancia agujeros +90912=Lista errores CN +90913=Materiales +90914=Agrega +90915=Remueve +90916=Herramientas actuales +90917=Parametros agujeros +90918=Rmin arcos ext. +90919=Parametros màquina +90920=Ninguno +90921=Agujero +90922=Fresa +90923=Ambos +90924=Amax arcos int. +90925=Parametros disco +90926=Un solo agujero en angùlo +90927=Cortes directos +90928=Inicio definitiva +90929=Parametros fresado +90930=Siempre sobre interiores +90931=Nesting +90932=Alineado +90933=Cargar herram. +90934=Nuevo +90935=Eliminar +90936=Altura sobremesa +90937=Recuadro Foto +90938=Fondo +90939=Margen +90940=Tolerancia +90941=Seco +90942=Confirmar la cancelación del material seleccionado? +90943=Setup di default +90944=Siempre en angùlo +90945=Seleccione la herramienta +90946=Cortes Progreso inicio/fin +90947=Longitud +90948=Reducc.% +90949=Acortar +90950=???Tastatura +//Machine +90951=Start +90952=Stop +90953=Reset +90954=Auto +90955=Single +90956=MDI +90957=Manual +90958=Home +90959=Download +90960=Upload +90961=Activate +90962=Delete +90963=MDI Confirm +90964=Modalidad CN +90965=controles de la máquina +90966=Cadena MDI +90967=Transferimiento part program +90968=???Do you want to change table? +// Options +90981=Idioma +90982=El nuevo idioma serà actualizado desde el pròximo inicio del programa. +90983=Unidad de medida +90984=Rotaciòn visiòn +90985=???Angolo inclinato +90986=???Un solo valore +90987=???Più valori +90988=???Inserimento diretto dei pezzi +90989=???Parametrici e DXF +90990=???CSV +90991=???Fast grid +90992=Permitir la creación de piezas estándar +90993=???Colore testo +90994=???Slab Dxf +90995=???Slab Layer +90996=???Parts Layer +90997=???Scrap Layer +90998=???Std Thick +90999=???ColorToSideAng +91000=???Enable +91001=???Tolerance +91002=???Heel +91003=???Side Angle +91004=???Feedback +91005=???Themes +91006=???Engrave from color +91007=???Depth +91008=???Width +91009=???Start program +91010=???Select start mode +91011=???Recent project +91012=???Last opening +91013=???Last project +91014=???New project +91015=???Open folder +91016=???Show window +//Alarms2 +91051=Trabajos +91052=Corte +91053=Perforar +91054=Fresado +91055=???DripSawing +91056=???DripDrilling +91057=WaterJet +91058=Parametros waterjet +91059=Automático +91060=Alineado y Guillotina +91061=Parámetros de grabado +91062=Con cortador +91063=Profundidad +91064=Anchura +91065=Salir precortado +91066=Guillotina +91067=Insertar pausa +91068=Marcos +91069=Vaciando +91070=???Scasso corrente +//Statistics +91071=???Day Production +91072=???Week Production +91073=???Project +91074=???Parts Area +91075=???Cuts Area +91076=???Day +91077=???Week +91078=???Reset +91079=???To Produce Area +//Lucidature +91089=???Offset +91090=???DB Lucidature +91091=???Lucidature +91092=???Movimento +91093=???Ripetizioni +91094=???Attacco/Uscita +91095=???Altezza +91096=???Lista utensili +91097=???Lunghezza +91098=↑ +91099=↓ +91100=???Precarico +//EgtMsgBox +91101=Salvar el proyecto actual? +91102=Salvar la herramienta actual? +91103=Salvar el trabajo actual? +91104=Nombre gya utilizado +91105=Hay interferencia, se pueden aparcar algunas piezas. ¿Quieres continuar? +91106=Ya existe un archivo con ese nombre. Sobreescribirlo? +91107=CONEXION AL CN +91108=Conexiòn en curso... +91109=Conexiòn no obtenida +91110=Conexiòn obtenida +91111=Mesa para usar ? +91112=Quieres borrar tambien las piezas provenientes de la lista Csv ? +91113=Piezas no se remueve porque esta libre +91114= o de otras listas Csv +91115=Error +91116=Opciòn Linea de producciòn no habilitada +91117=Error en copia archibo por OmagVIEW +91118=Conservo las pieza en estacionamiento? +91119=Error en la gestiòn dei pezzi rovinati +91120=???I caratteri \ / : * ? " < > | non sono permessi +91121=???Sei sicuro di voler cancellare i pezzi selezionati? +91122=???Attenzione +91123=Mesa +91124=???Salvare la lucidatura corrente? +91125=???Salvare le modifiche correnti? +91126=???Export +91127=???Import +91128=???DB WaterJet +91129=???Origine da laser +91130=???Start program? +// CSV +91201=Abrir +91202=Ingresar +91203=Nuevo +91204=Remuove +91205=???Errore nel salvataggio del file CSV, vuoi continuare lo stesso ? +91206=???Errore nella lettura del file CSV +// OmagVIEW +91301=Todos Validos +91302=Pieza Valida +91303=Pieza dañada +91304=Imprimir Etiqueta +91305=Confirmacòn +91306=???Stampa +// OmagOFFICE +// OptionPanel +91401=Crudo +91402=Disponer +91403=Trabajo +91404=Simula +// MachiningDbWindow +91451=Material +91452=Espesor mìnimo +91453=Espesor màxsimo +// TopCommandBar +91501=Es necesario salvar el proyecto antes de exportarlo +91502=Seleccionar el directorio de exportación +91503=Error en la exportación +91504=Exportación completada con éxito +91505=???Esporta in macchina +91506=???Esporta DXF +// Rawpart +91551=Error en el cargar la fotografia +91552=Importa fotografia +// VeinMatching +91601=Exporta +91602=Muestra Info +91603=Modificaciòn +91604=Comprobar +91605=Magnètica +91606=Pieza no seleccionable en esta situación +91607=Pieza no seleccionable porque pertenece a un grupo de trabajo no actual : +91608=???Ingombro dei pezzi DXF troppo grande per VeinMatching +// Generic +91651=Ok +91652=Cancelar +91653=A° +91654=T +91655=Comienzo +91656=Final +// ----- OmagPHOTO ----- +// General +92001=???Db non trovato! +92002=???Unable starting the program +// OptionPanel +92051=???Salva +92052=???Aggiungi +92053=???Annulla +92054=???Elimina +92055=???Sei sicuro di voler cancellare la lastra corrente? +92056=???Etichetta +92057=???Etichetta Freccia +92058=???Sfoglia +92059=???Stampa +92060=???Seleziona +// Slab +92071=???Id +92072=???Nome immagine +92073=???Stato +92074=???Progetto assegnato +92075=???Posizione in magazzino +92076=???Data +92101=???Nome già utilizzato +92102=???Il nome è obbligatorio +92103=???L'immagine è obbligatoria +// SearchPanel +92151=???Cerca +92152=???Tolleranza spessore +92153=???Data d'inizio +92154=???Data di fine +92155=???Reset +//Messaggi +92200=???Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=???Avviso +92202=???Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=???Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=???Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// General +101001=Importar BTL +101002=Diseña +101003=Posicionar +101004=Opciones +// ImportPage +101101 +// DrawPage +101201=Pared +101202=Puerta +101203=Ventana +101204=Agregar +101205=Anular +101206=Aplicar +101207=Eliminar +101208=Distanciador +// PlacePage +101301=General +101302=Transmitir +101303=Posicionamiento pared +101304=Introducir +101305=Estacionar +101306=Eliminar +101307=Espesor estratos +101308=Nùmero tablas encima +101309=Introducciòn no lograda +101310=Generaciòn lograda +101311=Error en generaciòn +101312=Lanzammiento transmisiòn con èxito +101313=Error en lanzamiento transmisiòn +101314=Transmisiòn completada con exito +101315=Transmisiòn no lograda +101316=Puentes todos discapacitados +101317=Archibo de Generaciòn faltante +// OptionsPage +101401=Opzioni macchina +101402=Caracteristicas vinculaciòn +101403=Extra bruto en X +101404=Extra bruto en Y +101405=Extra pegamento +101406=Caracteristicas mesa +101407=Ancho de la mesa +101408=N° tablas en un plano +101409=Activaciòn puentes +101410=Puente pegamento +101411=Puente tablas +101421=Opciones software +101422=Seleccionar Idioma +101423=El nuevo idioma estarà vigente al partir del pròximo inicio del programa +101424=Nùmero proyectos por salvar +101425=Posicionar tablas sobre puertas y ventanas +101426=Anticipada apertura pegamento +101427=Anticipado cierre pegamento +// OpenPage +101501=Proyecto no vàlido +// ----- End ----- diff --git a/ProgramData/EgtCAM5/Config/EgalTechFra.txt b/ProgramData/EgtCAM5/Config/EgalTechFra.txt new file mode 100644 index 0000000..cd62567 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgalTechFra.txt @@ -0,0 +1,3313 @@ +// File dei messaggi EgalTech Francese 2022/04/11 +0=FRA +// File +1=Fichier +3=Nouveau +5=Ouvrir +6=Ouvrir
un fichier récent (Shift) +7=Insérer +9=Sauvegarder +11=Copier +13=Importer +15=Exporter +17=Executer +19=Fichiers récents +20=Script récents +// Vista +101=Vue +103=Lignes +105=Bords +107=Solides +109=Zoom tout +111=Zoom plus +113=Zoom moins +115=Dessus +117=Face +119=Droite +121=Arrière +123=Gauche +125=Dessous +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Grille +136=Régler vue perpendiculaire à la grille actuelle +137=Dircourbes +139=Analyse +141=Distance +// Griglia +201=Grille +203=Dessus +205=Face +207=Droite +209=Arrière +211=Gauche +213=Dessous +215=Vue +216=Régler la grille perpendiculaire à la direction de Vue +217=Elévation +218=Régler élévation de la Grille +219=Origine +220=Régler Origine de la Grille +221=Pivoter +222=Pivoter Grille
Pivoter en 3d Grille (Shift) +223=3 Points +224=Régler Grille avec 3 Points +225=Perp +226=Régler la grille perpendiculaire à Objet +227=Objet +228=Régler Grille par Objet +// Disegna +301=Dessiner +303=Point +304=Point
Vecteur (Shift)
Référence (Ctrl) +305=Lin 2P +306=Ligne : 2 Points
Ligne : 2 Points avec Continuation (Ctrl) +307=Lin PDL +308=Ligne : Point initial, Direction, Longueur
Ligne : Point initial, Vecteur direction, Longueur (Shift) +309=Circ +310=Circonférence : Centre, Point
Circonférence : Centre, Diamètre (Shift) +311=Chan +312=Chanfrein : Rayon
Chanfrein : Dist (Shift) +313=Arc CIF +314=Arc : Centre, Point initial, Point final +315=Arc 3P +316=Arc : 3 Points +317=Arc IDF +318=Arc : Point initial, Direction, Point final
Arc : Point initial, Vecteur direction, Point final (Shift)
Arc : Point initial, Direction, Point final avec Continuation (Ctrl) +319=Rect 2P +320=Rectangle : 2 Points +321=Polygone +322=Polygone : Rayon ou Apothème
Polygone : Côté avec 2 Points (Shift) +323=Texte +324=Texte
Texte Avancée (Shift) +399=Continuation : 'L' avec ligne, 'A' avec arc +// Costruisci +401=Construire +403=Plan +404=Surface : plan entouré par une ou plusieurs courbes
Région plate (Shift) +405=Extruder +406=Surface : da extrusion de une ou plusieurs courbes +407=Pivoter +408=Surface : da rotation de une courbe +409=Hélice +410=Surface : da rototraslation de une courbe +411=Rainurée +412=Surface : Rainurée entre 2 courbes +413=Combiner +414=Combiner une ou plus Surfaces +415=Inverser +416=Inverser l'extérieur de une ou plusieurs Surfaces +417=Exploser +418=Exploser Surfaces ou Régions Planes +419=Balayée +420=Surface : balayer une courbe le long d'une autre +// Modifica +501=Modifier +503=Effacer +504=Effacer les Objects +505=Layer +506=Porter les Objects dans le Layer courant +507=Couleur +508=Changer Couleur
Supprimer Couleur spécifique (Shift)
Changer Transparence (Ctrl) +509=Inverser +510=Inverser Courbe +511=Trim/Est +512=Couper ou Prolonger Courbe +513=Couper +514=Couper Courbe
Diviser Courbe en Parties (Shift) +515=Joindre +516=Joindre Courbes
Joindre Courbes créant une Copie (Shift)
Fusionner les courbes dans la Composite (Ctrl) +517=Exploser +518=Exploser Texte ou Courbes en Composants +519=épaisseur +520=Régler épaisseur et direction de Extrusion sur une ou plusieurs courbes +521=Début +522=Changer Début de une Courbe fermée +// Trasforma +601=Transformer +603=Déplacer +604=Déplacer un ou plusieurs Objects +605=Pivoter +606=Pivoter un ou plusieurs Objects
Pivoter un ou plusieurs Objects en 3D (Shift) +607=Miroir +608=Miroir un ou plusieurs Objects
Miroir un ou plusieurs Objects en 3D (Shift) +609=Échelle +610=Échelle de un ou plusieurs Objects
échelle de un ou plusieurs Objects en 3D (Shift) +611=Offset +612=Offset de une Courbe +// Special +701=Special +703=Pièces 2d +704=Insérer Pièces Plans da DXF ou NGE +705=Compo +706=Insérer Composants Paramétriques +// Scene : Menù Selezione Entità +1001=Sélectionner Tout +1003=Desélectionner Tout +1005=Sélectionner avec Fenêtre +1007=Sélectionner Pièce +1009=Sélectionner Layer +1011=Sélectionner Parcours +1013=Sélectionner Parcours Complet +1015=Sélectionner Entité +1016=Sélectionner Tout Visible +// Scene : Menù Punto notevole +1101=Point Sketch +1102=Point Sketch +1103=Point Grille +1104=Point Grille +1105=Point Final +1106=Point Final +1107=Point Médian +1108=Point Médian +1109=Centre +1110=Centre +1111=Barycentre +1112=Barycentre +1113=Point Près +1114=Point Près +1115=Intersection +1116=Intersection +1117=Point Tangent +1118=Point Tang +1119=Point Perpendiculaire +1120=Point Perp +1121=Point à Distance minimum +1122=Point MinDist +1123=Exclure Surfaces +// Scene : Menù Varie +1201=Désactiver Glissement +1203=Activer Glissement +// Scene : Varie +1301=Dist= +// Controller +2001=Copier (V) +2002=Erreur +2003=Alarme +2051=Le Point doit être différente de le précédent +2052=Les points doivent être pas alignés +2053=Valeurs Nulles ou Négatives ne sont pas valides +2054=Valeurs Négatives ou Deux Valeurs Nulles ne sont pas valides +2055=Au moins une Entité est non modifiable +2056=Distance trop gros +2057=Courbe pas plate (dans son plan) +// Controller : Disegna +2101= +// Controller : Costruisci +2201= +// Controller : Modifica +2301= +// Controller : Trasforma +2401=Copier +2402=Déplacer +2403=Insérer Point Base +2404=Insérer Point Destination +2406=PIVOTER +2407=Insérer Centre +2408=Insérer Point Base +2409=Insérer Angle ou Point +2411=PIVOTER 3D +2412=Insérer Premier Point Axe +2413=Insérer Deuxième Point Axe +2414=Insérer Point Base +2415=Insérer Angle ou Point +2416=MIROIR +2417=Insérer Premier Point +2418=Insérer Deuxième Point +2421=MIROIR 3D +2422=Insérer Premier Point +2423=Insérer Deuxième Point +2424=Insérer Troisième Point +2426=ÉCHELLE +2427=Insérer Centre +2428=Insérer Coefficient +2431=ÉCHELLE 3D +2432=Insérer Centre +2433=Insérer Coefficients +2436=OFFSET +2437=Insérer Distance +2438=Raccord +2439=Chanfrein +2440=Étendre +// ----- EgtCAM5 ----- +5001=DESSINER +5002=USINER +5003=Outils +5004=Usinages +5005=Options +5006=BD Outils +5007=BD Usin. +5008=Options de la Machine +5009=???SetUp Db +5010=???SetUp Db +5020=Tables des Usinages +//Top CommandBar +5101=Nouveau +5102=Ouvrir
Ouvrir un fichier récent (Bouton droit) +5103=Sauvegarder +5104=Sauvegarder comme +5105=Insérer +5106=Importer +5107=Exporter +5108=Executer script
Executer un script récent (Bouton droit) +5109=Options +5110=???Mail di supporto non trovata. +5111=???Salvare il progetto corrente prima di mandare il feedback? +5112=???Mandare il feedback a {0} con allegata la cartella {1}. +5113=???Feedback +5114=???Mail di feedback pronta. +//Draw Panel +5150=Extraire les Bords libres des Surfaces et Régions plates +5151=Joindre Surfaces et Régions plates +5152=Soustraire Surfaces et Régions plates
Couper Surface avec Surface inversé (Shift) +5153=Intersecter Surfaces et Régions plates
Couper Surface avec Surface (Shift) +5154=Points, Courbes et Faces d'Intersection entre Surfaces +5155=Dimension Linéaire
Dimension Alignée (Shift) +5156=Circonférence 3 Points +5157=Extraire les Bords des Faces des Surfaces et des Régions plates +5158=Extraire Face de Surface +5159=Arc Renversé
Arc Explémentaire (Shift) +5160=Modifier la forme +5161=Ajouter un Point
Modifier en Arc (Shift)
Fermer la Courbe Composite (Ctrl) +5162=Supprimer un Point
Modifier en Ligne (Shift)
Ouvrir la Courbe Composite (Ctrl) +5163=Approximer Courbe
Approximer Courbes avec Lignes (Shift) +5201=Point
Vecteur (Shift)
Référence (Ctrl) +5202=Ligne 2 Points
Ligne 2 Points avec Continuation (Ctrl) +5203=Ligne Point initial Direction Longueur
Ligne Point initial Vecteur direction Longueur (Shift) +5204=Circonférence Centre Point +5205=Circonférence Centre Diamètre +5206=Arc Centre Point initial Point final +5207=Arc 3 Points +5208=Arc Point initial Direction Point final
Arc Point initial Vecteur direction Point final (Shift)
Arc Point initial Direction Point final avec Continuation (Ctrl) +5209=Arrondi +5210=Chanfrein +5211=Rectangle 2 Points +5212=Polygone Centre et Rayon ou Apothème +5213=Polygone Côté avec 2 Points +5214=Texte
Texte Avancée (Shift) +5215=Plan entouré par une ou plusieurs courbes
Région plate (Shift) +5216=Extruder +5217=Pivoter +5218=Hélice +5219=Rainurée +5220=Comibiner des Surfaces +5221=Exploser des Surfaces et des Régions Planes +5222=Renverser des Surfaces et des Régions Planes +5223=Effacer +5224=Changer Couche
Changer Couche avec Transformations (Shift) +5225=Changer Transparence +5226=Supprimer Couleur spécifique +5227=Changer Couleur +5228=Inverser Courbe +5229=Changer Début d'une Courbe fermée +5230=Couper ou Prolonger Courbe +5231=Couper Courbe +5232=Diviser Courbe en Parties +5233=Joindre Courbes
Joindre Courbes créant une Copie (Shift)
Fusionner les courbes dans la Composite (Ctrl) +5234=Exploser Courbes ou Textes en Composants +5235=Épaisseur et Extrusion des Courbes +5236=Déplacer +5237=Pivoter +5238=Pivoter en 3D +5239=Miroir +5240=Miroir en 3D +5241=Échelle +5242=Échelle en 3D +5243=Offset +5244=Dessin 2D +5245=Dessin 3D +5246=Modification +5247=Transformation +5248=Swept (Section, Guide) +5249=Modifier Texte +// Grid View Panel +5251=Lignes +5252=Bords +5253=Solids +5254=Zoom Tout +5255=Zoom Plus +5256=Zoom Moins +5257=Vue de Dessus +5258=Vue de Face +5259=Vue de Gauche +5260=Vue d'Arrière +5261=Vue de Droite +5262=Vue Iso de SO +5263=Vue Iso de SE +5264=Vue Iso de NE +5265=Vue Iso de NO +5266=Direction des Courbes +5267=Analyser +5268=Mesurer la distance +5269=Grille par Dessus +5270=Grille par Face +5271=Grille par Droite +5272=Grille par Arrière +5273=Grille par Gauche +5274=Grille par Dessous +5275=Grille perpendiculaire à la direction de Vue +5276=Élévation de la Grille +5277=Origine de la Grille +5278=Pivoter Grille
Pivoter Grille en 3d (Shift) +5279=Grille par 3 Points +5280=Grille perpendiculaire à Courbe +5281=Grille par Object +5282=Vue perpendiculaire à la Grille +5283=Zoom Sélection +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=FIN +5302=Surcourse +5303=Direction de l'outil inaccessible +5304=Erreur +5305=ERREUR +5306=Erreur dans la génération! +5307=Simulation +5308=Une étape à la fois +5309=Play/Pause +5310=Stop/Home +5311=PAUSE +5312=STOP +5313=Impossible d'arrêter maintenant. Arrêtez d'abord la simulation ou attendez qu'elle se termine! +5314=HOME +5315=AVERTISSEMENT +5316=Virtual Milling +5317=Erreur dans le calcul des estimations! +5318=Fichier d'estimations manquant +5319=Collision! +5320=INFORMATION +5330=GÉNÉRER +5331=Le projet doit être enregistré avant la génération CN. Voulez-vous le faire? +5332=Généré avec succès +5333=La licence n'autorise pas la génération CN +5340=Estimations +5341=Temps total +5342=Longueur totale +5343=Détails +5344=Estimations détaillées +// Draw Option +5351=Propriété +5352=Nouv. Pièce +5353=Nouv. Couche +5354=Couleur +5355=Paramètres de dessin +5356=Sélectionner +5357=Desélectionner +5358=Nom +5359=Info +5360=Transférer +5361=Copiér +5362=Effacer +5363=Sauvegarder +5364=Visualiser +5365=Confirmer +5366=Confirmation de la Suppression +5367=Pièce à usiner, voulez-vous la supprimer? +// Operation +5401=Liste des opérations +5402=Paramètres de l'opération +5403=Appliquer Usinage +5404=Nouveau Usinage +5405=Nouveau Dispo +5406=Effacer +5407=Générique +5408=Dépl. haut +5409=Dépl. bas +5410=Actualiser +5411=Actualisation terminée avec succès +5412=Liste des Nouveaux Usinages +5413=Aperçu de l'Outil +5414=Suivant +5415=Précédent +5416=Dupliquer +5417=Copier dans la bibliothèque +5418=Nom de l'usinage dans la bibliothèque +5419=Insertion de l'usinage pas réussi +5420=Renommer +5421=Le nom ne peut pas commencer par "Disp" +5422=Nom déjà utilisé +5423=L'usinage ne peut pas être appliqué pour les raisons suivantes: +// Disposition +5431=Ok +5432= +5433=Nouvelle +5434=Supprimer +5435=Longueur +5436=Largeur +5437=Hauteur +5438=Position +// Disposition Errors +5461=ERREUR DE EXECUTION SCRIPT +5462=Erreur dans l'exécution du script automatic pour la disposition +5463=Erreur dans l'exécution du script de début usinages +5464=Erreur dans l'exécution du script de fin usinages +// Mach Group +5501=Voulez-vous vraiment vider le Groupe d'Usinage? +5502=Voulez-vous vraiment supprimer le Groupe d'Usinage? +5551=Il n'y a aucun Groupe d'Usinage :
sélectionnez les pièces à insérer et
répétez la commande pour créer le premier +5552=Voulez-vous créer un nouveau Groupe d'Usinage?
avec les pièces sélectionnées ? +// Tools Db Page +6001=Foret +6002=Scie +6003=Fraise +6004=Mortaise +6005=Composite +6006=Long foret +6007=Scie plat +6008=Fraise de côté +6009=Chiseau +6010=Jet d'eau +6051=Compensation +6052=Sortie +6053=Type +6054=Réfrigérant +6055=Rayon de Coin +6056=Diamètre +6057=Diamètre Total +6058=Vitesse +6059=Vitesse Finale +6060=Vitesse Initiale +6061=Vitesse de Pointe +6062=Longueur +6063=Longueur Totale +6064=Matériau Maximum +6065=Décalage longitudinal +6066=Décalage radial +6067=Rotation +6068=Angle latéral +6069=Rotation maximale +6070=Épaisseur +6071=Absorption maximale +6072=Vitesse minimum +6073=Dessin +6074=Tête +6075=Nom +6076=Notes +6077=Pos. Change Outil +6078=Position +6079=Distance +6080=???Overtable +// Tools Errors +6100=Enregistrer l'outil modifié? +6101=ENREGISTRER +6102=Le fichier doit être .nge +6103=Le fichier n'existe pas ou n'est pas de type Nge +6104=Il n'y a pas de ToolMaker pour ce type d'outil +6105=L'outil ne peut pas être créé avec ces paramètres +6106=Le Matériau Maximum doit être supérieur à 0 +6107=Le Matériau Maximum doit être inférieur à Long +6108=L'Épaisseur doit être supérieure à 0 +6109=Le Diamètre doit être supérieur à 0 +6110=La Longueur doit être supérieure à 0 +6111=La Vitesse doit être inférieure à la Vitesse maximale +6112=Nom non valide +6113=La Longueur doit être inférieure à la Longueur Totale +6114=La Longueur doit être supérieure au Matériau Maximum +6115=La Longueur Totale doit être supérieure à 0 +6116=La Longueur Totale doit être supérieure à la Longueur +6117=Le Matériau Maximum doit être inférieur à 1/3 du Diamètre +6118=Le Diamètre doit être inférieur au Diamètre Total +6119=Le Diamètre doit être supérieur à 3 fois le Matériau Maximum +6120=Le Diamètre Total doit être supérieur à 0 +6121=Longueur trop petite avec porte-outil +6122=Voulez-vous vraiment effacer l'outil +6123=? +6124=EFFACER +6125=Fichier de configuration d'outillage pas trouvé! +6126=Erreur +6127=Définir le type de tête. +6128=Définir le type de sortie. +6129=L'outil n'est pas valide, corrigez-le ou supprimez-le avant de quitter la base de données d'outils. +6130=Impossible de recharger la base de données d'outils. Si le dossier machines se trouve sur un serveur, vérifiez que la connexion est active. +6131=L'Épaisseur doit être différente de 0 +6132=L'Angle Latéral doit être inférieur à 90 +6133=L'Angle Latéral doit être supérieur à -90 +6134=La Longueur Totale doit être supérieure à la Longueur + l'Épaisseur +6135=Le Rayon du Coin a une valeur trop grande +6136=L'Épaisseur est trop petite par rapport au Rayon de Coin +6137=Le Diamètre résultant dépasse le Diamètre Total +6138=Le Diamètre résultant est inférieur à 0 +6139=Le Diamètre de tige résultant est inférieur ou égal à 0 +6140=Le Matériau Maximum doit être supérieur au Rayon de Coin +6141=Le Matériau résultant Maximum doit être >= 0 +6142=Le Rayon des Coins ne doit pas dépasser la moitié de l'Épaisseur +6143=Enregistrer outil +6144=Outil modifié! Tous les outils doivent être enregistrés avant de modifier les activations. Enregistrer outil {0}? +6145=Position déjà occupé! +6146=Position non définie! +// Machinings Db Page +6201=Perçage +6202=Sciage +6203=Fraisage +6204=Vidage +6205=Mortaisage +6206=Dégrossissage avec scie +6207=Finition avec scie +6208=Usinage générique +6209=Ciselure +6210=Dégrossissage surfaces +6211=Finition surfaces +6212=Jet d'eau +6251=???Invert +6252=???Leave Tab +6253=???Type +6254=???Work Side +6255=???Head Side +6256=???Lead In +6257=???External Link Type +6258=???Lead Out +6259=???Curve Use +6260=???Step Type +6261=???Sub Type +6262=???Lead Link Type +6263=???Speed +6264=???Feed +6265=???Start Feed +6266=???End Feed +6267=???Tip Feed +6268=???Radial Offset +6269=???Longitudinal Offset +6270=???Depth +6271=???Side Angle +6272=???Approximation +6273=???Start Safety Length +6274=???Start Slow Length +6275=???End Slow Length +6276=???Throu Add Length +6277=???Step +6278=???Return Position +6279=???Length +6280=???Distance +6281=???Height +6282=???Angle +6283=???L.In Tangent Distance +6284=???L.In Perp. Distance +6285=???L.In Elevation +6286=???L.In Comp. Length +6287=???L.Out Tangent Distance +6288=???L.Out Perp. Distance +6289=???L.Out Elevation +6290=???L.Out Comp. Length +6291=???Start Add. Length +6292=???End Add. Length +6293=???Step External Arc +6294=???Step Internal Arc +6295=???Side Step +6296=???Vertical Feed +6297=???Name +6298=???Tool +6299=???Depth +6300=???Notes +6301=???Overlap +6302=???Offset +6303=???Sub Type +6304=???SCC +6305=Aucun +6306=Standard +6307=Contraire +6308=AuxDir X+ +6309=AuxDir X- +6310=AuxDir Y+ +6311=AuxDir Y- +6312=AuxDir Z+ +6313=AuxDir Z- +6314=Le plus proche de AuxDir +6315=Le plus loin de AuxDir +6320=???Center +6321=???Left +6322=???Right +6323=???External +6324=???Standard +6325=???Strict +6326=???Out +6327=???External Central +6328=???External Out +6329=???None +6330=???Linear +6331=???Tangent +6332=???Glide +6333=???Helix +6334=???External Prev +6335=???External Next +6336=???External Both +6337=???As Li +6338=???Skip +6339=???Approx +6340=???Convex +6341=???Keep +6342=???Zigzag +6343=???Oneway +6344=???Spiral +6345=???To And From +6346=???Along +6347=???Across +6348=???Spiral In +6349=???Spiral Out +6350=???Avanzati +6351=???Inverti direz. utensile +6352=???Lavorazione faccia +6353=???Non definito +6354=??? Parallelo +6355=??? Ortogonale +6356=??? Ortog. Su +6357=???Sotto +6358=???Sopra +6359=???Davanti +6360=???Dietro +6361=???Sinistra +6362=???Destra +6363=???Contorno +6364=???Angoli Suggeriti +6365=???Asse Bloccato +6366=Nombre max +6367=Nombre min +// Machining errors +6370=Enregistrer l'usinage modifié? +6371=SAUVEGARDER +6372=Nom invalide +6373=Les caractères \ / : * ? " < > | ne sont pas permis +6374=Êtes-vous sûr de vouloir annuler +6375=? +6376=EFFACER +6377=Impossible de recharger la base de données des usinages. Si le dossier est sur un serveur, vérifiez que la connexion est active. +6378=Oscillation +6379=Amplitude d'oscill. +6380=Long. rampe d'oscill. +6381=Long. crête d'oscill. +// Machining Option Page +6401=Z de sécurité +6402=Couper les arcs +6403=Jamais +6404=Plan générique +6405=Plan autre que XY +6406=Toujours +6407=Outillage par défaut +6408=Sécurité renvoi d'en bas +6409=Tolérance trous +// SetUp Window +6451=Outillage +6452=Actualiser +6453=Sauvegarder +6454=Ouvrir +6455=Auto +6456=Actualiser l'outillage courant avant de sortir? +6457=???New +// SetUp Errors +6471=Erreur +6472=Avis +6473=Outil pas trouvé +6474=dans le DB des outils. +6475=La position de l'outil par défaut est invalide. +6476=La position de l'outil par défaut est déjà occupée. +6477=Le fichier de configuration n'existe pas! +6478=L'outillage utilise une tête qui n'existe pas sur la machine! +6479=Erreur de chargement de l'outillage +// Option Page +6501=Langue actuelle +6502=La nouvelle langue sera mise à jour à partir du prochain démarrage du programme. +6503=Courbes +6504=Surfaces +6505=Courbes et Surfaces +6506=Géométrie sélectionnable +6507=Ajouter le nouveau usinage à la fin +6508=Utiliser le script de disposition +6509=Unité de mesure +6510=Couleur en haut de la vue +6511=Couleur en bas de la vue +6512=Couleur par défaut +6513=Tolérance géométrique +6514=Générale +6515=CAO +6516=FAO +6517=Couleur de la grille +6518=Surfaces lissées +6519=Importer +6520=DXF +6521=STL +6522=Images +6523=Exportation +6524=Image +6525=Largeur (pixel) +6526=Hauteur (pixel) +6527=Mettre à jour machine +6528=La machine "{0}" existe déjà,
que veux-tu faire? +6529=Le fichier {0} ne contient pas une machine. +6530=La machine "{0}" a été mise à jour avec succès. +6531=Remplacer +6532=Mettre à jour +6533=Annuler +6534=Avis +6535=La mise à jour de la machine "{0}" a échoué. +6536=Lignes épaisses +6537=Longueur supplémentaire de ligne +6538=Longueur de la flèche +6539=Distance du texte +6540=Unité de mesure +6541=Décimal +6542=Caractère +6543=Hauteur du texte +6544=Dimension +6545=Unité actuelle +6546=Autre +6547=Unité de mesure +6548=Facteur d'échelle +6549=Exporter la machine actuelle +6550=Sélectionner le dossier où enregistrer la machine +6551=L'exportation de la machine "{0}" a échoué. +6552=La machine "{0}" a été exportée avec succès. +6553=Nouvelle Licence +// Heads +6601=Tête vertical +6602=Tête horizontal +6603=Agrégat 2 sorties +6604=Agrégat 3 sorties +6605=Agrégat 4 sorties +6606=Tête 3 axes +6607=Tête 4 axes +6608=Tête 5 axes +6609=Navette 1 +6610=Navette 2 +6611=Carousel +6612=Perceuse Multiple +6613=Multi ciseau +6614=Agrégat d'en bas +6615=Scie 5 axes +6616=Scie à chaîne +6617=Agrégat 1 sortie +6618=Tête de palpage +6619=Flottante 360° +6620=Second Tête 5 axes +6621=Perceuse Horizontal +6622=Mortaiseuse +6623=Second Scie 5 axes +6624=Agrégat 1 sortie tilt. +6625=Extrudeuse +6799= +// StatusBar +6801=???Direttorio Machines non trovato. EgtCAM5 funzionerà in modo solo CAD. +// Doors +8001=???Crea nuova MTable +8002=???Salva MTable +8003=???Salva MTable Come +8004=???Elimina MTable +8005=???Salva file MTable +8006=???Sei sicuro di voler cancellare questa MTable? +8007=???Salva la MTable modificata? +8008=???Lista delle macchine attive +8009=???Nome della macchina +8010=???Genera Cn +8011=???Aggiorna grezzo +8012=???On +8013=???Nome Geometria +8014=???Operazione +8015=???MId +8016=???Spost. +8017=???Tipo Lavorazione +8018=???Lavorazione 1 +8019=???Lavorazione 2 +8020=???Lavorazione 3 +8021=???Aggiungi Macchina +8022=???Elimina Macchina +8023=???Aggiungi Lavorazione +8024=???Elimina Lavorazione +8025=???CORR +8026=???Imposta MTable corrente +8027=???GId +8028=???Proprietà +8029=???Lavorazione +8030=???Unisci +// Door errors +8101=???Errore +8102=???Errore nell'esecuzione del file Ddf +8103=???Attenzione +8104=???Path della cartella MTable non trovata +8105=???La cartella MTable non esiste +8106=???Mancano i file di configurazione nella cartella MTable +8107=???Errore sconosciuto +8108=???Questa è la MTable correntemente attiva. +8109=???Non può essere cancellata. +8110=???Sei sicuro di voler cancellare la lavorazione selezionata? +8111=???CANCELLA +8112=???Sei sicuro di voler cancellare la macchina selezionata? +8113=???Impossibile trovare la cartella delle macchine {0}. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +8114=???Provare a ricaricare la macchina? +8115=???Impossibile trovare la cartella {0}. Se la cartella Doors è su un server, verificare che la connessione sia attiva. +8116=???Provare a ricaricare la cartella Doors? +8117=???Errore di esecuzione (guarda il file di log) +// GunStock +8201=???Nuovo pezzo +8202=???Gunstock Nuovo Pezzo +8203=???Mod pezzo +8204=???Gunstock Modifica Pezzo +8205=???Parametri calcio +8206=???Nome file +8207=???Descrizione +8208=???Ok +8209=???Cancella +8210=???deve avere un valore. +8211=???Il valore deve essere compreso tra +8212=???e +8213=???Dimensioni del grezzo +// GunStock errors +8251=Erreur +8252=???Errore nel lancio dell'ambiente Gunstock +8253=???Errore nella lettura del file Modello +8254=???Errore nella scrittura del file Pezzo +// ----- Beams & Walls ----- +9000=Table des usinages des poutres +9001=On +9002=Nom +9003=Type +9004=Ajouter +9005=Effacer +9006=Sauver +9007=Enregistrer les modifications apportées? +9008=Erreur +9009=Impossible d'ouvrir l'éditeur des usinages des poutres.
Il n'y a pas les fichiers de configuration. +9010=Table des usinages des parois +9011=Impossible d'ouvrir l'éditeur des usinages des parois.
Il n'y a pas les fichiers de configuration. +// ----- Errors ----- +10001=???Error +10002=???Error on new file +10003=???Error opening file +10004=???Error saving file +10005=???File type unknown +10006=???Error importing file +10007=???Error exporting file +10008=???Error loading or creating Machining Group +10009=???Missing file +// Missing Key Window +10101=Erreur ! +10102=Key pas présent. +10103=Insérer-le et redémarrer le programme. +10104=Ok +10105=Programme sans permis. +10106=Insérer-le et redémarrer le programme. +10107=Exécutez GetMachineId et envoyez les résultats au fournisseur. +// Numeric virtual keyboard +10201=Expression incorrect +// ----- MessageBox ----- +15001=Erreur +15002=Alerte +15003=Information +15010=Erreur inconnue +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Expression incorrect +// EgtCalculatorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Canc +20043=OUI +20044=NO +// ----- EgtWPFLib5 ----- +// EgtSaveFileDialog +30001=Sauvegarder +30002=Annuler +30003=existe déjà. +30004=Le remplacer? +30005=Nom du fichier: +30006=Ouvrir +30007=ERREUR +30008=Le nom ne peut pas être vide! +30009=ALERTE +30010=Nom du fichier +30011=Nom du répertoire +// Top CommandBar +30501=Nouveau +30502=Ouvrir +30503=Sauvegarder +30504=Sauvegarder sous +30505=Insérer +30506=Importer +30507=Exporter +30508=Executer +30509=Options +30510=Adresse e-mail du support introuvable. +30511=Enregistrer le projet en cours avant d'envoyer le feedback? +30512=Envoyer le feedback à {0} avec le répertoire attaché {1}. +30513=Feedback +30514=E-mail du feedback prête. +// Grid View Panel +30801=???Wireframe +30802=???Linee Nascoste +30803=???Ombreggiatura +30804=???Zoom All +30805=???Zoom In +30806=???Zoom Out +30807=???Vista da Sopra +30808=???Vista di Fronte +30809=???Vista da Sinistra +30810=???Vista da Dietro +30811=???Vista da Destra +30812=???Vista Isometrica da SW +30813=???Vista Isometrica da SE +30814=???Vista Isometrica da NE +30815=???Vista Isometrica da NW +30816=???Mostra Direzione Curve +30817=???Analizza +30818=???Distanza +30819=???Griglia da Sopra +30820=???Griglia di Fronte +30821=???Griglia da Destra +30822=???Griglia da Dietro +30823=???Griglia da Sinistra +30824=???Griglia da Sotto +30825=???Griglia da Vista +30826=???Elevazione Griglia +30827=???Origine Griglia +30828=???Ruota Griglia +30829=???Griglia da 3 Punti +30830=???Griglia Perpendicolare a Curva +30831=???Griglia da Oggetto +30832=???Vista da Griglia +// MachGroupPanel +30901=Nouveau Groupe d'Usinage +30902=Nom: +30903=Machine: +// ToolDbWindow +31001=Foret +31002=Scie +31003=Fraise +31004=Mortaise +31005=Composite +31006=Long foret +31007=Scie plat +31008=Fraise de côté +31009=Chiseau +31010=Jet d'eau +31051=Compensation +31052=Sortie +31053=Type +31054=Réfrigérant +31055=Rayon de Coin +31056=Diamètre +31057=Diamètre Total +31058=Vitesse +31059=Vitesse Finale +31060=Vitesse Initiale +31061=Vitesse de Pointe +31062=Longueur +31063=Longueur Totale +31064=Matériau Maximum +31065=Décalage longitudinal +31066=Décalage radial +31067=Rotation +31068=Angle latéral +31069=Rotation maximale +31070=Épaisseur +31071=Absorption maximale +31072=Vitesse minimum +31073=Dessin +31074=Tête +31075=Nom +31076=Notes +31077=Pos. Change Outil +31078=Position +31079=Perçage +31080=Tranchant +// ToolDb Errors +31100=Enregistrer l'outil modifié? +31101=ENREGISTRER +31102=Le fichier doit être .nge +31103=Le fichier n'existe pas ou n'est pas de type Nge +31104=Il n'y a pas de ToolMaker pour ce type d'outil +31105=L'outil ne peut pas être créé avec ces paramètres +31106=Le Matériau Maximum doit être supérieur à 0 +31107=Le Matériau Maximum doit être inférieur à Long +31108=L'Épaisseur doit être supérieure à 0 +31109=Le Diamètre doit être supérieur à 0 +31110=La Longueur doit être supérieure à 0 +31111=La Vitesse doit être inférieure à la Vitesse maximale +31112=Nom non valide +31113=La Longueur doit être inférieure à la Longueur Totale +31114=La Longueur doit être supérieure au Matériau Maximum +31115=La Longueur Totale doit être supérieure à 0 +31116=La Longueur Totale doit être supérieure à la Longueur +31117=Le Matériau Maximum doit être inférieur à {0} +31118=Le Diamètre doit être inférieur au Diamètre Total +31119=Le Diamètre doit être supérieur à 3 fois le Matériau Maximum +31120=Le Diamètre Total doit être supérieur à 0 +31121=Longueur trop petite avec porte-outil +31122=Voulez-vous vraiment effacer l'outil +31123=? +31124=EFFACER +31125=Fichier de configuration d'outillage pas trouvé! +31126=Erreur +31127=Définir le type de tête. +31128=Définir le type de sortie. +31129=L'outil n'est pas valide, corrigez-le ou supprimez-le avant de quitter la base de données d'outils. +31130=Impossible de recharger la base de données d'outils. Si le dossier machines se trouve sur un serveur, vérifiez que la connexion est active. +31131=L'Épaisseur doit être différente de 0 +31132=L'Angle Latéral doit être inférieur à 90 +31133=L'Angle Latéral doit être supérieur à -90 +31134=La Longueur Totale doit être supérieure à la Longueur + l'Épaisseur +31135=Le Rayon du Coin a une valeur trop grande +31136=L'Épaisseur est trop petite par rapport au Rayon de Coin +31137=Le Diamètre résultant dépasse le Diamètre Total +31138=Le Diamètre résultant est inférieur à 0 +31139=Le Diamètre de tige résultant est inférieur ou égal à 0 +31140=Le Matériau Maximum doit être supérieur au Rayon de Coin +31141=Le Matériau résultant Maximum doit être >= 0 +31142=Le Tranchant doit être supérieur à 0 +31143=Le Tranchant doit être inférieur à Long +// ImportExportToolWindow +31161=Importer +31162=Exporter +31163=Outils +31164=Outil déjà existant dans la base de données. Ecraser? +31165=L'outil sera importé avec le nom suivi de "_imp" +31166=Les outils suivants ont été importés avec succès: +31167=Reset +// MachiningDbWindow +31201=Perçage +31202=Coupe de la lame +31203=Fraisage +31204=Vidage +31205=Sciage à chaîne +31206=Ebauche avec lame +31207=Finition avec lame +31208=Usinage générique +31209=???Scalpellatura +31210=???Waterjetting +31211=???Surffinishing +31251=Inverser +31252=Laisser onglets +31253=Type +31254=Côté de travail +31255=Côté de la tête +31256=Entrée +31257=Connexion +31258=Sortie +31259=Utilisation des courbes +31260=Type de marche +31261=Sous-type +31262=Type d'approche +31263=Rotation +31264=Vitesse +31265=Vitesse Initiale +31266=Vitesse Finale +31267=Vitesse de Pointe +31268=Décalage radial +31269=Décalage longitudinal +31270=Profondeur +31271=Inclinaison latéral +31272=Approximation +31273=Dist. sécurité +31274=Long. ralentiss. initial +31275=Long. ralentiss. final +31276=Long. ajoutée au trou +31277=Pas +31278=Position de retour +31279=Longueur +31280=Hauteur +31281=Angle +31282=Distance +31283=Dist. tangente +31284=Dist. perp. +31285=Élévation +31286=Long. Correction +31287=Nombre min +31288=Nombre max +31291=Longueur Additionnel +31293=Pas sur extérieur arc +31294=Pas sur inxtérieur arc +31295=Pas de côté +31296=Avance verticale +31297=Nom +31298=Outil +31299=Profondeur +31300=Notes +31301=Superposition +31302=Décalage +31303=Sous-type +31304=SCC +31305=Aucun +31306=Standard +31307=Opposé +31308=AuxDir Droit +31309=AuxDir Gauche +31310=AuxDir Derrière +31311=AuxDir Front +31312=AuxDir Sur +31313=AuxDir Sous +31314=AuxDir Plus Proche +31315=AuxDir Plus Éloigné +31320=Centre +31321=Gauche +31322=Droite +31323=Étendre +31324=Standard +31325=Intérieur +31326=Extérieur +31327=Étendu centré +31328=Étendu externe +31329=Aucun +31330=Linéaire +31331=Tangente +31332=Poursuite +31333=Hélice +31334=Étendre le précédent +31335=Prolonger ensuite +31336=Étendre les deux +31337=Même qu'entrée +31338=Éviter +31339=Approximer +31340=Convexe +31341=Garder +31342=ZigZag +31343=Aller simple +31344=Spirale +31345=Aller-retour +31346=Longitudinal +31347=Transversal +31348=Spirale vers l'intérieur +31349=Spirale vers l'éxtérieur +31350=Avancés +31351=Inverser Outil +31352=Usinage de faces +31353=Non défini +31354=Parallèle +31355=Orthogonal +31356=Ortog. vers haut +31357=Sous +31358=Sur +31359=Avant +31360=Derrière +31361=Gauche +31362=Droite +31363=Contour +31364=Angles suggérés +31365=Axe verrouillé +31366=???Last backward feed +31367=???Backward step +31368=???Tilted step +31369=???Tilted back step +31370=Inclinaison vers l'avant +31371=Palpage +31372=Dist. min. points +31373=Dist. max. points +31374=Extérieur +31375=Intérieur +31376=Longueur. ralentir. +31377=DÉCÉLÉRATION. % +31378=Trou d'attaque +31379=Rayon +31380=???Num. giri in LP +31381=???Num. giri in HP +31382=Oscillation +31383=Amplitude +31384=???Lungh. rampa +31385=???Lungh. cresta +31386=Génériques +31387=Avancés +31388=Tang+Perp +31389=Perp+Tang +//MachiningTreeView +31391=Normal +31392=Ralentir +31393=Anneau +31394=Activation +31395=???Add Length +31396=???Start +31397=???End +31398=???System notes +31399=???Epicycles radius +31400=???Epicycles distance +// MachiningDb Errors +31401=Enregistrer l'usinage modifié? +31402=ENREGISTRER +31403=Nom invalide +31404=Les caractères \ /: *? "<> | ne sont pas autorisés +31405=Êtes-vous sûr de vouloir annuler? +31406=???? +31407=SUPPRIMER +31408=Impossible de recharger la base de données d'usinage. Si le dossier machines se trouve sur un serveur, vérifiez que la connexion est active. +31409=Matériau de la machine non reconnu +31410=L'usinage n'est pas valide, corrigez-le ou supprimez-le avant de quitter. +31411=La longueur doit être positive +31412=La distance doit être positive +31413=La hauteur doit être positive +31414=L'angle doit être compris entre {0} ° et {1} ° +31415=Le nombre maximum doit être nul ou positif +31416=Le nombre maximum doit être supérieur ou égal au minimum +31417=Le nombre minimum doit être nul ou positif +31418=Le nombre minimum doit être inférieur ou égal au maximum +31419=L'activation de {0} désactivera {1}. Procéder? +// ImportExportMachiningWindow +31450=???Import +31451=???Export +31452=???Machinings +31453=???Machining already existing in DB. Overwrite? +31454=???Machining will be imported with the name followed by "_imp" +31455=???The following Machinings have been imported succesfully: +31456=???Reset +// SetUp Window +31501=Outillage +31502=Appliquer +31503=Enregistrer +31504=Récupérer +31505=Auto +31506=Appliquer l'outillage actuel avant de sortir? +// SetUp Errors +31551=Erreur +31552=Avertissement +31553=L'outil est introuvable +31554=Dans le DB d'outils. +31555=La position d'outil par défaut n'est pas valide. +31556=La position d'outil par défaut est déjà occupée. +31557=Le fichier de configuration n'existe pas! +31558=L'outillage utilise une tête qui n'existe pas sur la machine! +31559=Erreur lors du chargement de l'outillage +// Simulation +31601=Simulation achevé +31602=Surcourse +31603=Direction de l'outil inaccessible +31604=Erreur +31605=ERREUR +31606=Erreur de génération! +31607=Simulation +31608=Un pas à la fois +31609=Aller/Pause +31610=Arrêt/Accueil +31611=Pause +31612=Simulation arrêtée +31613=Impossible de quitter maintenant. Arrêtez d'abord la simulation ou attendez qu'elle se termine! +31614=AVERTISSEMENT +31615=Fichier d'estimation introuvable +31616=Estimations détaillées +//MachiningDbWindow/ToolDbWindow buttons +31701=Nouveau +31702=Enregistrer +31703=Effacer +31704=???Edit +//Db Waterjet +31751=???Waterjet Db +31752=???Thickness +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=???Do you want to save edits? +// ----- EgtDOORCreator ----- +//General +50001=???Width +50002=???Height +50003=???Thickness +50004=???Swing +50005=???Lockedge +50006=???Hingeedge +50007=???Top +50008=???Bottom +50009=???Type +50010=???Corner +50011=???Extension +50012=???Side +50013=???Offset wide side +50014=???Back set +50015=???Top to center application +50016=???Bottom rail +50017=???Lock stile +50018=???Offset from center +50019=???Point to pocket +50020=???Pocket length +50021=???Pocket offset narrow side +50022=???Point to arm +50023=???Arm length +50024=???CenterHung +50025=???Offset +50026=???Offset intermediate +50027=???Radius +50028=???Top rail +50029=???Position +50030=???Lenght +50031=???Template +50032=???Up +50033=???Down +50034=???Shape +50035=???Hinge +50036=???Top to top application +50037=???Center from top application +50038=???Center from top lock +50039=???Depth +50040=???General +50041=???Center +50042=???Thru +50043=???Face to center line application +50044=???Edge Type +50045=???Over Material +50046=???Send Feedback +50047=???Weight +50048=???Angle +50049=???Face +50050=???Secure +50051=???Keyway +50052=???Brand +50053=???Folder +50054=???Main Folder +50055=???Jamb +50056=???Light Up +50057=???Light Lock +50058=???Light Bottom +50059=???Light Hinge +50060=???Thickness Head +50061=???Overlap Hinge +50062=???Overlap Lock +50063=???Overlap Top +50064=???Delta T +50065=???Exterior +50066=???Number of Doors +50067=???Jambs and Doors +50068=???Order +50069=???Disposition +50070=???Customer +50071=???Invert bevel on Lock +//Compo Name +50072=???Flush Bolt +50073=???Flush Pull +50074=???Hinge +50075=???Lock +50076=???Louver Cut Out +50077=???Mail Slot +50078=???Over Head +50079=???Pivot +50080=???Roller Latch +50081=???Stops And Closer +50082=???Strike +50083=???Edge pull +50084=???Viewer +50085=???Vision cut out +50086=???Grove +50087=???Rabbet +50088=???Ept +50089=???Raceway +50090=???Face Decoration +//error messages +50100=???Directory not founded +50101=???Error +50102=???Failed reading DDF file. Missing incumbent parameter {0}. +50103=???Failed reading value +50104=???Failed reading DDF file's row +50105=???Row +50106=???Invalid value in +50107=???Empty file. +50108=???You can not add a compo if there is not a dorr! +50109=???Do you want to save this file ({0}) ? +50110=???Question +50111=???Add new door +50112=???Remove door +50113=???New Door +50114=???File name already exists in the current directory ({0}). +50115=???Caution +50116=???Do you want to delete this file ({0}.ddf)? +50117=???Confirm deleting ({0})?. +50118=???Information +50119=???Error in reading messages. There is no match with the number {0}. +50120=???Error reading name {0} in {1}. Expected numeric match. +50121=???Error reading {0} param in {1} compo: do not exist. +50122=???Error in {0} param in {1} compo. +50123=???Error reading {0} param in {1} compo: do not exist list. +50124=???Error reading {0} param in {1} compo: {2}. +50125=???Error in {0} param in {1} compo: do not exist value. +50126=???Delete +50127=???Error in EgtLoadMessages +50128=???You can not save a file if there is not a door! +50129=???Error in Project scene creation +50130=???Error in reading: line {0}. +50131=???Error in reading {0}: line {1}. Expected ':' after the name. +50132=???Error in reading {0}: line {1}. Expected 'template' or 'shape'. +50133=???{0} has not been created. +50134=???Error reading 'Template' in file {0}\{1}. Expetcted name. +50135=???Error reading 'Template' in file {0}\{1}. File {0}\{2} .lua does not exist. +50136=???Error in reading {0}: line {1}. It does not exist in the list of components in file 'Default.ini'. +50137=???Error in reading {0}: line {1}. It is not a member of the list. +50138=???This param will be initialized by default. +50139=???Error in reading: line {0}. Expected {1}. +50140=???All missing params will be initialized by default. +50141=???Invalid expression in {0}. +50142=???Remove compo +50143=???Invalid expression. +50144=???Warning +50145=???Impossible to create the current door. +50146=???Do you want to open a template? +50147=???Error expression in {0}. {1} does not match anything. +50148=???Invalid value.ù +50149=???Caution: Weight is setted in OptionPage. Do you want to remove? +50150=???Caution: Weight is setted in DDF. Do you want to add? +50151=???{0} is not a member of the current list of EdgeType. Check Bevel in option page. +50152=???Do you want to save this file ({0})? +50153=???Caution. Weight is setted in the current door. Do you want to remove? +50154=???It is the bevel of the current door. Do You want to proced? +50155=???Impossible to create a template if there is not a door! +50156=???Errore nella lettura ddf: la porta non è completa o il ddf è stato separato male da '---'. +50157=???Script Lua ( {0}\{1} )has not been found. +50158=???Bevel {0} can not be acceptable in Jamb. +50159=??? Missing parameter in ddf! +50160=???File {0} in directory {1} has not been found. +50161=???parameter +50162=???In file {0} param 'Default' must be numeric. +50163=???Error in reading General Assembly in DDF +50164=???In General Assembly: +50165=???CompoDir not found : +50166=???Jamb compo does not exist +50167=???Empty Line +50168=???No matching param +50169=???Door disposition has been modify. +50170=???Incongruity between the bevel, it has been resolved by default. +50171=???In file StdTempate.ini is missing numeric param in [Type]. +50172=???File does not exist. +50173=???Definition type is not correct: +50174=???Missing name of the new template! +50175=???The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=???Error in copying: {0} +50177=???Do you want to save the current changes? +50179=???Doors Compo Default.ini not found in {0} . +50180=???Warning : {0} does not exist. +50181=???Error in creating the print image +50182=???Error executing print +50183=???Some Doors could use this hardware, do you want to proceed deleting? +50184=???Impossible to delete Hardware if there is no Hardware selected! +50185=???Impossible to duplicate Hardware if there is no Hardware selected! +50186=???Project must be saved before copying +50187=???Do you want to copy all files ? {0} (No to copy only the current file) +50188=???Export to machine +50189=???Machine Directory not found +50190=???Error in copying: {0} +50191=???Impossible to copy a door if there is not a door! +50192=???Impossible to export to machine a door if there is not a door! +50193=???Impossible to print a door if there is not a door! +50194=???Properties has been deleted +50195=???The current ddf configuration ({0}) is different from the current program configuration ({1}).{2}To load the current ddf configuration you have to restart the program, do you want it? +50196=???Configuration ddf ({0}) does not exist! +50197=???Top Arch has been modified because of configuration. +50198=???Bevel on lock edge would be inverted. +//Option +50200=???Unit measure +50201=???General +50202=???LockEdgeOverMaterial +50203=???HingeEdgeOverMaterial +50204=???TopOverMaterial +50205=???BottomOverMaterial +50206=???Open Window +50207=???Last Project +50208=???Empty +50209=???Option Page +50210=???StartUp +50211=???Unit measure new door. +50212=???Directory Project +50213=???Option Start +50214=???Current Directory +50215=???Edge Type +50216=???Over Material +50217=???Browse +50218=???Close +50219=???Bevel +50220=???Bevel Up +50221=???Bevel Down +50222=???Door positioning in machining +50223=???Save as template +50224=???Matching +50225=???Brand +50226=???File +50227=???Template +50228=???Enable template +50229=???Enable Order +50230=???Open template door. +50231=???Open window order. +50232=???Directory Template +//Scene +50301=???Refresh +50302=???Add New Door +50303=???Remuve Door +50304=???New Project +50305=???Help +50306=???Directory Machine +50307=???Machine +50308=???Door +50309=???Wide Side Down (BU) +50310=???Wide Side Up (BD) +50311=???Resize +50312=???Design +50313=???Save as pdf +//Launcher +50400=???Launcher +50401=???Open New Project +50402=???Open Project +50403=???Open Last Project +50404=???New Project +50405=???New Hardware +50406=???Elevation +50407=???Project +50408=???PO +50409=???Line +50410=Sauvegarder +50411=???Print +50412=Annuler +50413=???Hardware +50414=???Dimensioning +50415=???Duplicate +50416=???Export to machine +50417=???New Template +50418=???Dimension +50419=???New Directory +50420=???Create Assembly +50421=???Relaod Directory +50422=???Save As +50423=???Reaload Compo on Jamb +//Error messages +50501=???Error reading {0} param in {1} compo: incomplete definition (look at StdTemplate.ini). +50502=???Error reading {0} param in {1} compo: no matching (look at StdTemplate.ini and GeometryNameList.ini). +50503=???Do you want to save? +50504=???File name contains empty spaces, do you want to rename file deleting empty spaces? +50505=???DDF is not an assembly, there are only: {0}, do you want to save? +50506=???Impossible to find the first door (DO_1)! +50507=???The swing is not a member of the swing list of single door. +50508=???The swing of left door is not a member of the swing list of left door. +50509=???The swing of right door is not a member of the swing list of right door. +50510=???The swing of left door is on the right door and viceverse. +50511=???The swing of left door is not a member of the swing list of left door. +50512=???The swing of right door is not a member of the swing list of right door. +50513=???Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=???The swing are absolutly wrong! +50515=???The first door is not realy the first, check the ddf. +50516=???The current ddf contains {0} jambs. +50517=???The current ddf does not contains doors! +50518=???The current ddf is not an assembly. +50519=???Impossible to open a ddf with no doors. +50520=???The current ddf is an assembly. +50521=???The current ddf is a jamb: {0}. +50522=???The profile {0} is not a member of the {1} profile list. +50523=???Missing profile on {0}. +50524=???{0} file open by another EgtDOORCreator {1}. +50525=???{0} file open by another EgtDOORCreator {1}. +50526=???Directory {0} already exists! Do you want to overwrite it? +50527=???Impossible to overwrite {0} +50528=???Impossible to save the door out of the project! +50530=???Property {0} does not exist in the list of {1}. Look at file "../Compo/Default.ini". +50531=???The current material {0} does not exist in the list of material. Look at file "../Compo/Default.ini". +50532=???Missing list of material at file "../Compo/Default.ini". +50533=???Impossible to load more than one property at time. +50534=???Property {0} does not exist in the list. Look at file "../Compo/Default.ini". +50535=???Impossible to delete a project if there is not a project! +50536=???Do you want to delete entire project? +50537=???Do you want to delete subdirectory {0} ? +50538=???Impossible to vreate a template door if there is not a door! +50539=???Do you want to change project? ( All doors will be deleted!) +50540=???The current ddf is a part of a frame, do you want to save? +50541=???{0} in reading {1}. +50542=???{0}: Directory does not exist! +50543=???It has been renamed file: {0}, {1}. +50544=???It has been created new file: {0}, {1}. +50545=???It has been deleted file: {0}, {1}. +50546=???Enable single door. +50547=???Project +50548=???The new configuration will take effect after restart. +50549=???File {0} exist, but it is not in the correct Directory! +50550=???Every componente on jambs will be relocated, do you want to continue +50551=???The current parameters have been modified: +50552=???Do you want to overwrite? +50553=??? has not been created. +50554=???Parameter {0} is already deinfed in geometry {1}. +50555=???Impossible to save. +50556=???File has nge extension. +50557=???Error in deleting file: {0} +50558=???Impossible to import a different hardware! +50559=???Open File Dialog +50560=???The hardware part has not been generated correctly. +50561=???Directory already exists +50562=???Folder {0} does not exist. Check in OptionPage. +50563=???Compo {0} does not exist. +50564=???In group {0} at paramater {1} does not exist: {2} +50565=???Brand {0} has not been found in HardwareManager. +50566=???Template {0} has not been found in HardwareManager. +50567=???Error in executing EgtCam5. +50568=???Error in definition {0} in file GeometryNameList.ini . +50569=???Error in definition {0} in file StdTemplate.ini . +50570=???Nothing has been selected. +//Added General messages +50701=???Lines +50702=???Rectangle +50703=???None +50704=???Radius +50705=???Angle +50706=???Pos_x +50707=???Top Arc +50708=???Top Angle +50709=???Properties +50710=???Material +50711=???Mach. +50712=???HardwarePart +50713=???Assemby +50714=???Total Dimension +50715=???Depth +50716=???Overlap Bottom +50717=???Thickness Bottom +50718=???Depth Bottom +50719=???Delta Bottom +50720=???GoToAssembly +50721=???New Geometry +50722=???Geometry Name +50723=???Type Hardware +50724=???Parameter +50725=???Part Dimension +50726=???Apply +50727=???Frame +50728=???Refresh Directory +50729=???General +50730=???Report +50731=???Opposite face +// ----- EgtBEAMEditor ------ +60951=???Cut +60952=???Longitudinal Cut +60953=???Double Cut +60954=???Ridge or Valley Cut +60955=???Saw Cut +60956=???Slot +60957=???Front Slot +60958=???Birds Mouth +60959=???Hip or Valley Rafter Notch +60960=???Ridge Lap +60961=???Lap Joint +60962=???Notch/Rabbet +60963=???Block House Half Lap, Stairs Riser Dado +60964=???Seathing Cut +60965=???French Ridge Lap +60966=???Chamfer +60967=???Block House Half Lap +60968=???Block House Front +60969=???Pocket +60970=???Drilling +60971=???Tenon +60972=???Mortise +60973=???Mortise Front +60974=???House +60975=???House Mortise +60976=???Dovetail Tenon +60977=???Dovetail Mortise +60978=???Dovetail Mortise Front +60979=???Marking/Labeling +60980=???Text +60981=???Simple Scarf +60982=???Scarf Joint +60983=???Step Joint +60984=???Step Joint Notch +60985=???Planing +60986=???Profile Front +60987=???Profile Head concave +60988=???Profile Head convex +60989=???Profile Head cambered +60990=???Round Arch +60991=???Profile Head +60992=???Sphere +60993=???Triangle Cut +60994=???Tyrolean Dovetail +60995=???Dovetail +60996=???Free Contour +60997=???Outline +60998=???Aperture +61001=???Distance from beam start to the reference point +61002=???Distance from the reference edge to the reference point +61003=???Distance from the reference side to the reference point (orthogonal) +61004=???Angle between cut edge and reference edge +61005=???Inclination between face and reference side +61008=???Limit of the 2 ends, binary code +61009=???Inclination to the reference side +61010=???Depth: If P11 is zero, then the face of the cut dispreads to the neigbour-sides or opposite-side to referenceside +61011=???Length: If P12 and P04 equal to zero, the processing is performed along the whole component length +61012=???Angle in face at start +61013=???Angle in face at end +61015=???Distance from the reference point to the reference edge +61016=???Angle between the first cutting edge and the reference edge +61017=???Inclination of the first cutting towards the reference side +61018=???Angle between the second cutting edge and the reference edge +61019=???Inclination of the second cutting towards the reference side +61023=???Inclination between the first face and the reference side +61024=???Inclination between the second face and the reference side +61025=???Depth +61027=???Angle in face at reference edge at start +61028=???Angle in face at reference edge at end +61029=???Angle in face in opposite to reference edge at start +61030=???Angle in face in opposite to reference edge at end +61033=???Displacement to the reference side +61036=???Angle to the reference edge in the cut face +61037=???Depth, orthogonal to the reference side +61038=???Length +61041=???Distance to the reference point orthogonal to the reference side P03 = 0: Slot on one of the 4 sides of the component. P03 > 0: Slot on one of the 2 front sides of the component +61042=???Limit of the 6 faces of the slot, binary code +61043=???Angle to the reference edge in the reference side +61045=???Interior angle at reference point +61046=???Interior angle at opposite of reference point +61047=???Addition to P09 +61048=???Depth orthogonal to the reference side +61049=???Length +61050=???Thickness +61051=???Displacement of the entrance edge at reference point +61052=???Displacement of the entrance edge at opposite of reference point +61055=???Distance to the reference point orthogonal to the reference side +61056=???Limit of the 6 faces of the Frotn Slot, binary code +61059=???Angle between the longitudinal axis of the slot and the reference side +61060=???Depth +61061=???Length +61062=???Width +61065=???Location of P09/P10, if P09>0 and P10>0. If P04=-1, then the location must be defined on the machineside +61066=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole. +61067=???Angle to the reference edge in the reference area +61068=???Inclination between face 1 and reference side +61069=???Inclination between face 2 and reference side +61070=???First cut angle of the counterpart. If P09 is zero, the limit face beside face 1 is parallel to component side. +61071=???First cut inclination of the counterpart. If P10 is zero, the limit face beside face 1 is parallel to component side. +61072=???Depth 1 orthogonal to reference side +61073=???Depth 2 orthogonal to reference side +61074=???Grooving depth in the transverse direction of the component. If P13 is zero, then its value must be calculated:P13=WRS-P02 +61075=???Height Counterpart. Zero means: no limit. Measurement orthogonal to face 1 (P07). +61076=???Width Counterpart. Zero means: no limit. Measurement orthogonal to face 2 (P08). +61079=???P05=1: drilhole for rafter nail, P05=0: no drillhole. The machineside defines place and direction of the drillhole +61080=???Angle notch 1 to the reference edge in the reference area +61081=???Angle notch 2 to the opposite reference edge in the reference area +61082=???Inclination between base area of notches and reference side +61083=???Depth orthogonal to reference side +61084=???Width of notch 1. If this value is equal 0, then the notch is not limited. +61085=???Width of notch 2. If this value is equal 0, then the notch is not limited. +61087=???0: Reference point on referene edge. 1: Reference point on the opposite edge +61088=???Angle to the reference edge in the reference side +61089=???Depth of Half Lap +61090=???Width of Half Lap +61091=???Drill hole diameter +61094=???Displacement to the reference side +61095=???Limit of the 6 faces of the lap, binary code +61096=???Angle to the reference edge in the reference side +61098=???Angle between edge and reference side in face +61099=???Angle in the floor face +61100=???Angle between base face and one face of lap +61101=???Distance (orthogonal) from reference side to point below reference point +61102=???Length +61103=???Chamfer angle +61104=???Grooving depth (length of the lapped scarf in transverse direction). If P14 is zero, then its value must be calculated: P14=WRS-P02 +61107=???Limit of the 6 faces of the notch/rabbet, binary code +61108=???Notch/Rabbet depth +61109=???Notch/Rabbet length +61110=???Notch/Rabbet width +61113=???Depth of the Half Lap on the reference side +61114=???Depth of the Half Lap opposite of the reference side +61115=???Length of the Half Lap / Dado +61117=???Depth of Seathing Cut +61118=???Length of Seathing Cut +61120=???0: Reference point on reference edge; 1: Reference point on the opposite edge +61121=???Angle to the reference edge in the reference side +61122=???Drill hole diameter +61124=???Input of edge(s) to be beveled, binary code: Bit 0=edge 1 ; Bit 1=edge 2; Bit 2=edge 3; Bit 3=edge 4. Example: P04=9: edge 1+4; P04=3: edge 1+2 +61125=???Depth +61126=???Length: If P12 is equal to zero, the processing is performed along the whole component length. +61127=???Shape for bevel exit: 0 = orthogonal, 1 = at 45 deg, 2 = round; +61129=???Depth orthogonal to reference side of the lap 2 and 4. If P03 is zero, then its value must be calculated: P03=HRS +61130=???0:all laps are symmetric to each other; 1:lap on reference edge moved to start beam, lap in opposite of reference edge moved to end beam; 2: lap on reference edge moved to end beam, lap in opposite of reference edge moved to start beam; +61131=???P05=1: drilhole for drop rod, P05=0: no drillhole. The machines defines place and direction of the drillhole. +61132=???lap 1: Depth +61133=???lap 1: Length +61134=???lap 2: Depth +61135=???lap 2: Length +61136=???lap 3: Depth +61137=???lap 3: Length +61138=???lap 4: Depth +61139=???lap 4: Length +61140=???Distance from end of arc orthogonal to the reference side +61141=???Radius of arc +61142=???Distance reference point to center of arc +61143=???Which arc (A, B,C or D) is to produced, binary code +61145=???0:only one lap on reference side; 1:one lap on reference side and one on the opposite side +61146=???Angle to the reference edge in the reference side +61147=???Depth at reference point +61148=???Depth opposite to the reference point +61149=???Depth at reference edge +61150=???Length +61153=???Limit of the 6 faces of the pocket, binary code +61154=???Rotation angle around the local z-axis of the cuboid +61155=???Rotation angle around the local y-axis of the cuboid, rotated with P06 +61156=???Rotation angle around the local x-axis of the cuboid, rotated with P06 and P07 +61157=???Internal angle at the reference point +61158=???Depth of reference point orthogonal to reference side +61159=???Length of Half Lap +61160=???Width of Half Lap +61163=???Distance from the reference face to the reference point. P03 = 0:Drilling on one of the 4 sides of the component. P03 <> 0:Drilling on one of the 2 front sides of the component. +61164=???P03 = 0:Angle to the reference edge in the reference side. P03 <> 0:Angle in the front side. +61165=???Inclination between drilling and reference side. P03 = 0: Inclination between drilling and reference side. P03 > 0: Inclination between drilling and front side +61166=???Depth, orthogonal to reference side or front side. +61167=???Drill hole diameter +61170=???Rounding +61171=???Chamfer +61174=???Angle between axis of the tenon and reference side +61175=???Radius for P04=4 +61176=???Tenon height +61177=???Tenon width +61178=???Margin on the reference side +61179=???Margin opposite the reference side +61182=???Displacement to the reference side +61183=???Rounding +61184=???Angle between axis and reference edge +61185=???Inclination between strut and reference side +61186=???Inclination of hole side walls towards reference side +61187=???Radius for P04=4 +61188=???Mortise depth +61189=???Mortise width +61190=???Height of strut +61191=???Margin on the reference point +61192=???Margin opposite the reference point +61193=???Inclination of hole front side towards reference side +61196=???Rounding +61199=???Angle between axis of the tenon and reference side +61200=???Radius for P04=4 +61201=???Mortise depth +61202=???Mortise width +61203=???Margin on the reference side +61204=???Margin opposite the reference side +61205=???Processident of the associated tenon or dovetail tenon +61206=???Processident of the associated mortise or dovetail mortise +61209=???0:with rounding at the bottom; 1:without rounding, unbounded +61210=???Angle between edge and reference edge +61212=???Angle between axis of the tenon and reference side +61213=???Middle flattening +61214=???Angle of cone +61215=???Tenon height +61216=???Diameter of the curve: If P12 < 0, then the radius must be defined on the machineside. +61217=???Margin on the reference side +61218=???Margin opposite the reference side +61221=???Displacement to the reference side +61222=???0:with rounding at the bottom; 1:without rounding, unbounded +61223=???0:with elongation; 1:with pocket +61224=???Angle between axis and reference edge +61225=???Inclination between strut and reference side +61226=???Middle flattening +61227=???Angle of cone +61228=???Mortise depth +61229=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61230=???Height of strut +61231=???Margin on the reference point +61232=???Margin opposite the reference point +61235=???Displacement to the front side +61236=???0=with rounding at the bottom; 1=without rounding, unbounded +61237=???0=with elongation; 1=with pocket +61240=???Angle between axis of the tenon and reference side +61241=???Middle flattening +61242=???Angle of cone +61243=???Mortise depth +61244=???Diameter of the curve. If P12 < 0, then the radius must be defined on the machineside. +61245=???Margin on the reference side +61246=???Margin opposite the reference side +61249=???Position and alignment of the text. P04 = 0 if there is no text. +61250=???Angle between axis and reference edge. If P06 equals 180°, then a horizontal line is defined, P12 defines the length of the line. +61251=???Interior angle. If P07 equals zero, 2 single markings have to be produced. +61252=???Width of quadrangle. If P11 equals zero, there is only a single marking. +61253=???Height of quadrangle. If P12 equals zero, marking is limited by the edge opposite to the reference edge. +61254=???Height of text. If P13 equals zero, the machine determines the text height. +61255=???Text (String max. 256 characters) +61258=???Angle between axis and reference edge +61259=???Alignment vertical. 0 = bottom, 1=middle, 2=top +61260=???Alignment horizontal. 0 = left, 1=middle, 2=right +61261=???Alignment in case of a multiline text. 0 = left-aligned, 1=centered, 2=right-aligned. A new line must be defined with this 2 letters: \n +61262=???Letters standard or horizontal placed. 0 = standard, 1=letters horizontal placed +61263=???Height of text. If P13 equals zero, the machine determines the text height. +61266=???Depth at the reference side +61267=???Depth at the opposite of reference side +61268=???Length of the overlap +61269=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61270=???Drilling 2 diameter. Placed at 2/3 P13 +61272=???Angle of inclination of the lapped scarf base +61273=???Shape of the lapped scarf or classic data identification: 1:when cutting orthogonal to reference side; -1:when cutting orthogonal to base side; 0:classic definition, P10 and P12 are not used +61274=???Length of the lapped scarf base +61275=???Depth of the lapped scarf base +61276=???Depth of the lapped scarf base orthogonal to reference side +61277=???Length +61278=???Drilling 1 diameter. P15=0: This drilling is placed at 1/2 P13. P15>0: This drilling is placed at 1/3 P13 +61279=???Drilling 2 diameter. Placed at 2/3 P13 +61281=???Type of heel notch:0=normal; 1=tapered +61282=???Inclination strut +61283=???Depth step joint +61284=???Depth heel notch +61285=???Height tenon. Which implementation (A or B) is used depends on the machine +61286=???Width tenon +61289=???Type of heel notch: 0=normal; 1=tapered +61290=???Inclination between strut and reference side +61291=???Width of the notch +61292=???Depth step joint +61293=???Depth heel notch +61294=???Height of strut +61295=???Depth of mortise. Which implementation (A or B) is used depends on the machine +61296=???Width of mortise +61298=???Specification of side(s) to be planed; binary coded +61299=???Planing depth +61300=???Length of the area to be planed +61303=???Rotation angle of the first curve of the profile +61304=???Rotation angle of the profile towards the reference edge +61305=???Offset angle +61306=???Radius of the first curve +61307=???Radius of the second curve +61309=???Radius +61310=???Depth +61311=???Displacement +61312=???Depth +61313=???Displacement +61315=???Radius +61316=???Depth +61317=???Displacement +61318=???Depth +61319=???Displacement +61321=???Profile length +61322=???Depth at the reference point +61323=???Maximum depth of profile +61324=???Minimum depth of profile +61325=???Depth at the profile end +61326=???Premill: 0=round; 1=angular +61328=???Depth of the arch segment +61329=???Length of the arch segment +61331=???Type of arc (convex, concave), binary coded. See table below. +61332=???Length of lap 1 +61333=???Depth of lap 1 +61334=???Displacement arc 1 +61335=???Horizontal length arc 1 +61336=???Vertical length arc 1 +61337=???Camber arc 2 +61338=???Length of lap 2 +61339=???Depth of lap 2 +61340=???Displacement arc 2 +61341=???Horizontal length arc 2 +61342=???Vertical length arc 2 +61343=???Camber arc 2 +61344=???Length of lap 3 +61345=???Depth of lap 3 +61348=???Distance from the reference side to the reference point +61349=???Radius +61350=???Start offset +61351=???Length +61354=???Distance from the reference side to the reference point +61355=???Normal vector 1: Length of X-component +61356=???Normal vector 1: Length of Y-component +61357=???Normal vector 1: Length of Z-component +61358=???Normal vector 2: Length of X-component +61359=???Normal vector 2: Length of Y-component +61360=???Normal vector 2: Length of Z-component +61362=???Distance between "inside" an side of part +61363=???Distance orthogonal to the reference side +61364=???0:"inside" at reference edge, 1:"inside" at opposite of reference edge +61365=???0:Without rebate or mitre, -1:With mitre, >0:With rebate +61366=???Angle to the reference edge in the reference side +61367=???Width +61368=???Depth +61369=???Inclination +61370=???Height +61371=???Radius +61372=???Length of tool (part of arc) +61373=???0:Angular corner joint, 1:Straight T-wall connection +61374=???Length +61375=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61377=???Distance between "inside" an side of part +61378=???Distance orthogonal to the reference side +61379=???0:"inside" at reference edge, 1:"inside" at oppostite of reference edge +61380=???0:Without rebate or mitre, -1:with mitre, >0:with rebate +61381=???Inclination +61382=???Depth 1 +61383=???Depth 2 +61384=???0:European Dovetail, 1:American Dovetail +61385=???Length +61386=???0:Processing on the reference side and opposite the reference side, 1:Processing only on the reference side, 2:Processing only opposite the reference side +61387=???Depth +61388=???Mode: 0=contour only, 1=countersink completely. Only for closed contours. +61389=???Contour type +61390=???Parameter depends on contour type(P13) +61391=???Parameter depends on the contour type(P13) +61400=???Reference point on referene edge +61401=???Reference point on the opposite edge +61402=???Reference point on referene edge +61403=???Reference point on the opposite edge +61404=???orthogonal +61405=???at 45 deg +61406=???round +61407=???all laps are symmetric to each other +61408=???lap on reference edge moved to end beam. lap in opposite of reference edge moved to start beam +61409=???lap on reference edge moved to start beam. lap in opposite of reference edge moved to end beam +61410=???only one lap on reference side +61411=???one lap on reference side and one on the opposite side +61412=???with rounding at the bottom +61413=???without rounding, unbounded +61414=???with elongation +61415=???with pocket +61416=???bottom +61417=???middle +61418=???top +61419=???left +61420=???right +61421=???left-aligned +61422=???centered +61423=???right-aligned +61424=???standard +61425=???letters horizontal placed +61426=???when cutting orthogonal to reference side +61427=???when cutting orthogonal to base side +61428=???classic definition, P10 and P12 are not used +61429=???normal +61430=???tapered +61431=???round +61432=???angular +61433=???"inside" at reference edge +61434=???"inside" at opposite of reference edge +61435=???Angular corner joint +61436=???Straight T-wall connection +61437=???Processing on the reference side and opposite the reference side +61438=???Processing only on the reference side +61439=???Processing only opposite the reference side +61440=???European Dovetail +61441=???American Dovetail +// ---Custom Parameter (Q) +61451=???Profondità smusso +61452=???0=Automatico; 1=Ciclo longitudinale con lama +61453=???Spessore testimone centrale per ciclo Q02 +61454=???0=Attacco centrato; 1=Attacco interno +61455=???0=Automatico; 1=Lavorazione con fresa di lato +61456=???1=Forza Lama; 0=Automatico +61457=???1=Solo smusso +61458=???0=Automatico; 1=Massima profondità +61459=???0=Automatico; 1=Truciolatore; 2=Truciolatore di lato; 3=Fresa; 4=Fresa di lato +61460=???0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +61461=???0=Automatico; 1=Massimo raggio ammesso su tasche non passanti +61462=???Diametro utensile per Q05 +61463=???Diametro utensile per Q07 +61464=???0=Raggio su spigolo; 1=Foro su spigolo; 2=Spigolo vivo +61465=???Diametro foro quando P05=1 +61466=???0=Automatico; 1=Sgrossatura con lama +61467=???Antischeggia: 0=No; 1=Con lama; 2=Con fresa +61468=???Aumenta dimensioni tasca +61469=???Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico +61470=???0=Automatico; 1=Solo contorno ; 2=Drill or Pocket +61471=???0=Automatico; 1=Lavoro da un lato solo +61472=???Incrementare/decrementare valore P01 per fori nei tenoni +61473=???0=Foratura rompi truciolo; 1=Foratura scarico truciolo +61474=???Profondità smusso quando P05=1 +61475=???Riduzione profondità tenone +61476=???Riduzione larghezza tenone +61477=???Riduzione altezza tenone +61478=???Riduzione profondità tenone +61479=???Ridurre/Allargare sagoma tenone +61480=???Ridurre/Allargare altezza tenone +61481=???aumenta profondità mortasa +61483=???Profondità di lavoro +61484=???Aumenta dimensioni P10 +61485=???0=Automatico; 1=Truciolatore +61486=???Riduzione lunghezza P14 +61487=???Riduzione larghezza P15 +61488=???Sovramateriale finitura +61489=???Numero divisioni ondulazioni dello smusso sulla lunghezza +61490=???1=Disabilita fresatura gradini +61491=???1=Attiva smusso superiore +61492=???1=Smusso superiore con lama +61493=???Spessore legno per supporto lavorazione +61494=???Attiva antischeggia +61495=???Profondità antischeggia +61496=???Massima elevazione (0=Automatico, >10=Manuale) +61497=???0=Automatico; 1=Lama +61498=???0=Automatico; 1=Disabilita controllo lunghezza fresa +61499=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61500=???0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61501=???0=Automatico 1=Lavorazione con fresa orizzontale se sopra o sotto (disabilita lama) +61502=???0=Automatico 1=Usa truciolatore se sotto +61503=???0=Attacco e uscita centrati 1=Attacco e uscita interni +61504=???0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +61505=???0=Automatico; 1=Lavora come Taglio Longitudinale +61506=???0=Automatico; 1=Lavorazione con fresa +// ----- EgtBEAMWALL - BTLParam ----- +61601=???SN +61602=???Abilita +61603=???Descrizione +61604=L +61605=W +61606=H +61607=???Material +61608=???Richiesti +61609=???In produzione +61610=???Prodotti +61611=???Ruotare +61612=???Group +61613=???Unit Time +61614=???Parametro +61615=???Valore +61616=???Minimo +61617=???Massimo +61618=???Single member number +61619=???Assembly number +61620=???Order number +61621=???Designation +61622=???Annotation +61623=???Subgroup/Storey +61624=???Group +61625=???Package +61626=???Material +61627=???Timber grade +61628=???Quality grade +61629=???Count +61630=???Colour +61631=???Transparency +61632=???Planing length +61633=???Start offset +61634=???End offset +61635=???Transformation: Origin +61636=???Transformation: X-axis dir. vect. +61637=???Transformation: Y-axis dir. vect. +61638=???Camber: Reference side +61639=???Camber: P01,P02,P03,P04 +61640=???Part offset: ref. side fix clamp +61641=???Part offset: P11,P12,P13,P14 +61642=???Processing quality +61643=???Recess +61644=???Storey type +61645=???Element number +61646=???Layer +61647=???Module number +61648=???USERATTRIBUTE +61649=???Comment +61650=???Grain direction: X,Y,Z +61651=???Grain direction: Align +61652=???Reference side +61653=???Reference side: Align +61654=???Alignment: Location +61655=???Alignment: Endtype +61656=???Material type: Group +61657=???Material type: Specification +61658=???AUTOMATIC +61659=???VISIBLE +61660=???FAST +61661=???MANUAL +61662=???CEILING +61663=???ROOF +61664=???WALL +61665=???inactiv +61666=???BR +61667=???TR +61668=???BA +61669=???TA +61670=???HC +61671=???VC +61672=???AC +61673=???R +61674=???A +61675=???D +61676=???Batten +61677=???Cladding +61678=???Massive timber +61679=???Membrane +61680=???Gypsum Board +61681=???Gypsum Fibre +61682=???Insulation +61683=???Sheet Component +61684=???Facade Panel +61685=???Profiled Panel +61686=???Plaster +61687=???Reference side 1 +61688=???Reference side 2 +61689=???Reference side 3 +61690=???Reference side 4 +61691=???UID +61692=???Project number +61693=???Project name +61694=???Project part +61695=???GUID +61696=???Listname +61697=???Customer +61698=???Architect +61699=???Editor name +61700=???Delivery date +61701=???Export date +61702=???Export time +61703=???Export release +61704=???Language +61705=???Range +61706=???Computername +61707=???User name +61708=???Path & name of CAD-File +61709=???Path & name of BTL-File +61710=???STANDARD +61711=???EXTENDED +61712=???Vol unit +61713=???Vol tot +61714=???Time unit +61715=???Time tot +61716=???Total parts number +61717=???Total volume +61718=???Total time +61719=???Total estimed time +61720=???Remaining time +61721=???Rawpart counter +61722=???BTL part counter +61723=???Added part counter +61724=???Part in rawpart counter +61725=???Done part counter +61726=???Quantity +61727=???Print PDF +//Ware???house +61751=???Current S +61752=???Current L +61753=???StartOffset +61754=???Kerf +61755=???Offset +61756=???S Parameters +61757=???L Parameters +61758=???New Value: +61759=???W +61760=???L +61761=???Confirm +61762=???Save +61763=???Cancel +61764=???Error +61765=???Input value already present +61766=???Input value not correct +61767=???Input pair already present +61768=???One or more input values not correct +61769=???Attention +61770=???Selected parameter is equivalent to current L/S. Are you sure you want to remove it? +61771=???SectionXMaterial +61772=???Alias +61773=???Values +61774=???Quantity +61775=???Min thickness +61776=???Max thickness +61777=???Increment Max thickness of the last range before adding a new range +// +61801=???Custom +61802=???Default +61803=???L +61804=???T +61805=???Process +61806=???Section time +61807=???Part time +61808=???Name +61809=???PDN +61810=???DO +61811=???X position +61812=???Y position +61813=???Added +61814=???Done +61815=???ID +61816=???Start offset +61817=???% Used +61818=???Waste +61819=???BTL File Name +61820=???List Name +61821=???Export Date +61822=???Creation Date +61823=???Delete +61824=???Face +61825=???Group +61826=???Modify +61827=???Save +61828=???Cancel +61829=???Nesting +61830=???Viewer +61831=???Optimizer +61832=???Configuration +61833=???Optimize +61834=???Update BTL +61835=???Go to optimization +61836=???Filter type +61837=???Search +61838=???Export project +61839=???Import project +61840=???Import BTL +61841=???Copy to Clipboard +61842=???DisplayIndex +61843=???Column name +61844=???CanUserReorder +61845=???CanUserResize +61846=???CanUserSort +61847=???IsReadOnly +61848=???Visible +61849=???Variable Path +61850=???Type +// +61851=???This part modification will cause the removal of the part from {0} raw parts. Do you want to proceed anyway? +61852=???Impossible create feature with this values +61853=???Impossible create part with this values +61854=???Impossible create bar with this values +61855=???Impossible create wall with this values +61856=???Value outside minimum and maximum +61857=???Impossible to insert a quantity inferior to the number of parts already in rawparts! +61858=???Impossible to modify these values +61859=???Error in machine parameter writing +61860=???Save machine parameters modification? +61861=???Save default values modification? +61862=???Changing type second path will be deleted. Do you want to proceed? +61863=???To produce part number reached: +61864=??? from BTL; +61865=??? added. Do you want to add another one? +61866=???Selected part has different section from selected bar. Impossible to add. +61867=???Selected part lenght is more then the selected bar lenght. Impossible to add. +61868=???Selected part has different height from selected wall. Impossibl to add. +61869=???Error in macro file execution! +61870=???Impossible create a Macro without selecting a Feature or with empty name +61871=???File not found! +61872=???Impossibie deleting current project +61873=???Impossibile deleting the project because already linked to an optimization +61874=???Impossibile deleting the project because some parts are already sent to production +61875=???Do you want to save the project modifications? +61876=???Impossible creating a new file! +61877=???Save project modification before continuing? +61878=???Impossible proceding with a new unsaved project! +61879=???Type of current machine is both Beam and Wall. Select the type you want to set the project to: +61880=???Select one of the available machines and/or types. Otherwise cancel the project import. +61881=???The opened project type is not compatible with the current machine type +61882=???Do you want to save the modifications to the DataGrid columns? +61883=???The columnn specified as "{0}" in the "{1}" table in the datagrid columns ini file was not found in the program +61884=???Select the machine you want to associate to the project: +61885=???The machine linked to the opening project cannot be found among the available machines +61886=???Machine +61887=???Impossible creating the inserted rawparts quantity +61888=???How many copies of the rawpart do you want to create? +61889=???Long Drill Area +61890=???Min Rule +61891=???Can't send feedback from Optimizer if there is no open Prod +// +61900=???Change paramter +61901=???Verify +61902=???Simulate +61903=???New raw part +61904=???Add to raw part +61905=???Copy part +61906=???Add part +61907=???Remove part +61908=???Copy feature +61909=???Create macro +61910=???Add feature +61911=???Remove feature +61912=???Produce rawpart +61913=???Produce all rawpart +61914=???Copy rawpart +61915=???Remove rawpart +61916=???Reorder parts +61917=???Move up part +61918=???Move down part +61919=???Remove part +61920=???Warehouse +61921=???Add project to optimization +61922=???Go to project +61923=???Statistics +61924=???Reset +61925=???Show all parts +61926=???Show solid +61927=???Show building +61928=???Verify all +61929=???Can't change machine because the Proj is already linked to a Prod +61930=???Inputs +61931=???Outputs +61932=???Calculate Flip & Rotation +61933=???Unlock Flip +61934=???Unlock Rotation +61935=???Length +61936=???Width +61937=???Offset +61938=???Kerf +61939=???Edit +61940=???Reset +61941=???Choose machine +61942=???BTL file already imported and optimized. Do you want to import it again? +61943=???BTL file already imported. Do you want to overwrite it? +61944=???Shift parts +61945=???Shift direction +61946=???Shift length +61947=???Parts can't be shifted outside the raw part +61948=???The inserted shift value is not valid +61949=???Search & Filter +61950=???Parameter Type +61951=???Parameter Value +61952=???R +61953=???A +61954=???P +61955=???D +61956=???All +61957=???Filtered +61958=???Update +61959=???Append +61960=???Check the parts you would like to add to update BTL +61961=???Change material +61962=???Project material +61963=???Warehouse material +61964=???Standard +61965=???From BTL +61966=???Save +61967=???Do NOT save +61968=???Waiting for optimizer save +61969=???Cancel + +// +62500=???Supervisor +62501=???Channel +62502=???OPMode +62503=???Produce All +62504=???Done RawPart +62505=???Reset RawPart +62506=???Delete RawPart +62507=???Print Label +62508=???Done Part +62509=???Resume started processing? +// Loading +63000=???Project opening +63001=???Loading project geometries +63002=???Loading machining groups +63003=???Loading production data +63004=???Optimization opening +63005=???Loading parts +63006=???Loading graphics +63007=???Project saving +63008=???BTL file importing +63009=???Reading BTL file +63010=???Project exporting +63011=???Loading environment +63012=???Saving geometry +63013=???Saving data on Db +63014=???Modifying parameters +63015=???Part viewer opening +63016=???Adding export info +63017=???Exporting... +63018=???Project importing +63019=???Loading project +63020=???Creating imported project +63021=???Modifying materials +// ----- FromLua ----- +65001= +// ----- OmagCUT ----- +// General +90001=Travail en cours +90002=Coupes Directs +90003=Coupes Cad +90004=Cadres +90005=Machine +90006=Options +// WorkInProgress +90101= +// DirectCut +90201=Mouvement manuel +90202=Coupe unique +90203=Coupe multiple +90204=Coupe de quadrillage +90205=MTH +90206=Planage +90207=Test lame +90208=Palpage lame +90209=Copier gabarit +90210=Prendre P1 +90211=Prendre P2 +90212=Laser +90213=Enfoncement +90214=Longueur +90215=Direction +90216=Inclinaison +90217=Nombre +90218=Dimensions +90219=Nombre X +90220=Dimensions X +90221=Nombre Y +90222=Dimensions Y +90223=Coupes côté broche +90224=Lame +90225=Dessin +90226=Largeur +90227=Superposition +90228=Offset +90229=Bloquer l'axe C +90230=Usiner +90231=Polissage +90232=Épaisseur lame +90241=Palpage lame +90242=Palpage en cours... +90243=Palpage réussi +90244=Erreur en palpage lame +90245=Nouveau nome du gabarit +90246=Palpage interrompue par l'utilisateur +90250=Ligne +90251=Arc +90252=Effacer +90253=Fermer +90254=Sauvgarder +90255=???Test +90256=???Verifica posizione taglio +90257=???Verifica posizione in corso... +90258=???Single drill +// CadCut +90301=Simuler +90302=Usiner +90303=Nouv. +90304=Ouvrir +90305=Enreg. +90306=Enreg. sous +90307=Nouveau nom de fichier +90308=CSV +90309=Vein Match +90310=Export +90311=Outil +90312=Usinage +90313=Photographie pas réussie +90314=Erreur dans la création du programme CN +90315=Erreur dans la transmission du programme CN +90316=Non connecté à la machine +90317=Transmission du programme CN réussie +90318=Programme CN refusé par la machine +90319=Programme CN déjà transmis, à renvoyer ? +90320=Machine différente +90321=Réduction des usinage pour éviter les interférences +90322=Outils manquants : +90323=Photographie de fond réalisée +90324=Reconnaissance contour pas réussi +90325=Erreur lors de l'enregistrement des statistiques +90326=Confirmer le redémarrage de la phase {0} ? +90327=Insérées de nouvelles pièces ruinées +90328=Surface des pièces : +90329=À produire : +90330=Programme CN déjà transmis, nouvelle dalle ? +// NestPage +90331=Insérer Pièce +90332=Stationn. Pièce +90333=Supprimer Pièce +90334=Sélectionn. Tout +90335=Desél. Tout +90336=Reset +90337=Une ou plusieurs pièces avec épaisseur, matériau ou finition non compatible +90338=Rotation au-delà des limites +90339=Rotation impossible +90340=Imbrication automatique en cours +// SplitPage +90341=On/Off +90342=Tous On +90343=Tous Off +90344=Allong/Raccour +90345=Début All/Racc +90346=Fin All/Racc +90347=Début Centre/Ext +90348=Débuts Tous Ext +90349=Débuts Tous Centre +90350=Calcul automatique impossible +90351=Scie trop grand pour utiliser ventouse +90352=Fin Centre/Ext +90353=Fin Tous Ext +90354=Fin Tous Centre +90355=Tous Allong +90356=Tous Raccour +90357=Modif. +90358=Auto +90359=Restart +// MoveRawPart +90361=Enlever +90362=Pièce trop petite : déplacement impossible +90363=Poste sélectionné déjà occupé +90364=???Part too havy : can not be moved +90365=???Part beyond strokes : can not be moved +// SplitPage 2 +90371=Pause On/Off +90372=Pause +90373=Début Modif. +90374=Fin Modif. +90375=Elongation +90376=Inverser +// DrawPage +90381=Nombre de Pièces +90382=Dimensions +90383=Inclinations +90384=Marquer en haut +90385=Dessin paramétrique +90386=Sélectionner un contour +90387=Pas de côtés éditables +90388=Nombre +90389=Données Trf +90390=Code de la commande +90391=Description de la commande +90392=Code du matériel +90393=Code de la surface +90394=Épaisseur +90395=Sélectionner un ou plusieurs trous +90396=Code de la pièce +90397=Graver +90398=Données Csv +90399=Tous les usinages mis à jour +90400=???Filo Top +// Component +// Massimo 17 caratteri senza immagine e massimo 12 avec l'immagine +90401=Triangle +90402=Rectangle +90403=Trapeze +90404=Quadrilatère +90405=Pied d'oie +90406=Seuil +90407=Plat Cuisine +90408=Plat Toilette +90409=Autres +90410=Triangle2C +90411=Triangle3C +90412=Isocèle +90413=Rectangle +90414=Scalène +90415=Scalène +90416=4Côtés 1Ang +90417=3Côtés 2Ang +90418=3Côtés 2Diag +90419=4Côtés 1Diag +90420=4Côtés 3Diag +90421=4Côtés 3Ang +90422=4Côtés 3Ang +90423=Angle droit +90424=Angle droit avec chanfrein +90425=Angle aligné +90426=Angle aligné avec chanfrein +90427=Partie A +90428=Partie B +90429=Angle +90430=Angle avec chanfrein +90431=Ellipse +90432=Ovale +90433=Arc +90434=Arc LHF +90435=Arc LLH +90436=Arc LLF +90437=Rectangle arrondi +90438=En dôme +90439=Trou +90440=2 Trous +90441=3 Trous +90442=Arc RHa +90443=Polygone +90444=Trou d'en bas +90445=Dxf +90446=Creux +90447=Composants internes +90448=Ajouter +90449=Supprimer +90450=???Confirm +// Import +90451=User Layers +90452=User Regions +90453=Reset +90454=mm +90455=inch +90456=User curves fermées +90457=Inclination +90458=Goutte +90459=Angle +90460=Décalage +90461=Enfoncement +90462=Raccourcissement +90463=???DXF import +90464=???Drill bottom +90465=Nombre +90466=Décalage2 +90467=Commande +90468=Liste +90469=Nom +// Component 2 +90470=Gravures Creux +90471=Gravures +90472=TriangleCH +90473=TriangleRT +90474=TrapèzeRtA +90475=3Côtés 2Ang +90476=???Nuova soglia +// FastGrid +90480=Nom de la commande +90481=Nombre de dalles +90482=Dernière dalle +90483=Type de pièce +90484=Insérer pièces +90485=Confirmer la commande +// Open +90491=Fichier non valide +90492=Fichier avec interférences. Pour le charger, désactiver les coupes pleines. +// RawPart +90499=Blanc non défini +90500=Rotation +90501=Rectangle +90502=Par points +90503=Longueur +90504=Largeur +90505=Épaisseur +90506=Offset X +90507=Offset Y +90508=Kerf +90509=Matériel +90510=Région ruiné +90511=Nouveau +90512=Effacer +90513=Points +90514=Ajouter +90515=Supprimer +90516=Longueur maximale = +90517=Largeur maximale = +90518=Hauteurs négatives pas autorisés +90519=Décalage minimum X = +90520=Décalage minimum Y = +90521=Kerf minimum = +90522=Kerf maximale = +90523=Palper blanc +90524=Confirmer +90525=Palpage blanc +90526=Palpage en cours... +90527=Palpage réussi +90528=Erreur en palpage +90529=Du dessin +90530=Du laser +90531=Fermer +90532=Erreur en acquisition du point +90533=Contour +90534=Scie trop grand pour palpage +90535=Par photo +//ChooseMachining +90536=Choisir l'usinage avec lame +90537=Choisir le deuxième usinage +90538=Choisir le perçage +90539=Choisir le fraisage +90540=Aucun +90541=Perçage +90542=Fraisage +90543=Les deux +90544=Choix des usinages actuels +90545=Choisir le jet d'eau +90546=Jet d'eau +90547=Erreur dans la position ou les mesures du brut +90548=Décalage maximale X = +90549=Décalage maximale Y = +90550=???Scegliere la svuotatura +// Simulation +90551=Simulation achevé +90552=Surcourse +90553=Direction de l'outil inaccessible +90554=Erreur +90555=ERREUR +90556=Erreur dans la génération! +90557=Simulation +90558=Une seule étape +90559=???Play/Pause +90560=???Stop/Home +90561=Pause +90562=Simulation interrompue +90563=Vue machine +90564=???Home +90565=Temps +90566=Longueur +90567=Surface utile +90568=Utilisation +90569=Estimations +90570=Détails +// FrameCut +90601=Le long de X +90602=Le long de Y +90603=Enlever +90604=Dégrossissage +90605=Finition +90606=Finition latéral +90607=Miroir +90608=Espace supér. +90609=Espace latéral +90610=Racc. début +90611=Raccourcir fin +90612=Coupe unique +90613=Arc +90614=Guide +90615=Section +90616=Guide +90617=Rad +90618=Ang +90619=Attention: rayon inférieur à la largeur de la section +90620=Erreur : création du cadre pas réussie +90621=Espace X +90622=Espace Y +90623=Coté opposé +// Machine +90701=Msg_Fra.xpi +90705=Données de la machine +90706=Outils +90707=Usinages +90708=Machine +90709=???Statistiche +90715=Nouveau +90716=Nouveau +90717=Sauvegarder +90718=Effacer +//ToolsDb +//param +90719=Longueur du porte-outil +90720=Noyau +90721=Nome +90722=Position +90723=Tête +90724=Exit +90725=Rotation +90726=Normale +90727=Maximale +90728=Vitesse +90729=Avance +90730=Tête +90731=Entrée +90732=Sortie +90733=Eau +90734=Correcteur +90735=Surépaisseur +90736=Longitudinal +90737=Radial +90738=Puissance max. +90739=Vitesse min. +90740=Enfoncement maximal +90741=Longueur +90742=Diamètre +90743=Epaisseur +90744=Tranchant +90745=Notes +90746=Numéro matricule +90747=Code +90748=Fournisseur +90749=Fin du service +//tools families +90751=Lame +90752=Foret +90753=Fraise +90754=Meule +90755=Jet d'eau +90756=Meule polissage +//Tool Setup +90759=Position d'outil par défaut déjà occupée +//MachiningsDb +//param +90761=Nome +90762=Enfoncement +90763=Angle d'inclinaison +90764=Inverser +90765=Step +90766=Côté de travail +90767=Côté de la tête +90768=Position de départ +90769=Entrée +90770=Liaison +90771=Sortie +90772=Utiliser curbes +90773=Tolérance +90774=Pas d'enfoncemet +90775=Normal +90776=Pas d'enfoncemet +90777=Intérieur d'arcs +90778=Extérieur d'arcs +90779=Longueur de ralentissement +90780=Initial +90781=Final +90782=Enfoncement supplémentaire +90783=Position de retour +90784=Outil +90785=Epaisseur minimum +90786=Epaisseur maximum +90787=Pas +90788=Vers le bas +90789=De côté +90790=Vertical +//machinings families +90791=Coupe +90792=Perçage +90793=Fraisage +90794=Dégrossissage avec scie +90795=Finition avec scie +90796=Fraisage de poches +90797=Jet d'eau +//ComboBox Param +90801=No +90802=Interne +90803=Externe +90804=les deux +90821=Centre +90822=Gauche +90823=Droit +90824=Centré +90825=Interne +90826=Externe +90827=Etendu centré +90828=Etendu externe +90829=Etendu précédent +90830=Etendu suivant +90831=Etendu les deux +90832=Centrée +90833=Interne +90834=Externe +90835=Ignorer +90836=Approximatif +90837=Convex +90838=Zig Zag +90839=Une manière +90840=Avant et arrière +90841=Usiner +90842=Aucun +90843=Standard +90844=Ralentir +90845=Boucle +90846=???Linear +90847=???Tangent +90848=???Glide +90849=???Helix +90850=???As lead in +// param 2 +90861=De côté +90862=Penché +90863=Penché à l'arrière +90864=En avant +90865=À l'arrière +90866=Dernier arrière +90867=Angle vers l'avant +90868=Palpage +90869=Min dist. points +90870=Max dist. points +90871=Externe +90872=Interne +90873=Long. ralent. +90874=Ralentissment % +90875=Trou d'entrée +90876=Rayon +90877=Tours LP +90878=Tours HP +90879=Permettre +90880=Coins +// Barcode +90881=Code-barres +90882=Bloc +90883=Nombre +90884=Données de dalle +// param3 +90890=Dist. tang. +90891=Dist. perp. +90892=Dist. tang. +90893=Dist. perp. +90894=Entrée céramique +90895=Longueur +90896=Pas +90897=???Last cut +90898=???Side angle cuts +// Alarms +90900=Jet d'eau courant +90901=Lame courante +90902=Deuxième outil +90903=Foret courant +90904=Fraise courante +90905=Z sûr +90906=Sécur. coupes +90907=Sécur. angles +90908=Observer les coupes pleines +90909=Décal. trous +90910=Superp. trous +90911=Tolérance +90912=Liste erreurs CN +90913=Materiaux +90914=Ajouter +90915=Effacer +90916=Outils actuels +90917=Paramètres trous +90918=R min arcs ext. +90919=Paramètres machine +90920=Aucun +90921=Foret +90922=Fraise +90923=Les deux +90924=A max arcs int. +90925=Paramètres lame +90926=Un seul trou dans coin +90927=Coupes directs +90928=Home à la fin +90929=Paramètres fraisages +90930=Toujours sur les intérieurs +90931=Nesting +90932=Aligné +90933=Outillage +90934=Nouveau +90935=Supprimer +90936=Hauteur table supplémentaire +90937=Contour de Photo +90938=Fonde +90939=Seuil +90940=Tolérance +90941=Lavage +90942=Confirmer l'annulation du matériel sélectionné? +90943=Outillage par défaut +90944=Toujours dans les coins +90945=Sélectionner l'outil à palper +90946=Coupes Feed start/end +90947=Longueur +90948=Réduction% +90949=Diminution +90950=Palpage +//Machine +90951=Start +90952=Stop +90953=Reset +90954=Auto +90955=Single +90956=MDI +90957=Manual +90958=Home +90959=Download +90960=Upload +90961=Activate +90962=Delete +90963=MDI Confirm +90964=Modalité CN +90965=Commandes de la machine +90966=Caractères MDI +90967=Transfert programme pièce +90968=???Do you want to change table? +// Options +90981=Sélection du langage +90982=Le nouveau langage deviendra courant au prochain démarrage du programme +90983=Unité de mesure +90984=Rotation de la vue +90985=Angle d'inclinaison +90986=Une valeur +90987=Plus de valeurs +90988=Insertion directe des pièces +90989=Paramétrés et DXF +90990=CSV +90991=Fast grid +90992=Permetter la création de pièces standard +90993=???Colore testo +90994=???Slab Dxf +90995=???Slab Layer +90996=???Parts Layer +90997=???Scrap Layer +90998=???Std Thick +90999=???ColorToSideAng +91000=???Enable +91001=???Tolerance +91002=???Heel +91003=???Side Angle +91004=???Feedback +91005=???Themes +91006=???Engrave from color +91007=???Depth +91008=???Width +91009=???Start program +91010=???Select start mode +91011=???Recent project +91012=???Last opening +91013=???Last project +91014=???New project +91015=???Open folder +91016=???Show window +//Alarms2 +91051=Usinages +91052=Sciage +91053=Perçage +91054=Fraisage +91055=???DripSawing +91056=???DripDrilling +91057=Jet d'eau +91058=Paramètres jet d'eau +91059=Automatique +91060=Aligné et Guillotine +91061=Paramètres de gravure +91062=Avec fraise +91063=Profondeur +91064=Largeur +91065=Sortie prédécoupée +91066=Guillotine +91067=Insérer une pause +91068=Cadres +91069=Vidage +91070=???Scasso corrente +//Statistics +91071=???Produzione del giorno +91072=???Produzione della settimana +91073=???Progetto +91074=???Area Pezzi +91075=???Area Tagli +91076=???Giorno +91077=???Settimana +91078=???Reset +91079=???Area da Tagliare +//Lucidature +91089=???Offset +91090=Polissages +91091=Polissages +91092=Mouvement +91093=Nombre +91094=Entrée/Sortie +91095=Hauteur +91096=Liste d'outils +91097=Longueur +91098=↑ +91099=↓ +91100=Charge +//EgtMsgBox +91101=Sauvegarder le fichier actuel? +91102=Sauvegarder l'outil actuel? +91103=Sauvegarder l'usinage actuel? +91104=Nom déjà utilisé +91105=Il ya des interferences, des pièces seront en stationnement. Voulez continuer? +91106=Un fichier de ce nom existe déjà. Ecraser? +91107=CONNEXION AU CN +91108=Connexion en cours... +91109=Connexion pas réussie +91110=Connexion réussie +91111=Table à utiliser ? +91112=Supprimer aussi les pièces des listes CSV ? +91113=Pièce pas supprimés parce que libres +91114= ou d'autres listes Csv +91115=Erreur +91116=Option Ligne de production pas activé +91117=Erreur dans la copie des fichiers pour OmagVIEW +91118=Garder les pièces stationnés ? +91119=Erreur avec pièces ruinées +91120=???I caratteri \ / : * ? " < > | non sono permessi +91121=Voulez-vous vraiment supprimer les parties sélectionnées ? +91122=Alerte +91123=Table +91124=???Salvare la lucidatura corrente? +91125=???Salvare le modifiche correnti? +91126=???Export +91127=???Import +91128=???DB WaterJet +91129=???Origine da laser +91130=???Start program? +// CSV +91201=Ouvrir +91202=Insérer +91203=Nouveau +91204=Retirer +91205=Erreur d'enregistrement du fichier CSV, continuer de toute façon ? +91206=Erreur de lecture du fichier CSV +// OmagVIEW +91301=Toutes Bonnes +91302=Partie Bonne +91303=Partie Ruinée +91304=Imprimer Etiquette +91305=Confirmer +91306=Imprimer +// OmagOFFICE +// OptionPanel +91401=Brut +91402=Disposer +91403=Usiner +91404=Simuler +// MachiningDbWindow +91451=???Materiale +91452=???Spessore minimo +91453=???Spessore massimo +// TopCommandBar +91501=Vous devez enregistrer votre projet avant l'exportation +91502=Sélectionnez le répertoire export +91503=Erreur in export +91504=Export terminé avec succès +91505=Exporter à la machine +91506=Exporter DXF +// Rawpart +91551=Erreur pendant le chargement de la photo +91552=???Importa fotografia +// VeinMatching +91601=Export +91602=Afficher Info +91603=Modifier +91604=Vérifier +91605=Magnétique +91606=Pièce non sélectionnable dans cette situation +91607=Pièce non sélectionnable car appartenant à un groupe de travail non actuel : +91608=Empreinte des pièces DXF trop grande pour VeinMatching +// Generic +91651=???Ok +91652=???Annulla +91653=A° +91654=T +91655=Démarrer +91656=Finir +// ----- OmagPHOTO ----- +// General +92001=???Db non trovato! +92002=???Unable starting the program +// OptionPanel +92051=Enregistrer +92052=Ajouter +92053=Annuler +92054=Effacer +92055=???Sei sicuro di voler cancellare la lastra corrente? +92056=???Etichetta +92057=???Etichetta Freccia +92058=???Sfoglia +92059=???Stampa +92060=???Seleziona +// Slab +92071=Id +92072=Nom de l'image +92073=État +92074=Attaché à un projet +92075=Position en magazine +92076=Date +92101=Nom déjà utilisé +92102=Le nom est obligatoire +92103=L'image est obligatoire +// SearchPanel +92151=Rechercher +92152=Tolérance d'épaisseur +92153=Date de début +92154=Date de fin +92155=???Reset +//Messaggi +92200=???Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=???Avviso +92202=???Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=???Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=???Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// General +101001=Importer BTL +101002=Dessiner +101003=Positionner +101004=Options +// ImportPage +101101 +// DrawPage +101201=Mur +101202=Port +101203=Fenêtre +101204=Ajouter +101205=Annuler +101206=Appliquer +101207=Supprimer +101208=Espaceur +// PlacePage +101301=Générer +101302=Transmettre +101303=Positionnement mur +101304=Insérer +101305=Stationner +101306=Supprimer +101307=Epaisseur couches +101308=N. planches au sommet +101309=Insertion impossible +101310=Succès génération +101311=Erreur en génération +101312=Succès en exec transmission +101313=Erreur en exec transmission +101314=Transmission réussie +101315=Transmission pas réussie +101316=Portiques tous désactivé +101317=Fichier de Génération non trouvé +// OptionsPage +101401=Options machine +101402=Caractéristiques collage +101403=Extra brut en X +101404=Extra brut en Y +101405=Extra colle +101406=Caractéristiques bois +101407=Largeur planche +101408=N. planches dans un plane +101409=Activation portiques +101410=Portique colle +101411=Portique bois +101421=Options du logiciel +101422=Sélection du langage +101423=Le nouveau langage deviendra courant au prochain démarrage du programme +101424=Nombre de projets à sauvegarder +101425=Placer planches sur portes et fenêtres +101426=Avance ouverture colle +101427=Avance fermeture colle +// OpenPage +101501=Projet non valide +// ----- End ----- diff --git a/ProgramData/EgtCAM5/Config/EgalTechIta.txt b/ProgramData/EgtCAM5/Config/EgalTechIta.txt new file mode 100644 index 0000000..69b3993 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgalTechIta.txt @@ -0,0 +1,3312 @@ +// File dei messaggi EgalTech Italiano 2022/04/11 +0=ITA +// File +1=File +3=Nuovo +5=Apri +6=Apri
File recenti (Shift) +7=Inserisci +9=Salva +11=Copia +13=Importa +15=Esporta +17=Esegui +19=File Recenti +20=Script Recenti +// Vista +101=Vista +103=Linee +105=Bordi +107=Solidi +109=ZoomAll +111=ZoomIn +113=ZoomOut +115=Sopra +117=Fronte +119=Destra +121=Dietro +123=Sinistra +125=Sotto +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Griglia +136=Imposta Vista perpendicolare alla Griglia corrente +137=DirCurve +139=Analisi +141=Distanza +// Griglia +201=Griglia +203=Sopra +205=Fronte +207=Destra +209=Dietro +211=Sinistra +213=Sotto +215=Vista +216=Imposta Griglia perpendicolare alla direzione di Vista +217=Elevaz +218=Imposta Elevazione della Griglia +219=Origine +220=Imposta Origine della Griglia +221=Ruota +222=Ruota Griglia
Ruota Griglia in 3d (Shift) +223=3 Punti +224=Imposta Griglia da 3 Punti +225=Perp +226=Imposta Griglia Perpendicolare a Oggetto +227=Oggetto +228=Imposta Griglia da Oggetto +// Disegna +301=Disegna +303=Punto +304=Punto
Vettore (Shift)
Riferimento (Ctrl) +305=Lin 2P +306=Linea : 2 Punti
Linea : 2 punti con Continuazione (Ctrl) +307=Lin PDL +308=Linea : Punto iniziale, Direzione, Lunghezza
Linea : Punto iniziale, Vettore direzione, Lunghezza (Shift) +309=Circ +310=Circonferenza : Centro, Punto
Circonferenza : Centro, Diametro (Shift) +311=Racc +312=Raccordo : Raggio
Smusso : Dist (Shift) +313=Arco CIF +314=Arco : Centro, Punto iniziale, Punto finale +315=Arco 3P +316=Arco : 3 Punti +317=Arc IDF +318=Arco : Punto iniziale, Direzione, Punto finale
Arco : Punto iniziale, Vettore direzione, Punto finale (Shift)
Arco : Punto iniziale, Direzione, Punto finale con Continuazione (Ctrl) +319=Rett 2P +320=Rettangolo : 2 Punti +321=Poligono +322=Poligono : Raggio o Apotema
Poligono : Lato con 2 Punti (Shift) +323=Testo +324=Testo
Testo Avanzato (Shift) +399=Continuazione : 'L' con linea, 'A' con arco +// Costruisci +401=Costruisci +403=Piano +404=Superficie : piano contornato da una o più curve
Regione piana (Shift) +405=Estrudi +406=Superficie : da estrusione di una o più curve +407=Ruota +408=Superficie : da rotazione di una curva +409=Avvita +410=Superficie : da rototraslazione di una curva +411=Rigata +412=Superficie : rigata tra 2 curve +413=Combina +414=Combina una o più Superfici +415=Inverti +416=Inverte l'esterno di una o più Superfici +417=Esplodi +418=Esplodi Superfici o Regioni Piane +419=Swept +420=Superficie : da spostamento di una curva lungo un'altra +// Modifica +501=Modifica +503=Cancella +504=Cancella gli Oggetti +505=Layer +506=Porta gli Oggetti nel Layer corrente +507=Colore +508=Cambia Colore
Rimuovi Colore specifico (Shift)
Cambia Trasparenza (Ctrl) +509=Inverti +510=Inverti Curva +511=Trim/Est +512=Taglia o Estendi Curva +513=Spezza +514=Spezza Curva
Dividi Curva in Parti (Shift) +515=Unisci +516=Unisci Curve
Unisci Curve creando una Copia (Shift)
Fondi Curve nella Composita (Ctrl) +517=Esplodi +518=Explodi Testi o Curve in Componenti +519=Spess +520=Imposta Spessore e direzione di Estrusione su una o più Curve +521=Inizio +522=Cambia Inizio di Curva Chiusa +// Trasforma +601=Trasforma +603=Muovi +604=Muovi uno o più Oggetti +605=Ruota +606=Ruota uno o più Oggetti
Ruota uno o più Oggetti in 3D (Shift) +607=Specch +608=Specchia uno o più Oggetti
Specchia uno o più Oggetti in 3D (Shift) +609=Scala +610=Scala uno o più Oggetti
Scala uno o più Oggetti in 3D (Shift) +611=Offset +612=Offset di una Curva +// Special +701=Special +703=Pezzi 2d +704=Inserisci Pezzi Piani da DXF o NGE +705=Compo +706=Inserisci Componenti Parametrici +// Scene : Menù Selezione Entità +1001=Seleziona Tutto +1003=Deseleziona Tutto +1005=Seleziona con Finestra +1007=Seleziona Pezzo +1009=Seleziona Layer +1011=Seleziona Percorso +1013=Seleziona Percorso Completo +1015=Seleziona Entità +1016=Seleziona Tutti i Visibili +// Scene : Menù Punto notevole +1101=Punto Sketch +1102=Punto Sketch +1103=Punto Griglia +1104=Punto Griglia +1105=Punto Finale +1106=Punto Finale +1107=Punto Medio +1108=Punto Medio +1109=Centro +1110=Centro +1111=Baricentro +1112=Baricentro +1113=Punto Vicino +1114=Punto Vicino +1115=Intersezione +1116=Intersezione +1117=Punto Tangente +1118=Punto Tang +1119=Punto Perpendicolare +1120=Punto Perp +1121=Punto a Minima Distanza +1122=Punto MinDist +1123=Escludi Superfici +// Scene : Menù Varie +1201=Disattiva Trascinamento +1203=Attiva Trascinamento +// Scene : Varie +1301=Dist= +// Controller +2001=Copia (V) +2002=Errore +2003=Allarme +2051=Il Punto deve essere diverso dal precedente +2052=I Punti devono essere non allineati +2053=Valori Nulli o Negativi non sono ammessi +2054=Valori Negativi o Due Valori Nulli non sono ammessi +2055=Almeno una Entità non è scalabile +2056=Distanza troppo grande +2057=Curva non piatta (nel suo piano) +// Controller : Disegna +2101= +// Controller : Costruisci +2201= +// Controller : Modifica +2301= +// Controller : Trasforma +2401=COPIA +2402=MUOVI +2403=Inserisci Punto Base +2404=Inserisci Punto Destinazione +2406=RUOTA +2407=Inserisci Centro +2408=Inserisci Punto Base +2409=Inserisci Angolo o Punto +2411=RUOTA 3D +2412=Inserisci Primo Punto Asse +2413=Inserisci Secondo Punto Asse +2414=Inserisci Punto Base +2415=Inserisci Angolo o Punto +2416=SPECCHIA +2417=Inserisci Primo Punto +2418=Inserisci Secondo Punto +2421=SPECCHIA 3D +2422=Inserisci Primo Punto +2423=Inserisci Secondo Punto +2424=Inserisci Terzo Punto +2426=SCALA +2427=Inserisci Centro +2428=Inserisci Coefficiente +2431=SCALA 3D +2432=Inserisci Centro +2433=Inserisci Coefficienti +2436=OFFSET +2437=Inserisci Distanza +2438=Raccordo +2439=Smusso +2440=Estendi +// ----- EgtCAM5 ----- +5001=DISEGNA +5002=LAVORA +5003=Db Utensili +5004=Db Lavorazioni +5005=Opzioni +5006=Db Ut. +5007=Db Lav. +5008=Opzioni Macchina +5009=Db Att. +5010=Db Attrezzaggio +5020=Tabelle Lavorazioni +//Top CommandBar +5101=Nuovo +5102=Apri
Apri File recenti (Tasto Destro) +5103=Salva +5104=Salva come +5105=Inserisci +5106=Importa +5107=Esporta +5108=Esegui Script
Esegui Script recenti (Tasto Destro) +5109=Opzioni +5110=Indirizzo mail di supporto non trovato. +5111=Salvare il progetto corrente prima di mandare il feedback? +5112=Mandare il feedback a {0} con allegata la cartella {1}. +5113=Feedback +5114=Mail di feedback pronta. +// Draw Panel +5150=Estrai Bordi Liberi di Superfici e Regioni Piane +5151=Unisci Superfici e Regioni Piane +5152=Sottrai Superfici e Regioni Piane
Taglia Superficie con Superficie Inversa (Shift) +5153=Interseca Superfici e Regioni Piane
Taglia Superficie con Superficie (Shift) +5154=Punti, Curve e Facce di Intersezione Tra Superfici +5155=Quota Lineare
Quota Allineata (Shift) +5156=Cerchio 3 Punti +5157=Estrai Bordi di Facce di Superfici e di Parti di Regioni Piane +5158=Estrai Faccia da Superficie +5159=Arco Capovolto
Arco Esplementare (Shift) +5160=Modifica forma +5161=Aggiungi Punto
Trasforma in Arco (Shift)
Chiudi Curva Composita (Ctrl) +5162=Rimuovi Punto
Trasforma in Retta (Shift)
Apri Curva Composita (Ctrl) +5163=Approssima Curva
Approssima Curva con Linee (Shift) +5201=Punto
Vettore (Shift)
Riferimento (Ctrl) +5202=Linea 2 Punti
Linea 2 Punti con Continuazione (Ctrl) +5203=Linea Punto Direzione Lunghezza
Linea Punto Vettore Direzione Lunghezza (Shift) +5204=Cerchio Centro Punto +5205=Cerchio Centro Diametro +5206=Arco Centro Punti Inizio e Fine +5207=Arco 3 Punti +5208=Arco Punto e Direzione Inizio Punto Fine
Arco Punto e Vettore Direzione Inizio Punto Fine (Shift)
Arco Punto e Direzione Inizio Punto Fine con Continuazione (Ctrl) +5209=Raccordo +5210=Smusso +5211=Rettangolo 2 Punti +5212=Poligono +5213=Poligono da Lato +5214=Testo
Testo Avanzato (Shift) +5215=Piano contornato
Regione piana (Shift) +5216=Estrusione +5217=Rivoluzione +5218=Avvitamento +5219=Rigata +5220=Unisci Superfici +5221=Esplodi Superfici e Regioni Piane +5222=Inverti Superfici e Regioni Piane +5223=Cancella +5224=Cambia Layer
Cambia Layer con Trasformazioni (Shift) +5225=Cambia Trasparenza +5226=Annulla Colore +5227=Cambia Colore +5228=Inverti Curva +5229=Cambia Punto Iniziale di Curva Chiusa +5230=Estendi o Accorcia Curva +5231=Spezza Curva +5232=Dividi Curva +5233=Unisci Curve
Unisci Curve creando una Copia (Shift)
Fondi Curve nella Composita (Ctrl) +5234=Esplodi Curve e Testi +5235=Spessore e Estrusione Curva +5236=Muovi +5237=Ruota +5238=Ruota 3D +5239=Specchia +5240=Specchia 3D +5241=Scala +5242=Scala 3D +5243=Offset +5244=Disegno 2D +5245=Disegno 3D +5246=Modifica +5247=Trasforma +5248=Swept (Sezione, Guida) +5249=Modifica Testo +// Grid View Panel +5251=Wireframe +5252=Linee Nascoste +5253=Ombreggiatura +5254=Zoom All +5255=Zoom In +5256=Zoom Out +5257=Vista da Sopra +5258=Vista di Fronte +5259=Vista da Sinistra +5260=Vista da Dietro +5261=Vista da Destra +5262=Vista Isometrica da SW +5263=Vista Isometrica da SE +5264=Vista Isometrica da NE +5265=Vista Isometrica da NW +5266=Mostra Direzione Curve +5267=Analizza +5268=Distanza +5269=Griglia da Sopra +5270=Griglia di Fronte +5271=Griglia da Destra +5272=Griglia da Dietro +5273=Griglia da Sinistra +5274=Griglia da Sotto +5275=Griglia da Vista +5276=Elevazione Griglia +5277=Origine Griglia +5278=Ruota Griglia
Ruota Griglia in 3d (Shift) +5279=Griglia da 3 Punti +5280=Griglia Perpendicolare a Curva +5281=Griglia da Oggetto +5282=Vista da Griglia +5283=Zoom Selezione +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=END +5302=Extra corsa +5303=Direzione utensile irraggiungibile +5304=Errore +5305=ERRORE +5306=Errore in generazione! +5307=Simulazione +5308=Un passo alla volta +5309=Play/Pausa +5310=Stop/Home +5311=PAUSA +5312=STOP +5313=Impossibile uscire ora. Prima fermare la simulazione o aspettarne la fine! +5314=HOME +5315=AVVERTIMENTO +5316=Virtual Milling +5317=Errore nel calcolo delle stime! +5318=File delle stime non trovato +5319=Collisione! +5320=INFORMAZIONE +5330=GENERA +5331=Il progetto deve essere salvato prima della generazione CN. Vuoi farlo ? +5332=Generato con successo +5333=La licenza non permette la Generazione CN +5340=Stime +5341=Tempo totale +5342=Lunghezza totale +5343=Dettagli +5344=Stime dettagliate +// Draw Option +5351=Proprietà +5352=Nuovo Pezzo +5353=Nuovo Layer +5354=Colore +5355=Parametri di disegno +5356=Seleziona +5357=Deseleziona +5358=Nome +5359=Info +5360=Sposta +5361=Copia +5362=Elimina +5363=Salva +5364=Mostra +5365=Conferma +5366=Conferma Cancellazione +5367=Pezzo in lavorazione, vuoi cancellarlo lo stesso ? +// Operation +5401=Operazioni +5402=Parametri Operazione +5403=Applica Lavorazione +5404=Nuova Lav +5405=Nuova Disp +5406=Cancella +5407=Generici +5408=Sposta su +5409=Sposta giù +5410=Aggiorna +5411=Aggiornamento completato con successo +5412=Nuove Lavorazioni +5413=Anteprima Utensile +5414=Avanti +5415=Indietro +5416=Duplica +5417=Copia nel Db +5418=Nome lavorazione nel Db +5419=Inserimento lavorazione non riuscito +5420=Rinomina +5421=Il nome non può iniziare con "Disp" +5422=Nome già utilizzato +5423=La lavorazione non può essere applicata per i seguenti motivi: +// Disposition +5431=Ok +5432= +5433=Nuovo +5434=Rimuovi +5435=Lunghezza +5436=Larghezza +5437=Altezza +5438=Posizione +// Mach & Disposition Errors +5461=ERRORE DI ESECUZIONE SCRIPT +5462=Errore nella esecuzione dello script automatico di disposizione +5463=Errore nella esecuzione dello script di inizio lavorazioni +5464=Errore nella esecuzione dello script di fine lavorazioni +// Mach Group +5501=Sicuro di voler pulire il Gruppo di Lavorazione? +5502=Sicuro di voler cancellare il Gruppo di Lavorazione? +5551=Non ci sono Gruppi di Lavorazione :
selezionare i pezzi da inserire e
ripetere il comando per creare il primo +5552=Vuoi creare un nuovo Gruppo di Lavoro
con i pezzi selezionati ? +// Tools Db Page +6001=Punta +6002=Lama +6003=Fresa +6004=Mortasatrice +6005=Composito +6006=Punta lunga +6007=Lama piatta +6008=Fresa senza punta +6009=Scalpello +6010=WaterJet +6051=Correttore +6052=Uscita +6053=Tipo +6054=Refrigerante +6055=Raggio Corner +6056=Diametro +6057=Diametro Totale +6058=Avanzamento +6059=Avanzamento Finale +6060=Avanzamento Iniziale +6061=Avanzamento di Punta +6062=Lunghezza +6063=Lunghezza totale +6064=Massimo Materiale +6065=Offset Longitudinale +6066=Offset Radiale +6067=Rotazione +6068=Angolo di Lato +6069=Rotazione Massima +6070=Spessore +6071=Assorbimento Massimo +6072=Avanzamento Minimo +6073=Disegno +6074=Testa +6075=Nome +6076=Note +6077=Posiz. Cambio Utensile +6078=Posizione +6079=Distanza +6080=Sovratavola +// Tools Errors +6100=Salvare l'utensile modificato ? +6101=SALVA +6102=Il file deve essere .nge +6103=Il file non esiste o non è di tipo Nge +6104=Non esiste il ToolMaker per questo tipo di utensile +6105=Impossibile creare l'utensile con questi parametri +6106=Il Massimo Materiale deve essere maggiore di 0 +6107=Il Massimo Materiale deve essere minore di Lung +6108=Lo Spessore deve essere maggiore di 0 +6109=Il Diametro deve essere maggiore di 0 +6110=La Lunghezza deve essere maggiore di 0 +6111=La Rotazione deve essere minore della Rotazione Massima +6112=Nome non valido +6113=La Lunghezza deve essere minore della Lunghezza Totale +6114=La Lunghezza deve essere maggiore del Massimo Materiale +6115=La Lunghezza Totale deve essere maggiore di 0 +6116=La Lunghezza Totale deve essere maggiore della Lunghezza +6117=Il Massimo Materiale deve essere minore di 1/3 del Diametro +6118=Il Diametro deve essere minore del Diametro Totale +6119=Il Diametro deve essere maggiore di 3 volte il Massimo Materiale +6120=Il Diametro Totale deve essere maggiore di 0 +6121=Lunghezza troppo piccola con il portautensile +6122=Sei sicuro di voler cancellare l'utensile +6123=? +6124=CANCELLA +6125=File di configurazione attrezzaggio non trovato! +6126=Errore +6127=Impostare il tipo di testa. +6128=Impostare il tipo di uscita. +6129=Utensile non valido, correggerlo o cancellarlo prima di uscire dal Db Utensili. +6130=Impossibile ricaricare il database utensili. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +6131=Lo Spessore deve essere differente da 0 +6132=L'Angolo di Lato deve essere minore di 90 +6133=L'Angolo di Lato deve essere maggiore di -90 +6134=La Lunghezza Totale deve essere maggiore di Lunghezza + Spessore +6135=Raggio Corner ha un valore troppo grande +6136=Lo Spessore ha un valore troppo piccolo rispetto al Raggio Corner +6137=Il diametro risultante supera il Diametro Totale +6138=Il diametro risultante è minore di 0 +6139=Il diametro stelo risultante è minore o uguale a 0 +6140=Massimo Materiale deve essere maggiore del Raggio Corner +6141=Massimo Materiale risultante deve essere >= 0 +6142=Raggio Corner non deve superare metà Spessore +6143=Salvataggio utensile +6144=Utensile modificato! Tutti gli utensili devono essere salvati prima di cambiare le attivazioni. Salvare l'utensile {0}? +6145=Posizione già occupata! +6146=Posizione non definita! +// Machinings Db Page +6201=Foratura +6202=Taglio di lama +6203=Fresatura +6204=Svuotatura +6205=Mortasatura +6206=Sgrossatura con lama +6207=Finitura con lama +6208=Lav. generica +6209=Scalpellatura +6210=Sgrossatura superfici +6211=Finitura superfici +6212=WaterJet +6251=Inverti +6252=Tab +6253=Tipo +6254=Lato di lavoro +6255=Lato della testa +6256=Attacco +6257=Collegamento +6258=Uscita +6259=Uso curve +6260=Tipo di Step +6261=Sottotipo +6262=Tipo approccio +6263=Rotazione +6264=Feed +6265=Feed iniziale +6266=Feed finale +6267=Feed di testa +6268=Offset radiale +6269=Offset longitudinale +6270=Affondamento +6271=Angolo di fianco +6272=Approssimazione +6273=Dist. di sicurezza +6274=Lungh. rallent. iniziale +6275=Lungh. rallent. finale +6276=Lungh. passante agg. +6277=Passo +6278=Posizione di ritorno +6279=Lunghezza +6280=Distanza +6281=Altezza +6282=Angolo +6283=Dist. tangente attacco +6284=Dist. perp. attacco +6285=Elevazione attacco +6286=Lungh. correz. attacco +6287=Dist. tangente di uscita +6288=Dist. perp. di uscita +6289=Elevazione di uscita +6290=Lungh. correz. di uscita +6291=Lungh. addiz. attacco +6292=Lungh. addiz. di uscita +6293=Passo su esterno arco +6294=Passo su interno arco +6295=Passo di lato +6296=Feed verticale +6297=Nome +6298=Utensile +6299=Affondamento +6300=Note +6301=Sovrapposizione +6302=Offset +6303=Sottotipo +6304=SCC +6305=Nessuno +6306=Standard +6307=Opposto +6308=AuxDir Destra +6309=AuxDir Sinistra +6310=AuxDir Dietro +6311=AuxDir Davanti +6312=AuxDir Sopra +6313=AuxDir Sotto +6314=Più Vicino AuxDir +6315=Più Lontano AuxDir +6320=Centro +6321=Sinistra +6322=Destra +6323=Estendi +6324=Standard +6325=Interno +6326=Esterno +6327=Esteso centrato +6328=Esteso esterno +6329=Nessuno +6330=Lineare +6331=Tangente +6332=Inseguimento +6333=Elica +6334=Estendi precedente +6335=Estendi successivo +6336=Estendi entrambi +6337=Come attacco +6338=Salta +6339=Approssima +6340=Convesso +6341=Mantieni +6342=ZigZag +6343=Una via +6344=Spirale +6345=Va e torna +6346=Longitudinale +6347=Trasversale +6348=Spirale In +6349=Spirale Out +6350=Avanzati +6351=Inverti direz. utensile +6352=Lavorazione faccia +6353=Non definito +6354= Parallelo +6355= Ortogonale +6356= Ortog. Su +6357=Sotto +6358=Sopra +6359=Davanti +6360=Dietro +6361=Sinistra +6362=Destra +6363=Contorno +6364=Angoli Suggeriti +6365=Asse Bloccato +6366=N° massimo +6367=N° minimo +// Machining errors +6370=Salvare la lavorazione modificata? +6371=SALVA +6372=Nome non valido +6373=I caratteri \ / : * ? " < > | non sono permessi +6374=Sei sicuro di voler cancellare +6375=? +6376=CANCELLA +6377=Impossibile ricaricare database lavorazioni. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +6378=Oscillazione +6379=Ampiezza di oscill. +6380=Lungh. rampa di oscill. +6381=Lungh. cresta di oscill. +// Machining Option Page +6401=Z di sicurezza +6402=Spezzatura archi +6403=Mai +6404=Piano generico +6405=Piano diverso da XY +6406=Sempre +6407=Attrezzaggio predefinito +6408=Sicurezza rinvio da sotto +6409=Tolleranza fori +// SetUp Window +6451=SetUp +6452=Applica +6453=Salva +6454=Recupera +6455=Auto +6456=Applicare l'attrezzaggio corrente prima di uscire? +6457=Nuovo +// SetUp Errors +6471=Errore +6472=Avviso +6473=Impossibile trovare l'utensile +6474=nel DB utensili. +6475=La posizione predefinita dell'utensile non è valida. +6476=La posizione predefinita dell'utensile è già occupata. +6477=Il file di configurazione non esiste! +6478=L'attrezzaggio usa una testa che non esiste sulla macchina! +6479=Errore nel caricamento del setup +// Option Page +6501=Lingua corrente +6502=La nuova lingua diventerà corrente dal prossimo avvio del programma. +6503=Curve +6504=Superfici +6505=Curve e Superfici +6506=Geometria selezionabile +6507=Aggiungi la nuova lavorazione alla fine +6508=Usa script di disposizione +6509=Unità di misura +6510=Colore della vista in alto +6511=Colore della vista in basso +6512=Colore di default +6513=Tolleranza geometrica +6514=Generale +6515=CAD +6516=CAM +6517=Colore della griglia +6518=Superfici smussate +6519=Import +6520=DXF +6521=STL +6522=Immagini +6523=Export +6524=Immagine +6525=Larghezza (pixel) +6526=Altezza (pixel) +6527=Aggiorna Macchina +6528=La macchina "{0}" esiste già,
cosa vuoi fare ? +6529=Il file {0} non contiene una macchina. +6530=La macchina "{0}" è stata aggiornata con successo. +6531=Sostituisci +6532=Aggiorna +6533=Annulla +6534=Avviso +6535=L'aggiornamento della macchina "{0}" non è riuscito. +6536=Linee spesse +6537=Lunghezza extra del riferimento +6538=Lunghezza della freccia +6539=Distanza del testo +6540=Unità di misura +6541=Decimali +6542=Font +6543=Altezza del testo +6544=Quotatura +6545=Unità corrente +6546=Altra +6547=Unità di misura +6548=Fattore di scala +6549=Esporta Macchina Corrente +6550=Seleziona la cartella in cui si desidera esportare la Macchina +6551=L'esportazione della macchina "{0}" non è riuscita. +6552=La macchina "{0}" è stata esportata con successo. +6553=Aggiorna Licenza +// Heads +6601=Verticale +6602=Orizzontale +6603=Aggr. 2 uscite +6604=Aggr. 3 uscite +6605=Aggr. 4 uscite +6606=Testa 3 assi +6607=Testa 4 assi +6608=Testa 5 assi +6609=Navetta 1 +6610=Navetta 2 +6611=Multi rotante +6612=Gr. a forare +6613=Multi scalp. +6614=Rinvio sotto +6615=Lama 5 assi +6616=Sega a catena +6617=Aggr. 1 uscite +6618=Testa tastatura +6619=Flottante 360° +6620=Seconda Testa 5 assi +6621=Foratore orizzontale +6622=Mortasatrice +6623=Seconda Lama 5 assi +6624=Aggr. 1 uscita tilt. +6625=Estrusore +6799= +// StatusBar +6801=Direttorio Machines non trovato. EgtCAM5 funzionerà in modo solo CAD. +// Doors +8001=Crea nuova MTable +8002=Salva MTable +8003=Salva MTable Come +8004=Elimina MTable +8005=Salva file MTable +8006=Sei sicuro di voler cancellare questa MTable? +8007=Salva la MTable modificata? +8008=Lista delle macchine attive +8009=Nome della macchina +8010=Genera Cn +8011=Aggiorna grezzo +8012=On +8013=Nome Geometria +8014=Operazione +8015=MId +8016=Spost. +8017=Tipo Lavorazione +8018=Lavorazione 1 +8019=Lavorazione 2 +8020=Lavorazione 3 +8021=Aggiungi Macchina +8022=Elimina Macchina +8023=Aggiungi Lavorazione +8024=Elimina Lavorazione +8025=CORR +8026=Imposta MTable corrente +8027=GId +8028=Proprietà +8029=Lavorazione +8030=Unisci +// Door errors +8101=Errore +8102=Errore nell'esecuzione del file Ddf +8103=Avvertimento +8104=Path della cartella MTable non trovata +8105=La cartella MTable non esiste +8106=Mancano i file di configurazione nella cartella MTable +8107=Errore sconosciuto +8108=Questa è la MTable correntemente attiva. +8109=Non può essere cancellata. +8110=Sei sicuro di voler cancellare la lavorazione selezionata? +8111=CANCELLA +8112=Sei sicuro di voler cancellare la macchina selezionata? +8113=Impossibile trovare la cartella delle macchine {0}. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +8114=Provare a ricaricare la macchina? +8115=Impossibile trovare la cartella {0}. Se la cartella Doors è su un server, verificare che la connessione sia attiva. +8116=Provare a ricaricare la cartella Doors? +8117=Errore di esecuzione (guarda il file di log) +// GunStock +8201=Nuovo pezzo +8202=Gunstock Nuovo Pezzo +8203=Mod pezzo +8204=Gunstock Modifica Pezzo +8205=Parametri calcio +8206=Nome file +8207=Descrizione +8208=Ok +8209=Cancella +8210=deve avere un valore. +8211=Il valore deve essere compreso tra +8212=e +8213=Dimensioni del grezzo +// GunStock errors +8251=Errore +8252=Errore nel lancio dell'ambiente Gunstock +8253=Errore nella lettura del file Modello +8254=Errore nella scrittura del file Pezzo +// ----- Beams & Wall ----- +9000=Tabelle delle lavorazioni delle travi +9001=On +9002=Nome +9003=Tipo +9004=Aggiungi +9005=Elimina +9006=Salva +9007=Salvare le modifiche apportate? +9008=Errore +9009=Impossibile aprire l'Editor delle lavorazioni delle travi.
Mancano i file di configurazione. +9010=Tabelle delle lavorazioni delle pareti +9011=Impossibile aprire l'Editor delle lavorazioni delle pareti.
Mancano i file di configurazione. +// ----- Errori ----- +10001=Errore +10002=Errore nella creazione di un nuovo file +10003=Errore nell'apertura del file +10004=Errore nel salvataggio del file +10005=Tipo di file sconosciuto +10006=Errore nell'importazione del file +10007=Errore nell'esportazione del file +10008=Errore caricando o creando il Gruppo di Lavoro +10009=Non esiste il file +// Missing Key Window +10101=Errore ! +10102=Chiave non presente. +10103=Inserirla e riavviare il programma. +10104=Ok +10105=Programma senza licenza. +10106=Caricala e riavvia il programma. +10107=Esegui GetMachineId e invia i risultati al fornitore. +// Numeric virtual keyboard +10201=Espressione errata +// ----- MessageBox ----- +15001=Errore +15002=Avviso +15003=Informazione +15010=Errore interno (guarda log file) +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Espressione errata +// EgtCalculatorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Canc +20043=SI +20044=NO +// ----- EgtWPFLib5 ----- +// EgtSaveFileDialog +30001=Salva +30002=Annulla +30003=esiste già. +30004=Sostituirlo? +30005=Nome file: +30006=Apri +30007=ERRORE +30008=Il nome non può essere vuoto! +30009=ATTENZIONE +30010=Nome File +30011=Nome Cartella +// Top CommandBar +30501=Nuovo +30502=Apri +30503=Salva +30504=Salva come +30505=Inserisci +30506=Importa +30507=Esporta +30508=Esegui +30509=Opzioni +30510=Indirizzo mail di supporto non trovato. +30511=Salvare il progetto corrente prima di mandare il feedback? +30512=Mandare il feedback a {0} con allegata la cartella {1}. +30513=Feedback +30514=Mail di feedback pronta. +// Grid View Panel +30801=Wireframe +30802=Linee Nascoste +30803=Ombreggiatura +30804=Zoom All +30805=Zoom In +30806=Zoom Out +30807=Vista da Sopra +30808=Vista di Fronte +30809=Vista da Sinistra +30810=Vista da Dietro +30811=Vista da Destra +30812=Vista Isometrica da SW +30813=Vista Isometrica da SE +30814=Vista Isometrica da NE +30815=Vista Isometrica da NW +30816=Mostra Direzione Curve +30817=Analizza +30818=Distanza +30819=Griglia da Sopra +30820=Griglia di Fronte +30821=Griglia da Destra +30822=Griglia da Dietro +30823=Griglia da Sinistra +30824=Griglia da Sotto +30825=Griglia da Vista +30826=Elevazione Griglia +30827=Origine Griglia +30828=Ruota Griglia +30829=Griglia da 3 Punti +30830=Griglia Perpendicolare a Curva +30831=Griglia da Oggetto +30832=Vista da Griglia +// MachGroupPanel +30901=Nuovo gruppo di lavorazione +30902=Nome: +30903=Macchina: +// ToolDbWindow +31001=Punta +31002=Lama +31003=Fresa +31004=Mortasatrice +31005=Composito +31006=Punta lunga +31007=Lama piatta +31008=Fresa senza punta +31009=Scalpello +31010=Waterjet +31051=Correttore +31052=Uscita +31053=Tipo +31054=Refrigerante +31055=Raggio Corner +31056=Diametro +31057=Diametro Totale +31058=Avanzamento +31059=Avanzamento Finale +31060=Avanzamento Iniziale +31061=Avanzamento di Punta +31062=Lunghezza +31063=Lunghezza totale +31064=Massimo Materiale +31065=Offset Longitudinale +31066=Offset Radiale +31067=Rotazione +31068=Angolo di Lato +31069=Rotazione Massima +31070=Spessore +31071=Assorbimento Massimo +31072=Avanzamento Minimo +31073=Disegno +31074=Testa +31075=Nome +31076=Note +31077=Posiz. Cambio Utensile +31078=Posizione +31079=Foratura +31080=Tagliente +// ToolDb Errors +31100=Salvare l'utensile modificato ? +31101=SALVA +31102=Il file deve essere .nge +31103=Il file non esiste o non è di tipo Nge +31104=Non esiste il ToolMaker per questo tipo di utensile +31105=Impossibile creare l'utensile con questi parametri +31106=Il Massimo Materiale deve essere maggiore di 0 +31107=Il Massimo Materiale deve essere minore di Len +31108=Lo Spessore deve essere maggiore di 0 +31109=Il Diametro deve essere >= 0 +31110=La Lunghezza deve essere maggiore di 0 +31111=La Rotazione deve essere minore della Rotazione Massima +31112=Nome non valido +31113=La Lunghezza deve essere minore della Lunghezza Totale +31114=La Lunghezza deve essere maggiore del Massimo Materiale +31115=La Lunghezza Totale deve essere maggiore di 0 +31116=La Lunghezza Totale deve essere maggiore della Lunghezza +31117=Il Massimo Materiale deve essere minore di {0} +31118=Il Diametro deve essere minore del Diametro Totale +31119=Il Diametro deve essere maggiore di 8/3 del Massimo Materiale +31120=Il Diametro Totale deve essere maggiore di 0 +31121=Lunghezza troppo piccola con il portautensile +31122=Sei sicuro di voler cancellare l'utensile +31123=? +31124=CANCELLA +31125=File di configurazione attrezzaggio non trovato! +31126=Errore +31127=Impostare il tipo di testa. +31128=Impostare il tipo di uscita. +31129=Utensile non valido, correggerlo o cancellarlo prima di uscire dal Db Utensili. +31130=Impossibile ricaricare il database utensili. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +31131=Lo Spessore deve essere differente da 0 +31132=L'Angolo di Lato deve essere minore di 90° +31133=L'Angolo di Lato deve essere maggiore di -90° +31134=La Lunghezza Totale deve essere maggiore di Lunghezza + Spessore +31135=Raggio Corner ha un valore troppo grande +31136=Lo Spessore ha un valore troppo piccolo rispetto al Raggio Corner +31137=Il Diametro risultante supera il Diametro Totale +31138=Il Diametro risultante è minore di 0 +31139=Il Diametro stelo risultante è minore o uguale a 0 +31140=Il Massimo Materiale deve essere più grande del Raggio Corner +31141=Il Massimo Materiale risultante deve essere >= 0 +31142=Il Tagliente deve essere maggiore di 0 +31143=Il Tagliente deve essere minore di Len +// ImportExportToolWindow +31161=Importa +31162=Esporta +31163=Utensili +31164=L'utensile esiste già, sovrascriverlo? +31165=L'utensile verrà importato col nome seguito da "_imp" +31166=I seguenti Utensili sono stati importati correttamente: +31167=Reset +// MachiningDbWindow +31201=Foratura +31202=Taglio di lama +31203=Fresatura +31204=Svuotatura +31205=Mortasatura +31206=Sgrossatura con lama +31207=Finitura con lama +31208=Lav. generica +31209=Scalpellatura +31210=Waterjetting +31211=Finitura superfici +31251=Inverti +31252=Tab +31253=Tipo +31254=Lato di lavoro +31255=Lato della testa +31256=Attacco +31257=Collegamento +31258=Uscita +31259=Uso curve +31260=Tipo di Step +31261=Sottotipo +31262=Tipo approccio +31263=Rotazione +31264=Avanzamento +31265=Avanzamento iniziale +31266=Avanzamento finale +31267=Avanzamento di testa +31268=Offset radiale +31269=Offset longitudinale +31270=Affondamento +31271=Angolo di fianco +31272=Approssimazione +31273=Dist. di sicurezza +31274=Lungh. rallent. iniziale +31275=Lungh. rallent. finale +31276=Lungh. passante agg. +31277=Passo +31278=Posizione di ritorno +31279=Lunghezza +31280=Altezza +31281=Angolo +31282=Distanza +31283=Dist. tangente +31284=Dist. perp. +31285=Elevazione +31286=Lungh. correz. +31287=N° minimo +31288=N° massimo +31291=Lungh. addiz. +31293=Passo su esterno arco +31294=Passo su interno arco +31295=Passo di lato +31296=Feed verticale +31297=Nome +31298=Utensile +31299=Affondamento +31300=Note +31301=Sovrapposizione +31302=Offset +31303=Sottotipo +31304=SCC +31305=Nessuno +31306=Standard +31307=Opposto +31308=AuxDir Destra +31309=AuxDir Sinistra +31310=AuxDir Dietro +31311=AuxDir Davanti +31312=AuxDir Sopra +31313=AuxDir Sotto +31314=Più Vicino AuxDir +31315=Più Lontano AuxDir +31320=Centro +31321=Sinistra +31322=Destra +31323=Estendi +31324=Standard +31325=Interno +31326=Esterno +31327=Esteso centrato +31328=Esteso esterno +31329=Nessuno +31330=Lineare +31331=Tangente +31332=Inseguimento +31333=Elica +31334=Estendi precedente +31335=Estendi successivo +31336=Estendi entrambi +31337=Come attacco +31338=Salta +31339=Approssima +31340=Convesso +31341=Mantieni +31342=ZigZag +31343=Una via +31344=Spirale +31345=Va e torna +31346=Longitudinale +31347=Trasversale +31348=Spirale In +31349=Spirale Out +31350=Avanzati +31351=Inverti direz. utensile +31352=Lavorazione faccia +31353=Non definito +31354= Parallelo +31355= Ortogonale +31356= Ortog. Su +31357=Sotto +31358=Sopra +31359=Davanti +31360=Dietro +31361=Sinistra +31362=Destra +31363=Contorno +31364=Angoli Suggeriti +31365=Asse Bloccato +31366=Feed ultimo all'indietro +31367=Passo all'indietro +31368=Passo inclinato +31369=Passo all'indietro inclinato +31370=Inclinazione in avanti +31371=Tastatura +31372=Min dist. punti +31373=Max dist. punti +31374=Esterni +31375=Interni +31376=Lungh. rall. +31377=Rallentam. % +31378=Foro di attacco +31379=Raggio +31380=Num. giri in LP +31381=Num. giri in HP +31382=Oscillazione +31383=Ampiezza +31384=Lungh. rampa +31385=Lungh. cresta +31386=Generici +31387=Avanzati +31388=Tang+Perp +31389=Perp+Tang +// MachiningTreeView +31391=Normale +31392=Rallenta +31393=Anello +31394=Abilitazione +31395=Allunga +31396=Inizio +31397=Fine +31398=Note di sistema +31399=Raggio epicicli +31400=Distanza epicicli +// MachiningDb Errors +31401=Salvare la lavorazione modificata? +31402=SALVA +31403=Nome non valido +31404=I caratteri \ / : * ? " < > | non sono permessi +31405=Sei sicuro di voler cancellare +31406=? +31407=CANCELLA +31408=Impossibile ricaricare database lavorazioni. Se la cartella delle macchine è su un server, verificare che la connessione sia attiva. +31409=Materiale della macchina non riconosciuto +31410=Lavorazione non valida, correggerla o cancellarla prima di uscire. +31411=La Lunghezza deve essere positiva +31412=La Distanza deve essere positiva +31413=L'Altezza deve essere positiva +31414=L'Angolo deve essere compreso tra {0}° e {1}° +31415=N° massimo deve essere nullo o positivo +31416=N° massimo deve essere maggiore o uguale al minimo +31417=N° minimo deve essere nullo o positivo +31418=N° minimo deve essere minore o uguale al massimo +31419=L'abilitazione di {0} disabiliterà {1}. Procedere? +// ImportExportMachiningWindow +31450=Importa +31451=Esporta +31452=Lavorazioni +31453=La lavorazione esiste già, sovrascriverla? +31454=La lavorazione verrà importata col nome seguito da "_imp" +31455=Le seguenti Lavorazioni sono state importate correttamente: +31456=Reset +// SetUp Window +31501=SetUp +31502=Applica +31503=Archivia +31504=Recupera +31505=Auto +31506=Applicare l'attrezzaggio corrente prima di uscire? +// SetUp Errors +31551=Errore +31552=Avviso +31553=Impossibile trovare l'utensile +31554=nel DB utensili. +31555=La posizione predefinita dell'utensile non è valida. +31556=La posizione predefinita dell'utensile è già occupata. +31557=Il file di configurazione non esiste! +31558=L'attrezzaggio usa una testa che non esiste sulla macchina! +31559=Errore nel caricamento del setup +// Simulation +31601=Simulazione completata +31602=Extra corsa +31603=Direzione utensile irrangiungibile +31604=Errore +31605=ERRORE +31606=Errore in generazione! +31607=Simulazione +31608=Un passo alla volta +31609=Play/Pausa +31610=Stop/Home +31611=Pausa +31612=Simulazione interrotta +31613=Impossibile uscire ora. Prima fermare la simulazione o aspettarne la fine! +31614=ATTENZIONE +31615=File delle stime non trovato +31616=Stime dettagliate +//MachiningDbWindow/ToolDbWindow/WaterjetDbWindow buttons +31701=Nuovo +31702=Salva +31703=Rimuovi +31704=Modifica +//Db Waterjet +31751=Db Waterjet +31752=Spessore +31753=Q1 +31754=Q2 +31755=Q3 +31756=Q4 +31757=Q5 +31758=QExtra +31759=Salvare le modifiche? +// ----- EgtDOORCreator ----- +//General +50001=Larghezza +50002=Altezza +50003=Spessore +50004=???Swing +50005=Lato-serratura +50006=Lato-cerniera +50007=???Top +50008=Fondo +50009=Tipo +50010=Angolo +50011=???Extension +50012=Lato +50013=???Offset wide side +50014=Margine +50015=???Top to center application +50016=Traverso basso +50017=???Lock stile +50018=???Offset from center +50019=???Point to pocket +50020=???Pocket length +50021=???Pocket offset narrow side +50022=???Point to arm +50023=???Arm length +50024=???CenterHung +50025=Traslato +50026=Intermedio traslato +50027=Raggio +50028=Traverso alto +50029=Posizione +50030=Lunghezza +50031=Modello +50032=???Up +50033=???Down +50034=???Shape +50035=Cerniera +50036=???Top to top application +50037=???Center from top application +50038=???Center from top lock +50039=Profondità +50040=Generale +50041=Centro +50042=???Thru +50043=???Face to center line application +50044=Tipo di spigolo +50045=Sovramateriale +50046=Invia Feedback +50047=Peso +50048=???Angle +50049=???Face +50050=???Secure +50051=???Keyway +50052=???Brand +50053=???Folder +50054=???Main Folder +50055=???Jamb +50056=???Light Up +50057=???Light Lock +50058=???Light Bottom +50059=???Light Hinge +50060=???Thickness Head +50061=???Overlap Hinge +50062=???Overlap Lock +50063=???Overlap Top +50064=???Delta T +50065=???Exterior +50066=???Number of Doors +50067=???Jambs and Doors +50068=Ordine +50069=Disposizione +50070=Cliente +50071=Inverti profilo serratura +//Compo Name +50072=Catenacci +50073=Maniglia di superficie +50074=Cerniera +50075=Serratura +50076=Passaggio animali +50077=Buca delle lettere +50078=Ferramenta lato superiore +50079=Cerniera perno +50080=Fermo rullo +50081=???Stops And Closer +50082=Piastrina di battuta +50083=Maniglia incassata tirare +50084=Spioncino +50085=Sfinestratura +50086=Gole +50087=Ribassi +50088=???Ept +50089=???Raceway +50090=Decorazioni +//error messages +50100=Direttorio non trovato +50101=Errore +50102=Fallita lettura del file ddf. Manca un parametro fondamentale {0}. +50103=Fallita lettura valore. +50104=Fallita lettura nella riga del file ddf +50105=Riga +50106=Valore non accettabile in +50107=File vuoto. +50108=Impossibile aggiunegere la componente. Inserire una porta! +50109=Vuoi salvare questo file ({0}) ? +50110=Domanda +50111=Aggiungi nuova porta +50112=Rimuovi porta +50113=Nuova Porta +50114=Il nome del file già esiste nel direttorio corrente ({0}). +50115=Attenzione +50116=Vuoi cancellare questo file ({0}.ddf) ? +50117=Confermi la cancellazione ({0}.ddf) ? +50118=Informazione +50119=Errore nella lettura dei messaggi. Non esiste corrispondenza con il numero {0}. +50120=Errore nella lettura del nome {0} in {1}. Attesa una corrispondenza numerica. +50121=Errore nella lettura {0} nel parametro {1} della componente: non esiste. +50122=Errore nel parametro {0} della componente {1} della componente. +50123=Errore nella lettura {0} nel parametro {1} della componente: non esiste la lista. +50124=Errore nella lettura {0} nel parametro {1} della componente: {2}. +50125=Errore nel parametro {0} della componente {1} della componente: non esiste il valore. +50126=Elimina +50127=Errore in EgtLoadMessages +50128=Impossibile salvare un file se non esiste una porta! +50129=Errore nella creazione della scena. +50130=Errore nella lettura della riga {0}. +50131=Errore in lettura {0}: riga {1}. Atteso ':' dopo il nome. +50132=Errore in lettura {0}: riga {1}. Atteso 'template' o 'shape'. +50133={0} non è stato creato. +50134=Errore nella lettura di 'Template' nel file {0}\{1}. Atteso nome. +50135=Errore nella lettura di 'Template' nel file {0}\{1}. File {0}\{2} .lua non esiste. +50136=Errore nella lettura {0}: riga {1}. Non esite la componente nel file 'Default.ini'. +50137=Errore nella lettura {0}: riga {1}. Non è un memebro della lista. +50138=Questo parametro sarà inizializzato di default. +50139=Errore in lettura: riga {0}. Atteso {1}. +50140=Tutti i parametri mancanti saranno inizializzati di default. +50141=Espressione non valida in {0}. +50142=Rimuovi componente +50143=Espressione non valida +50144=Avvertenza +50145=Impossibile creare la porta corrente. +50146=Vuoi aprire un modello? +50147=Errore nell'espressione {0}. {1} non associa nulla. +50148=Valore non valido. +50149=Attenzione: il peso è selezionato nella pagine delle impostazioni. Vuoi disabilitarlo? +50150=Attenzione: il peso è un parametro del file .ddf. Vuoi aggiungerlo alle impostazioni? +50151={0} Non appartiene alla lista degli spigoli. Seleziona il Bevel nella pagina delle impostazioni. +50152=Vuoi salvare questo file ({0})? +50153=Attenzioni: il peso è un parametro della porta corrente. Vuoi rimuoverlo dalla porta? +50154=Questo bevel è selezionato nella porta corrente. Vuoi procedere? +50155=Impossibile creare un modello se non esite una porta! +50156=???Errore nella lettura ddf: la porta non è completa o il ddf è stato separato male da '---'. +50157=???Script Lua ( {0}\{1} )has not been found. +50158=???Bevel {0} can not be acceptable in Jamb. +50159=??? Missing parameter in ddf! +50160=Il file {0} nel direttorio {1} non esite. +50161=???parameter +50162=???In file {0} param 'Default' must be numeric. +50163=???Error in reading General Assembly in DDF +50164=???In General Assembly: +50165=???CompoDir not found : +50166=???Jamb compo does not exist +50167=???Empty Line +50168=???No matching param +50169=???Door disposition has been modify. +50170=???Incongruity between the bevel, it has been resolved by default. +50171=???In file StdTempate.ini is missing numeric param in [Type]. +50172=???File does not exist. +50173=???Definition type is not correct: +50174=???Missing name of the new template! +50175=???The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=???Error in copying: {0} +50177=???Do you want to save the current changes? +50179=Il file Default.ini non esiste nella cartella {0} . +50180=Attenzione : {0} non esiste. +50181=Errore nella stampa dell'immagine. +50182=Errore nell'esecuzione della stampa +50183=Alcune porte potrebbero usare questa ferramenta, confermi l'eliminazione? +50184=???Impossible to delete Hardware if there is no Hardware selected! +50185=???Impossible to duplicate Hardware if there is no Hardware selected! +50186=Il progetto deve essere salvato prima di essere copiato. +50187=Vuoi copiare tutti i files ? {0} (No: per copiare solo il file corrente) +50188=Esporta in macchina +50189=Direttorio macchina non trovato +50190=Errore durante la copia: {0} +50191=Non c'è alcuna porta, impossibile copiare +50192=Non c'è alcuna porta, impossibile esportare verso la macchina +50193=Non c'è alcuna porta, impossibile stampare +50194=Le proprietà sono state cancellate +50195=La configurazione del ddf corrente ({0}) è differente dalla configurazione del programma ({1}).{2}Per caricare la configurazione del ddf corrente devi rilanciare il programma, vuoi farlo? +50196=La configurazione del ddf ({0}) non esiste! +50197=Porta ad arco modificata perchè la configurazioe non la pravede. +50198=Il profilo sul lato serratura dovrebbe essere invertito. +//Option +50200=Unità di misura +50201=Generale +50202=???LockEdgeOverMaterial +50203=???HingeEdgeOverMaterial +50204=???TopOverMaterial +50205=???BottomOverMaterial +50206=Apri finestra +50207=Ultimo progetto +50208=Vuoto +50209=Pagina delle opzioni +50210=Avvio programma +50211=Unità di misura nuova porta. +50212=???Directory Project +50213=Impostazione di avvio +50214=???Current Directory +50215=???Edge Type +50216=???Over Material +50217=???Browse +50218=Chiudi +50219=???Bevel +50220=???Bevel Up +50221=???Bevel Down +50222=Posizionamento porta in lavorazione. +50223=Salva come modello +50224=Associazione +50225=Marca +50226=Modello +50227=???Template +50228=???Enable template +50229=???Enable Order +50230=???Open template door. +50231=???Open window order. +50232=Direttorio modelli +//Scene +50301=Aggiorna +50302=Aggiungi Nuova Porta +50303=Rimuovi Porta +50304=Nuovo Progetto +50305=???Help +50306=Direttorio Macchina +50307=Macchina +50308=Anta +50309=???Wide Side Down (BU) +50310=???Wide Side Up (BD) +50311=???Resize +50312=???Design +50313=Salva come pdf +//Launcher +50400=???Launcher +50401=Apri Nuovo Progetto +50402=Apri Progetto +50403=Apri Ultimo Progetto +50404=Nuovo Progetto +50405=Nuova Ferramenta +50406=???Elevation +50407=???Project +50408=???PO +50409=???Line +50410=Salva +50411=Stampa +50412=Annulla +50413=Ferramenta +50414=???Dimensioning +50415=Duplica +50416=Esporta in macchina +50417=???New Template +50418=???Dimension +50419=Nuovo Direttorio +50420=Ricalcola posizione Hardware +50421=Aggiorna +50422=Salva come +50423=Ricarica componente +//Error (continue) +50501=Errore nella lettura del parametro {0 nel componente {1} : definizione incompleta (controlla StdTemplate.ini). +50502=Errore nella lettura del parametro {0 nel componente {1} : nessuna associazione (controlla StdTemplate.ini e GeometryNameList.ini). +50503=Vuoi salvare? +50504=Il nome del file contiene spazi vuoti agli estremi, vuoi eliminarli ? +50505=Il DDF non è un assemblato, le parti resenti sono: {0}, vuoi salvare? +50506=Impossibile trovare la prima anta! +50507=???The swing is not a member of the swing list of single door. +50508=???The swing of left door is not a member of the swing list of left door. +50509=???The swing of right door is not a member of the swing list of right door. +50510=???The swing of left door is on the right door and viceverse. +50511=???The swing of left door is not a member of the swing list of left door. +50512=???The swing of right door is not a member of the swing list of right door. +50513=???Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=???The swing are absolutly wrong! +50515=???The first door is not realy the first, check the ddf. +50516=???The current ddf contains {0} jambs. +50517=???The current ddf does not contains doors! +50518=???The current ddf is not an assembly. +50519=???Impossible to open a ddf with no doors. +50520=???The current ddf is an assembly. +50521=Il ddf corrente è un pezzo del telaio: {0}. +50522=???The profile {0} is not a member of the {1} profile list. +50523=Manca il profile sul lato {0}. +50524={0} file aperto da un altro EgtDOORCreator {1}. +50525={0} file in lettura da un altro EgtDOORCreator {1}. +50526=Il direttorio {0} già esiste! Vuoi sovrascriverlo? +50527=Impossibile sovrascrivere {0} +50528=Impossibile salvare il file fuori dal progetto corrente! +50530=La proprietà {0} non esiste nella lista {1}. Verificare nel file "../Compo/Default.ini". +50531=Il materiale corrente {0} non esiste nella lista dei materiali. Verificare nel file "../Compo/Default.ini". +50532=Lista dei materiali non trovata "../Compo/Default.ini". +50533=Impossible caricare più di una proprietà alla volta. +50534=La proprietà {0} non esiste. Verificre nel file "../Compo/Default.ini". +50535=Impossibile eliminare u progetto se non è selezionato! +50536=Vuoi eliminare il progetto? (Tutte le porte saranno eliminate!) +50537=Vuoi eliminare il sottodirettorio {0} ? (Tutte le porte saranno eliminate!) +50538=Impossibile creare un modello senza avere un porta in lettura! +50539=Vuoi cambiare progetto? +50540=???The current ddf is a part of a frame, do you want to save? +50541=???{0} in reading {1}. +50542=???{0}: Directory does not exist! +50543=Il file è stato rinominato: {0} {1}. +50544=Nuovo file: {0} {1}. +50545=Il file è stato eliminato: {0} {1}. +50546=Abilita porta singola +50547=Progetto +50548=La nuova configurazione sarà attiva dal prossimo riavvio. +50549=Il file {0} esiste, ma non è nel direttorio corretto! +50550=Ogni compenente verrà ricalcolata, vuoi continuare? +50551=Questo parametro è stato modificato: +50552=Vuoi sovrascireve? +50553= non è stato creato. +50554=Il parametro {0} è già stato definito nella geometria {1} +50555=Impossibile salvare. +50556=Il file ha estensione nge. +50557=Errore in fase di cancellazione file: {0} +50558=Impossibile importare una ferramenta differente. +50559=Apertura file +50560=La ferramenta non è stata generata correttamente. +50561=Il direttorio è già esistente. +50562=Il direttorio {0} non esiste. Verificare nella pagina delle impostazioni. +50563=La componente non esiste. +50564=Nel gruppo {0} al parametro {1} non esiste: {2} +50565=il brand {0} non è stato trovato. +50566=il modello {0} non è stato trovato. +50567=Errore nell'avvio del programma EgtCam5. +50568=Errore nella definizione di {0} nel file GeometryNameList.ini . +50569=Errore nella definizione di {0} in file StdTemplate.ini . +50570=Nessun elemento selezionato +//Added General messages +50701=Linee +50702=Rettangoli +50703=Nessuna +50704=Raggio +50705=Angolo +50706=Pos_x +50707=Top ad Arco +50708=Top ad Angolo +50709=Proprietà +50710=Materiali +50711=???Mach. +50712=???HardwarePart +50713=Assemblato +50714=Dimensioni totali +50715=Profondità +50716=Sovrapposizione fondo +50717=Spessore fondo +50718=Profondità fondo +50719=Delta fondo +50720=VaiAssemblato +50721=Nuova geometria +50722=Nome geometria +50723=Tipo di ferramenta +50724=Parametro +50725=Dimensione parte +50726=Applica +50727=Telaio +50728=Aggiorna direttori +50729=???General +50730=???Report +50731=Faccia opposta +// ----- EgtBEAMEditor ------ +60951=Taglio +60952=Taglio Longitudinale +60953=Doppio Taglio +60954=Cantonale o Conversa +60955=Taglio con lama +60956=Scanalatura +60957=Scanalatura frontale +60958=Tacca +60959=Tacca cantonale +60960=Mezzolegno di colmo +60961=Mezzolegno +60962=Scanalatura o Battuta +60963=Mezzolegno chalet +60964=Rivestimento +60965=Mezzolegno colmo francese +60966=Smusso +60967=Mezzolegno chalet +60968=Mezzolegno chalet frontale +60969=Tasca +60970=Foratura +60971=Tenone +60972=Mortasa +60973=Mortasa frontale +60974=Avanzamento +60975=Abbassamento +60976=Tenone a coda di rondine +60977=Mortasa a coda di rondine +60978=Mortasa frontale a coda di rondine +60979=Marcatura +60980=Testo +60981=Giunto Gerber +60982=Giunto a dardo di giove +60983=Incastro dietro +60984=Incastro semplice +60985=Piallatura +60986=Profilo di testa +60987=Profilo concavo +60988=Profilo convesso +60989=Profilo caudato +60990=Arco +60991=Testa sagomata +60992=Sfera +60993=Taglio a triangolo +60994=Incastro tirolese +60995=Incastro a coda di rondine +60996=Contorno libero +60997=Contorno +60998=Apertura +61001=Distanza dall'inizio della trave al punto di riferimento +61002=Distanza dal bordo di riferimento al punto di riferimento +61003=Distanza dal lato di riferimento al punto di riferimento (ortogonale) +61004=Angolo tra il bordo di taglio e il bordo di riferimento +61005=Inclinazione tra faccia e lato di riferimento +61008=Limite dei 2 estremi, codice binario +61009=Inclinazione rispetto al lato di riferimento +61010=Profondità +61011=Lunghezza +61012=Angolo in faccia all'inizio +61013=Angolo in faccia all'estremità +61015=Distanza dal punto di riferimento al bordo di riferimento +61016=Angolo tra il primo tagliente e il bordo di riferimento +61017=Inclinazione del primo taglio verso il lato di riferimento +61018=Angolo tra il secondo tagliente e il bordo di riferimento +61019=Inclinazione del secondo taglio verso il lato di riferimento +61023=Inclinazione tra la prima faccia e il lato di riferimento +61024=Inclinazione tra la seconda faccia e il lato di riferimento +61025=Profondità +61027=Angolo in faccia al bordo di riferimento all'inizio +61028=Angolo in faccia al bordo di riferimento all'estremità +61029=Angolo in faccia opposto al bordo di riferimento all'inizio +61030=Angolo in faccia opposto al bordo di riferimento all'estremità +61033=Spostamento sul lato di riferimento +61036=Angolo rispetto al bordo di riferimento nella faccia di taglio +61037=Profondità, ortogonale al lato di riferimento +61038=Lunghezza +61041=Distanza dal punto di riferimento ortogonale al lato di riferimento +61042=Limite delle 6 facce della fessura, codice binario +61043=Angolo rispetto al bordo di riferimento nel lato di riferimento +61045=Angolo interno al punto di riferimento +61046=Angolo interno opposto al punto di riferimento +61047=Aggiunta a P09 +61048=Profondità ortogonale al lato di riferimento +61049=Lunghezza +61050=Spessore +61051=Spostamento del bordo di ingresso nel punto di riferimento +61052=Spostamento del bordo di ingresso in corrispondenza del punto di riferimento +61055=Distanza dal punto di riferimento ortogonale al lato di riferimento +61056=Limite delle 6 facce della fessura frontale, codice binario +61059=Angolo tra l'asse longitudinale dell'asola e il lato di riferimento +61060=Profondità +61061=Lunghezza +61062=Larghezza +61065=Posizione di P09 / P10 +61066=P05 = 1: foro, P05 = 0: nessun foro +61067=Angolo rispetto al bordo di riferimento nell'area di riferimento +61068=Inclinazione tra faccia 1 e lato di riferimento +61069=Inclinazione tra faccia 2 e lato di riferimento +61070=Primo angolo di taglio della controparte +61071=Inclinazione primo taglio della controparte +61072=Profondità 1 ortogonale al lato di riferimento +61073=Profondità 2 ortogonale al lato di riferimento +61074=Profondità di scanalatura nella direzione trasversale del componente +61075=Altezza controparte +61076=Larghezza controparte +61079=P05 = 1: foro, P05 = 0: nessun foro +61080=Tacca angolo 1 rispetto al bordo di riferimento nell'area di riferimento +61081=Tacca angolo 2 rispetto al bordo di riferimento opposto nell'area di riferimento +61082=Inclinazione tra l'area di base delle tacche e il lato di riferimento +61083=Profondità ortogonale al lato di riferimento +61084=Larghezza della tacca 1 +61085=Larghezza della tacca 2 +61087=0: punto di riferimento sul bordo di riferimento. 1: punto di riferimento sul bordo opposto +61088=Angolo rispetto al bordo di riferimento nel lato di riferimento +61089=Profondità della tasca +61090=Larghezza della tasca +61091=Diametro del foro +61094=Spostamento rispetto al lato di riferimento +61095=Limite delle 6 facce dell tasca, codice binario +61096=Angolo rispetto al bordo di riferimento nel lato di riferimento +61098=Angolo tra bordo e lato di riferimento in faccia +61099=Angolo nella superficie del pavimento +61100=Angolo tra la faccia di base e una faccia della tasca +61101=Distanza (ortogonale) dal lato di riferimento al punto sotto il punto di riferimento +61102=Lunghezza +61103=Angolo di smusso +61104=Profondità di scanalatura +61107=Limite delle 6 facce della tacca / battuta, codice binario +61108=Profondità tacca / battuta +61109=Lunghezza tacca / battuta +61110=Larghezza tacca / battuta +61113=Profondità della tasca sul lato di riferimento +61114=Profondità della tasca opposta al lato di riferimento +61115=Lunghezza del mezzo legno / Dado +61117=Profondità di taglio +61118=Lunghezza del taglio +61120=0: punto di riferimento sul riferimento bordo; 1: punto di riferimento sul bordo opposto +61121=Angolo rispetto al bordo di riferimento nel lato di riferimento +61122=Diametro del foro +61124=Ingresso bordo (i) da smussare, codice binario: Bit 0 = bordo 1; Bit 1 = fronte 2; Bit 2 = bordo 3; Bit 3 = fronte 4. Esempio: P04 = 9: fronte 1 + 4; P04 = 3: bordo 1 + 2 +61125=Profondità +61126=Lunghezza +61127=Forma per uscita smusso: 0 = ortogonale, 1 = a 45 gradi, 2 = rotondo +61129=Profondità ortogonale al lato di riferimento della tasca 2 e 4 +61130=0: tutti i giri sono simmetrici tra loro; 1: sovrapposizione sul bordo di riferimento spostato alla trave iniziale, sovrapposizione in opposizione al bordo di riferimento spostata alla trave finale; 2: sovrapposizione sul bordo di riferimento spostata alla trave finale, sovrapposizione in opposizione al bordo di riferimento spostata alla trave iniziale; +61131=P05 = 1: foro, P05 = 0: nessun foro +61132=Tasca 1: profondità +61133=Tasca 1: lunghezza +61134=Tasca 2: profondità +61135=Tasca 2: lunghezza +61136=Tasca 3: Profondità +61137=Tasca 3: lunghezza +61138=Tasca 4: profondità +61139=Tasca 4: lunghezza +61140=Distanza dalla fine dell'arco ortogonale al lato di riferimento +61141=Raggio dell'arco +61142=Distanza dal punto di riferimento al centro dell'arco +61143=Quale arco (A, B, C o D) deve essere prodotto, codice binario +61145=0: un solo giro sul lato di riferimento; 1: un giro sul lato di riferimento e uno sul lato opposto +61146=Angolo rispetto al bordo di riferimento nel lato di riferimento +61147=Profondità al punto di riferimento +61148=Profondità opposta al punto di riferimento +61149=Profondità al bordo di riferimento +61150=Lunghezza +61153=Limite delle 6 facce della tasca, codice binario +61154=Angolo di rotazione attorno all'asse z locale del parallelepipedo +61155=Angolo di rotazione attorno all'asse y locale del parallelepipedo, ruotato con P06 +61156=Angolo di rotazione attorno all'asse x locale del parallelepipedo, ruotato con P06 e P07 +61157=Angolo interno nel punto di riferimento +61158=Profondità del punto di riferimento ortogonale al lato di riferimento +61159=Lunghezza del mezzo legno +61160=Larghezza del mezzo legno +61163=Distanza dalla faccia di riferimento al punto di riferimento +61164=P03 = 0: angolo rispetto al bordo di riferimento nel lato di riferimento +61165=Inclinazione tra foratura e lato di riferimento +61166=Profondità ortogonale al lato di riferimento o al lato anteriore. +61167=Diametro del foro +61170=Arrotondamento +61171=Smusso +61174=Angolo tra l'asse del tenone e il lato di riferimento +61175=Raggio per P04 = 4 +61176=Altezza tenone +61177=Larghezza tenone +61178=Margine sul lato di riferimento +61179=Margine opposto al lato di riferimento +61182=Spostamento rispetto al lato di riferimento +61183=Arrotondamento +61184=Angolo tra l'asse e il bordo di riferimento +61185=Inclinazione tra puntone e lato di riferimento +61186=Inclinazione delle pareti laterali del foro verso il lato di riferimento +61187=Raggio per P04 = 4 +61188=Profondità mortasa +61189=Larghezza mortasa +61190=Altezza del montante +61191=Margine sul punto di riferimento +61192=Margine opposto al punto di riferimento +61193=Inclinazione del lato anteriore del foro verso il lato di riferimento +61196=Arrotondamento +61199=Angolo tra l'asse del tenone e il lato di riferimento +61200=Raggio per P04 = 4 +61201=Profondità mortasa +61202=Larghezza mortasa +61203=Margine sul lato di riferimento +61204=Margine opposto al lato di riferimento +61205=Processident del tenone associato o del tenone a coda di rondine +61206=Processident della mortasa associata o mortasa a coda di rondine +61209=0: con arrotondamento in basso; 1: senza arrotondamento, illimitato +61210=Angolo tra bordo e bordo di riferimento +61212=Angolo tra l'asse del tenone e il lato di riferimento +61213=Appiattimento centrale +61214=Angolo del cono +61215=Altezza tenone +61216=Diametro della curva +61217=Margine sul lato di riferimento +61218=Margine opposto al lato di riferimento +61221=Spostamento rispetto al lato di riferimento +61222=0: con arrotondamento in basso; 1: senza arrotondamento, illimitato +61223=0: con allungamento; 1: con tasca +61224=Angolo tra l'asse e il bordo di riferimento +61225=Inclinazione tra puntone e lato di riferimento +61226=Appiattimento centrale +61227=Angolo del cono +61228=Profondità mortasa +61229=Diametro della curva +61230=Altezza del montante +61231=Margine sul punto di riferimento +61232=Margine opposto al punto di riferimento +61235=Spostamento sul lato anteriore +61236=0 = con arrotondamento in basso; 1 = senza arrotondamenti, illimitato +61237=0 = con allungamento; 1 = con tasca +61240=Angolo tra l'asse del tenone e il lato di riferimento +61241=Appiattimento centrale +61242=Angolo del cono +61243=Profondità mortasa +61244=Diametro della curva. Se P12 <0, il raggio deve essere definito sul lato macchina. +61245=Margine sul lato di riferimento +61246=Margine opposto al lato di riferimento +61249=Posizione e allineamento del testo +61250=Angolo tra l'asse e il bordo di riferimento +61251=Angolo interno +61252=Larghezza del quadrilatero +61253=Altezza del quadrilatero +61254=Altezza del testo +61255=Testo (stringa max.256 caratteri) +61258=Angolo tra l'asse e il bordo di riferimento +61259=Allineamento verticale. 0 = in basso, 1 = al centro, 2 = in alto +61260=Allineamento orizzontale. 0 = sinistra, 1 = centro, 2 = destra +61261=Allineamento in caso di testo su più righe. 0 = allineato a sinistra, 1 = centrato, 2 = allineato a destra. +61262=Lettere standard o orizzontali. 0 = standard, 1 = lettere posizionate orizzontalmente +61263=Altezza del testo. Se P13 è uguale a zero, la macchina determina l'altezza del testo. +61266=Profondità sul lato di riferimento +61267=Profondità opposta al lato di riferimento +61268=Lunghezza della sovrapposizione +61269=Foratura 1 diametro. P15 = 0: questa foratura è posta a 1/2 P13. P15> 0: questa foratura è posta a 1/3 P13 +61270=Foratura 2 diametri. Posizionato a 2/3 P13 +61272=Angolo di inclinazione della base della sciarpa lappata +61273=Forma o identificazione classica dell' incastro +61274=Lunghezza della base della sciarpa lappata +61275=Profondità della base della sciarpa lappata +61276=Profondità della base della sciarpa lappata ortogonale al lato di riferimento +61277=Lunghezza +61278=Foratura 1 diametro. P15 = 0: questa foratura è posta a 1/2 P13. P15> 0: questa foratura è posta a 1/3 P13 +61279=Foratura 2 diametri. Posizionato a 2/3 P13 +61281=Tipo di tacca del tallone: ​​0 = normale; 1 = rastremato +61282=Puntone inclinato +61283=Giunzione gradino di profondità +61284=Profondità del tallone +61285=Altezza tenone. Quale implementazione (A o B) viene utilizzata dipende dalla macchina +61286=Larghezza tenone +61289=Tipo di tacca del tallone: ​​0 = normale; 1 = rastremato +61290=Inclinazione tra puntone e lato di riferimento +61291=Larghezza della tacca +61292=Giunzione gradino di profondità +61293=Profondità del tallone +61294=Altezza del montante +61295=Profondità di mortasa. Quale implementazione (A o B) viene utilizzata dipende dalla macchina +61296=Larghezza della mortasa +61298=Specifica dei lati da piallare; codice binario +61299=Profondità di piallatura +61300=Lunghezza dell'area da piallare +61303=Angolo di rotazione della prima curva del profilo +61304=Angolo di rotazione del profilo verso il bordo di riferimento +61305=Angolo di offset +61306=Raggio della prima curva +61307=Raggio della seconda curva +61309=Raggio +61310=Profondità +61311=Spostamento +61312=Profondità +61313=Spostamento +61315=Raggio +61316=Profondità +61317=Spostamento +61318=Profondità +61319=Spostamento +61321=Lunghezza profilo +61322=Profondità nel punto di riferimento +61323=Profondità massima del profilo +61324=Profondità minima del profilo +61325=Profondità all'estremità del profilo +61326=Premill: 0 = rotondo; 1 = angolare +61328=Profondità del segmento dell'arco +61329=Lunghezza del segmento dell'arco +61331=Tipo di arco (convesso, concavo), codificato binario. Vedere la tabella di seguito. +61332=Lunghezza della tasca 1 +61333=Profondità della tasca 1 +61334=Arco di spostamento 1 +61335=Arco di lunghezza orizzontale 1 +61336=Lunghezza arco verticale 1 +61337=Arco di campanatura 2 +61338=Lunghezza della tasca 2 +61339=Profondità della tasca 2 +61340=Arco di spostamento 2 +61341=Arco di lunghezza orizzontale 2 +61342=Lunghezza arco verticale 2 +61343=Arco di campanatura 2 +61344=Lunghezza della tasca 3 +61345=Profondità della tasca 3 +61348=Distanza dal lato di riferimento al punto di riferimento +61349=Raggio +61350=Offset iniziale +61351=Lunghezza +61354=Distanza dal lato di riferimento al punto di riferimento +61355=Vettore normale 1: lunghezza della componente X +61356=Vettore normale 1: lunghezza della componente Y +61357=Vettore normale 1: lunghezza della componente Z +61358=Vettore normale 2: lunghezza della componente X +61359=Vettore normale 2: lunghezza della componente Y +61360=Vettore normale 2: lunghezza della componente Z +61362=Distanza tra "dentro" un lato del pezzo +61363=Distanza ortogonale al lato di riferimento +61364=0: "dentro" al bordo di riferimento, 1: "dentro" al bordo di riferimento +61365=0: senza ribasso o obliquo, -1: con taglio obliquo,> 0: con ribasso +61366=Angolo rispetto al bordo di riferimento nel lato di riferimento +61367=Larghezza +61368=Profondità +61369=Inclinazione +61370=Altezza +61371=Raggio +61372=Lunghezza dell'utensile (parte dell'arco) +61373=0: giunto angolare angolare, 1: raccordo diritto a T a parete +61374=Lunghezza +61375=0:Entrambi i lati, 1:lato di riferimento, 2:lato opposto +61377=Distanza tra "dentro" un lato del pezzo +61378=Distanza ortogonale al lato di riferimento +61379=0: "interno" al bordo di riferimento, 1: "interno" all'opposto del bordo di riferimento +61380=0: senza ribasso o taglio obliquo, -1: con taglio obliquo,> 0: con ribasso +61381=Inclinazione +61382=Profondità 1 +61383=Profondità 2 +61384=0: coda di rondine europea, 1: coda di rondine americana +61385=Lunghezza +61386=0:Entrambi i lati, 1:lato di riferimento, 2:lato opposto +61387=Profondità +61388=Modalità: 0 = solo contorno, 1 = svasatura completa. Solo per contorni chiusi. +61389=Tipo di contorno +61390=Il parametro dipende dal tipo di profilo (P13) +61391=Il parametro dipende dal tipo di profilo (P13) +61400=Punto di riferimento sul bordo di riferimento +61401=Punto di riferimento sul bordo opposto +61402=Punto di riferimento sul bordo di riferimento +61403=Punto di riferimento sul bordo opposto +61404=ortogonale +61405=a 45 gradi +61406=rotondo +61407=tutti i giri sono simmetrici tra loro +61408=Tasca sul bordo di riferimento spostato alla trave finale. Tasca opposto al bordo di riferimento spostato per iniziare il raggio +61409=Tasca sul bordo di riferimento spostato per iniziare il raggio. Tasca opposto al bordo di riferimento spostato alla trave finale +61410=una sola tasca sul lato di riferimento +61411=Una tasca sul lato di riferimento e uno sul lato opposto +61412=con arrotondamento in basso +61413=senza arrotondamenti, illimitato +61414=con allungamento +61415=con tasca +61416=fondo +61417=centro +61418=in alto +61419=sinistra +61420=destra +61421=allineato a sinistra +61422=centrato +61423=allineato a destra +61424=standard +61425=lettere posizionate orizzontalmente +61426=durante il taglio ortogonale al lato di riferimento +61427=quando si taglia ortogonalmente al lato base +61428=definizione classica, P10 e P12 non vengono utilizzati +61429=normale +61430=rastremato +61431=rotondo +61432=angolare +61433="interno" al bordo di riferimento +61434="dentro" all'opposto del bordo di riferimento +61435=Giunto angolare angolare +61436=Raccordo diritto a T a parete +61437=Lavorazione sul lato di riferimento e opposto al lato di riferimento +61438=Elaborazione solo sul lato di riferimento +61439=Elaborazione solo di fronte al lato di riferimento +61440=coda di rondine europea +61441=coda di rondine americana +// ---Custom Parameter (Q) +61451=Profondità smusso +61452=0=Automatico;1=Ciclo longitudinale con lama +61453=Spessore testimone centrale per ciclo Q02 +61454=0=Attacco centrato 1=Attacco interno +61455=0=Automatico 1=Lavorazione con fresa di lato +61456=1=Forza Lama 0=Automatico +61457=1=Solo smusso +61458=0=Automatico; 1=Massima profondità +61459=0=Automatico; 1=Truciolatore; 2=Truciolatore di lato; 3=Fresa; 4=Fresa di lato +61460=0=Automatico; 1=Esegui perimetro con fresa diametro minore; 2=Pulitura solo su angoli +61461=0=Automatico; 1=Massimo raggio ammesso su tasche non passanti +61462=Diametro utensile per Q05 +61463=Diametro utensile per Q07 +61464=0=Raggio su spigolo; 1=Foro su spigolo; 2=Spigolo vivo +61465=Diametro foro quando P05=1 +61466=0=Automatico; 1=Sgrossatura con lama +61467=Antischeggia : 0=No; 1=Con lama; 2=Con fresa +61468=Aumenta dimensioni tasca +61469=Pulisci spigoli: 0=No; 1=Con fresa conica dopo rimozione manuale sfridi; 2=Con fresa conica piccola;3=Con gola di scarico +61470=0=Automatico; 1=Solo contorno ; 2=Svuota +61471=0=Automatico; 1=Lavoro da un lato solo +61472=Incrementare/decrementare valore P01 per fori nei tenoni +61473=0=Foratura rompi truciolo; 1=Foratura scarico truciolo +61474=Profondità smusso quando P05=1 +61475=Riduzione profondità tenone +61476=Riduzione larghezza tenone +61477=Riduzione altezza tenone +61478=Riduzione profondità tenone +61479=Ridurre/Allargare sagoma tenone +61480=Ridurre/Allargare altezza tenone +61481=aumenta profondità mortasa +61483=Profondità di lavoro +61484=Aumenta dimensioni P10 +61485=0=Automatico; 1=Truciolatore +61486=Riduzione lunghezza P14 +61487=Riduzione larghezza P15 +61488=Sovramateriale finitura +61489=Numero divisioni ondulazioni dello smusso sulla lunghezza +61490=1=Disabilita fresatura gradini +61491=1=Attiva smusso superiore +61492=1=Smusso superiore con lama +61493=Spessore legno per supporto lavorazione +61494=Attiva antischeggia +61495=Profondità antischeggia +61496=Massima elevazione (0=Automatico, >10=Manuale) +61497=0=Automatico; 1=Lama +61498=0=Automatico; 1=Disabilita controllo lunghezza fresa +61499=0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61500=0=Automatico 1=Lama lungo faccia 2=Lama su fianchi e sotto 3=Lama su facce non passanti 4=Lama su fianchi e sotto su facce non passanti +61501=0=Automatico 1=Lavorazione con fresa orizzontale se sopra o sotto (disabilita lama) +61502=0=Automatico 1=Usa truciolatore se sotto +61503=0=Attacco e uscita centrati 1=Attacco e uscita interni +61504=0=Automatico; 1=Esegui con lato fresa tipo lama; 2=Esegui con lato fresa tipo lama ma limita uso su facce sopra +61505=0=Automatico; 1=Lavora come Taglio Longitudinale +61506=0=Automatico 1=Lavorazione con fresa +// ----- EgtBEAMWALL - BTLParam ----- +61601=SN +61602=Abilita +61603=Descrizione +61604=L +61605=W +61606=H +61607=Materiale +61608=Richiesti +61609=In produzione +61610=Prodotti +61611=Ruotare +61612=Gruppo +61613=Unit Time +61614=Parametro +61615=Valore +61616=Minimo +61617=Massimo +61618=Numero pezzo +61619=Ordine Assemblaggio +61620=Numero Ordine +61621=Designazione +61622=Annotazione +61623=Sottogruppo +61624=Gruppo +61625=Package +61626=Materiale +61627=Qualità del legno +61628=Grado di qualità +61629=Quantità +61630=Colore +61631=Trasparenza +61632=Lunghezza di piallatura +61633=Start offset +61634=End offset +61635=Transformazione: Origine +61636=Transformazione: Asse X +61637=Transformazione: Asse Y +61638=Camber: Lato di riferimento +61639=Camber: P01,P02,P03,P04 +61640=Part offset: Lato rif. pinza +61641=Part offset: P11,P12,P13,P14 +61642=Qualità di lavorazione +61643=Recesso +61644=Tipo di piano +61645=Numero Elemento +61646=Layer +61647=Numero modulo +61648=USERATTRIBUTE +61649=Comment +61650=Direzione fibre: X, Y, Z +61651=Direzione fibre: allineate +61652=Lato di riferimento +61653=Lato di riferimento: Allineato +61654=Allineamento: posizione +61655=Allineamento: finale +61656=Tipo di materiale: Gruppo +61657=Tipo di materiale: Specifica +61658=AUTOMATICO +61659=VISIBILE +61660=VELOCE +61661=MANUALE +61662=SOFFITTO +61663=TETTO +61664=PARETE +61665=inattivo +61666=BR +61667=TR +61668=BA +61669=TA +61670=HC +61671=VC +61672=AC +61673=R +61674=A +61675=D +61676=Perline +61677=Rivestimento +61678=Legno massiccio +61679=Membrana +61680=Cartongesso +61681=Fibra di gesso +61682=Isolamento +61683=Componente foglio +61684=Pannello per facciate +61685=Pannello profilato +61686=Intonaco +61687=Lato di riferimento 1 +61688=Lato di riferimento 2 +61689=Lato di riferimento 3 +61690=Lato di riferimento 4 +61691=UID +61692=Numero del progetto +61693=Nome del progetto +61694=Parte del progetto +61695=GUID +61696=Nome elenco +61697=Cliente +61698=Architetto +61699=Nome del disegnatore +61700=Data di consegna +61701=Data di esportazione +61702=Ora di esportazione +61703=Versione di esportazione +61704=Lingua +61705=Intervallo +61706=Nome computer +61707=Nome utente +61708=Percorso e nome del file CAD +61709=Percorso e nome del file BTL +61710=STANDARD +61711=ESTESO +61712=Vol unit +61713=Vol tot +61714=Tempo unit +61715=Tempo tot +61716=Numero totale pezzi +61717=Volume totale +61718=Tempo totale +61719=Tempo totale stimato +61720=Tempo rimanente +61721=Numero di grezzi +61722=Numero di pezzi da BTL +61723=Numero di pezzi aggiunti +61724=Numero di pezzi inseriti nei grezzi +61725=Numero di pezzi completati +61726=Quantita' +61727=Stampa PDF +//Warehouse +61751=Current S +61752=Current L +61753=StartOffset +61754=Kerf +61755=Offset +61756=Parametri S +61757=Parametri L +61758=Nuovo valore: +61759=W +61760=L +61761=Conferma +61762=Salva +61763=Annulla +61764=Errore +61765=Il valore immesso è gia presente +61766=Il valore immesso non è corretto +61767=La coppia di valori immessi è gia presente +61768=Uno o più valori immessi non sono corretti +61769=Attenzione +61770=Il parametro selezionato corrisponde al parametro corrente. Sei sicuro di volerlo rimuovere? +61771=SectionXMaterial +61772=Alias +61773=Valori +61774=Quantità +61775=Spessore minimo +61776=Spessore massimo +61777=Aumentare lo Spessore massimo dell'ultimo intervallo prima di aggiungerne un altro +// +61801=Custom +61802=Default +61803=L +61804=T +61805=Processo +61806=Tempo sezione +61807=Tempo pezzo +61808=Nome +61809=PDN +61810= +61811=Posizione X +61812=Posizione Y +61813=Aggiunti +61814=Lavorati +61815=ID +61816=Ritaglio iniziale +61817=% utilizzo +61818=Scarto +61819=Nome file BTL +61820=Nome lista +61821=Data esportazione +61822=Data creazione +61823=Elimina +61824=Faccia +61825=Gruppo +61826=Modifica +61827=Salva +61828=Annulla +61829=Nesting +61830=Visualizzatore +61831=Ottimizzatore +61832=Configurazione +61833=Ottimizza +61834=Aggiorna BTL +61835=Vai a ottimizzazione +61836=Tipo filtro +61837=Cerca +61838=Esporta progetto +61839=Importa progetto +61840=Importa BTL +61841=Copia su Clipboard +61842=DisplayIndex +61843=Nome colonna +61844=CanUserReorder +61845=CanUserResize +61846=CanUserSort +61847=IsReadOnly +61848=Visible +61849=Path Variabile +61850=Tipo +// +61851=La modifica di questo parametro comporta la rimozione del pezzo da {0} grezzi. Procedere comunque? +61852=Impossibile creare una feature con questi valori +61853=Impossibile creare un pezzo con questi valori +61854=Impossibile creare una barra con questi valori +61855=Impossibile creare una parete con questi valori +61856=Valore non compreso tra minimo e massimo +61857=Impossibile inserire una quantita' inferiore al numero di pezzi gia' inseriti nei grezzi! +61858=Impossibile modificare questi valori +61859=Errore nella scrittura di un parametro Macchina +61860=Salvare le modifiche apportate ai parametri Macchina? +61861=Salvare le modifiche apportate ai valori di default? +61862=Passando ad un altro tipo verra' eliminato il secondo percorso. Procedere? +61863=Raggiunto numero di pezzi da produrre: +61864= da BTL; +61865= aggiunti. Aggiungerne un altro? +61866=Il pezzo selezionato ha sezione diversa dalla barra selezionata. Impossibile aggiungerlo. +61867=Il pezzo selezionato supera la lunghezza dalla barra selezionata. Impossibile aggiungerlo. +61868=Il pezzo selezionato ha spessore diverso dalla parete selezionata. Impossibile aggiungerlo. +61869=Errore nell'esecuzione del file Macro! +61870=Impossibile creare una Macro senza selezionare una Feature o col Nome vuoto +61871=File non trovato! +61872=Impossibile cancellare il progetto correntemente aperto +61873=Impossibile cancellare il progetto perche' gia' collegato ad una produzione +61874=Impossibile cancellare il progetto perche' alcuni grezzi sono gia' stati mandati in produzione +61875=Salvare le modifiche apportate al progetto? +61876=Impossibile creare un nuovo file! +61877=Salvare progetto modificato prima di continuare? +61878=Impossibile procedere con un nuovo progetto non salvato! +61879=La macchina corrente è di tipo sia Beam che Wall. Scegli il tipo a cui settare il progetto: +61880=Selezionare macchina e/o tipo tra i disponibili. Altrimenti annullare l'importazione del progetto. +61881=Il tipo del progetto aperto non è compatibile col tipo della macchina corrente +61882=Salvare le modifiche apportate alle colonne delle DataGrid? +61883=La colonna "{0}" della tabella "{1}" specificata nel file ini delle colonne delle datagrid non è stata trovata nel programma +61884=Selezionare la macchina che si desidera associare al progetto: +61885=La macchina associata al progetto in apertura non è presente tra quelle disponibili +61886=Macchina +61887=Impossibile creare il numero di grezzi specificato +61888=Quante copie del grezzo realizzare? +61889=Area punte lunghe +61890=Punteggio minimo +61891=Non è possibile inviare feedback dall'Ottimizzatore se non c'è alcun Prod aperto +// +61900=Cambio parametro +61901=Verifica +61902=Simula +61903=Nuovo grezzo +61904=Aggiungi al grezzo +61905=Copia pezzo +61906=Aggiungi pezzo +61907=Rimuovi pezzo +61908=Copia feature +61909=Crea macro +61910=Aggiungi feature +61911=Rimuovi feature +61912=Produrre grezzo +61913=Produrre tutti i grezzi +61914=Copia grezzo +61915=Rimuovi grezzo +61916=Riordina pezzi +61917=Muovi su pezzo +61918=Muovi giu pezzo +61919=Rimuovi pezzo +61920=Magazzino +61921=Aggiungi progetto a ottimizzazione +61922=Vai a progetto +61923=Statistiche +61924=Reset +61925=Mostra tutti i pezzi +61926=Mostra solido +61927=Mostra assemblato +61928=Verifica tutti +61929=Non è possibile cambiare macchina poichè il Proj è già associato ad un Prod +61930=Ingressi +61931=Uscite +61932=Calcola Flip e Rotazione +61933=Sblocca Flip +61934=Sblocca Rotazione +61935=Lunghezza +61936=Larghezza +61937=Offset +61938=Kerf +61939=Modifica +61940=Reset +61941=Scegli macchina +61942=File BTL gia' importato ed ottimizzato. Importarlo di nuovo? +61943=File BTL gia' importato. Sovrascriverlo? +61944=Muovi pezzi +61945=Direzione spostamento +61946=Lunghezza spostamento +61947=Non è possibile muovere i pezzi fuori dal grezzo +61948=Il valore inserito per lo spostamento non è valido +61949=Filtri di ricerca +61950=Tipo Parametro +61951=Valore Prametro +61952=R +61953=A +61954=I +61955=P +61956=Tutti +61957=Filtrati +61958=Aggiorna +61959=Accoda +61960=Checkare i pezzi che si desidera aggiungere per aggiornare il BTL +61961=Cambio materiale +61962=Materiale progetto +61963=Materiale magazzino +61964=Standard +61965=Da BTL +61966=Salva +61967=Non Salvare +61968=In attesa di salvataggio in optimizer +61969=Annulla +// +62500=Supervisore +62501=Canale +62502=Modo operativo +62503=Produci Tutti +62504=Pannello Lavorato +62505=Reset Pannello +62506=Elimina Pannello +62507=Stampa etichetta +62508=Pezzo fatto +62509=Riprendere lavorazione barra iniziata? +// Loading +63000=Apertura progetto +63001=Caricamento geometrie del progetto +63002=Caricamento gruppi di lavorazione +63003=Caricamento dati di produzione +63004=Apertura ottimizzazione +63005=Caricamento pezzi +63006=Caricameno grafica +63007=Salvataggio progetto +63008=Importazione file BTL +63009=Lettura file BTL +63010=Esportazione progetto +63011=Caricamento ambiente +63012=Salvataggio geometrie +63013=Salvataggio dati su Db +63014=Modifica parametri +63015=Apertura visualizzatore +63016=Aggiungendo informazioni di esportazione +63017=Esportando... +63018=Importazione progetto +63019=Caricamento progetto +63020=Creando progetto importato +63021=Modifica materiali +// ----- FromLua ----- +65001= +// ----- OmagCUT ----- +// General +90001=IN LAVORO +90002=TAGLI DIRETTI +90003=TAGLI CAD +90004=CORNICI +90005=MACCHINA +90006=OPZIONI +// WorkInProgress +90101= +// DirectCut +90201=Movimento manuale +90202=Taglio singolo +90203=Taglio multiplo +90204=Taglio griglia +90205=MTH +90206=Spianatura +90207=Test lama +90208=Tasta lama +90209=Copia dima +90210=Acquisisci P1 +90211=Acquisisci P2 +90212=Laser +90213=Affondamento +90214=Lunghezza +90215=Direzione +90216=Inclinazione +90217=Numero +90218=Dimensioni +90219=Numero X +90220=Dimensioni X +90221=Numero Y +90222=Dimensioni Y +90223=Tagli lato motore +90224=Lama +90225=Disegno +90226=Larghezza +90227=Sovrapposizione +90228=Offset +90229=Blocca Asse C +90230=Esegui +90231=Lucidatura +90232=Spessore lama +90241=Tastatura lama +90242=Tastatura in corso... +90243=Tastatura completata con successo +90244=Errore in tastatura lama +90245=Nuovo nome della dima +90246=Tastatura interrotta dall'utente +90250=Linea +90251=Arco +90252=Rimuovi +90253=Chiudi +90254=Salva +90255=Test +90256=Verifica posizione taglio +90257=Verifica posizione in corso... +90258=Foro singolo +// CadCut +90301=Simula +90302=Esegui +90303=Nuovo +90304=Carica +90305=Salva +90306=Salva come +90307=Nuovo nome del progetto +90308=CSV +90309=Vein Match +90310=Esporta +90311=Utensile +90312=Lavorazione +90313=Fotografia non riuscita +90314=Errore nella generazione del programma CN +90315=Errore nella trasmissione del programma CN +90316=Non connesso alla macchina +90317=Programma CN trasmesso +90318=La macchina non accetta il programma CN +90319=Programma già trasmesso, vuoi ritrasmetterlo ? +90320=Macchina diversa +90321=Ridotte alcune lavorazioni per evitare interferenze +90322=Mancano gli utensili : +90323=Fotografia di sfondo eseguita +90324=Riconoscimento contorno non riuscito +90325=Errore nel salvataggio delle statistiche +90326=Confermi ripartenza dalla fase {0} ? +90327=Inseriti Nuovi Pezzi Rovinati +90328=Area Pezzi : +90329=Da Produrre : +90330=Programma già trasmesso, è una nuova lastra ? +// NestPage +90331=Inserisci pezzo +90332=Parcheggia pezzo +90333=Elimina pezzo +90334=Seleziona tutto +90335=Deseleziona tutto +90336=Reset +90337=Uno o più pezzi con spessore, materiale o finitura non compatibili +90338=Rotazione oltre i limiti +90339=Rotazione impossibile +90340=Nesting Automatico in corso +// SplitPage +90341=On/Off +90342=Tutti On +90343=Tutti Off +90344=Allunga/Accorc +90345=Inizio All/Acc +90346=Fine All/Acc +90347=Inizio Centro/Fuori +90348=Inizi Tutti Fuori +90349=Inizi Tutti Centro +90350=Calcolo automatico non riuscito +90351=Lama troppo grande per utilizzo ventosa +90352=Fine Centro/Fuori +90353=Fine Tutti Fuori +90354=Fine Tutti Centro +90355=Tutti Allunga +90356=Tutti Accorc. +90357=Modif. +90358=Auto +90359=Restart +// MoveRawPart +90361=Rimuovi +90362=Pezzo troppo piccolo : non si può muovere +90363=Posizione scelta già occupata +90364=Pezzo troppo pesante: non si può muovere +90365=Pezzo oltre le corse: non si può muovere +// SplitPage 2 +90371=Pausa On/Off +90372=Pausa +90373=Inizio Modif. +90374=Fine Modif. +90375=Allungamento +90376=Inverti +// DrawPage +90381=Numero pezzi +90382=Misure +90383=Inclina lati +90384=Indica Lato Sopra +90385=Disegno Parametrico +90386=Selezionare un contorno +90387=Non ci sono lati modificabili +90388=Nome +90389=Dati Trf +90390=Codice ordine +90391=Descrizione ordine +90392=Codice materiale +90393=Codice superficie +90394=Spessore +90395=Selezionare uno o più fori +90396=Codice pezzo +90397=Incidi +90398=Dati Csv +90399=Aggiornate tutte le lavorazioni +90400=Filo Top +// Component +// Massimo 30 caratteri senza immagine e massimo 20 con l'immagine +90401=Triangolo +90402=Rettangolo +90403=Trapezio +90404=Quadrilatero +90405=Piedoca +90406=Soglia +90407=Piano Cucina +90408=Piano Bagno +90409=Altri +90410=Triangolo2L +90411=Triangolo3L +90412=Isoscele +90413=Rettangolo +90414=Scaleno +90415=Scaleno +90416=4Lati 1Ang +90417=3Lati 2Ang +90418=3Lati 2Diag +90419=4Lati 1Diag +90420=4Lati 3Diag +90421=4Lati 3Ang +90422=4Lati 3Ang +90423=Angolo Retto +90424=Angolo Retto Smussato +90425=Angolo Allineato +90426=Angolo All. Smussato +90427=Parte A +90428=Parte B +90429=Angolo +90430=Angolo Smussato +90431=Ellisse +90432=Ovale +90433=Arco +90434=Arco LHF +90435=Arco LLH +90436=Arco LLF +90437=Rettangolo smussato +90438=Bombato +90439=Foro +90440=2 Fori +90441=3 Fori +90442=Arco RHa +90443=Poligono +90444=Foro da sotto +90445=Dxf +90446=Ribasso +90447=Componenti interni +90448=Aggiungi +90449=Rimuovi +90450=Conferma +// Import +90451=Usa layer +90452=Usa regioni +90453=Reset +90454=mm +90455=inch +90456=Usa curve chiuse +90457=Inclina lati +90458=Incidi da sotto +90459=Angolo +90460=Offset +90461=Affondamento +90462=Accorciamento +90463=Importa DXF +90464=Fora da sotto +90465=Quantità +90466=Offset2 +90467=Ordine +90468=Distinta +90469=Nome +// Component 2 +90470=Incisioni Ribasso +90471=Incisioni +90472=TriangoloCH +90473=TriangoloRT +90474=TrapezioRtA +90475=3Lati 2Ang +90476=Soglia smusso +// FastGrid +90480=Nome ordine +90481=N° Lastra +90482=Ultima lastra +90483=Tipo pezzo +90484=Inserisci pezzi +90485=Conferma ordine +// Open +90491=Progetto non valido +90492=Progetto con interferenze. Per caricarlo disabilita rispetto tagli completi. +// RawPart +90499=Grezzo non definito +90500=Rotazione +90501=Rettangolo +90502=Per punti +90503=Lunghezza +90504=Larghezza +90505=Spessore +90506=Offset X +90507=Offset Y +90508=Kerf +90509=Materiale +90510=Zona rovinata +90511=Nuovo +90512=Cancella +90513=Punti +90514=Aggiungi +90515=Cancella +90516=Massima lunghezza = +90517=Massima larghezza = +90518=Non sono ammessi spessori negativi +90519=Minimo offset X = +90520=Minimo offset Y = +90521=Minimo kerf = +90522=Massimo kerf = +90523=Tasta grezzo +90524=Conferma +90525=Tastatura grezzo +90526=Tastatura in corso... +90527=Tastatura completata con successo +90528=Errore nella tastatura del grezzo +90529=Dal disegno +90530=Dal laser +90531=Chiudi +90532=Errore nell'acquisizione del punto +90533=Contorno +90534=Lama troppo grande per tastatura +90535=Da fotografia +// ChooseMachining +90536=Scegliere la lavorazione di lama +90537=Scegliere la lavorazione secondaria +90538=Scegliere la foratura +90539=Scegliere la fresatura +90540=Nessuna +90541=Foratura +90542=Fresatura +90543=Entrambe +90544=Scelta lavorazioni correnti +90545=Scegliere il waterjet +90546=Taglio waterjet +90547=Errore nella posizione o dimensione del grezzo +90548=Massimo offset X = +90549=Massimo offset Y = +90550=Scegliere la svuotatura +// Simulation +90551=Simulazione completata +90552=Extracorsa +90553=Direzione utensile irraggiungibile +90554=Errore +90555=ERRORE +90556=Errore in generazione! +90557=Simulazione +90558=Un passo alla volta +90559=Play/Pausa +90560=Stop/Home +90561=Pausa +90562=Simulazione interrotta +90563=Vista macchina +90564=Home +90565=Tempo +90566=Lunghezza +90567=Area pezzi +90568=Utilizzo +90569=Stime +90570=Dettagli +// FrameCut +90601=Lungo X +90602=Lungo Y +90603=Rimuovi +90604=Sgrossatura +90605=Finitura +90606=Spatolatura +90607=Specchia +90608=Distanza sopra +90609=Distanza inizio +90610=Accorcia inizio +90611=Accorcia fine +90612=Taglio singolo +90613=Arco +90614=Guida +90615=Sezione +90616=Guida +90617=Rad +90618=Ang +90619=Errore : raggio più piccolo della larghezza della sezione +90620=Errore : creazione della cornice non riuscita +90621=Distanza X +90622=Distanza Y +90623=Lato Opposto +// Machine +90701=Msg_Ita.xpi +90705=Dati macchina +90706=DB utensili +90707=DB lavorazioni +90708=Macchina +90709=Statistiche +90715=Nuovo +90716=Nuova +90717=Salva +90718=Elimina +//ToolsDb +//param +90719=Lunghezza portautensili +90720=Anima +90721=Nome +90722=Posizione +90723=Testa +90724=Uscita +90725=Rotazione +90726=Normale +90727=Massima +90728=Feed +90729=Avanzamento +90730=Testa +90731=Ingresso +90732=Uscita +90733=Acqua +90734=Correttore +90735=Sovramateriale +90736=Longitudinale +90737=Radiale +90738=Max assorb. +90739=Feed minima +90740=Max affond. +90741=Lunghezza +90742=Diametro +90743=Spessore +90744=Tagliente +90745=Note +90746=Numero di Serie +90747=Codice +90748=Fornitore +90749=Fine Servizio +//tools families +90751=Lama +90752=Foretto +90753=Fresa +90754=Mola da scasso +90755=Waterjet +90756=Mola lucidante +//Tool Setup +90759=Posizione utensile predefinita già occupata +//MachiningsDb +//param +90761=Nome +90762=Affondamento +90763=Angolo sbandamento +90764=Inverti +90765=Tipo di step +90766=Lato di lavoro +90767=Lato testa +90768=Posizione inizio +90769=Attacco +90770=Collegamento +90771=Uscita +90772=Utilizza curve +90773=Tolleranza +90774=Passo di affondamento +90775=Normale +90776=Passo di affondamento +90777=Interno archi +90778=Esterno archi +90779=Lunghezza del rallentamento +90780=Iniziale +90781=Finale +90782=Affondamento agg. +90783=Posizione di ritorno +90784=Utensile +90785=Spessore minimo +90786=Spessore massimo +90787=Passo +90788=In affondo +90789=Di lato +90790=In verticale +//machinings families +90791=Taglio +90792=Foratura +90793=Fresatura +90794=Sgrossatura con lama +90795=Finitura con lama +90796=Svuotatura +90797=Waterjet +//ComboBox Param +90801=No +90802=Interna +90803=Esterna +90804=Entrambe +90821=Centro +90822=Sinistra +90823=Destra +90824=Centrato +90825=Interno +90826=Esterno +90827=Esteso centrato +90828=Esteso esterno +90829=Esteso precedente +90830=Esteso successivo +90831=Estesi entrambi +90832=Centrata +90833=Interna +90834=Esterna +90835=Salta +90836=Approssima +90837=Convesso +90838=Zig Zag +90839=Una via +90840=Va e vieni +90841=Lavora +90842=Nessuno +90843=Normale +90844=Rallenta +90845=Anello +90846=Lineare +90847=Tangente +90848=Inseguimento +90849=Elica +90850=Come attacco +// param2 +90861=Spatolatura +90862=Inclinato +90863=Incl. ritorno +90864=Andata +90865=Ritorno +90866=Ultimo ritorno +90867=Inclinazione in avanti +90868=Tastatura +90869=Min dist. punti +90870=Max dist. punti +90871=Esterni +90872=Interni +90873=Lungh. rall. +90874=Rallentam. % +90875=Foro di attacco +90876=Raggio +90877=Num. giri in LP +90878=Num. giri in HP +90879=Abilitazione +90880=Angoli +// Barcode +90881=Codice a barre +90882=Blocco +90883=Numero +90884=Dati lastra +// param3 +90890=Dist. tang. +90891=Dist. perp. +90892=Dist. tang. +90893=Dist. perp. +90894=Attacco ceramica +90895=Lunghezza +90896=Passo +90897=Ultimo taglio +90898=Tagli inclinati +// Alarms +90900=Waterjet corrente +90901=Lama corrente +90902=Utensile ausiliario +90903=Foretto corrente +90904=Fresa corrente +90905=Z sicura +90906=Sicurezza tagli +90907=Sicur. angoli +90908=Rispetta i tagli completi +90909=Offset fori +90910=Sovrapp. fori +90911=Tolleranza fori +90912=Lista errori CN +90913=Materiali +90914=Aggiungi +90915=Rimuovi +90916=Utensili correnti +90917=Parametri fori +90918=Rmin archi est. +90919=Parametri macchina +90920=Nessuno +90921=Foretto +90922=Fresa +90923=Entrambi +90924=Amax archi int. +90925=Parametri lama +90926=Un solo foro in angolo +90927=Tagli diretti +90928=Home finale +90929=Parametri fresature +90930=Sempre sugli interni +90931=Nesting +90932=Allineato +90933=Attrezzaggio +90934=Nuovo +90935=Elimina +90936=Altezza sovratavola +90937=Contorno da Foto +90938=Sfondo +90939=Soglia +90940=Tolleranza +90941=Lavaggio +90942=Confermi la cancellazione del materiale selezionato? +90943=Setup di default +90944=Sempre sugli angoli +90945=Selezionare l'utensile da tastare +90946=Tagli Feed inizio/fine +90947=Lunghezza +90948=Riduzione % +90949=Accorciamento +90950=Tastatura +// Machine +90951=Start +90952=Stop +90953=Reset +90954=Auto +90955=Single +90956=MDI +90957=Manual +90958=Home +90959=Download +90960=Upload +90961=Activate +90962=Delete +90963=MDI Confirm +90964=Modalità CN +90965=Comandi macchina +90966=Stringa MDI +90967=Trasferimento part program +90968=Vuoi cambiare tavola? +// Options +90981=Lingua +90982=La nuova lingua diventerà corrente dal prossimo avvio del programma. +90983=Unità di misura +90984=Rotazione vista +90985=Angolo inclinato +90986=Un solo valore +90987=Più valori +90988=Inserimento diretto dei pezzi +90989=Parametrici e DXF +90990=CSV +90991=Fast grid +90992=Abilita la creazione di pezzi standard +90993=Colore testo +90994=Slab Dxf +90995=Layer Lastra +90996=Layer Pezzi +90997=Layer Scarti +90998=Spessore std +90999=Inclinazione da Colore +91000=Abilita +91001=Tolleranza +91002=Tallone +91003=Inclinazione +91004=Feedback +91005=Temi +91006=Incisioni da colore +91007=Affondamento +91008=Larghezza +91009=Avvio programma +91010=Seleziona modalità di avvio +91011=Progetti recenti +91012=Ultima apertura +91013=Ultimo progetto +91014=Nuovo progetto +91015=Apri cartella +91016=Mostra finestra +//Alarms2 +91051=Lavorazioni +91052=Taglio lama +91053=Foratura +91054=Fresatura +91055=DripSawing +91056=DripDrilling +91057=WaterJet +91058=Parametri waterjet +91059=Automatico +91060=Allineato e Ghigliottina +91061=Parametri incisioni +91062=Con fresa +91063=Profondità +91064=Larghezza +91065=Pretaglio uscite +91066=Ghigliottina +91067=Inserisci pausa +91068=Cornici +91069=Svuotatura +91070=Scasso corrente +//Statistics +91071=Produzione del giorno +91072=Produzione della settimana +91073=Progetto +91074=Area Pezzi +91075=Area Tagli +91076=Giorno +91077=Settimana +91078=Reset +91079=Area da Tagliare +//Lucidature +91089=Offset +91090=DB Lucidature +91091=Lucidature +91092=Movimento +91093=Ripetizioni +91094=Attacco/Uscita +91095=Altezza +91096=Lista utensili +91097=Lunghezza +91098=Su +91099=Giù +91100=Precarico +//EgtMsgBox +91101=Salvare il progetto corrente? +91102=Salvare l'utensile corrente? +91103=Salvare la lavorazione corrente? +91104=Nome già utilizzato +91105=Ci sono interferenze, alcuni pezzi saranno parcheggiati. Vuoi continuare? +91106=Esiste già un file con questo nome. Sovrascriverlo? +91107=CONNESSIONE AL CN +91108=Connessione in corso... +91109=Connessione non riuscita +91110=Connessione riuscita +91111=Tavola da usare ? +91112=Vuoi cancellare anche i pezzi provenienti da lista Csv ? +91113=Pezzi non rimossi perché liberi +91114= o di altre liste Csv +91115=Errore +91116=Opzione Linea di produzione non abilitata +91117=Errore in copia file per OmagVIEW +91118=Conservo i pezzi in parcheggio ? +91119=Errore nella gestione dei pezzi rovinati +91120=I caratteri \ / : * ? " < > | non sono permessi +91121=Sei sicuro di voler cancellare i pezzi selezionati? +91122=Avvertimento +91123=Tavola +91124=Salvare la lucidatura corrente? +91125=Salvare le modifiche correnti? +91126=Esporta +91127=Importa +91128=DB WaterJet +91129=Origine da laser +91130=Esegui programma? +// CSV +91201=Apri +91202=Inserisci +91203=Nuovo +91204=Rimuovi +91205=Errore nel salvataggio del file CSV, vuoi continuare lo stesso ? +91206=Errore nella lettura del file CSV +// OmagVIEW +91301=Tutti Validi +91302=Pezzo Valido +91303=Pezzo Rovinato +91304=Stampa Etichetta +91305=Conferma +91306=Stampa +// OmagOFFICE +// OptionPanel +91401=Grezzo +91402=Disponi +91403=Lavora +91404=Simula +// MachiningDbWindow +91451=Materiale +91452=Spessore minimo +91453=Spessore massimo +// TopCommandBar +91501=E' necessario salvare il progetto prima di esportarlo +91502=Seleziona il direttorio di esportazione +91503=Errore nell'esportazione +91504=Esportazione completata con successo +91505=Esporta in macchina +91506=Esporta DXF +// Rawpart +91551=Errore nel caricamento della fotografia +91552=Importa fotografia +// VeinMatching +91601=Esporta +91602=Mostra Info +91603=Modifica +91604=Verifica +91605=Magnetico +91606=Pezzo non selezionabile in questa situazione +91607=Pezzo non selezionabile perchè appartenente a gruppo di lavoro non corrente : +91608=Ingombro dei pezzi DXF troppo grande per VeinMatching +// Generic +91651=Ok +91652=Annulla +91653=A° +91654=T +91655=Inizio +91656=Fine +// ----- OmagPHOTO ----- +// General +92001=Db non trovato! +92002=Impossiblie avviare il programma +// OptionPanel +92051=Salva +92052=Aggiungi +92053=Annulla +92054=Elimina +92055=Sei sicuro di voler cancellare la lastra corrente? +92056=Etichetta +92057=Etichetta Freccia +92058=Sfoglia +92059=Stampa +92060=Seleziona +// Slab +92071=Id +92072=Nome immagine +92073=Stato +92074=Progetto assegnato +92075=Posizione in magazzino +92076=Data +92101=Nome già utilizzato +92102=Il nome è obbligatorio +92103=L'immagine è obbligatoria +// SearchPanel +92151=Cerca +92152=Tolleranza spessore +92153=Data d'inizio +92154=Data di fine +92155=Reset +//Messaggi +92200=Modifiche in sospeso: procedere al salvataggio e alla stampa? +92201=Avviso +92202=Stai prelevando una lastra assegnata al progetto: {0}Vuoi procedere?" +92203=Stai assegnado una lastra senza progetto: {0}Vuoi procedere? +92204=Stai liberando una lastra con progetto: {0}Vuoi procedere? +// ----- SarmaxWall ----- +// General +101001=Importa BTL +101002=Disegna +101003=Posiziona +101004=Opzioni +// ImportPage +101101 +// DrawPage +101201=Parete +101202=Porta +101203=Finestra +101204=Aggiungi +101205=Annulla +101206=Applica +101207=Elimina +101208=Distanziale +// PlacePage +101301=Genera +101302=Trasmetti +101303=Posizionamento parete +101304=Inserisci +101305=Parcheggia +101306=Elimina +101307=Spessore strati +101308=Numero tavole in cima +101309=Inserimento non riuscito +101310=Generazione riuscita +101311=Errore in generazione +101312=Lancio trasmissione riuscito +101313=Errore in lancio trasmissione +101314=Trasmissione completata con successo +101315=Trasmissione non riuscita +101316=Ponti tutti disabilitati +101317=File di Generazione mancante +// OptionsPage +101401=Opzioni macchina +101402=Caratteristiche incollaggio +101403=Extra grezzo in X +101404=Extra grezzo in Y +101405=Extra colla +101406=Caratteristiche tavole +101407=Larghezza tavola +101408=N° tavole in un piano +101409=Attivazione ponti +101410=Ponte colla +101411=Ponte tavole +101421=Opzioni software +101422=Selezione lingua +101423=La nuova lingua diventerà corrente dal prossimo avvio del programma +101424=Numero progetti da salvare +101425=Posiziona tavole su porte e finestre +101426=Anticipo apertura colla +101427=Anticipo chiusura colla +// OpenPage +101501=Progetto non valido +// ----- End ----- diff --git a/ProgramData/EgtCAM5/Config/EgalTechTur.txt b/ProgramData/EgtCAM5/Config/EgalTechTur.txt new file mode 100644 index 0000000..72271b3 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgalTechTur.txt @@ -0,0 +1,2255 @@ +// Message File EgalTech Turkish 2019/12/07 +0=TUR +// File +1=File +3=New +5=Open +6=Open
Recent files (Shift) +7=Insert +9=Save +11=Save as +13=Import +15=Export +17=Exec +19=Recent Files +20=Recent Scripts +// View +101=View +103=WFrame +105=HLine +107=Shading +109=ZoomAll +111=ZoomIn +113=ZoomOut +115=Top +117=Front +119=Right +121=Back +123=Left +125=Bottom +127=Iso SW +129=Iso SE +131=Iso NE +133=Iso NW +135=Grid +136=SetView perpendicular to current Grid +137=CurveDir +139=Analyze +141=GetDist +// Grid +201=Grid +203=Top +205=Front +207=Right +209=Back +211=Left +213=Bottom +215=View +216=Set Grid perpendicular to View +217=Elevat +218=Set Grid Elevation +219=Origin +220=Set Grid Origin +221=Rotate +222=Rotate Grid
3D Rotate Grid (Shift) +223=3 Points +224=Set Grid from 3 Points +225=Perp +226=Set Grid Perpendicular to Object +227=Object +228=Set Grid from Object +// Draw +301=Draw +303=Point +304=Point
Vector (Shift)
Frame (Ctrl) +305=Line 2P +306=Line : 2 Points
Line : 2 Points with Continue (Ctrl) +307=LineSDL +308=Line : Start, Direction, Length
Line : Start, Direction Vector, Length (Shift) +309=Circle +310=Circle : Center, Point
Circle : Center, Diameter (Shift) +311=Fillet +312=Fillet : Radius
Chamfer : Dist (Shift) +313=Arc CSE +314=Arc : Center, Start, End +315=Arc 3P +316=Arc : 3 Points +317=Arc SDE +318=Arc : Start, Direction, End
Arc : Start, Direction Vector, End (Shift)
Arc : Start, Direction, End with Continue (Ctrl) +319=Rect 2P +320=RectAci : 2 Points +321=Polygon +322=Polygon : Radius or Apothem
Polygon : Kenar with 2 Points (Shift) +323=Text +324=Text
Advanced Text (Shift) +399=Continue : 'L' with line, 'A' with arc +// Construct +401=Construct +403=Plane +404=Surface : between planar curves
Flat Region (Shift) +405=Extrude +406=Surface : curve extrusion +407=Revolve +408=Surface : curve revolution +409=Screw +410=Surface : curve screwing +411=Ruled +412=Surface : ruled between 2 curves +413=Merge +414=Merge Surfaces +415=Flip +416=Flip Surface OutKenar +417=Explode +418=Explode Surfaces or Flat Regions +419=Swept +420=Surface :sweeping a curve along another +// Edit +501=Edit +503=Delete +504=Delete Objects +505=Layer +506=ChAcie Object Layer to Current +507=Color +508=ChAcie Color
Remove Color (Shift)
ChAcie Trasparency (Ctrl) +509=Invert +510=Invert Curve +511=Trim/Ext +512=Trim or Extend Curve +513=Break +514=Break Curve
Split Curve in Pieces (Shift) +515=Join +516=Join Curves
Join Curves making a Copy (Shift) +517=Explode +518=Explode Text or Curve in Components +519=Thick +520=Set Curve Thickness and Extrusion +521=Start +522=ChAcie Closed Curve Start Point +// Transform +601=Transform +603=Move +604=Object Move +605=Rotate +606=Object Rotate
3D Object Rotate (Shift) +607=Mirror +608=Object Mirror
3D Object Mirror (Shift) +609=Scale +610=Object Scale
3D Object Scale (Shift) +611=Offset +612=Curve Offset +// Special +701=Special +703=Flat Parts +704=Insert DXF or NGE flat parts +705=Compo +706=Insert parametric components +// Scene : Entity selection Menu +1001=Select All +1003=Deselect All +1005=Select Window +1007=Select Part +1009=Select Layer +1011=Select Path +1013=Select Full Path +1015=Select Entity +1016=Select All Visible +// Scene : Point selection Menu + Statusbar +1101=Sketch Point +1102=Sketch Point +1103=Grid Point +1104=Grid Point +1105=End Point +1106=End Point +1107=Mid Point +1108=Mid Point +1109=Center Point +1110=Center +1111=Centroid +1112=Centroid +1113=Near Point +1114=Near Point +1115=Intersection Point +1116=Inters Point +1117=TAcient Point +1118=TAci Point +1119=Perpendicular Point +1120=Perp Point +1121=Min.Distance Point +1122=MinDist Point +1123=Exclude Surfaces +// Scene : Other Menu +1201=Drag Off +1203=Drag On +// Scene : Others +1301=Dist= +// Controller +2001=Copy (V) +2002=Error +2003=Warning +2051=The Point must be different from previous +2052=The Points must be not aligned +2053=Zero or Negative Values not allowed +2054=Two Zero or Negative Values not allowed +2055=At least one Entity is not scalable +2056=Distance too big +2057=Curve not flat (in its plane) +// Controller : Draw +2101= +// Controller : Construct +2201= +// Controller : Modify +2301= +// Controller : Transform +2401=COPY +2402=MOVE +2403=Insert Base Point +2404=Insert Target Point +2406=ROTATE +2407=Insert Center +2408=Insert Base Point +2409=Insert Aci or Rotation Point +2411=ROTATE 3D +2412=Insert First Point on Axis +2413=Insert Second Point on Axis +2414=Insert Base Point +2415=Insert Aci or Rotation Point +2416=MIRROR +2417=Insert First Point +2418=Insert Second Point +2421=MIRROR 3D +2422=Insert First Point +2423=Insert Second Point +2424=Insert Third Point +2426=SCALE +2427=Insert Center +2428=Insert Factor +2431=SCALE 3D +2432=Insert Center +2433=Insert Factors +2436=OFFSET +2437=Insert Distance +2438=Fillet +2439=Chamfer +2440=Extend +// ----- EgtCAM5 ----- +5001=DRAW +5002=MACHINING +5003=Tool Db +5004=Machining Db +5005=Options +5006=Tool Db +5007=Mach Db +5008=Machine Options +5009=SetUp Db +5010=SetUp Db +5020=Machining Table Db +//Top CommandBar +5101=New +5102=Open
Open recent File (Right button) +5103=Save +5104=Save as +5105=Insert +5106=Import +5107=Export +5108=Exec Script
Exec recent Script (Right button) +5109=Options +5110=Can't find support address. +5111=Save current file before sending feedback? +5112=Send a feedback to {0} with the {1} directory attached. +5113=Feedback +5114=Feedback mail ready. +// Draw Panel +5150=Extract Free Edges of Surfaces
Extract Edges of Surface Faces (Shift) +5151=Join Surfaces and Flat Regions +5152=Subtract Surfaces and Flat Regions +5153=Intersect Surfaces and Flat Regions +5154=Points, Curves and Faces from Surfaces Intersection +5201=Point
Vector (Shift)
Frame (Ctrl) +5202=Line 2 Points
Line 2 Points with Continue (Ctrl) +5203=Line Point Direction Length
Line Point Direction vector Length (Shift) +5204=Circle Center Point +5205=Circle Center Diameter +5206=Arc Center Start End points +5207=Arc 3 Points +5208=Arc Start point Direction End point
Arc Start point Direction vector End point (Shift)
Arc Start point Direction End point with Continue (Ctrl) +5209=Fillet +5210=Chamfer +5211=Rectangle 2 Points +5212=Polygon +5213=Polygon Side +5214=Text
Advanced Text (Shift) +5215=Plane from boundary curves
Flat Region (Shift) +5216=Extrude +5217=Revolve +5218=Screw +5219=Ruled +5220=Merge Surfaces +5221=Explode Surfaces and Flat Regions +5222=Invert Surface and Flat Regions +5223=Delete +5224=Change Layer
Change Layer with Transformations (Shift) +5225=Change Transparency +5226=Reset Color +5227=Change Color +5228=Invert Curve +5229=Change closed Curve Start point +5230=Trim or Extend Curve +5231=Break Curve +5232=Split Curve +5233=Join Curves
Join Curves making a Copy (Shift) +5234=Explode Curves and Texts +5235=Thick and Extrusion Curve +5236=Move +5237=Rotate +5238=Rotate 3D +5239=Mirror +5240=Mirror 3D +5241=Scale +5242=Scale 3D +5243=Offset +5244=2D Draw +5245=3D Draw +5246=Modify +5247=Transform +5248=Swept +5249=Edit Text +// Grid View Panel +5251=Wireframe +5252=Hidden Lines +5253=Shading +5254=Zoom All +5255=Zoom In +5256=Zoom Out +5257=Top View +5258=Front View +5259=Left View +5260=Back View +5261=Right View +5262=SW Isometric View +5263=SE Isometric View +5264=NE Isometric View +5265=NW Isometric View +5266=Show Curve Direction +5267=Analyze +5268=Distance +5269=Top Grid +5270=Front Grid +5271=Right Grid +5272=Back Grid +5273=Left Grid +5274=Bottom Grid +5275=Grid From View +5276=Grid Elevation +5277=Grid Origin +5278=Grid Rotation
Grid 3D Rotation (Shift) +5279=Grid From 3 Points +5280=Grid Perpendicular to Curve +5281=Grid From Object +5282=View From Grid +5283=Zoom Selection +// Draw Option Panel +// Machining Option Panel +// Simulation +5301=END +5302=Outstroke +5303=Tool direction unreachable +5304=Error +5305=ERROR +5306=Error in generation! +5307=Simulation +5308=One step +5309=Play/Pause +5310=Stop/Home +5311=Pause +5312=STOP +5313=Can't exit now. Stop the Simulation or wait until the end of it! +5314=HOME +5315=WARNING +5316=Virtual Milling +5317=Error in estimates calculation! +5318=Estimation file missing +5319=Collision! +5330=GENERATE +5331=The project must be saved before generated. Save it ? +5332=Generation completed successfully +5340=Estimations +5341=Total time +5342=Total length +5343=Details +5344=Estimations details +// Draw Option +5351=Properties +5352=New Part +5353=New Layer +5354=Color +5355=Drawings Parameters +5356=Select +5357=Deselect +5358=Name +5359=Info +5360=Relocate +5361=Copy +5362=Delete +5363=Save +5364=Show +5365=Ok +5366=Delete Confirm +5367=Workpiece, do you want to delete it? +// Operation +5401=Operations +5402=Operation Parameters +5403=Apply Machining +5404=New Mach +5405=New Disp +5406=Delete +5407=Generic +5408=Move Up +5409=Move Down +5410=Update +5411=Update completed successfully +5412=New Machinings +5413=Tool Preview +5414=Next +5415=Prev +5416=Duplicate +5417=Copy to Db +5418=Machining name in Db +5419=Machining adding failed +5420=Rename +5421=Name can not start with "Disp" +5422=Name already used. +// Disposition +5431=Ok +5432= +5433=New +5434=Remove +5435=Length +5436=Width +5437=Height +5438=Position +// Disposition Errors +5461=SCRIPT EXECUTION ERROR +5462=Error executing automatic disposition script +5463=Error executing machining init script +5464=Error executing machining exit script +// Mach Group +5501=Are you sure you want to reset the Machining Group ? +5502=Are you sure you want to delete the Machining Group ? +5551=There are no Machining Groups :
select the parts to insert and
repeat the command to create the first one. +5552=Do you want to create a new Machining Group
with the selected parts? +// Tools Db Page +6001=Drillbit +6002=Sawblade +6003=Mill +6004=Mortise +6005=Compo +6006=Long drill +6007=Flat saw +6008=No tip mill +6009=Chisel +6010=WaterJet +6051=Compensation +6052=Exit +6053=Type +6054=Coolant +6055=Corner Radius +6056=Diameter +6057=Total Diameter +6058=Feed +6059=End Feed +6060=Start Feed +6061=Tip Feed +6062=Length +6063=Total Length +6064=Max Material +6065=Longitudinal Offset +6066=Radial Offset +6067=Speed +6068=Side Angle +6069=Max Speed +6070=Thick +6071=Max Absorption +6072=Min Feed +6073=Draw +6074=Head +6075=Name +6076=Notes +6077=Tool Changer Position +6078=Position +// Tools Errors +6100=Save the modified tool? +6101=SAVE +6102=File has to be .nge +6103=File does not exist or is not Nge type +6104=ToolMaker does not exist for this kind of tool +6105=Impossible creating tool with this parameter +6106=MaxMat value must be greater than 0 +6107=MaxMat value must be less than Len +6108=Thick value must be greater than 0 +6109=Diam value must be greater than 0 +6110=Len value must be greater than 0 +6111=Speed value must be less than MaxSpeed +6112=Invalid Name +6113=Length value must be less than Total Length +6114=Length value must be greater than Max Material +6115=Total Length must be greater than 0 +6116=Total Length must be greater than Length +6117=Max Material must be less than 1/3 Diameter +6118=Diameter must be less than Total Diameter +6119=Diameter must be greater than 3 times Max Material +6120=Total Diameter must be greater than 0 +6121=Length too small with toolholder +6122=Are you sure you want to delete +6123=? +6124=DELETE +6125=SetUp configuration file not found! +6126=Error +6127=Head value must be set +6128=Exit value must be set +6129=Invalid tool, correct or delete it before exit Tool Db. +6130=Impossible reloading Tool database. If the machine dir is on a server, verify the connection is active. +6131=???Thick value must be different than 0 +6132=???Side Angle value must be smaller than 90 +6133=???Side Angle value must be bigger than -90 +6134=???Total Length must be greater than Length + Thick +6135=???Corner Radius value is too big +6136=???Thick value is too small for insert radius +6137=???Calculated Diameter must be less than Total Diameter +6138=???Calculated Diameter is less than 0 +6139=???Calculated Diameter is less or equal than 0 +6140=???MaxMat value must be greater than Corner Radius +6141=???Calculated MaxMat must be >= 0 +6142=???Corner Radius must not exceed half Thick +6143=???Save tool +6144=???Tool modified! All tools must be saved before changing activations. Save tool {0}? +6145=???Position already occupied! +// Machinings Db Page +6201=Drilling +6202=Sawing +6203=Milling +6204=Pocketing +6205=Mortising +6206=Sawroughing +6207=Sawfinishing +6208=Gen Machining +6209=Chiseling +6210=Surface Roughing +6211=Surface Finishing +6212=WaterJet +6251=Invert +6252=Leave Tab +6253=Type +6254=Work Side +6255=Head Side +6256=Lead In +6257=Link +6258=Lead Out +6259=Curve Use +6260=Step Type +6261=Sub Type +6262=Lead Link Type +6263=Speed +6264=Feed +6265=Start Feed +6266=End Feed +6267=Tip Feed +6268=Radial Offset +6269=Longitudinal Offset +6270=Depth +6271=Side Angle +6272=Approximation +6273=Start Safety Length +6274=Start Slow Length +6275=End Slow Length +6276=Throu Add Length +6277=Step +6278=Return Position +6279=Tab Length +6280=Tab Distance +6281=Tab Height +6282=Tab Angle +6283=L.In Tangent Distance +6284=L.In Perp. Distance +6285=L.In Elevation +6286=L.In Comp. Length +6287=L.Out Tangent Distance +6288=L.Out Perp. Distance +6289=L.Out Elevation +6290=L.Out Comp. Length +6291=Start Add. Length +6292=End Add. Length +6293=Step External Arc +6294=Step Internal Arc +6295=Side Step +6296=Vertical Feed +6297=Name +6298=Tool +6299=Depth +6300=Notes +6301=Overlap +6302=Offset +6303=Sub Type +6304=SCC +6305=None +6306=Standard +6307=Opposite +6308=AuxDir X+ +6309=AuxDir X- +6310=AuxDir Y+ +6311=AuxDir Y- +6312=AuxDir Z+ +6313=AuxDir Z- +6314=Nearest AuxDir +6315=Farthest AuxDir +6320=Center +6321=Left +6322=Right +6323=Extend +6324=Standard +6325=Strict +6326=Out +6327=Extend Central +6328=Extend Out +6329=None +6330=Linear +6331=Tangent +6332=Glide +6333=Helix +6334=Extend Prev +6335=Extend Next +6336=Extend Both +6337=As Lead In +6338=Skip +6339=Approx +6340=Convex +6341=Keep +6342=ZigZag +6343=Oneway +6344=Spiral +6345=To And From +6346=Along +6347=Across +6348=Spiral In +6349=Spiral Out +6350=Advanced +6351=Invert tool direction +6352=Face machining +6353=Not defined +6354= Parallel +6355= Orthogonal +6356= Orthog. Up +6357=Down +6358=Top +6359=Front +6360=Back +6361=Left +6362=Right +6363=Contour +6364=Suggested Angles +6365=Blocked Axis +// Machining errors +6370=Save the modified machining? +6371=SAVE +6372=Invalid name +6373=Characters \ / : * ? " < > | are not allowed +6374=Are you sure you want to delete +6375=? +6376=DELETE +6377=Impossible reloading Machining database. If the machine dir is on a server, verify the connection is active. +6378=Oscillation +6379=Oscill. Amplitude +6380=Oscill. Ramp Length +6381=Oscill. Flat Length +// Machining Option Page +6401=Safe Z +6402=Split Arcs +6403=Never +6404=Gen plane +6405=No XY plane +6406=Always +6407=Default Setup +6408=Safe Z bottom aggregate +6409=Delik tolerans +// SetUp Window +6451=SetUp +6452=Apply +6453=Save +6454=Retrieves +6455=Auto +6456=Apply current setup before exit? +// SetUp Errors +6471=Error +6472=Warning +6473=Can't find tool +6474=in Tool Database. +6475=The tool's default position is not valid. +6476=Tools not setup because their default position is alredy occupied: +6477=SetUp configuration file doesn't exist! +6478=SetUp configuration use a head that doesn't exist on the machine! +6479=Error loading default setup +// Option Page +6501=Current language +6502=The new language become the current one from the next software run. +6503=Curves +6504=Surfaces +6505=Curves & Surfaces +6506=Selecting geometry +6507=New machining is the last one +6508=Use disposition script +6509=Measure Unit +6510=View top color +6511=View bottom color +6512=Default color +6513=Geometric tolerance +6514=Generic +6515=CAD +6516=CAM +6517=Grid color +6518=Smoothed surfaces +6519=Import +6520=DXF : scale factor +6521=STL : scale factor +6522=Images : scale factor +6523=Export +6524=Image +6525=Width (pixel) +6526=Height (pixel) +6527=Update Machine +6528="{0}" machine already exists,
what do you want to do ? +6529=File {0} does not contain a machine. +6530=The machine "{0}" has been successfully updated. +6531=Replace +6532=Update +6533=Cancel +6534=Warning +6535=The update of the "{0}" machine failed. +6536=Thick lines +// Heads +6601=Vertical head +6602=Horizontal head +6603=2 exit aggregate +6604=3 exit aggregate +6605=4 exit aggregate +6606=3 axis head +6607=4 axis head +6608=5 axis head +6609=Shuttle 1 +6610=Shuttle 2 +6611=Carousel +6612=Gang drill +6613=Multi chisel +6614=Bottom aggregate +6615=5 axis saw +6616=Chainsaw +6617=1 exit aggr. +6618=Probe head +6619=Floating 360deg +6799= +// StatusBar +6801=Machines dir not found. EgtCAM5 wil be run in CAD-ONLY mode. +// Doors +8001=Create new MTable +8002=Save MTable +8003=Save MTable As +8004=Delete MTable +8005=Save MTable file +8006=Are you sure to delete this MTable? +8007=Save the modified MTable? +8008=Active Machines List +8009=Machine Name +8010=Nc Generate +8011=Make Raw +8012=On +8013=Geometry Name +8014=Operation +8015=MId +8016=Shift +8017=Machining Type +8018=Machining 1 +8019=Machining 2 +8020=Machining 3 +8021=Add Machine +8022=Remove Machine +8023=Add Machining +8024=Remove Machining +8025=CURR +8026=Set active MTable +8027=GId +8028=Property +8029=Machining +8030=Join +// Door errors +8101=Error +8102=Error running Ddf file +8103=Warning +8104=MTable dir path not found +8105=MTable dir not exist +8106=Missing configuration files in MTable dir +8107=Unknown error +8108=This MTable is currently the active one. +8109=You can't delete it. +8110=Are you sure you want to delete the selected machining? +8111=DELETE +8112=Are you sure you want to delete the selected machine? +8113=Can't find {0} machine dir. If the machine dir is on a server, verify the connection is active. +8114=Try to reload the machine? +8115=Can't find {0} dir. If the Doors dir is on a server, verify the connection is active. +8116=Try to reload Doors dir? +8117=Execution error (see log file) +// GunStock +8201=New Part +8202=Gunstock new part +8203=Modify Part +8204=Gunstock modify part +8205=Gunstock parameters +8206=File name +8207=Description +8208=Ok +8209=Cancel +8210=must have a value. +8211=The value has to be between +8212=and +8213=Rawpart dimensions +// GunStock errors +8251=Error +8252=Error running Gunstock environment +8253=Error reading model file +8254=Error writing part file +// ----- Beams ----- +9000=Beam machining tables +9001=On +9002=Name +9003=Type +9004=Add +9005=Delete +9006=Save +9007=Salvare le modifiche apportate? +9008=Error +9009=Impossible to open Beam Machining Editor.
Can't find config files. +// ----- Errors ----- +10001=Error +10002=Error on new file +10003=Error opening file +10004=Error saving file +10005=File type unknown +10006=Error importing file +10007=Error exporting file +10008=Error loading or creating Machining Group +10009=Missing file +// Missing Key Window +10101=Error ! +10102=Missing Protection Key. +10103=Insert Dongle and restart the program. +10104=Ok +10105=Program without licence. +10106=Load Licence and restart the program. +10107=Run GetMachineId and send results to supplier. +// Numeric virtual keyboard +10201=Wrong Expression +// ----- MessageBox ----- +15001=Error +15002=Warning +15003=Information +15010=Unknown error +// ----- EgtWPFLib ----- +// EgtCalculator +20011=Wrong Expression +// EgtCalculatorWD +20021= +// EgtKeyboard +20031= +// EgtMsgBox +20041=Ok +20042=Iptal +20043=EVET +20044=HAYIR +// ----- EgtWPFLib5 ----- +// EgtSaveFileDialog +30001=???Save +30002=???Cancel +30003=???alredy exists. +30004=???Do you want to replace it? +30005=???File name: +30006=???Open +30007=???ERROR +30008=???Name can't be empty! +30009=???WARNING +30010=???File Name +30011=???Folder Name +// Top CommandBar +30501=???New +30502=???Open +30503=???Save +30504=???Save as +30505=???Insert +30506=???Import +30507=???Export +30508=???Exec +30509=???Options +30510=???Can't find support address. +30511=???Save current file before sending feedback? +30512=???Send a feedback to {0} with the {1} directory attached. +30513=???Feedback +30514=???Feedback mail ready. +// Grid View Panel +30801=???Wireframe +30802=???Hidden Lines +30803=???Shading +30804=???Zoom All +30805=???Zoom In +30806=???Zoom Out +30807=???Top View +30808=???Front View +30809=???Left View +30810=???Back View +30811=???Right View +30812=???SW Isometric View +30813=???SE Isometric View +30814=???NE Isometric View +30815=???NW Isometric View +30816=???Show Curve Direction +30817=???Analyze +30818=???Distance +30819=???Top Grid +30820=???Front Grid +30821=???Right Grid +30822=???Back Grid +30823=???Left Grid +30824=???Bottom Grid +30825=???Grid From View +30826=???Grid Elevation +30827=???Grid Origin +30828=???Grid Rotation +30829=???Grid From 3 Points +30830=???Grid Perpendicular to Curve +30831=???Grid From Object +30832=???View From Grid +// MachGroupPanel +30901=???New Mach Group +30902=???Name: +30903=???Machine: +// ToolDbWindow +31001=???Drillbit +31002=???Sawblade +31003=???Mill +31004=???Mortise +31005=???Compo +31006=???Long drill +31007=???Flat saw +31008=???No tip mill +31009=???Chisel +31010=???Waterjet +31051=???Compensation +31052=???Exit +31053=???Type +31054=???Coolant +31055=???Corner Radius +31056=???Diameter +31057=???Total Diameter +31058=???Feed +31059=???End Feed +31060=???Start Feed +31061=???Tip Feed +31062=???Length +31063=???Total Length +31064=???Max Material +31065=???Longitudinal Offset +31066=???Radial Offset +31067=???Speed +31068=???Side Angle +31069=???Max Speed +31070=???Thick +31071=???Max Absorption +31072=???Min Feed +31073=???Draw +31074=???Head +31075=???Name +31076=???Notes +31077=???Tool Changer Position +31078=???Position +31079=???Drilling +// ToolDb Errors +31100=???Save the modified tool? +31101=???SAVE +31102=???File has to be .nge +31103=???File does not exist or is not Nge type +31104=???ToolMaker does not exist for this kind of tool +31105=???Impossible creating tool with this parameter +31106=???MaxMat value must be greater than 0 +31107=???MaxMat value must be less than Len +31108=???Thick value must be greater than 0 +31109=???Diam value must be greater than 0 +31110=???Len value must be greater than 0 +31111=???Speed value must be less than MaxSpeed +31112=???Invalid Name +31113=???Length value must be less than Total Length +31114=???Length value must be greater than Max Material +31115=???Total Length must be greater than 0 +31116=???Total Length must be greater than Length +31117=???Max Material must be less than 1/3 Diameter +31118=???Diameter must be less than Total Diameter +31119=???Diameter must be greater than 3 times Max Material +31120=???Total Diameter must be greater than 0 +31121=???Length too small with toolholder +31122=???Are you sure you want to delete +31123=???? +31124=???DELETE +31125=???SetUp configuration file not found! +31126=???Error +31127=???Head value must be set +31128=???Exit value must be set +31129=???Invalid tool, correct or delete it before exit Tool Db. +31130=???Impossible reloading Tool database. If the machine dir is on a server, verify the connection is active. +31131=???Thick value must be different than 0 +31132=???Side Angle value must be smaller than 90 +31133=???Side Angle value must be bigger than -90 +31134=???Total Length must be greater than Length + Thick +31135=???Corner Radius value is too big +31136=???Thick value is too small for insert radius +31137=???Calculated Diameter must be less than Total Diameter +31138=???Calculated Diameter is less than 0 +31139=???Calculated Diameter is less or equal than 0 +31140=???MaxMat value must be greater than Corner Radius +31141=???Calculated MaxMat must be >= than 0 +// MachiningDbWindow +31201=???Drilling +31202=???Sawing +31203=???Milling +31204=???Pocketing +31205=???Mortising +31206=???Sawroughing +31207=???Sawfinishing +31208=???Gen Machining +31209=???Chiseling +31210=???Waterjetting +31251=???Invert +31252=???Leave Tab +31253=???Type +31254=???Work Side +31255=???Head Side +31256=???Lead In +31257=???Link +31258=???Lead Out +31259=???Curve Use +31260=???Step Type +31261=???Sub Type +31262=???Lead Link Type +31263=???Speed +31264=???Feed +31265=???Start Feed +31266=???End Feed +31267=???Tip Feed +31268=???Radial Offset +31269=???Longitudinal Offset +31270=???Depth +31271=???Side Angle +31272=???Approximation +31273=???Start Safety Length +31274=???Start Slow Length +31275=???End Slow Length +31276=???Throu Add Length +31277=???Step +31278=???Return Position +31279=???Tab Length +31280=???Tab Distance +31281=???Tab Height +31282=???Tab Angle +31283=???L.In Tangent Distance +31284=???L.In Perp. Distance +31285=???L.In Elevation +31286=???L.In Comp. Length +31287=???L.Out Tangent Distance +31288=???L.Out Perp. Distance +31289=???L.Out Elevation +31290=???L.Out Comp. Length +31291=???Start Add. Length +31292=???End Add. Length +31293=???Step External Arc +31294=???Step Internal Arc +31295=???Side Step +31296=???Vertical Feed +31297=???Name +31298=???Tool +31299=???Depth +31300=???Notes +31301=???Overlap +31302=???Offset +31303=???Sub Type +31304=???SCC +31305=???None +31306=???Standard +31307=???Opposite +31308=???AuxDir X+ +31309=???AuxDir X- +31310=???AuxDir Y+ +31311=???AuxDir Y- +31312=???AuxDir Z+ +31313=???AuxDir Z- +31314=???Nearest AuxDir +31315=???Farthest AuxDir +31320=???Center +31321=???Left +31322=???Right +31323=???Extend +31324=???Standard +31325=???Strict +31326=???Out +31327=???Extend Central +31328=???Extend Out +31329=???None +31330=???Linear +31331=???Tangent +31332=???Glide +31333=???Helix +31334=???Extend Prev +31335=???Extend Next +31336=???Extend Both +31337=???As Lead In +31338=???Skip +31339=???Approx +31340=???Convex +31341=???Keep +31342=???ZigZag +31343=???Oneway +31344=???Spiral +31345=???To And From +31346=???Along +31347=???Across +31348=???Spiral In +31349=???Spiral Out +31350=???Advanced +31351=???Invert tool direction +31352=???Face machining +31353=???Not defined +31354=??? Parallel +31355=??? Orthogonal +31356=??? Orthog. Up +31357=???Down +31358=???Top +31359=???Front +31360=???Back +31361=???Left +31362=???Right +31363=???Contour +31364=???Suggested Angles +31365=???Blocked Axis +31366=???Last backward feed +31367=???Backward step +31368=???Tilted step +31369=???Tilted back step +31370=???Forward angle +31371=???Probing +31372=???Min dist. points +31373=???Max dist. points +31374=???External +31375=???Internal +31376=???Slowdown len. +31377=???Slowdown % +31378=???Lead in hole +31379=???Radius +31380=???LP turns +31381=???HP turns +//MachiningTreeView +31391=???Standard +31392=???Slowdown +31393=???Loop +// MachiningDb Errors +31401=???Save the modified machining? +31402=???SAVE +31403=???Invalid name +31404=???Characters \ / : * ? " < > | are not allowed +31405=???Are you sure you want to delete +31406=???? +31407=???DELETE +31408=???Impossible reloading Machining database. If the machine dir is on a server, verify the connection is active. +// SetUp Window +31501=???SetUp +31502=???Apply +31503=???Archive +31504=???Retrieves +31505=???Auto +31506=???Apply current setup before exit? +// SetUp Errors +31551=???Error +31552=???Warning +31553=???Can't find tool +31554=???in Tool Database. +31555=???The tool's default position is not valid. +31556=???Tools not setup because their default position is alredy occupied: +31557=???SetUp configuration file doesn't exist! +31558=???SetUp configuration use a head that doesn't exist on the machine! +31559=???Error loading default setup +// Simulation +31601=???Complete simulation +31602=???Outstroke +31603=???Tool direction unreachable +31604=???Error +31605=???ERROR +31606=???Error in generation! +31607=???Simulation +31608=???One step at a time +31609=???Play/Pause +31610=???Stop/Home +31611=???Pause +31612=???Stopped simulation +31613=???Can't exit now. Stop the Simulation or wait until the end of it! +31614=???WARNING +31615=???Estimation file missing +31616=???Estimation details +// ----- EgtDOORCreator ----- +//General +50001=???Width +50002=???Height +50003=???Thickness +50004=???Swing +50005=???Lockedge +50006=???Hingeedge +50007=???Top +50008=???Bottom +50009=???Type +50010=???Corner +50011=???Extension +50012=???Side +50013=???Offset wide side +50014=???Back set +50015=???Top to center application +50016=???Bottom rail +50017=???Lock stile +50018=???Offset from center +50019=???Point to pocket +50020=???Pocket length +50021=???Pocket offset narrow side +50022=???Point to arm +50023=???Arm length +50024=???CenterHung +50025=???Offset +50026=???Offset intermediate +50027=???Radius +50028=???Top rail +50029=???Position +50030=???Lenght +50031=???Template +50032=???Up +50033=???Down +50034=???Shape +50035=???Hinge +50036=???Top to top application +50037=???Center from top application +50038=???Center from top lock +50039=???Depth +50040=???General +50041=???Center +50042=???Thru +50043=???Face to center line application +50044=???Edge Type +50045=???Over Material +50046=???Send Feedback +50047=???Weight +50048=???Angle +50049=???Face +50050=???Secure +50051=???Keyway +50052=???Brand +50053=???Folder +50054=???Main Folder +50055=???Jamb +50056=???Light Up +50057=???Light Lock +50058=???Light Bottom +50059=???Light Hinge +50060=???Thickness Head +50061=???Overlap Hinge +50062=???Overlap Lock +50063=???Overlap Top +50064=???Delta T +50065=???Exterior +50066=???Number of Doors +50067=???Jambs and Doors +50068=???Order +50069=???Disposition +50070=???Customer +50071=???Invert bevel on Lock +//Compo Name +50072=???Flush Bolt +50073=???Flush Pull +50074=???Hinge +50075=???Lock +50076=???Louver Cut Out +50077=???Mail Slot +50078=???Over Head +50079=???Pivot +50080=???Roller Latch +50081=???Stops And Closer +50082=???Strike +50083=???Edge pull +50084=???Viewer +50085=???Vision cut out +50086=???Grove +50087=???Rabbet +50088=???Ept +50089=???Raceway +50090=???Face Decoration +//error messages +50100=???Directory not founded +50101=???Error +50102=???Failed reading DDF file. Missing incumbent parameter {0}. +50103=???Failed reading value +50104=???Failed reading DDF file's row +50105=???Row +50106=???Invalid value in +50107=???Empty file. +50108=???You can not add a compo if there is not a dorr! +50109=???Do you want to save this file ({0}) ? +50110=???Question +50111=???Add new door +50112=???Remove door +50113=???New Door +50114=???File name already exists in the current directory ({0}). +50115=???Caution +50116=???Do you want to delete this file ({0}.ddf)? +50117=???Confirm deleting ({0})?. +50118=???Information +50119=???Error in reading messages. There is no match with the number {0}. +50120=???Error reading name {0} in {1}. Expected numeric match. +50121=???Error reading {0} param in {1} compo: do not exist. +50122=???Error in {0} param in {1} compo. +50123=???Error reading {0} param in {1} compo: do not exist list. +50124=???Error reading {0} param in {1} compo: {2}. +50125=???Error in {0} param in {1} compo: do not exist value. +50126=???Delete +50127=???Error in EgtLoadMessages +50128=???You can not save a file if there is not a door! +50129=???Error in Project scene creation +50130=???Error in reading: line {0}. +50131=???Error in reading {0}: line {1}. Expected ':' after the name. +50132=???Error in reading {0}: line {1}. Expected 'template' or 'shape'. +50133=???{0} has not been created. +50134=???Error reading 'Template' in file {0}\{1}. Expetcted name. +50135=???Error reading 'Template' in file {0}\{1}. File {0}\{2} .lua does not exist. +50136=???Error in reading {0}: line {1}. It does not exist in the list of components in file 'Default.ini'. +50137=???Error in reading {0}: line {1}. It is not a member of the list. +50138=???This param will be initialized by default. +50139=???Error in reading: line {0}. Expected {1}. +50140=???All missing params will be initialized by default. +50141=???Invalid expression in {0}. +50142=???Remove compo +50143=???Invalid expression. +50144=???Warning +50145=???Impossible to create the current door. +50146=???Do you want to open a template? +50147=???Error expression in {0}. {1} does not match anything. +50148=???Invalid value.ù +50149=???Caution: Weight is setted in OptionPage. Do you want to remove? +50150=???Caution: Weight is setted in DDF. Do you want to add? +50151=???{0} is not a member of the current list of EdgeType. Check Bevel in option page. +50152=???Do you want to save this file ({0})? +50153=???Caution. Weight is setted in the current door. Do you want to remove? +50154=???It is the bevel of the current door. Do You want to proced? +50155=???Impossible to create a template if there is not a door! +50156=???Error in reading ddf: door is not completed or ddf has been slpitted by '---' bad. +50157=???Script Lua ( {0}\{1} )has not been found. +50158=???Bevel {0} can not be acceptable in Jamb. +50159=??? Missing parameter in ddf! +50160=???File {0} in directory {1} has not been found. +50161=???parameter +50162=???In file {0} param 'Default' must be numeric. +50163=???Error in reading General Assembly in DDF +50164=???In General Assembly: +50165=???CompoDir not found : +50166=???Jamb compo does not exist +50167=???Empty Line +50168=???No matching param +50169=???Door disposition has been modify. +50170=???Incongruity between the bevel, it has been resolved by default. +50171=???In file StdTempate.ini is missing numeric param in [Type]. +50172=???File does not exist. +50173=???Definition type is not correct: +50174=???Missing name of the new template! +50175=???The file: {0} already exist in directory {1} . Do you want to overwrite it +50176=???Error in copying: {0} +50177=???Do you want to save the current changes? +50179=???Doors Compo Default.ini not found in {0} . +50180=???Warning : {0} does not exist. +50181=???Error in creating the print image +50182=???Error executing print +50183=???Some Doors could use this hardware, do you want to proceed deleting? +50184=???Impossible to delete Hardware if there is no Hardware selected! +50185=???Impossible to duplicate Hardware if there is no Hardware selected! +50186=???Project must be saved before copying +50187=???Do you want to copy all files ? {0} (No to copy only the current file) +50188=???Export to machine +50189=???Machine Directory not found +50190=???Error in copying: {0} +50191=???Impossible to copy a door if there is not a door! +50192=???Impossible to export to machine a door if there is not a door! +50193=???Impossible to print a door if there is not a door! +50194=???Properties has been deleted +50195=???The current ddf configuration ({0}) is different from the current program configuration ({1}).{2}To load the current ddf configuration you have to restart the program, do you want it? +50196=???Configuration ddf ({0}) does not exist! +50197=???Top Arch has been modified because of configuration. +50198=???Bevel on lock edge would be inverted. +//Option +50200=???Unit measure +50201=???General +50202=???LockEdgeOverMaterial +50203=???HingeEdgeOverMaterial +50204=???TopOverMaterial +50205=???BottomOverMaterial +50206=???Open Window +50207=???Last Project +50208=???Empty +50209=???Option Page +50210=???StartUp +50211=???Unit measure new door. +50212=???Directory Project +50213=???Option Start +50214=???Current Directory +50215=???Edge Type +50216=???Over Material +50217=???Browse +50218=???Close +50219=???Bevel +50220=???Bevel Up +50221=???Bevel Down +50222=???Door positioning in machining +50223=???Save as template +50224=???Matching +50225=???Brand +50226=???File +50227=???Template +50228=???Enable template +50229=???Enable Order +50230=???Open template door. +50231=???Open window order. +//Scene +50301=???Refresh +50302=???Add New Door +50303=???Remuve Door +50304=???New Project +50305=???Help +50306=???Directory Machine +50307=???Machine +50308=???Door +50309=???Wide Side Down (BU) +50310=???Wide Side Up (BD) +//Launcher +50400=???Launcher +50401=???Open New Project +50402=???Open Project +50403=???Open Last Project +50404=???New Project +50405=???New Hardware +50406=???Elevation +50407=???Project +50408=???PO +50409=???Line +50410=???Save +50411=???Print +50412=???Cancel +50413=???Hardware +50414=???Dimensioning +50415=???Duplicate +50416=???Export to machine +50417=???New Template +50418=???Dimension +50419=???New Directory +50420=???Create Assembly +50421=???Reload Directory +//Error messages +50501=???Error reading {0} param in {1} compo: incomplete definition (look at StdTemplate.ini). +50502=???Error reading {0} param in {1} compo: no matching (look at StdTemplate.ini and GeometryNameList.ini). +50503=???Do you want to save? +50504=???File name contains empty spaces, do you want to rename file deleting empty spaces? +50505=???DDF is not an assembly, there are only: {0}, do you want to save? +50506=???Impossible to find the first door (DO_1)! +50507=???The swing is not a member of the swing list of single door. +50508=???The swing of left door is not a member of the swing list of left door. +50509=???The swing of right door is not a member of the swing list of right door. +50510=???The swing of left door is on the right door and viceverse. +50511=???The swing of left door is not a member of the swing list of left door. +50512=???The swing of right door is not a member of the swing list of right door. +50513=???Impossible to find the first door (DO_1) and the second door (DO_2)! +50514=???The swing are absolutly wrong! +50515=???The first door is not realy the first, check the ddf. +50516=???The current ddf contains {0} jambs. +50517=???The current ddf does not contains doors! +50518=???The current ddf is not an assembly. +50519=???Impossible to open a ddf with no doors. +50520=???The current ddf is an assembly. +50521=???The current ddf is a jamb: {0}. +50522=???The profile {0} is not a member of the {1} profile list. +50523=???Missing profile on {0}. +50524=???{0} file open by another EgtDOORCreator {1}. +50525={0} file open by another EgtDOORCreator {1}. +50526=Directory {0} already exists! Do you want to overwrite it? +50527=???Impossible to overwrite {0} +50528=???Impossible to save the door out of the project! +50530=???Property {0} does not exist in the list of {1}. Look at file "../Compo/Default.ini". +50531=???The current material {0} does not exist in the list of material. Look at file "../Compo/Default.ini". +50532=???Missing list of material at file "../Compo/Default.ini". +50533=???Impossible to load more than one property at time. +50534=???Property {0} does not exist in the list. Look at file "../Compo/Default.ini". +50535=???Impossible to delete a project if there is not a project! +50536=???Do you want to delete entire project? +50537=???Do you want to delete subdirectory {0} ? +50538=???Impossible to vreate a template door if there is not a door! +50539=???Do you want to change project? ( All doors will be deleted!) +50540=???The current ddf is a part of a frame, do you want to save? +50541=???{0} in reading {1}. +50542=???{0}: Directory does not exist! +50543=???It has been renamed file: {0}, {1}. +50544=???It has been created new file: {0}, {1}. +50545=???It has been deleted file: {0}, {1}. +50546=???Enable single door. +50547=???Project +50548=???The new configuration will take effect after restart. +//Added General messages +50701=???Lines +50702=???Rectangle +50703=???None +50704=???Radius +50705=???Angle +50706=???Pos_x +50707=???Top Arc +50708=???Top Angle +50709=???Properties +50710=???Material +50711=???Mach. +50712=???HardwarePart +50713=???Assemby +50714=???Total Dimension +// ----- OmagCUT ----- +// General +90001=GECERLI KESIM +90002=MANUEL KESIMLER +90003=CAD KESIMLER +90004=PROFILLER +90005=MAKINE +90006=OPSIYONLAR +// Current Machining +90101= +// Direct Cuts +90201=Manuel Hareket +90202=Tek kesim +90203=Coklu kesim +90204=Serit kesim +90205=MTH +90206=Yuzey kalibre +90207=Testere testi +90208=Testere probu +90209=Sablon Kopyala +90210=P1 noktasini okut +90211=P2 noktasini okut +90212=Lazerle okut +90213=Derinlik +90214=Boy +90215=Yon +90216=Kesim acisi +90217=Adet +90218=Ebat +90219=X eks. adet +90220=X eks. ebat +90221=Y eks. adet +90222=Y eks. ebat +90223=Motor yonu kesim +90224=Testere +90225=Cizim +90226=En +90227=Telafi +90228=???Offset +90229=???C Axis Lock +90230=Baslat +90241=Tes. probla +90242=Problama yurutuluyor... +90243=Problama tamam +90244=Problamada hata +90245=Yeni Sablon Adi +90246=???Probing canceled by user +90250=Cizgi +90251=Yay +90252=Cikart +90253=Kapa +90254=Kaydet +// Cad Cuts +90301=Simulasyon +90302=Baslat +90303=Yeni +90304=Yukle +90305=Kayit +90306=Farkli kayit +90307=Yeni Proje Adi +90308=CSV +90309=???Vein Match +90310=???Export +90311=Takim +90312=Kesim +90313=Foto kamera basarisiz +90314=NC program yazma hatasi +90315=NC program aktarma hatasi +90316=Makineye baglanti yok +90317=NC program aktarma +90318=NC programi reddedildi +90319=NC programi aktarildi, tekrarlansin mi +90320=Farkli makine +90321=Dalmayi engellemek icin bazi kesimler kisitlandi +90322=Eksik takimlar : +90323=???Background photo taken +90324=???Contour recognition failed +90325=???Error saving statistics +90326=???Confirm restart from phase {0} ? +90327=???New Ruined Parts +90328=???Parts Area : +90329=???To be Produced : +// NestPage +90331=Parca ekle +90332=Parca park +90333=Parca cikar +90334=Tumunu sec +90335=Tum secim iptal +90336=Iptal +90337=???One or more parts with non-compatible thickness, material or finish +90338=???Rotation beyond the limits +90339=???Rotation impossible +90340=???Automatic nesting in progress +// SplitPage +90341=On/Off +90342=Tumu On +90343=Tumu Off +90344=Uzat/Kisalt +90345=Baslangic Uzat/Kisalt +90346=Bitis Uzat/Kisalt +90347=Giris merkezden/distan +90348=Tum girisler distan +90349=Tum girisler merkezden +90350=???Automatic computation failed +90351=???Saw too big for vacuum use +90352=???End Cnt/Out +90353=???All End Out +90354=???All End Center +90355=???All Extend +90356=???All Reduce +90357=???Modify +90358=???Auto +90359=???Restart +// MoveRawPart +90361=Cikart +90362=???Part too small : can not be moved +90363=???Selected position already occupied +// SplitPage 2 +90371=???Pause On/Off +90372=???Pause +90373=???Start Modif. +90374=???End Modif. +90375=???Elongation +// DrawPage +90381=Parca Sayisi +90382=Olcum +90383=Kenar acilari +90384=???Mark Top +90385=???Parametric Draw +90386=???Select a contour +90387=???No editable sides +90388=???Name +90389=???Trf Data +90390=???Order Code +90391=???Order Description +90392=???Material Code +90393=???Surface Code +90394=???Thickness +90395=???Select one or more holes +90396=???Part Code +// Component +// Massimo 17 caratteri senza immagine e massimo 12 con l'immagine +90401=Ucgen +90402=Dikdortgen +90403=Yamuk +90404=Dortgen +90405=Besgen +90406=Denizlik +90407=Mutfak tezgah +90408=Banyo tezgah +90409=Digerleri +90410=2Kenar 1Aci +90411=3Kenar +90412=Ikizkenar +90413=Dik +90414=Cesitkenar +90415=Cesitkenar +90416=4Kenar 1Aci +90417=3Kenar 2Aci +90418=3Kenar 2Koseg +90419=4Kenar 1Koseg +90420=4Kenar 3Koseg +90421=4Kenar 3Aci +90422=4Kenar 3Aci +90423=Dik Aci +90424=Pahli Dik Aci +90425=???Aligned Angle +90426=???Chamfered Aligned Angle +90427=Parca A +90428=Parca B +90429=Aci +90430=Pah Aci +90431=Elips +90432=Oval +90433=Yay +90434=Yay LHF +90435=Yay LLH +90436=Yay LLF +90437=???Rounded Rectangle +90438=???Convex +90439=???Hole +90440=???2 Holes +90441=???3 Holes +90442=Yay RHa +90443=???Polygon +90444=???Bottom Hole +90445=Dxf +90446=???Recess +90447=???Internal Features +90448=???Add +90449=???Remove +90450=???Confirm +// Import +90451=Katmanlari kullan +90452=Bolgeleri kullan +90453=Iptal +90454=mm +90455=inch +90456=Kapali Egri kullan +90457=Kenar Aci +90458=???Drip +90459=???Angle +90460=???Offset +90461=Derinlik +90462=???Shortening +90463=???DXF import +90464=???Drill bottom +90465=???Number +90466=???Offset2 +// Component 2 +90470=???Recess engravings +90471=???Recess +// FastGrid +90480=???Order name +90481=???N. slab +90482=???Last slab +90483=???Piece type +90484=???Insert pieces +90485=???Confirm order +// Open +90491=Gecersiz proje +90492=Projede carpma var. Yuklemek icin sikistirmalari iptal et. +// RawPart +90499=???Undefined Raw part +90500=???Rotation +90501=Dikdortgen +90502=Nokta ile +90503=Boy +90504=En +90505=Kalinlik +90506=Ofset X +90507=Ofset Y +90508=Telafi +90509=Malzeme +90510=Kullanilmayacak bolge +90511=Yeni +90512=Sil +90513=Noktalar +90514=Ekle +90515=Cikar +90516=Maks. boy = +90517=Maks. en = +90518=Negatif kalinlik izin yok +90519=Min ofset X = +90520=Min ofset Y = +90521=Min telafi = +90522=Maks telafi = +90523=Yuzey prob +90524=???Ok +90525=Yuzey probla +90526=Problama yurutuluyor... +90527=Problama tamam +90528=Problamada hata +90529=Cizimden +90530=Lazerden +90531=Kapat +90532=Lazer ile nokta aliminda hata +90533=Dis cerceve +90534=???Saw too big for probing +90535=???From photo +//ChooseMachining +90536=Testere sec +90537=Ek kesimi sec +90538=Delmeyi sec +90539=Frezeyi sec +90540=Hicbiri +90541=Delme +90542=Freze +90543=Ikiside +90544=???Choose Current Machining +90545=???Choose waterjet +90546=???Waterjet Cut +90547=???Error in the position or size of the raw +90548=Maks ofset X = +90549=Maks ofset Y = +// Simulation +90551=Komple simulasyon +90552=Eksen disi +90553=Takim yönü ulasilamaz +90554=Hata +90555=???ERROR +90556=???Error in generation! +90557=???Simulation +90558=???One step at a time +90559=???Play/Pause +90560=???Stop/Home +90561=???Pause +90562=???Stopped simulation +90563=???Mach view +90564=???Home +90565=???Time +90566=???Length +90567=???Parts Area +90568=???Usage +90569=???Estimations +90570=???Details +// FrameCut +90601=X boyunca +90602=Y boyunca +90603=Cikart +90604=Kaba alma +90605=Finis +90606=Kenar finis +90607=Aynalama +90608=Ust silme +90609=Kenar silme +90610=???Trim start +90611=???Trim end +90612=Tek kesim +90613=???Arc +90614=???Guide +90615=???Section +90616=???Guide +90617=???Rad +90618=???Ang +90619=???Warning : radius smaller then section width +90620=???Error : frame creation failed +90621=???X clearance +90622=???Y clearance +// Machine +90701=Msg_Ita.xpi +90705=Makine bilgi +90706=Takimlar DB +90707=Kesim DB +90708=Makine +90709=???Statistics +90715=Yeni +90716=Yeni +90717=Kayit +90718=Sil +//ToolsDb +//param +90721=Isim +90722=Pozisyon +90723=Kafa +90724=Cikis +90725=Devir rpm +90726=Standart +90727=Maksimum +90728=Ilerleme Hizi +90729=Standart +90730=Tip +90731=Giris +90732=Cikis +90733=Sogutucu +90734=Kompanzasyon +90735=Malzeme payi +90736=Boyuna +90737=Radyal +90738=Maks guc +90739=Min ilerleme +90740=Maks derinlik +90741=Boy +90742=Cap +90743=Kalinlik +90744=Kesici +90745=???Notes +90746=???Serial Number +90747=???Code +90748=???Supplier +90749=???End Life +//tools families +90751=Testere +90752=Delici +90753=Freze +90754=???Pocket mill +90755=???Waterjet +//MachiningsDb +//param +90761=Isim +90762=Derinlik +90763=Kenar Aci +90764=Ters cevir +90765=Adim tipi +90766=Kesim Kenari +90767=Baslama Kenari +90768=Baslama pozisyonu +90769=Giris +90770=Baglanti +90771=Cikis +90772=Egri kullan +90773=Tolerans +90774=Derinlik kademesi +90775=Standart +90776=Derinlik adimi +90777=Ic yay +90778=Dis yay +90779=Yavalama boyu +90780=Baslangic +90781=Bitis +90782=Ek derinlik +90783=Pozisyona geri don +90784=Takim +90785=Min kalinlik +90786=Maks kalinlik +90787=Kademe +90788=Asagi +90789=Kenar +90790=Dikey +//machinings families +90791=Testere +90792=Delme +90793=Freze +90794=Testere ile kaba alma +90795=Testere ile finis +90796=???Pocketing +90797=???Waterjet +//ComboBox Param +90801=Hayir +90802=Ic +90803=Dis +90804=Ikiside +90821=Merkez +90822=Sol +90823=Sag +90824=Merkezde +90825=Ic +90826=Dis +90827=???Cent. Extended +90828=???Outer Extended +90829=???Prev Extended +90830=???Next Extended +90831=???Booth Extended +90832=Merkezde +90833=Ic +90834=Dis +90835=Atla +90836=Takribi +90837=Konveks +90838=Zig Zag +90839=Tek yone +90840=Geri ve ileri +90841=Tut +90842=None +90843=???Standard +90844=???Slowdown +90845=???Loop +90846=???Linear +90847=???Tangent +90848=???Glide +90849=???Helix +90850=???As lead in +// param2 +90861=Kenar +90862=???Tilted +90863=???Tilted back +90864=???Forward +90865=???Backward +90866=???Last backward +90867=???Forward angle +90868=???Probing +90869=???Min dist. points +90870=???Max dist. points +90871=???External +90872=???Internal +90873=???Slowdown len. +90874=???Slowdown % +90875=???Lead in hole +90876=???Radius +90877=???LP turns +90878=???HP turns +90879=???Enable +90880=???Corners +// Barcode +90881=Barcode +// param3 +90890=???Dist. tang. +90891=???Dist. perp. +90892=???Dist. tang. +90893=???Dist. perp. +// Alarms +90900=???Current Waterjet +90901=Kullanilan testere +90902=Ek takim +90903=Kullanilan delici +90904=Kullanilan freze +90905=Guvenli Z +90906=Guvenli kesim +90907=Guvenli kose +90908=Tum kesim muhafaza +90909=Delik ofset +90910=Delik denklik +90911=Delik tolerans +90912=NC Hata Listesi +90913=Malzemeler +90914=Ekle +90915=Cikar +90916=Kullanilan takimlar +90917=Delik parametre +90918=Dis yay min radyus +90919=Makine parametre +90920=Hicbiri +90921=Delici +90922=Freze +90923=Ikisi de +90924=???Int arc max A +90925=Testere parametre +90926=???Single hole in corner +90927=???Direct cuts +90928=???Final home +90929=???Millings parameters +90930=???Always on sinks +90931=???Nesting +90932=???Aligned +90933=???Setup +90934=???New +90935=???Delete +90936=???Overtable height +90937=???Camera +90938=???Background +90939=???Threshold +90940=???Tolerance +90941=???Washing +90942=???Confirm deletion of selected material? +90943=???Default setup +90944=???Always on corners +90945=???Select tool to probe +90946=???Cuts Feed start/end +90947=???Length +90948=???Slowdown% +90949=???Shortening +90950=???Probing +//Machine +90951=Baslat +90952=Durdur +90953=Iptal +90954=Oto +90955=Tek +90956=MDI +90957=Manuel +90958=Sifir +90959=Indir +90960=Yukle +90961=Aktive et +90962=Sil +90963=MDI Onayla +90964=CN Modu +90965=Makine komutlari +90966=MDI satir +90967=Parca program transferi +// Opsiyonlar +90981=Dil +90982=Yeni dil bir sonraki program acilisinda aktive olur. +90983=Olcum birimi +90984=Rotasyonu goruntule +90985=???Side angle +90986=???Same value +90987=???Multiple values +90988=???Direct insertion of parts +90989=???Parametrics and DXF +90990=???CSV +90991=???Fast grid +90992=???Enable standard pieces creation +90993=???Text color +90994=???Slab Dxf +90995=???Slab Layer +90996=???Parts Layer +90997=???Scrap Layer +90998=???Std Thick +90999=???ColorToSideAng +91000=???Enable +91001=???Tolerance +91002=???Heel +91003=???Side Angle +91004=???Feedback +91005=???Themes +//Alarms2 +91051=???Machinings +91052=???Sawing +91053=???Drilling +91054=???Milling +91055=???DripSawing +91056=???DripDrilling +91057=???WaterJet +91058=???Waterjet parameters +91059=???Automatic +//Statistics +91071=???Day Production +91072=???Week Production +91073=???Project +91074=???Parts Area +91075=???Cuts Area +91076=???Day +91077=???Week +91078=???Reset +91079=???To Produce Area +//EgtMsgBox +91101=Degisiklikler gecerli projeye kaydedilsin mi ? +91102=Degisiklikler gecerli takima kaydedilsin mi ? +91103=Degisiklikler gecerli kesime kaydedilsin mi ? +91104=Zaten kullanilan isim +91105=Carpma var bazi parcalar cekilecek. Devam mi? +91106=Ayni isimde bir dosya zaten var, uzerine kaydedilsin mi ? +91107=NC BAGLANTI +91108=Baglanmayi deneyiniz +91109=Baglanti basarisiz +91110=Baglanti basarili +91111=Hangi tabla kullanilsin ? +91112=CSV listesinden de parcalar silinsin mi ? +91113=Parcalar cikartilmadi +91114=Veya diger CSV listelerinden +91115=Hata +91116=Opsiyon uretim hatti aktif degil +91117=OmagVIEW icin dosya kopyalama hatasi +91118=???Retain parked parts ? +91119=???Error in ruined parts management +91120=???Characters \ / : * ? " < > | are not allowed +91121=???Are you sure you want to delete selected pieces? +91122=???Warning +91123=Tabla +// CSV +91201=Ac +91202=Ekle +91203=Yeni +91204=Kaldir +91205=???Error saving CSV file, continue anyway ? +91206=???Error reading CSV file +// OmagVIEW +91301=Tumu tamam +91302=Parca tamam +91303=Atik parca +91304=Etiket yazdir +91305=Onay +91306=???Print +// OmagOFFICE +// OptionPanel +91401=???RawPart +91402=???Disposition +91403=???Work +91404=???Simulation +// MachiningDbWindow +91451=???Material +91452=???Min Thickness +91453=???MaxThickness +// TopCommandBar +91501=???Save project is mandatory before export +91502=???Select export directory +91503=???Error in export +91504=???Export completed successfully +// Rawpart +91551=???Error loading photo +91552=???Import photo +// VeinMatching +91601=???Export +91602=???Show Info +91603=???Edit +91604=???Verify +91605=???Magnetic +91606=???Part not selectable in this situation +91607=???Part not selectable because belonging to non-current workgroup : +//Generic +91651=???Ok +91652=???Cancel +// ----- OmagPHOTO ----- +// General +92001=???Db not found! Impossible open software +// OptionPanel +92051=???Save +92052=???Add +92053=???Cancel +92054=???Remove +92055=???Are you sure you want to delete current slab? +// Slab +92071=???Id +92072=???Image name +92073=???State +92074=???Project assigned to +92075=???Warehouse position +92076=???Date +92101=???Name already used +92102=???Name is mandatory +92103=???Image is mandatory +// SearchPanel +92151=???Search +92152=???Thickness tolerance +92153=???Start date +92154=???End date +92155=???Reset +// ----- SarmaxWall ----- +// General +101001=BTL aktar +101002=Ciz +101003=Yerlestir +101004=Opsiyonlar +// ImportPage +101101 +// DrawPage +101201=Duvar +101202=Kapi +101203=Pencere +101204=Ekle +101205=Iptal +101206=Uygula +101207=Cikart +101208=Bosluk +// PlacePage +101301=Olustur +101302=Aktar +101303=Duvar yerlestir +101304=Ekle +101305=Yerlestir +101306=Cikart +101307=Katman kalinlik +101308=Ustten tabla sayisi +101309=Ekleme basarisiz +101310=Olusturma basarili +101311=Olusturma hatasi +101312=Aktarma uygulama basarili +101313=Aktarma uygulama hatasi +101314=Aktarma uygulama tamam +101315=Aktarma uygulama basarisiz +101316=Tum gantriler iptal +101317=Olusturma dosyasi eksik +// OptionsPage +101401=Makine opsiyonlari +101402=Yapistirma parametreleri +101403=X Ek ham +101404=Y Ek ham +101405=Ekstra yapistirma +101406=Sim parametre +101407=Sim genislik +101408=KAtman tabla sayisi +101409=Gantri aktivasyon +101410=Gantri yapistirma +101411=Sim gantri +101421=Yazilim opsiyonlari +101422=Dil secimi +101423=Yeni dil bir sonraki program acilisinda aktive olur. +101424=Kaydedilen proje numarasi +101425=Kapi ve pencerelere sim yerlesitr +101426=Acma yapistirici ilerlet +101427=Kapama yapistirici ilerlet +// OpenPage +101501=Gecersiz proje +// ----- End ----- diff --git a/ProgramData/EgtCAM5/Config/EgtCAM5 21h2.old b/ProgramData/EgtCAM5/Config/EgtCAM5 21h2.old new file mode 100644 index 0000000..0d00d4b --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgtCAM5 21h2.old @@ -0,0 +1,169 @@ +; Commento per evitare BOM con UTF-8 +[General] +Debug=3 +Licence=EgtCAM5-Key149-CarloB.lic +UserLevel=10 +MaxInstances=2 +Instances=0 +CommandLog=1 +Messages=English +Support=support@egaltech.com +WinPlace=1,1825,0,1090,994 +LastNgeDir=C:\EgtData\TEST\Data\T5 +LastNgeObjDir=C:\Temp +LastLuaDir=C:\EgtData\TEST\Data\Lua +LastImpDir=C:\EgtData\TEST\Data\T5\CommonwSPLIT +LastExpDir=C:\EGALTECH\LIGNA 2019\x sito & grafica\Progetto Skyline +2DDraw=1 +3DDraw=1 +Modify=1 +Transform=1 +HidePlace=0,0,2000,10,10 + +[Languages] +Count=3 +Language1=Italiano,EgalTechIta.txt +Language2=English,EgalTechEng.txt +Language3=Francais,EgalTechFra.txt + +[Lua] +LibsDir=C:\ProgramData\Egaltech\EgtCAM5\LuaLibs +BaseLib=EgtBase + +[GeomDB] +DefaultFont=ModernPropS.Nfe +NfeFontDir=C:\ProgramData\Egaltech\EgtCAM5\Fonts +DefaultColor=128,64,0 +SaveType=2 + +[OpenGL] +DoubleBuffer=1 +ColorBits=32 +DepthBits=24 +Driver=3 ; 1=software, 2=OldWay, 3=NewWay + +[Scene] +BackTop=176,208,210 +BackBottom=145,177,196 +ShowGFrame=1 +Mark=255,255,0 +SelSurf=255,255,192 +ShowMode=2 +CurveDir=0 +ShowTriaAdv=0 +ShowZmap=9 +TextureMaxLinPixels=4096 +ZoomWin=0,255,255,255,30 +DistLine=255,0,0 +MmUnits=1 +CustomColors=12890513,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215 + +[Grid] +DrawShowGrid=1 +MachiningShowGrid=0 +ShowFrame=1 +SnapStep=200 +SnapStepInch=12.7 +MinLineSStep=1 +MajLineSStep=10 +ExtSStep=100 +MinLnColor=153,153,153 +MajLnColor=153,153,153 + +[Import] +CncFlag=0 ; 0=Std,1=Chain,2=SkipZeroMach,4=SkipRapid +BtlFlag=24 ; +1=FlatPos +2=VertPos +4=SpecialTrim +8=TS3Pos +16=Ordinati + +[Export] +ImgWidth=2048 +ImgHeight=1536 + +[Beam] +BtlEnable=1 +BaseDir=C:\ProgramData\Egaltech\EgtCAM5\Beam +BtlExec=BatchProcess.lua +Button1=Process.lua,Images\Process.png,Lavora Travi +Button2=ClearProcess.lua,Images\ClearProcess.png,Cancella Lavorazione Trave +Button3=Swap.lua,Images\Swap.png,Scambia estremi trave +Button4=Rotate.lua,Images\Rotate.png,Ruota trave +Button5=DisableFeatures.lua,Images\DisableFeatures.png,Disabilita lavorazioni +Button6=EnableFeatures.lua,Images\EnableFeatures.png,Abilita lavorazioni +Button7=BeamMachinings,Images\BeamMachinings.png,Lista lavorazioni +Button8=HideAll.lua,Images\HideAll.png,Nascondi tutte le travi non selezionate +Button9=ShowAll.lua,Images\ShowAll.png,Visualizza tutte le travi +Button10=ShowBuilding.lua,Images\ShowBuilding.png,Visualizza struttura/Visualizza pezzi + +[Doors] +DdfEnable=0 +BaseDir=C:\EgtData\Doors\EgtCompoBase +DdfExec=Main.lua +DdfFun=DGD.Doors() +DdfMachExec=Machining.lua +TablesDir=MTables +CurrMTable=MAX_NE +DdfDir=C:\EgtData\TestCam\CMS_Doors +DdfDefaultDir=C:\EgtData\Varie\DDF +MTableWinPlace=0,145,63,1650,924 + +[Gunstock] +GsEnable=0 +GsExec=C:\EgtData\GunStock\Main.lua +ReadModFun=GGD.ReadModParams() +ReadPezFun=GGD.ReadPezParams() +WritePezFun=GGD.WritePezParams() +CreateFun=GGD.CreateGunstock() +ModDir=C:\EgtData\Varie\Gunstock\MAT7769\MOD +PezDir=C:\EgtData\Varie\Gunstock\MAT1217\PEZ + +[Special] +SpecialEnable=0 +; Reverse Post Proc +;Button1=C:\EgtData\ReversePost\Import.lua,C:\EgtData\ReversePost\Images\Import.png,Importa cnc +;Button2=C:\EgtData\ReversePost\Export.lua,C:\EgtData\ReversePost\Images\Export.png,Esporta cnc +;Button3=C:\EgtData\ReversePost\Simul.lua,C:\EgtData\ReversePost\Images\Simul.png,Prepara Simulazione +;Button4=C:\EgtData\ReversePost\Move.lua,C:\EgtData\ReversePost\Images\Move.png,Sposta punti + +[Special] +SpecialEnable=0 + +[Mach] +MachinesDir=C:\EgtData\Machines +ToolMakersDir=C:\ProgramData\Egaltech\EgtCAM5\ToolMakers +CurrMach=Essetre-FAST +SelGeomSawing=1 +SelGeomDrilling=1 +SelGeomMilling=1 +SelGeomPocketing=1 +SelGeomMortising=1 +SelGeomSawRoughing=1 +SelGeomSawFinishing=1 +MachiningGroup=1 +ShowOnlyTable=1 + +[Simul] +SliderX=0.25 +SliderVal=61.6 +[Options] +NewMachiningIsLastOne=1 +UseDispositionScript=1 + +[MruFiles] +File1=C:\EgtData\TEST\Data\T5\Part__19__43.nge +File2=C:\EgtData\TEST\Result.lua\T5-Part__22__1.nge +File3=C:\EgtData\TEST\Result.nge\T5-Part__22__1.nge +File4=C:\EgtData\TEST\Data\T5\T5-Part__22__1.nge +File5=C:\EgtData\TEST\Result.nge\Part__22__1.nge +File6=S:\CarloB\EsempiPerTestTravi\Part__19__43 S1.nge +File7=C:\EgtData\TEST\TestEssetreFAST\Travi prova 00\C1-3.nge +File8=C:\EgtData\TEST\TestEssetreFAST\Travi prova 00\Trave03 .nge + +[MruScripts] +File1=C:\EgtData\TEST\Data\Lua\BatchT5-SF3 1b.lua +File2=C:\EgtData\TEST\Data\Lua\BatchT5-SF3 1a.lua +File3=C:\EgtData\TEST\Data\Lua\BatchT5-SF3 00.lua +File4=C:\EgtData\Test\Data\Lua\T4-FSC2.lua +File5=C:\EgtData\Test\Data\Lua\T4-FSC2b-Lib.lua +File6=C:\EgtData\Test\Data\Lua\T4-FSC2-Lib.lua +File7=C:\EgtData\Test\Data\Lua\T4-FSC2b.lua +File8=C:\EgtData\Test\Data\Lua\T4-FSC2a.lua + diff --git a/ProgramData/EgtCAM5/Config/EgtCAM5-Key149-CarloB.lic b/ProgramData/EgtCAM5/Config/EgtCAM5-Key149-CarloB.lic new file mode 100644 index 0000000..5566817 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgtCAM5-Key149-CarloB.lic @@ -0,0 +1,12 @@ +; Commento per evitare BOM con UTF-8 +[Licence] +Customer=Key149-CarloB +LockId=EGTECH-000149-oOoAdI +Product=3279 +Ver=21 +Lev=10 +ExpDays=18292 +Opt1=191 +Opt2=87 +OptExpDays=18292 +Key=Z2VlT0lGIELqYQle4I6H/K3U36+saD7jyXup86NIPg0Q+lRq diff --git a/ProgramData/EgtCAM5/Config/EgtCAM5-Key149.lic b/ProgramData/EgtCAM5/Config/EgtCAM5-Key149.lic new file mode 100644 index 0000000..8eed9e2 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgtCAM5-Key149.lic @@ -0,0 +1,12 @@ +; Commento per evitare BOM con UTF-8 +[Licence] +Customer=Key149-CarloB +LockId=EGTECH-000149-oOoAdI +Product=3279 +Ver=19 +Lev=10 +ExpDays=17927 +Opt1=191 +Opt2=23 +OptExpDays=17927 +Key=Mctg8ooYpdnucqn0srTqvxwu6+5Yh57mkaCBSpNU0UldbVai diff --git a/ProgramData/EgtCAM5/Config/EgtCAM5-Key335-CarloB.lic b/ProgramData/EgtCAM5/Config/EgtCAM5-Key335-CarloB.lic new file mode 100644 index 0000000..0b41479 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgtCAM5-Key335-CarloB.lic @@ -0,0 +1,12 @@ +; Commento per evitare BOM con UTF-8 +[Licence] +Customer=Key-000335-EgtCAM5-Carlo B. +LockId=EGTECH-000335-oOoCcE +Product=3279 +Ver=21 +Lev=10 +ExpDays=18292 +Opt1=255 +Opt2=83 +OptExpDays=18292 +Key=1Od6WQ04Ftd6vPprLU1eUYSSUIQZRHY9cvk6VecqsLCGIyAT diff --git a/ProgramData/EgtCAM5/Config/EgtCAM5-Key335-InternaBaronchelli.lic b/ProgramData/EgtCAM5/Config/EgtCAM5-Key335-InternaBaronchelli.lic new file mode 100644 index 0000000..24847c3 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgtCAM5-Key335-InternaBaronchelli.lic @@ -0,0 +1,12 @@ +; Commento per evitare BOM con UTF-8 +[Licence] +Customer=Key-000335-EgtCAM5-Carlo B. +LockId=EGTECH-000335-oOoCcE +Product=3279 +Ver=2301 +Lev=10 +ExpDays=19023 +Opt1=255 +Opt2=83 +OptExpDays=19023 +Key=cD20J4ajO5/gVc9UfEIN4Di8mnLts1caNaFIcZLo/aZQ3Irt diff --git a/ProgramData/EgtCAM5/Config/EgtCAM5.ini b/ProgramData/EgtCAM5/Config/EgtCAM5.ini new file mode 100644 index 0000000..4787e99 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/EgtCAM5.ini @@ -0,0 +1,198 @@ +; Commento per evitare BOM con UTF-8 +[General] +Debug=3 +Licence=Key-000335-EgtCAM5-Carlo Baronchelli_OpzioneWall..lic +UserLevel=10 +MaxInstances=2 +Instances=0 +CommandLog=5 +Messages=English +Support=support@egaltech.com +WinPlace=1,327,0,760,742 +LastNgeDir=C:\ProgramData\EgalTech\EgtBeamWall\Projs\0001 +LastNgeObjDir=C:\Temp +LastLuaDir=C:\EgtDev\frontalini\Frontalini_ecc\CompoAF +LastImpDir=C:\EgtData\TEST\Data\T101-TestFAST +LastExpDir=C:\EGALTECH\LIGNA 2019\x sito & grafica\Progetto Skyline +2DDraw=1 +3DDraw=1 +Modify=1 +Transform=1 +HidePlace=0,0,2000,10,10 + +[Languages] +Count=5 +Language1=Italiano,EgalTechIta.txt +Language2=English,EgalTechEng.txt +Language3=Francais,EgalTechFra.txt +Language4=Deutsch,EgalTechDeu.txt +Language5=Espagnol,EgalTechEsp.txt + +[Lua] +LibsDir=C:\ProgramData\Egaltech\EgtCAM5\LuaLibs +BaseLib=EgtBase + +[GeomDB] +DefaultFont=ModernPropS.Nfe +NfeFontDir=C:\ProgramData\Egaltech\EgtCAM5\Fonts +DefaultColor=128,64,0 +SaveType=2 + +[OpenGL] +DoubleBuffer=1 +ColorBits=32 +DepthBits=24 +Driver=3 ; 1=software, 2=OldWay, 3=NewWay + +[Scene] +BackTop=176,208,210 +BackBottom=145,177,196 +ShowGFrame=1 +Mark=255,255,0 +SelSurf=255,255,192 +ShowMode=2 +CurveDir=1 +ShowTriaAdv=0 +ShowZmap=9 +TextureMaxLinPixels=4096 +ZoomWin=0,255,255,255,30 +DistLine=255,0,0 +MmUnits=1 +CustomColors=12890513,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215 + +[Grid] +DrawShowGrid=1 +MachiningShowGrid=0 +ShowFrame=1 +SnapStep=100 +SnapStepInch=12.7 +MinLineSStep=1 +MajLineSStep=10 +ExtSStep=100 +MinLnColor=153,153,153 +MajLnColor=153,153,153 + +[Import] +CncFlag=0 ; 0=Std,1=Chain,2=SkipZeroMach,4=SkipRapid +BtlFlag=24 ; +1=FlatPos +2=VertPos +4=SpecialTrim +8=TS3Pos +16=Ordinati +BtlAuxDir=C:\ProgramData\Egaltech\EgtCAM5\BtlAux + +[Export] +ImgWidth=2048 +ImgHeight=1536 + +[Beam] +BtlEnable=1 +BaseDir=C:\ProgramData\EgalTech\EgtCAM5\Beam +BtlExec=BatchProcess.lua +BweExec=BatchProcessNew.lua +Button1=Process.lua,Images\Process.png,Lavora Travi +Button2=Swap.lua,Images\Swap.png,Scambia estremi Trave +Button3=Rotate.lua,Images\Rotate.png,Ruota Trave +Button4=BeamMachinings,Images\BeamMachinings.png,Lista lavorazioni Travi +DATA_DIR=C:\ProgramData\EgtData +Machines=FAST,ONE,PF + +[BeamWall] +BtlEnable=1 +BaseDir=C:\ProgramData\EgalTech\EgtCAM5\BeamWall +Button1=ClearProcess.lua,Images\ClearProcess.png,Cancella Lavorazioni Pezzo +Button2=DisableFeatures.lua,Images\DisableFeatures.png,Disabilita Lavorazioni +Button3=EnableFeatures.lua,Images\EnableFeatures.png,Abilita Lavorazioni +Button4=HideAll.lua,Images\HideAll.png,Nascondi i Pezzi non selezionati +Button5=ShowAll.lua,Images\ShowAll.png,Visualizza tutti i Pezzi +Button6=ShowSolid.lua,Images\ShowSolid.png,Visualizza/Nascondi Solido +Button7=ShowBuilding.lua,Images\ShowBuilding.png,Visualizza Struttura/Pezzi + +[Wall] +BtlEnable=1 +;BaseDir=C:\ProgramData\EgalTech\EgtCAM5\Wall +BaseDir=C:\EGALTECH\ProgettoRestylingWall\Wall +BtlExec=BatchProcess.lua +BweExec=BatchProcessNew.lua +DATA_DIR=C:\ProgramData\EgtData +Button1=Process.lua,Images\Process.png,Lavora Pareti +Button2=Rotate.lua,Images\Rotate.png,Ruota Parete +Button3=Overturn.lua,Images\Overturn.png,Ribalta Parete +Button4=WallMachinings,Images\WallMachinings.png,Lista lavorazioni Pareti +[Doors] +DdfEnable=0 +BaseDir=C:\EgtData\Doors\EgtCompoBase +DdfExec=Main.lua +DdfFun=DGD.Doors() +DdfMachExec=Machining.lua +TablesDir=MTables +CurrMTable=MAX_NE +DdfDir=C:\EgtData\TestCam\CMS_Doors +DdfDefaultDir=C:\EgtData\Varie\DDF +MTableWinPlace=0,145,63,1650,924 + +[Gunstock] +GsEnable=0 +GsExec=C:\EgtData\GunStock\Main.lua +ReadModFun=GGD.ReadModParams() +ReadPezFun=GGD.ReadPezParams() +WritePezFun=GGD.WritePezParams() +CreateFun=GGD.CreateGunstock() +ModDir=C:\EgtData\Varie\Gunstock\MAT7769\MOD +PezDir=C:\EgtData\Varie\Gunstock\MAT1217\PEZ + +[Special] +SpecialEnable=0 +; Reverse Post Proc +;Button1=C:\EgtData\ReversePost\Import.lua,C:\EgtData\ReversePost\Images\Import.png,Importa cnc +;Button2=C:\EgtData\ReversePost\Export.lua,C:\EgtData\ReversePost\Images\Export.png,Esporta cnc +;Button3=C:\EgtData\ReversePost\Simul.lua,C:\EgtData\ReversePost\Images\Simul.png,Prepara Simulazione +;Button4=C:\EgtData\ReversePost\Move.lua,C:\EgtData\ReversePost\Images\Move.png,Sposta punti + +[Special] +SpecialEnable=0 + +[Mach] +MachinesDir=C:\EgtData\Machines +ToolMakersDir=C:\ProgramData\Egaltech\EgtCAM5\ToolMakers +CurrMach=Essetre-90480027 +SelGeomSawing=1 +SelGeomDrilling=1 +SelGeomMilling=1 +SelGeomPocketing=1 +SelGeomMortising=1 +SelGeomSawRoughing=1 +SelGeomSawFinishing=1 +MachiningGroup=1 +ShowOnlyTable=1 +SelGeomGenMachining=1 +SelGeomChiseling=1 +SelGeomSurfFinishing=3 +MoveThroughDisps=1 + +[Simul] +SliderX=0.25 +SliderVal=77.1 +[Options] +NewMachiningIsLastOne=1 +UseDispositionScript=1 + +[MruFiles] +File1=C:\ProgramData\EgalTech\EgtBeamWall\Projs\0001\5.bwe +File2=C:\ProgramData\EgalTech\EgtBeamWall\Projs\0001\0001.nge +File3=C:\ProgramData\EgalTech\EgtBeamWall\Projs\0001\CasaMosca0001.nge +File4=E:\EGALWARE\ProgramData\BeamWall\CasaMosca0001.nge +File5=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\PcucinaC23.nge +File6=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\PcucinaC23__CAM-SimRib.nge +File7=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\PcucinaC23__CAM-Sim.nge +File8=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\PcucinaC23__CAM-Rib.nge + +[MruScripts] +File1=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\Alz&Front.lua +File2=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\PCucinaC23.lua +File3=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\Alz&Front daSara 00a.lua +File4=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\PCucinaD23.lua +File5=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\PCucinaC1.lua +File6=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\PCucinaD1.lua +File7=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\PCucinaA23.lua +File8=C:\EgtDev\frontalini\Frontalini__ecc\CompoAF\PCucinaA1.lua + +[DimensionStyle] +TextHeight=20 + diff --git a/ProgramData/EgtCAM5/Config/Key-000335-EgtCAM5-Carlo Baronchelli_OpzioneWall..lic b/ProgramData/EgtCAM5/Config/Key-000335-EgtCAM5-Carlo Baronchelli_OpzioneWall..lic new file mode 100644 index 0000000..192ffc3 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/Key-000335-EgtCAM5-Carlo Baronchelli_OpzioneWall..lic @@ -0,0 +1,13 @@ +; Commento per evitare BOM con UTF-8 +[Licence] +Customer=Key-000335-EgtCAM5-Carlo B. +LockId=EGTECH-000335-oOoCcE +Product=3279 +Ver=2401 +Lev=1 +ExpDays=19388 +Opt1=255 +Opt2=595 +OptExpDays=19388 +Key=Zozxn61iW+bCSIl7mxHhuOaS3AfIrm/ZoCjNjMGiX2M5nBdY + diff --git a/ProgramData/EgtCAM5/Config/OmagCUT-Key335-CarloB.lic b/ProgramData/EgtCAM5/Config/OmagCUT-Key335-CarloB.lic new file mode 100644 index 0000000..06c8cf4 --- /dev/null +++ b/ProgramData/EgtCAM5/Config/OmagCUT-Key335-CarloB.lic @@ -0,0 +1,12 @@ +; Commento per evitare BOM con UTF-8 +[Licence] +Customer=Key-000335-OmagCUT +LockId=EGTECH-000335-oOoCcE +Product=9423 +Ver=22 +Lev=10 +ExpDays=18658 +Opt1=175 +Opt2=255599 +OptExpDays=18658 +Key=TMKZEnY79ouITJ6mXxG9a1CEcAIBLSoh5qBJ87bJ14ql2ZdK diff --git a/ProgramData/EgtCAM5/Data/ProvaNUM01.nge b/ProgramData/EgtCAM5/Data/ProvaNUM01.nge new file mode 100644 index 0000000..f13a36d Binary files /dev/null and b/ProgramData/EgtCAM5/Data/ProvaNUM01.nge differ diff --git a/ProgramData/EgtCAM5/Data/ProvaNUM01_VM_Mach_2.Nge b/ProgramData/EgtCAM5/Data/ProvaNUM01_VM_Mach_2.Nge new file mode 100644 index 0000000..d916546 Binary files /dev/null and b/ProgramData/EgtCAM5/Data/ProvaNUM01_VM_Mach_2.Nge differ diff --git a/ProgramData/EgtCAM5/DataRoot.ini b/ProgramData/EgtCAM5/DataRoot.ini new file mode 100644 index 0000000..8b31c54 --- /dev/null +++ b/ProgramData/EgtCAM5/DataRoot.ini @@ -0,0 +1,3 @@ +; Commento per evitare BOM con UTF-8 +[Data] +DataRoot=C:\EgtDev\refactorwall\ProgramData\EgtCAM5 diff --git a/ProgramData/EgtCAM5/Fonts/ModernProp.Nfe b/ProgramData/EgtCAM5/Fonts/ModernProp.Nfe new file mode 100644 index 0000000..7a4efc7 Binary files /dev/null and b/ProgramData/EgtCAM5/Fonts/ModernProp.Nfe differ diff --git a/ProgramData/EgtCAM5/Fonts/ModernPropS.Nfe b/ProgramData/EgtCAM5/Fonts/ModernPropS.Nfe new file mode 100644 index 0000000..c316e84 Binary files /dev/null and b/ProgramData/EgtCAM5/Fonts/ModernPropS.Nfe differ diff --git a/ProgramData/EgtCAM5/Fonts/ScriptS.Nfe b/ProgramData/EgtCAM5/Fonts/ScriptS.Nfe new file mode 100644 index 0000000..bdbf7b7 Binary files /dev/null and b/ProgramData/EgtCAM5/Fonts/ScriptS.Nfe differ diff --git a/ProgramData/EgtCAM5/LuaCmd/CompactId.lua b/ProgramData/EgtCAM5/LuaCmd/CompactId.lua new file mode 100644 index 0000000..65597f6 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/CompactId.lua @@ -0,0 +1,96 @@ +-- CompactId.lua 2018/04/21 +-- Non funziona in presenza di lavorazioni + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- funzione per spostare gli Id +local function ChangeAllId( nBase, nFirstId, vTab) + local nNewId = nFirstId + local nId = EgtGetFirstInGroup( nBase) + while nId do + EgtChangeId( nId, nNewId) + vTab[nId] = nNewId + nId = nNewId + nNewId = nNewId + 1 + if EgtGetType( nId) == GDB_TY.GROUP then + nNewId = ChangeAllId( nId, nNewId, vTab) + end + nId = EgtGetNext( nId) + end + return nNewId +end + +-- funzione per aggiornare un riferimento agli Id +local function UpdateRefId( nId, sKey, vTab) + local sVal = EgtGetInfo( nId, sKey) + if sVal then + local sNewVal = '' + local vVal = EgtSplitString( sVal, ',') + for i = 1, #vVal do + local nRefId = tonumber( vVal[i]) + local nNewRefId = vTab[nRefId] + sNewVal = sNewVal .. EgtIf( i > 1, ',', '') .. tostring( nNewRefId) + end + EgtSetInfo( nId, sKey, sNewVal) + end +end + +-- funzione per aggiornare riferimenti agli Id +local function UpdateAllRefId( nBase, vTab) + local nId = EgtGetFirstInGroup( nBase) + while nId do + UpdateRefId( nId, '!SOU', vTab) + UpdateRefId( nId, '!BAS', vTab) + UpdateRefId( nId, '!LST', vTab) + if EgtGetType( nId) == GDB_TY.GROUP then + UpdateAllRefId( nId, vTab) + end + nId = EgtGetNext( nId) + end +end + +-- funzione per aggiornare gli identificativi dei grezzi nelle disposizioni +-- DA FARE : manca funzione Egt per cambiare id grezzi disposizioni + +-- funzione per aggiornare i riferimenti geometrici delle lavorazioni +-- DA FARE + +-- devo essere in modalità disegno +if EgtGetCurrMachGroup() then + EgtOutBox( 'Non è possibile compattare gli Id in LAVORA', 'CompactId', 'WARNING') + return +end + +-- per ora richiedo non ci siano gruppi di lavorazione +if EgtGetMachGroupCount() > 0 then + EgtOutBox( 'Non è possibile compattare gli Id in progetti con Gruppi di Lavoro', 'CompactId', 'WARNING') + return +end + +-- elimino l'eventuale gruppo delle macchine +EgtErase( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'MachAux') or GDB_ID.NULL) + +-- recupero Id Max +local nNextId = EgtGetNewId() + +-- sposto tutti gli Id dal Max in su +local vTab = {} +ChangeAllId( GDB_ID.ROOT, nNextId, vTab) + +-- sposto gli Id in basso +local vTab2 = {} +ChangeAllId( GDB_ID.ROOT, 1, vTab2) +for k, v in pairs( vTab) do + vTab[k] = vTab2[v] +end + +-- aggiorno i riferimenti agli Id nelle Info +UpdateAllRefId( GDB_ID.ROOT, vTab) + +-- aggiorni i roferimenti agli Id nelle disposizioni + +-- aggiorno i riferimenti agli Id nelle lavorazioni diff --git a/ProgramData/EgtCAM5/LuaCmd/Exec.lua b/ProgramData/EgtCAM5/LuaCmd/Exec.lua new file mode 100644 index 0000000..cfe9289 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/Exec.lua @@ -0,0 +1,20 @@ +-- 2019/03/16 +-- Esecuzione di un comando lua +-- Istruzioni : +-- inserire il comando nel dialogo e confermare. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Imposto dialogo per modifica +local vsVal = EgtDialogBox( 'Exec', + {'Command', ''}) +if not vsVal then return end +local sCode = vsVal[1] + +-- Eseguo comando +assert( load( sCode))() + +EgtDraw() diff --git a/ProgramData/EgtCAM5/LuaCmd/FlattenCurve.lua b/ProgramData/EgtCAM5/LuaCmd/FlattenCurve.lua new file mode 100644 index 0000000..f6f1cb6 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/FlattenCurve.lua @@ -0,0 +1,40 @@ +-- 2018/09/01 +-- Appiattimento di una curva +-- Istruzioni : +-- 1) selezionare la curva da appiattire +-- 3) eseguire il componente. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato (curva da appiattire) +local nId = EgtGetFirstSelectedObj() +local nType = EgtGetType( nId) +if nType ~= GDB_TY.CRV_LINE and nType ~= GDB_TY.CRV_ARC and nType ~= GDB_TY.CRV_BEZ and nType ~= GDB_TY.CRV_COMPO then + EgtOutText( 'Il primo oggetto selezionato non è una curva') + EgtPause( 500) + return +end + +-- Recupero Estrusione e la annullo +local vtExtr = EgtCurveExtrusion( nId) +EgtModifyCurveExtrusion( nId, V_NULL()) + +-- Recupero piano medio della curva e verifico se abbastanza piatta +local bFlat, vtN, dDist = EgtCurveIsFlat( nId, 0.1) +if not bFlat then + EgtOutText( 'La curva è molto ingobbita (scostamento oltre 0.1 mm)') +end + +-- Eseguo l'appiattimento +local bOk = EgtProjectCurveOnPlane( nId, dDist * vtN, vtN, GDB_RT.LOC) + +-- Imposto versore estrusione +if vtExtr and vtExtr * vtN < 0 then vtN = - vtN end +EgtModifyCurveExtrusion( nId, vtN) + +EgtDraw() +EgtPause( 500) diff --git a/ProgramData/EgtCAM5/LuaCmd/ImportPnt.lua b/ProgramData/EgtCAM5/LuaCmd/ImportPnt.lua new file mode 100644 index 0000000..d2ee8e8 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/ImportPnt.lua @@ -0,0 +1,13 @@ +-- 2018/04/26 +-- Importazione punti + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato +EgtImportPnt( 'c:\\EgtData\\Varie\\DxfNgePnt_Saw_2D\\P_EST.pnt') + +EgtZoom( SCE_ZM.ALL) diff --git a/ProgramData/EgtCAM5/LuaCmd/RegionDifference.lua b/ProgramData/EgtCAM5/LuaCmd/RegionDifference.lua new file mode 100644 index 0000000..4c7f3af --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/RegionDifference.lua @@ -0,0 +1,46 @@ +-- 2018/06/21 +-- Differenza booleana di due regioni +-- Istruzioni : +-- 1) selezionare le due +-- 2) eseguire il componente + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato (regione) +local nId1 = EgtGetFirstSelectedObj() +if not nId1 or EgtGetType( nId1) ~= GDB_TY.SRF_FRGN then + EgtOutText( 'Il primo oggetto selezionato non è una regione') + EgtPause( 1000) + return +end + +-- Recupero secondo oggetto selezionato (regione) +local nId2 = EgtGetNextSelectedObj() +if not nId2 or EgtGetType( nId2) ~= GDB_TY.SRF_FRGN then + EgtOutText( 'Il secondo oggetto selezionato non è una regione') + EgtPause( 1000) + return +end + +-- eseguo la differenza +local bOk = EgtSurfFrSubtract( nId1, nId2) + +-- cancello la seconda regione +if bOk then + EgtErase( nId2) + if not EgtExistsObj( nId1) then + EgtOutText( 'La differenza tra le regioni è vuota') + EgtPause( 1000) + return + end +else + EgtOutText( 'La differenza tra le regioni non è riuscita') + EgtPause( 1000) + return +end + +EgtDraw() diff --git a/ProgramData/EgtCAM5/LuaCmd/RegionGetLoops.lua b/ProgramData/EgtCAM5/LuaCmd/RegionGetLoops.lua new file mode 100644 index 0000000..85963d8 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/RegionGetLoops.lua @@ -0,0 +1,40 @@ +-- 2018/06/20 +-- Recupero dei bordi di una regione +-- Istruzioni : +-- 1) selezionare la regione +-- 2) eseguire il componente. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato (superficie da cui recuperare i contorni) +local nId1 = EgtGetFirstSelectedObj() +if not nId1 or EgtGetType( nId1) ~= GDB_TY.SRF_FRGN then + EgtOutText( 'Il primo oggetto selezionato non è una regione') + EgtPause( 1000) + return +end + +-- verifico ci sia un layer corrente in cui mettere le curve +local nDestId = EgtGetCurrLayer() +if not nDestId then + EgtOutText( 'Non è definito il layer corrente dove mettere le curve') + EgtPause( 1000) + return +end + +-- Recupero i contorni della regione +local nTotChunk = EgtSurfFrChunkCount( nId1) +for nChk = 1, nTotChunk do + local nCrvFstId = EgtExtractSurfFrChunkLoops( nId1, nChk - 1, nDestId) + if not nCrvFstId then + EgtOutText( 'La superficie non ha bordi (è chiusa)') + EgtPause( 1000) + return + end +end + +EgtDraw() diff --git a/ProgramData/EgtCAM5/LuaCmd/RegionIntersection.lua b/ProgramData/EgtCAM5/LuaCmd/RegionIntersection.lua new file mode 100644 index 0000000..0e6b6a8 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/RegionIntersection.lua @@ -0,0 +1,46 @@ +-- 2018/06/21 +-- Differenza booleana di due regioni +-- Istruzioni : +-- 1) selezionare le due +-- 2) eseguire il componente + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato (regione) +local nId1 = EgtGetFirstSelectedObj() +if not nId1 or EgtGetType( nId1) ~= GDB_TY.SRF_FRGN then + EgtOutText( 'Il primo oggetto selezionato non è una regione') + EgtPause( 1000) + return +end + +-- Recupero secondo oggetto selezionato (regione) +local nId2 = EgtGetNextSelectedObj() +if not nId2 or EgtGetType( nId2) ~= GDB_TY.SRF_FRGN then + EgtOutText( 'Il secondo oggetto selezionato non è una regione') + EgtPause( 1000) + return +end + +-- eseguo l'intersezione +local bOk = EgtSurfFrIntersect( nId1, nId2) + +-- cancello la seconda regione +if bOk then + EgtErase( nId2) + if not EgtExistsObj( nId1) then + EgtOutText( 'La intersezione tra le regioni è vuota') + EgtPause( 1000) + return + end +else + EgtOutText( 'La intersezione tra le regioni non è riuscita') + EgtPause( 1000) + return +end + +EgtDraw() diff --git a/ProgramData/EgtCAM5/LuaCmd/RegionOffset.lua b/ProgramData/EgtCAM5/LuaCmd/RegionOffset.lua new file mode 100644 index 0000000..ed05f07 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/RegionOffset.lua @@ -0,0 +1,59 @@ +-- 2018/06/20 +-- Offset di una regione +-- Istruzioni : +-- 1) selezionare la regione +-- 2) eseguire il componente +-- 3) inserire i parametri richiesti nel dialogo. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato (regione da offsettare) +local nId1 = EgtGetFirstSelectedObj() +if not nId1 or EgtGetType( nId1) ~= GDB_TY.SRF_FRGN then + EgtOutText( 'Il primo oggetto selezionato non è una regione') + EgtPause( 1000) + return +end + +-- Chiedo i parametri di offset +local vsVal = EgtDialogBox( 'Region Offset', { 'Distanza', '0.0'}, { 'Tipo', 'CB:Raccordo,Smusso,Estendi'}, { 'Copia', 'CB:True,*False'}) +if not vsVal or #vsVal ~= 3 then return end +local dDist = tonumber( vsVal[1]) +local nType = GDB_OT.FILLET +if vsVal[2] == 'Smusso' then + nType = GDB_OT.CHAMFER +elseif vsVal[2] == 'Estendi' then + nType = GDB_OT.EXTEND +end +local bCopy = true +if vsVal[3] == 'False' then + bCopy = false +end + +-- Se richiesta copia, la eseguo +local nId2 = nId1 +if bCopy then + nId2 = EgtCopy( nId1, nId1, GDB_IN.AFTER) + if not nId2 then + EgtOutText( 'Errore nella copia della regione') + EgtPause( 1000) + end +end + +-- Eseguo l'offset della superficie +local bOk = EgtSurfFrOffset( nId2, dDist, nType) + +-- Se copia, sistemazioni finali +if bCopy then + if bOk then + EgtSetAlpha( nId1, 30) + else + EgtErase( nId2) + end +end + +EgtDraw() diff --git a/ProgramData/EgtCAM5/LuaCmd/RegionUnion.lua b/ProgramData/EgtCAM5/LuaCmd/RegionUnion.lua new file mode 100644 index 0000000..94cee1e --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/RegionUnion.lua @@ -0,0 +1,41 @@ +-- 2018/06/21 +-- Unione booleana di due regioni +-- Istruzioni : +-- 1) selezionare le due +-- 2) eseguire il componente + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato (regione) +local nId1 = EgtGetFirstSelectedObj() +if not nId1 or EgtGetType( nId1) ~= GDB_TY.SRF_FRGN then + EgtOutText( 'Il primo oggetto selezionato non è una regione') + EgtPause( 1000) + return +end + +-- Recupero secondo oggetto selezionato (regione) +local nId2 = EgtGetNextSelectedObj() +if not nId2 or EgtGetType( nId2) ~= GDB_TY.SRF_FRGN then + EgtOutText( 'Il secondo oggetto selezionato non è una regione') + EgtPause( 1000) + return +end + +-- eseguo l'unione +local bOk = EgtSurfFrAdd( nId1, nId2) + +-- cancello la seconda regione +if bOk then + EgtErase( nId2) +else + EgtOutText( 'La unione tra le regioni non è riuscita') + EgtPause( 1000) + return +end + +EgtDraw() diff --git a/ProgramData/EgtCAM5/LuaCmd/SaveVmill.lua b/ProgramData/EgtCAM5/LuaCmd/SaveVmill.lua new file mode 100644 index 0000000..0d56fd3 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/SaveVmill.lua @@ -0,0 +1,112 @@ +-- 2019/04/24 +-- Salvataggio Virtual Milling + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Recupero numero dei gruppi di lavoro +local nMGrpCount = EgtGetMachGroupCount() + +-- Se non ci sono gruppi di lavoro, non c'è niente da fare +if nMGrpCount == 0 then + EgtOutBox( 'VMills missing (no Machining Group)', 'Warning', 'WARNING') +end + +-- Se esiste il gruppo dei VMill (per macchine travi) +local VMillId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') +if VMillId then + -- Disabilito segnalazione modifiche + local bOldEnabModif = EgtGetEnableModified() + EgtDisableModified() + -- Lo rendo user level e visibile + EgtSetLevel( VMillId, GDB_LV.USER) + EgtSetStatus( VMillId, GDB_ST.ON) + -- Chiedo il nome del file in cui salvare + local sFile = EgtSplitPath( EgtGetCurrFilePath()) .. 'VMill.nge' + local sFilePath = EgtFileDialog( false, sFile, "Nge Files (*.nge)|*.nge||") + -- Lo salvo + EgtSaveObjToFile( VMillId, sFilePath, GDB_NT.CMPTXT) + EgtOutText( sFilePath .. ' saved') + -- Ripristino il livello temporaneo e lo stato nascosto + EgtSetLevel( VMillId, GDB_LV.TEMP) + EgtSetStatus( VMillId, GDB_ST.OFF) + -- Ripristino precedente stato segnalazione modifiche + if bOldEnabModif then + EgtEnableModified() + end + return +end + +-- Se c'è un solo gruppo di lavoro, lo rendo corrente +if nMGrpCount == 1 then + EgtSetCurrMachGroup() +-- altrimenti ci sono più gruppi di lavoro, chiedo da quale prendere i VMill e lo rendo corrente +else + -- Creo la lista dei gruppi di lavoro + local sMGrp = 'CB:' + local nMGrpId = EgtGetFirstMachGroup() + while nMGrpId do + sMGrp = sMGrp .. EgtGetMachGroupName( nMGrpId) .. ',' + nMGrpId = EgtGetNextMachGroup( nMGrpId) + end + -- Dialogo di scelta + local vVal = EgtDialogBox( 'SaveVmill 2', { 'Gruppo di lavoro', sMGrp}) + if not vVal or #vVal == 0 then + return + end + EgtSetCurrMachGroup( EgtGetMachGroupId( vVal[1]) or GDB_ID.NULL) +end + +-- Recupero tutti i Vmill del gruppo di lavoro corrente +local vVMill = {} +local nRawId = EgtGetFirstRawPart() +while nRawId do + local nVMillId = EgtGetFirstNameInGroup( nRawId, 'VMill') + if nVMillId then + table.insert( vVMill, nVMillId) + end + nRawId = EgtGetNextRawPart( nRawId) +end + +-- Se trovati VMill, creo un pezzo+layer e ve li copio +if #vVMill > 0 then + -- Disabilito segnalazione modifiche + local bOldEnabModif = EgtGetEnableModified() + EgtDisableModified() + -- Creo o svuoto gruppo per copia finale degli oggetti virtual milling + local nVmPrtId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + if nVmPrtId then + EgtSetStatus( nVmPrtId, GDB_ST.ON) + EgtEmptyGroup( nVmPrtId) + else + nVmPrtId = EgtGroup( GDB_ID.ROOT) + EgtSetName( nVmPrtId, 'VMill') + end + -- Creo layer + local nVmLayId = EgtGroup( nVmPrtId) + -- Copio tutti i VMill nel layer + for i = 1, #vVMill do + local nNewId = EgtCopyGlob( vVMill[i], nVmLayId) + EgtSetLevel( nNewId, GDB_LV.USER) + EgtSetStatus( nNewId, GDB_ST.ON) + end + -- Chiedo il nome del file in cui salvare + local sFile = EgtSplitPath( EgtGetCurrFilePath()) .. 'VMill.nge' + local sFilePath = EgtFileDialog( false, sFile, "Nge Files (*.nge)|*.nge||") + -- Lo salvo + EgtSaveObjToFile( nVmPrtId, sFilePath, GDB_NT.CMPTXT) + EgtOutText( sFilePath .. ' saved') + -- Elimino il gruppo + EgtErase( nVmPrtId) + -- Ripristino precedente stato segnalazione modifiche + if bOldEnabModif then + EgtEnableModified() + end +else + EgtOutBox( 'VMills missing', 'Warning', 'WARNING') +end + +-- Reset gruppo di lavoro corrente +EgtResetCurrMachGroup() diff --git a/ProgramData/EgtCAM5/LuaCmd/SetSystemLevel.lua b/ProgramData/EgtCAM5/LuaCmd/SetSystemLevel.lua new file mode 100644 index 0000000..f97ee46 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/SetSystemLevel.lua @@ -0,0 +1,15 @@ +-- 2018/04/26 +-- Cambio livello oggetto a utente + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +if not nId then return end + +-- Imposto livello utente +EgtSetLevel( nId, GDB_LV.SYSTEM) diff --git a/ProgramData/EgtCAM5/LuaCmd/SetUserLevel.lua b/ProgramData/EgtCAM5/LuaCmd/SetUserLevel.lua new file mode 100644 index 0000000..35f9091 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/SetUserLevel.lua @@ -0,0 +1,15 @@ +-- 2018/04/26 +-- Cambio livello oggetto a utente + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +if not nId then return end + +-- Imposto livello utente +EgtSetLevel( nId, GDB_LV.USER) diff --git a/ProgramData/EgtCAM5/LuaCmd/SurfTmCut.lua b/ProgramData/EgtCAM5/LuaCmd/SurfTmCut.lua new file mode 100644 index 0000000..2282427 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/SurfTmCut.lua @@ -0,0 +1,35 @@ +-- 2018/06/20 +-- Taglio di una supertifie trimesh con un piano +-- Istruzioni : +-- 1) selezionare la superficie da tagliare +-- 2) selezionare il piano di taglio +-- 3) eseguire il componente. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato (superficie da tagliare) +local nId1 = EgtGetFirstSelectedObj() +if not nId1 or EgtGetType( nId1) ~= GDB_TY.SRF_MESH then + EgtOutText( 'Il primo oggetto selezionato non è una superficie') + EgtPause( 1000) + return +end + +-- Recupero secondo oggetto selezionato (piano di taglio) +local nId2 = EgtGetNextSelectedObj() +if not nId2 or EgtGetType( nId2) ~= GDB_TY.SRF_MESH or EgtSurfTmFacetCount( nId2) ~= 1 then + EgtOutText( 'Il secondo oggetto selezionato non è un piano') + EgtPause( 1000) + return +end + +-- Eseguo il taglio +local ptOn, vtN = EgtSurfTmFacetCenter( nId2, 0, GDB_ID.ROOT) +local bOk = EgtCutSurfTmPlane( nId1, ptOn, vtN, false, GDB_RT.GLOB) + +EgtDraw() + diff --git a/ProgramData/EgtCAM5/LuaCmd/SurfTmGetLoops.lua b/ProgramData/EgtCAM5/LuaCmd/SurfTmGetLoops.lua new file mode 100644 index 0000000..0ec8f4a --- /dev/null +++ b/ProgramData/EgtCAM5/LuaCmd/SurfTmGetLoops.lua @@ -0,0 +1,37 @@ +-- 2018/06/20 +-- Recupero dei bordi di una superficie trimesh +-- Istruzioni : +-- 1) selezionare la superficie +-- 2) eseguire il componente. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- Recupero primo oggetto selezionato (superficie da cui recuperare i contorni) +local nId1 = EgtGetFirstSelectedObj() +if not nId1 or EgtGetType( nId1) ~= GDB_TY.SRF_MESH then + EgtOutText( 'Il primo oggetto selezionato non è una superficie') + EgtPause( 1000) + return +end + +-- verifico ci sia un layer corrente in cui mettere le curve +local nDestId = EgtGetCurrLayer() +if not nDestId then + EgtOutText( 'Non è definito il layer corrente dove mettere le curve') + EgtPause( 1000) + return +end + +-- Recupero i contorni della superficie +local nCrvFstId = EgtExtractSurfTmLoops( nId1, nDestId) +if not nCrvFstId then + EgtOutText( 'La superficie non ha bordi (è chiusa)') + EgtPause( 1000) + return +end + +EgtDraw() diff --git a/ProgramData/EgtCAM5/LuaLibs/EgtBBox3d.lua b/ProgramData/EgtCAM5/LuaLibs/EgtBBox3d.lua new file mode 100644 index 0000000..bb1ea3a --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EgtBBox3d.lua @@ -0,0 +1,313 @@ +-- EgtBBox3d.lua by EgalTech s.r.l. 2021/12/26 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtBBox3d = {} + +EgtOutLog( 'EgtBBox3d started', 1) + +-- Include +require( 'EgtPoint3d') +--EnableDebug( false) + + +-- Definizione classe BBox3d +BBox3d = {{},{}} +BBox3d.__index = BBox3d + +-- funzione di utilita' per identificazione tipo +function isBBox3d( a) + return ( getmetatable( a) == BBox3d) +end + +local function New( a, b) + local b3d = setmetatable( {{GEO.INFINITO,GEO.INFINITO,GEO.INFINITO},{-GEO.INFINITO,-GEO.INFINITO,-GEO.INFINITO}}, BBox3d) + if not a then + b3d[1] = Point3d( GEO.INFINITO, GEO.INFINITO, GEO.INFINITO) + b3d[2] = Point3d( -GEO.INFINITO, -GEO.INFINITO, -GEO.INFINITO) + elseif isBBox3d( a) then + b3d[1] = Point3d( a[1]) + b3d[2] = Point3d( a[2]) + elseif isBBox3d( a) and isBBox3d( b) then + b3d[1] = Point3d( a[1]) + b3d[2] = Point3d( a[2]) + BBox3d.AddPoint( b3d, b[1]) + BBox3d.AddPoint( b3d, b[2]) + elseif type(a) == 'table' and #a >= 2 and + type(a[1]) == 'table' and #a[1] >= 3 and + type(a[2]) == 'table' and #a[2] >= 3 then + b3d[1] = Point3d( GEO.INFINITO, GEO.INFINITO, GEO.INFINITO) + b3d[2] = Point3d( -GEO.INFINITO, -GEO.INFINITO, -GEO.INFINITO) + if a[1][1] < ( a[2][1] + GEO.EPS_SMALL) and + a[1][2] < ( a[2][2] + GEO.EPS_SMALL) and + a[1][3] < ( a[2][3] + GEO.EPS_SMALL) then + BBox3d.AddPoint( b3d, a[1]) + BBox3d.AddPoint( b3d, a[2]) + end + elseif isPoint3d( a) and isPoint3d( b) then + b3d[1] = Point3d(GEO.INFINITO,GEO.INFINITO,GEO.INFINITO) + b3d[2] = Point3d(-GEO.INFINITO,-GEO.INFINITO,-GEO.INFINITO) + BBox3d.AddPoint( b3d, a) + BBox3d.AddPoint( b3d, b) + elseif isPoint3d( a) then + b3d[1] = Point3d(GEO.INFINITO,GEO.INFINITO,GEO.INFINITO) + b3d[2] = Point3d(-GEO.INFINITO,-GEO.INFINITO,-GEO.INFINITO) + BBox3d.AddPoint( b3d, a) + else + error( 'A parameter is wrong', 2) + end + return b3d +end + +setmetatable( BBox3d, { __call = function( _, ...) return New( ...) end }) + +-- verifico se vuoto +function BBox3d:isEmpty() + -- il minimo non è minore del massimo + return not ( self[1][1] < ( self[2][1] + GEO.EPS_SMALL) and + self[1][2] < ( self[2][2] + GEO.EPS_SMALL) and + self[1][3] < ( self[2][3] + GEO.EPS_SMALL) ) +end + +-- somma di due box (+) +function BBox3d.__add( a, b) + if isBBox3d( a) and isBBox3d( b) then + return New( a, b) + else + error( 'A parameter is not a BBox3d', 2) + end +end + +-- aggiungo box o punto +function BBox3d:Add( a) + if isBBox3d( a) then + if not a:isEmpty() then + self:AddPoint( a[1]) + self:AddPoint( a[2]) + end + else + self:AddPoint( a) + end +end + +-- aggiungo un punto (solo per uso interno) +function BBox3d:AddPoint( ptP) + if ptP[1] < self[1][1] then + self[1][1] = ptP[1] + end + if ptP[2] < self[1][2] then + self[1][2] = ptP[2] + end + if ptP[3] < self[1][3] then + self[1][3] = ptP[3] + end + if ptP[1] > self[2][1] then + self[2][1] = ptP[1] + end + if ptP[2] > self[2][2] then + self[2][2] = ptP[2] + end + if ptP[3] > self[2][3] then + self[2][3] = ptP[3] + end + return true +end + +-- espansione isotropa +function BBox3d:expand( dDelta) + if not isBBox3d( self) then + return false + end + if BBox3d.isEmpty(self) then + return true + end + self[1][1] = self[1][1] - dDelta + self[1][2] = self[1][2] - dDelta + self[1][3] = self[1][3] - dDelta + self[2][1] = self[2][1] + dDelta + self[2][2] = self[2][2] + dDelta + self[2][3] = self[2][3] + dDelta +end + +-- traslazione +function BBox3d:move( m) + if not isBBox3d( self) then + return false + end + if BBox3d.isEmpty(self) then + return true + end + if isVector3d( m) or ( type( m) == 'table' and #m >= 3) then + self[1][1] = self[1][1] + m[1] + self[1][2] = self[1][2] + m[2] + self[1][3] = self[1][3] + m[3] + self[2][1] = self[2][1] + m[1] + self[2][2] = self[2][2] + m[2] + self[2][3] = self[2][3] + m[3] + return true + else + return false + end +end + +function BBox3d:rotate( ptAx, vtAx, dAngDeg) + if not isBBox3d( self) or not isPoint3d( ptAx) or not isVector3d( vtAx) or type( dAngDeg) ~= 'number' then + return false + end + if BBox3d.isEmpty(self) then + return true + end + local bOk, b3New = EgtBBoxRotate( self, ptAx, vtAx, dAngDeg) + if bOk then + self[1] = Point3d( b3New[1]) + self[2] = Point3d( b3New[2]) + end + return bOk +end + +-- trasformazione di riferimento verso globale +function BBox3d:toGlob( fTool) + if not isBBox3d( self) or not isFrame3d( fTool) then + return false + end + if BBox3d.isEmpty(self) then + return true + end + local bOk, b3New = EgtBBoxToGlob( self, fTool) + if bOk then + self[1] = Point3d( b3New[1]) + self[2] = Point3d( b3New[2]) + end + return bOk +end + +-- trasformazione di riferimento verso locale +function BBox3d:toLoc( fTool) + if not isBBox3d( self) or not isFrame3d( fTool) then + return false + end + if BBox3d.isEmpty(self) then + return true + end + local bOk, b3New = EgtBBoxToLoc( self, fTool) + if bOk then + self[1] = Point3d( b3New[1]) + self[2] = Point3d( b3New[2]) + end + return bOk +end + +-- trasformazione di riferimento da locale a locale +function BBox3d:locToLoc( fOri, fDest) + if not isBBox3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then + return false + end + if BBox3d.isEmpty(self) then + return true + end + local bOk, b3New = EgtBBoxLocToLoc( self, fOri, fDest) + if bOk then + self[1] = Point3d( b3New[1]) + self[2] = Point3d( b3New[2]) + end + return bOk +end + +-- restituzione componenti +function BBox3d:getMin() + if BBox3d.isEmpty(self) then + return nil + end + return Point3d( self[1]) +end + +function BBox3d:getMax() + if BBox3d.isEmpty(self) then + return nil + end + return Point3d( self[2]) +end + +function BBox3d:getDimX() + if BBox3d.isEmpty(self) then + return nil + end + return ( self[2][1] - self[1][1]) +end + +function BBox3d:getDimY() + if BBox3d.isEmpty(self) then + return nil + end + return ( self[2][2] - self[1][2]) +end + +function BBox3d:getDimZ() + if BBox3d.isEmpty(self) then + return nil + end + return ( self[2][3] - self[1][3]) +end + +function BBox3d:getCenter() + if BBox3d.isEmpty(self) then + return nil + end + return 0.5 * ( Point3d( self[1]) + Point3d( self[2])) +end + +function BBox3d:getRadius() + if BBox3d.isEmpty(self) then + return nil + end + return 0.5 * dist( Point3d( self[1]), Point3d( self[2])) +end + +-- conversione in stringa (tostring) +function BBox3d:__tostring() + if BBox3d.isEmpty(self) then + return '(empty)' + end + return '('.. tostring(self[1])..','..tostring(self[2])..')' +end + +-- verifica che il box includa il punto in XY +function EnclosesPointXY( b3Box, ptP) + if b3Box[2][1] < ptP[1] - GEO.EPS_SMALL or b3Box[1][1] > ptP[1] + GEO.EPS_SMALL then + return false + end + if b3Box[2][2] < ptP[2] - GEO.EPS_SMALL or b3Box[1][2] > ptP[2] + GEO.EPS_SMALL then + return false + end + return true +end + +-- verifica che il primo box includa il secondo in XY +function EnclosesXY( b3First, b3Second) + if not isBBox3d( b3First) or not isBBox3d( b3Second) then + return false + end + if BBox3d.isEmpty( b3First) or BBox3d.isEmpty( b3Second) then + return false + end + return EnclosesPointXY( b3First, b3Second:getMin()) and EnclosesPointXY( b3First, b3Second:getMax()) +end + +-- verifica di interferenza tra due box in XY +function OverlapsXY( b3First, b3Second) + if not isBBox3d( b3First) or not isBBox3d( b3Second) then + return false + end + if BBox3d.isEmpty( b3First) or BBox3d.isEmpty( b3Second) then + return false + end + if b3First[2][1] < b3Second[1][1] - GEO.EPS_SMALL or b3First[1][1] > b3Second[2][1] + GEO.EPS_SMALL then + return false + end + if b3First[2][2] < b3Second[1][2] - GEO.EPS_SMALL or b3First[1][2] > b3Second[2][2] + GEO.EPS_SMALL then + return false + end + return true +end + + +return EgtBBox3d diff --git a/ProgramData/EgtCAM5/LuaLibs/EgtBase.lua b/ProgramData/EgtCAM5/LuaLibs/EgtBase.lua new file mode 100644 index 0000000..cdfb48f --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EgtBase.lua @@ -0,0 +1,647 @@ +-- EgtLib.lua libreria di base EgalTech per Lua 2022/04/12 +-- 2019/12/04 EgtTestBreak interruzione se valore 1. +-- 2020/06/04 Aggiunta funzione EgtCurveIsACircle. +-- 2020/06/16 Aggiunta funzione EgtSurfTmGetFacetBBoxRef. +-- 2021/11/27 Aggiunta funzione EgtClamp. +-- 2022/04/12 Aggiunta funzione EgtGetValInNotes. + +-- Tavola per definizione modulo (serve ma non usata) +local EgtBase = {} + +EgtOutLog( 'EgtBase started', 1) + +-- Funzioni del package matematico rese globali e con angoli in gradi +abs = math.abs +fmod = math.fmod +floor = math.floor +ceil = math.ceil +min = math.min +max = math.max +huge = math.huge +modf = math.modf +sqrt = math.sqrt +pow = function( x, y) return x ^ y end +exp = math.exp +log = math.log +log10 = function( x) return math.log( x, 10) end +ldexp = function( x, exp) return x * 2.0 ^ exp end +deg = math.deg +rad = math.rad +pi = math.pi +sin = function( x) return math.sin( math.rad( x)) end +cos = function( x) return math.cos( math.rad( x)) end +tan = function( x) return math.tan( math.rad( x)) end +asin = function( x) return math.deg( math.asin( x)) end +acos = function( x) return math.deg( math.acos( x)) end +atan = function( y, x) return math.deg( math.atan( y, x)) end +atan2 = function( y, x) return math.deg( math.atan( y, x)) end +random = math.random +randomseed = math.randomseed +tointeger = math.tointeger + +---------------------------------------------------------------------------- +function EgtIf( bCond, Val1, Val2) + if bCond then + return Val1 + else + return Val2 + end +end + +---------------------------------------------------------------------------- +function EgtClamp( Val, Min, Max) + if Min > Max then + Min, Max = Max, Min + end + if Val < Min then + return Min + elseif Val > Max then + return Max + else + return Val + end +end + +---------------------------------------------------------------------------- +-- Funzione per protezione variabili e funzioni globali +function EgtProtectGlobal() + local newgt = {} + setmetatable( newgt, {__index = _G, + __newindex = function( t, k, v) + local k3 = string.sub( k, 1, 3) + if k3 == 'Egt' or k3 == 'Emt' or + k3 == 'GEO' or k3 == 'GDB' or k3 == 'SCE' or k3 == 'MCH' then + error( "attempting to change global "..tostring( k)..' to '..tostring( v), 2) + else + rawset( t, k, v) + end + end + }) + return newgt +end + +-- Funzione per lancio, se richiesta, predisposizione debug +function EgtEnableDebug( bOn) + if not bOn then + EgtOutLog( 'Release Mode', 1) + return true + elseif EgtIs64bit() then + -- non funziona a 64 bit + EgtOutLog( 'Skipped Debug Activation (64bit)') + return false + else + -- carico il modulo opportuno + EgtOutLog( 'Debug Mode (32bit)', 1) + return require( 'mobdebug').start() + end +end + +-- Funzione per reset librerie +function EgtResetLibs() + package.loaded.EgtTest = nil + package.loaded.EgtBase = nil + package.loaded.EgtConst = nil + package.loaded.EgtVector3d = nil + package.loaded.EgtPoint3d = nil + package.loaded.EgtFrame3d = nil + package.loaded.EgtBBox3d = nil + package.loaded.EgtColor3d = nil + package.loaded.Dimension = nil + package.loaded.EgtLinearDimension = nil + package.loaded.EmtGenerator = nil +end + +---------------------------------------------------------------------------- +-- Funzione per OutLog di tutte le variabili globali +function EgtOutLogAllGlobVars() + local a = {} + for k,v in pairs( _G) do + a[#a+1] = k .. " => ".. tostring( v) + end + table.sort( a) + EgtOutLog( 'Global Variables (#' .. #a .. ') :') + for _,v in ipairs( a) do + EgtOutLog( v) + end +end + +---------------------------------------------------------------------------- +-- Funzione per avere direttorio del file che lancia la funzione +function EgtGetSourceDir( nUp) + local nSou = 2 + if nUp then nSou = nSou + nUp end + local info = debug.getinfo( nSou, 'S') + local dir = info.source:match("^@?(.-)([^\\/]-%.?([^%.\\/]*))$") + return dir +end + +---------------------------------------------------------------------------- +-- Funzione per avere direttorio e file che lancia la funzione +function EgtGetSourcePath( nUp) + local nSou = 2 + if nUp then nSou = nSou + nUp end + local info = debug.getinfo( nSou, 'S') + local dir = string.gsub( info.source, '@', '') + return dir +end + +-- Funzione per accodare path di ricerca librerie lua +function EgtAddToPackagePath( path) + if not package.path:find( path, 1, true) then + if package.path:sub( -1) == ';' then + package.path = package.path .. path .. ';' + else + package.path = package.path .. ';' .. path .. ';' + end + end +end + +-- Funzione per rimuovere direttori macchine da path di ricerca librerie lua +function EgtRemoveBaseMachineDirFromPackagePath() + local vLibDir = EgtSplitString( _G.package.path, ';') + if not vLibDir or #vLibDir == 0 then return end + local sBaseMachDir = EgtSplitPath( EgtGetCurrMachineDir() or '') + if not sBaseMachDir or #sBaseMachDir == 0 then return end + package.path = '' + for i = 1, #vLibDir do + if #vLibDir[i] > 0 and not vLibDir[i]:find( sBaseMachDir, 1, true) then + package.path = package.path .. vLibDir[i] .. ';' + end + end +end + +-- Funzione per dividere Path in Direttorio, NomeFile e Estensione +function EgtSplitPath( sPath) + local sDir, sFile = string.match(sPath, "(.-)([^\\/]*)$") + local sName, sExt + if sFile and string.find(sFile,'%.') then + sName, sExt = string.match(sFile,'(.*)([%.].-)$') + else + sName = sFile + sExt = '' + end + return sDir, sName, sExt +end + +-- Funzione per cambiare estensione di una Path +function EgtChangePathExtension( sPath, sExt) + local sFileDir, sFileName, sFileExt = EgtSplitPath( sPath) + if string.sub( sExt, 1, 1) == '.' then + return sFileDir .. sFileName .. sExt + else + return sFileDir .. sFileName .. '.' .. sExt + end +end + +---------------------------------------------------------------------------- +-- Funzioni di trim di stringhe di caratteri +function EgtTrimRight( sStr) + if not sStr then return nil end + return sStr:match( "(.-)%s*$") +end +function EgtTrimLeft( sStr) + if not sStr then return nil end + return sStr:match( "^%s*(.*)") +end +function EgtTrim( sStr) + if not sStr then return nil end + return sStr:match( "^%s*(.-)%s*$") +end + +---------------------------------------------------------------------------- +-- Funzione per aggiungere/togliere coppie chiave/valore da una stringa di note +function EgtAdjustNotes( sNotes, sKey, Val) + local sNewNotes = '' + local vItem = EgtSplitString( sNotes, ';') or {} + for i = 1, #vItem do + local sItem = EgtTrim( vItem[i]) + if sItem and #sItem > 0 and not sItem:find( sKey, 1, true) then + sNewNotes = sNewNotes .. sItem .. ';' + end + end + if Val and Val ~= '' then + sNewNotes = sNewNotes .. EgtSetVal( sKey, Val) + end + return sNewNotes +end + +---------------------------------------------------------------------------- +-- Funzione per recuperare un valore data la chiave da una stringa di note +function EgtGetValInNotes( sNotes, sKey, sType) + local vItem = EgtSplitString( sNotes, ';') or {} + for i = 1, #vItem do + local sItem = EgtTrim( vItem[i]) + if sItem and #sItem > 0 and sItem:find( sKey..'=', 1, true) then + return EgtGetVal( sItem, sKey, sType) + end + end + return nil +end + +---------------------------------------------------------------------------- +-- Funzione per creare tabella da primo indice per numero indici consecutivi +function EgtTableFill( nStart, nCount) + if not nStart or nCount <= 0 then return nil end + local T = {} + for i = 0,nCount-1 do + table.insert( T, nStart+i) + end + return T +end + +-- Funzione per aggiungere a tabella da primo indice per numero indici consecutivi +function EgtTableAdd( T, nStart, nCount) + if not nStart or nCount <= 0 then return T end + for i = 0,nCount-1 do + table.insert( T, nStart+i) + end + return T +end + +-- Funzione per unire due tabelle +function EgtJoinTables( Ta, Tb) + for k, v in ipairs( Tb) do + table.insert( Ta, v) + end + return Ta +end + + +---------------------------------------------------------------------------- +-- Funzione per aggiornare interfaccia e consentire interruzione esecuzione +function EgtTestBreak( nProc, nPause) + local nRet = EgtProcessEvents( nProc, nPause) + if nRet == 1 then + error( "User aborted", 2) + end +end + +---------------------------------------------------------------------------- +-- Richiamo librerie componenti +require( 'EgtConst') +require( 'EgtVector3d') +require( 'EgtPoint3d') +require( 'EgtFrame3d') +require( 'EgtBBox3d') +require( 'EgtColor3d') + + +-- Ridefinizione funzioni per ritornare Vector3d +local o_EgtGetGridVersZ = EgtGetGridVersZ +EgtGetGridVersZ = function(...) + local vtV = o_EgtGetGridVersZ(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtSV = EgtSV +EgtSV = function(...) + local vtV = o_EgtSV(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtEV = EgtEV +EgtEV = function(...) + local vtV = o_EgtEV(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtMV = EgtMV +EgtMV = function(...) + local vtV = o_EgtMV(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtUV = EgtUV +EgtUV = function(...) + local vtV = o_EgtUV(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtET = EgtET +EgtET = function(...) + local vtV = o_EgtET(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtCurveExtrusion = EgtCurveExtrusion +EgtCurveExtrusion = function(...) + local vtV = o_EgtCurveExtrusion(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtArcNormVersor = EgtArcNormVersor +EgtArcNormVersor = function(...) + local vtV = o_EgtArcNormVersor(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtSurfFrNormVersor = EgtSurfFrNormVersor +EgtSurfFrNormVersor = function(...) + local vtV = o_EgtSurfFrNormVersor(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtSurfTmFacetNormVersor = EgtSurfTmFacetNormVersor +EgtSurfTmFacetNormVersor = function(...) + local vtV = o_EgtSurfTmFacetNormVersor(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtTextNormVersor = EgtTextNormVersor +EgtTextNormVersor = function(...) + local vtV = o_EgtTextNormVersor(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtGetCalcToolDirFromAngles = EgtGetCalcToolDirFromAngles +EgtGetCalcToolDirFromAngles = function(...) + local vtV = o_EgtGetCalcToolDirFromAngles(...) + if vtV then return Vector3d( vtV) end +end +local o_EgtGetCalcAuxDirFromAngles = EgtGetCalcAuxDirFromAngles +EgtGetCalcAuxDirFromAngles = function(...) + local vtV = o_EgtGetCalcAuxDirFromAngles(...) + if vtV then return Vector3d( vtV) end +end + +-- Ridefinizione funzioni per ritornare Vector3d e altri parametri +local o_EgtCurveIsFlat = EgtCurveIsFlat +EgtCurveIsFlat = function(...) + local bFlat, vtN, dDist = o_EgtCurveIsFlat(...) + if vtN then return bFlat, Vector3d( vtN), dDist end +end +local o_EgtCurveArea = EgtCurveArea +EgtCurveArea = function(...) + local vtN, dDist, dArea = o_EgtCurveArea(...) + if vtN then return Vector3d( vtN), dDist, dArea end +end + +-- Ridefinizione funzioni per ritornare Point3d +local o_EgtSP = EgtSP +EgtSP = function(...) + local ptP = o_EgtSP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtEP = EgtEP +EgtEP = function(...) + local ptP = o_EgtEP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtMP = EgtMP +EgtMP = function(...) + local ptP = o_EgtMP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtCP = EgtCP +EgtCP = function(...) + local ptP = o_EgtCP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGP = EgtGP +EgtGP = function(...) + local ptP = o_EgtGP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtUP = EgtUP +EgtUP = function(...) + local ptP = o_EgtUP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtNP = EgtNP +EgtNP = function(...) + local ptP = o_EgtNP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtIP = EgtIP +EgtIP = function(...) + local ptP = o_EgtIP(...) + if ptP then return Point3d( ptP) end +end +local o_EgtCurveCompoCenter = EgtCurveCompoCenter +EgtCurveCompoCenter = function(...) + local ptP = o_EgtCurveCompoCenter(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGetTableRef = EgtGetTableRef +EgtGetTableRef = function(...) + local ptP = o_EgtGetTableRef(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGetCalcTipFromPositions = EgtGetCalcTipFromPositions +EgtGetCalcTipFromPositions = function(...) + local ptP = o_EgtGetCalcTipFromPositions(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGetRawPartCenter = EgtGetRawPartCenter +EgtGetRawPartCenter = function(...) + local ptP = o_EgtGetRawPartCenter(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGetMachiningStartPoint = EgtGetMachiningStartPoint +EgtGetMachiningStartPoint = function(...) + local ptP = o_EgtGetMachiningStartPoint(...) + if ptP then return Point3d( ptP) end +end +local o_EgtGetMachiningEndPoint = EgtGetMachiningEndPoint +EgtGetMachiningEndPoint = function(...) + local ptP = o_EgtGetMachiningEndPoint(...) + if ptP then return Point3d( ptP) end +end + +-- Ridefinizione funzioni per ritornare Point3d e altri parametri +local o_EgtSurfTmFacetsContact = EgtSurfTmFacetsContact +EgtSurfTmFacetsContact = function(...) + local bAdj, ptP1, ptP2, dAng = o_EgtSurfTmFacetsContact(...) + if bAdj and ptP1 and ptP2 and dAng then + return bAdj, Point3d( ptP1), Point3d( ptP2), dAng + else + return bAdj + end +end +local o_EgtSurfTmFacetOppositeSide = EgtSurfTmFacetOppositeSide +EgtSurfTmFacetOppositeSide = function(...) + local ptP1, ptPm, ptP2, vtV1, vtV2, dL, dW = o_EgtSurfTmFacetOppositeSide(...) + if ptP1 and ptPm and ptP2 and vtV1 and vtV2 then + return Point3d( ptP1), Point3d( ptPm), Point3d( ptP2), Vector3d( vtV1), Vector3d( vtV2), dL, dW + end +end +local o_EgtPointCurveDist = EgtPointCurveDist +EgtPointCurveDist = function(...) + local dDist, ptNear, dU = o_EgtPointCurveDist(...) + if dDist then return dDist, Point3d( ptNear), dU end +end +local o_EgtGetLastSelInfo = EgtGetLastSelInfo +EgtGetLastSelInfo = function(...) + local nId, nSub, ptSel = o_EgtGetLastSelInfo(...) + if nId then return nId, nSub, Point3d( ptSel) end +end +local o_EgtGetPrevSelInfo = EgtGetPrevSelInfo +EgtGetPrevSelInfo = function(...) + local nId, nSub, ptSel = o_EgtGetPrevSelInfo(...) + if nId then return nId, nSub, Point3d( ptSel) end +end +local o_EgtSurfBezierGetPoint = EgtSurfBezierGetPoint +EgtSurfBezierGetPoint = function(...) + local ptP = o_EgtSurfBezierGetPoint(...) + if ptP then + return Point3d( ptP) + end +end +local o_EgtSurfBezierGetPointD1 = EgtSurfBezierGetPointD1 +EgtSurfBezierGetPointD1 = function(...) + local ptP, vtDerU, vtDerV = o_EgtSurfBezierGetPointD1(...) + if ptP and vtDerU and vtDerV then + return Point3d( ptP), Vector3d( vtDerU), Vector3d( vtDerV) + end +end +local o_EgtSurfBezierGetPointNrmD1 = EgtSurfBezierGetPointNrmD1 +EgtSurfBezierGetPointNrmD1 = function(...) + local ptP, vtN, vtDerU, vtDerV = o_EgtSurfBezierGetPointNrmD1(...) + if ptP and vtDerU and vtDerV then + return Point3d( ptP), Vector3d( vtN), Vector3d( vtDerU), Vector3d( vtDerV) + end +end + +-- Ridefinizione funzioni per ritornare Point3d e Vector3d +local o_EgtSurfTmFacetNearestEndPoint = EgtSurfTmFacetNearestEndPoint +EgtSurfTmFacetNearestEndPoint = function(...) + local ptP, vtN = o_EgtSurfTmFacetNearestEndPoint(...) + if ptP and vtN then return Point3d( ptP), Vector3d( vtN) end +end +local o_EgtSurfTmFacetNearestMidPoint = EgtSurfTmFacetNearestMidPoint +EgtSurfTmFacetNearestMidPoint = function(...) + local ptP, vtN = o_EgtSurfTmFacetNearestMidPoint(...) + if ptP and vtN then return Point3d( ptP), Vector3d( vtN) end +end +local o_EgtSurfTmFacetCenter = EgtSurfTmFacetCenter +EgtSurfTmFacetCenter = function(...) + local ptP, vtN = o_EgtSurfTmFacetCenter(...) + if ptP and vtN then return Point3d( ptP), Vector3d( vtN) end +end +local o_EgtCurveIsACircle = EgtCurveIsACircle +EgtCurveIsACircle = function(...) + local bCirc, ptC, vtN, dRad, bCCW = o_EgtCurveIsACircle(...) + if bCirc then return bCirc, Point3d( ptC), Vector3d( vtN), dRad, bCCW end +end + +-- Ridefinizione funzioni per ritornare Frame3d +local o_EgtGetGridFrame = EgtGetGridFrame +EgtGetGridFrame = function() + local frRef = o_EgtGetGridFrame() + if frRef then return Frame3d( frRef) end +end +local o_EgtGetGlobFrame = EgtGetGlobFrame +EgtGetGlobFrame = function(...) + local frRef = o_EgtGetGlobFrame(...) + if frRef then return Frame3d( frRef) end +end +local o_EgtGetGroupGlobFrame = EgtGetGroupGlobFrame +EgtGetGroupGlobFrame = function(...) + local frRef = o_EgtGetGroupGlobFrame(...) + if frRef then return Frame3d( frRef) end +end +local o_EgtFR = EgtFR +EgtFR = function(...) + local frRef = o_EgtFR(...) + if frRef then return Frame3d( frRef) end +end +local o_EgtGetTextureFrame = EgtGetTextureFrame +EgtGetTextureFrame = function(...) + local frRef = o_EgtGetTextureFrame(...) + if frRef then return Frame3d( frRef) end +end + +-- Ridefinizione funzioni per ritornare Frame3d e altri parametri +local o_EgtCurveMinAreaRectangleXY = EgtCurveMinAreaRectangleXY +EgtCurveMinAreaRectangleXY = function(...) + local frRect, dDimX, dDimY = o_EgtCurveMinAreaRectangleXY(...) + if frRect then return Frame3d( frRect), dDimX, dDimY end +end +local o_EgtSurfTmFacetMinAreaRectangle = EgtSurfTmFacetMinAreaRectangle +EgtSurfTmFacetMinAreaRectangle = function(...) + local frRect, dDimX, dDimY = o_EgtSurfTmFacetMinAreaRectangle(...) + if frRect then return Frame3d( frRect), dDimX, dDimY end +end + +-- Ridefinizione funzioni per ritornare BBox3d +local o_EgtGetBBox = EgtGetBBox +EgtGetBBox = function(...) + local b3Box = o_EgtGetBBox(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtGetBBoxGlob = EgtGetBBoxGlob +EgtGetBBoxGlob = function(...) + local b3Box = o_EgtGetBBoxGlob(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtGetBBoxRef = EgtGetBBoxRef +EgtGetBBoxRef = function(...) + local b3Box = o_EgtGetBBoxRef(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtGetTableArea = EgtGetTableArea +EgtGetTableArea = function(...) + local b3Box = o_EgtGetTableArea(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtGetRawPartBBox = EgtGetRawPartBBox +EgtGetRawPartBBox = function(...) + local b3Box = o_EgtGetRawPartBBox(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtSurfTmGetFacetBBox = EgtSurfTmGetFacetBBox +EgtSurfTmGetFacetBBox = function(...) + local b3Box = o_EgtSurfTmGetFacetBBox(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtSurfTmGetFacetBBoxGlob = EgtSurfTmGetFacetBBoxGlob +EgtSurfTmGetFacetBBoxGlob = function(...) + local b3Box = o_EgtSurfTmGetFacetBBoxGlob(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtSurfTmGetFacetBBoxRef = EgtSurfTmGetFacetBBoxRef +EgtSurfTmGetFacetBBoxRef = function(...) + local b3Box = o_EgtSurfTmGetFacetBBoxRef(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtVolZmapGetPartBBox = EgtVolZmapGetPartBBox +EgtVolZmapGetPartBBox = function(...) + local b3Box = o_EgtVolZmapGetPartBBox(...) + if b3Box then return BBox3d( b3Box) end +end +local o_EgtVolZmapGetPartBBoxGlob = EgtVolZmapGetPartBBoxGlob +EgtVolZmapGetPartBBoxGlob = function(...) + local b3Box = o_EgtVolZmapGetPartBBoxGlob(...) + if b3Box then return BBox3d( b3Box) end +end + +-- Ridefinizione funzioni per ritornare Color3d +local o_EgtStdColor = EgtStdColor +EgtStdColor = function(...) + local c3Col = o_EgtStdColor(...) + if c3Col then return Color3d( c3Col) end +end +local o_EgtGetColor = EgtGetColor +EgtGetColor = function(...) + local c3Col = o_EgtGetColor(...) + if c3Col then return Color3d( c3Col) end +end +local o_EgtGetCalcColor = EgtGetCalcColor +EgtGetCalcColor = function(...) + local c3Col = o_EgtGetCalcColor(...) + if c3Col then return Color3d( c3Col) end +end +local o_EgtGetBackground = EgtGetBackground +EgtGetBackground = function(...) + local c3Top, c3Bot = o_EgtGetBackground(...) + if c3Top and c3Bot then return Color3d( c3Top), Color3d( c3Bot) end +end + +-- Ridefinizione funzioni per tornare diversi tipi di oggetti +local o_EgtGetInfo = EgtGetInfo +EgtGetInfo = function( Id, Key, sType) + local Val = o_EgtGetInfo( Id, Key, sType) + if sType == 'v' or sType == 'V' then + if Val then return Vector3d( Val) end + elseif sType == 'p' or sType == 'P' then + if Val then return Point3d( Val) end + elseif sType == 'x' or sType == 'X' then + if Val then return BBox3d( Val) end + elseif sType == 'f' or sType == 'F' then + if Val then return Frame3d( Val) end + else + return Val + end +end + + +return EgtBase diff --git a/ProgramData/EgtCAM5/LuaLibs/EgtColor3d.lua b/ProgramData/EgtCAM5/LuaLibs/EgtColor3d.lua new file mode 100644 index 0000000..d1541f8 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EgtColor3d.lua @@ -0,0 +1,170 @@ +-- EgtColor3d.lua by EgalTech s.r.l. 2019/03/31 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtColor3d = {} + +EgtOutLog( 'EgtColor3d started', 1) + +-- Include +require( 'EgtConst') +--EnableDebug( false) + + +-- Definizione classe Color3d +Color3d = {} +Color3d.__index = Color3d + +-- funzione di utilita' per identificazione tipo +function isColor3d( a) + return ( getmetatable( a) == Color3d) +end + +local function New( r, g, b, a) + local col = setmetatable( {0,0,0,0}, Color3d) + local function Clip( val, min, max) + if val < min then + return min + elseif val > max then + return max + else + return val + end + end + if not r then + return nil + elseif isColor3d( r) then + col[1] = r[1] + col[2] = r[2] + col[3] = r[3] + if type( g) == 'number' then + col[4] = Clip( g, 0, 100) + else + col[4] = r[4] + end + elseif type( r) == 'table' and #r >= 3 then + col[1] = Clip( r[1], 0, 255) + col[2] = Clip( r[2], 0, 255) + col[3] = Clip( r[3], 0, 255) + if #r >= 4 then + col[4] = Clip( r[4], 0, 100) + else + col[4] = 100 + end + elseif type( r) == 'number' and type( g) == 'number' and type( b) == 'number' then + col[1] = Clip( r, 0, 255) + col[2] = Clip( g, 0, 255) + col[3] = Clip( b, 0, 255) + if type( a) == 'number' then + col[4] = Clip( a, 0, 100) + else + col[4] = 100 + end + elseif type( r) == 'string' then + local stdCol = EgtStdColor( r) + col[1] = stdCol[1] + col[2] = stdCol[2] + col[3] = stdCol[3] + col[4] = stdCol[4] + else + error( 'A parameter is wrong', 2) + end + return col +end + +setmetatable( Color3d, { __call = function( _, ...) return New(...) end }) + +-- restituzione componenti +function Color3d:getRed() + return self[1] +end + +function Color3d:getGreen() + return self[2] +end + +function Color3d:getBlue() + return self[3] +end + +function Color3d:getAlpha() + return self[4] +end + +-- conversione in stringa (tostring) +function Color3d:__tostring() + return '('.. self[1]..','..self[2]..','..self[3]..','..self[4] ..')' +end + +-- funzione di confronto +function AreSameColor( a, b, Tol) + if isColor3d( a) and isColor3d( b) then + if not Tol then + Tol = 0 + end + return math.abs( a[1] - b[1]) < Tol + 0.1 and + math.abs( a[2] - b[2]) < Tol + 0.1 and + math.abs( a[3] - b[3]) < Tol + 0.1 and + math.abs( a[4] - b[4]) < Tol + 0.1 + else + return false + end +end + +-- Colori notevoli +function WHITE() + return Color3d( 'WHITE') +end +function LGRAY() + return Color3d( 'LGRAY') +end +function GRAY() + return Color3d( 'GRAY') +end +function BLACK() + return Color3d( 'BLACK') +end +function RED() + return Color3d( 'RED') +end +function MAROON() + return Color3d( 'MAROON') +end +function YELLOW() + return Color3d( 'YELLOW') +end +function OLIVE() + return Color3d( 'OLIVE') +end +function LIME() + return Color3d( 'LIME') +end +function GREEN() + return Color3d( 'GREEN') +end +function AQUA() + return Color3d( 'AQUA') +end +function TEAL() + return Color3d( 'TEAL') +end +function BLUE() + return Color3d( 'BLUE') +end +function NAVY() + return Color3d( 'NAVY') +end +function FUCHSIA() + return Color3d( 'FUCHSIA') +end +function PURPLE() + return Color3d( 'PURPLE') +end +function ORANGE() + return Color3d( 'ORANGE') +end +function BROWN() + return Color3d( 'BROWN') +end + + +return EgtColor3d diff --git a/ProgramData/EgtCAM5/LuaLibs/EgtConst.lua b/ProgramData/EgtCAM5/LuaLibs/EgtConst.lua new file mode 100644 index 0000000..1a93d36 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EgtConst.lua @@ -0,0 +1,975 @@ +-- EgtConst.lua libreria di costanti EgalTech per Lua 2022/02/04 +-- 2018/02/22 Sistemata package.cpath per lua 5.3 con "/bin/clibs53/?.dll;" +-- 2019/07/24 Portato GEO.EPS_ZERO a 1e-8 come nel programma. +-- 2020/01/15 Aggiunta costante GDB_TY.EXT_DIMENSION. +-- 2020/02/06 Aggiunte costanti GDB_CRC. +-- 2020/02/14 Aggiunta costante MCH_GP.MAXDEPTHSAFE. +-- 2020/02/21 Aggiunta costante MCH_TY.MILL_POLISHING. +-- 2020/03/26 Aggiunta costante GDB_TY.SRF_BEZ. +-- 2020/06/05 Aggiunte costanti MCH_MP.TABMIN e MCH_MP.TABMAX. +-- 2020/10/12 Aggiunte costanti EEX_FL. +-- 2021/02/14 Aggiunte costanti NST_CORNER. +-- 2021/05/21 Aggiunta costante MCH_SIM_COB.CONE (tronco di cono). +-- 2021/07/28 Aggiunte costanti MCH_MP.SIDEANGFEED e MCH_MP.STEPLAST. +-- 2021/09/24 Aggiunte costanti MCH_MILL_LI.TG_PERP e MCH_MILL_LO.PERP_TG. +-- 2022/02/04 Aggiunte costanti MCH_MP.EPICYCLESRAD e MCH_MP.EPICYCLESDIST. + +-- Tavola per definizione modulo (serve ma non usata) +local EgtConst = {} + +EgtOutLog( 'EgtConst started', 1) + +-- Per eventuale debug +local ZBS = "c:/ZeroBraneStudio" +if not package.path:find(ZBS,1,true) then + package.path = ZBS .. "/lualibs/?/?.lua;" .. ZBS .. "/lualibs/?.lua;" .. package.path + package.cpath = ZBS .. "/bin/?.dll;" .. ZBS .. "/bin/clibs53/?.dll;" .. package.cpath +end + +-- Funzione per rendere non modificabili le costanti +local protect = function(tbl) + return setmetatable({}, { + __index = tbl, + __newindex = function(t, key, value) + error("attempting to change constant " .. + tbl[1]..tostring(key) .. " to " .. tostring(value), 2) + end + }) +end + +-- Costanti geometriche +GEO = { + 'GEO.', + EPS_SMALL = 1.0e-3, + EPS_ZERO = 1.0e-8, + INFINITO = 1.0e10, + EPS_ANG_SMALL = 1.0e-3, + ONE_MM = 1.0, + ONE_INCH = 25.4 +} +GEO = protect( GEO) +-- Costanti per tipo di file Nge +GDB_NT = { + 'GDB_NT.', + TXT = 0, + BIN = 1, + CMPTXT = 2 +} +GDB_NT = protect( GDB_NT) +-- Costanti per identificativi speciali di GDB +GDB_ID = { + 'GDB_ID.', + ROOT = 0, -- radice + NULL = -1, -- non valido + SEL = -2, -- selezione + GRID = -3, -- griglia + CP = -4, -- current part + CL = -5 -- current layer +} +GDB_ID = protect( GDB_ID) +-- Costanti per posizione di inserimento in GDB in copia/trasferisci +GDB_IN = { + 'GDB_IN.', + FIRST_SON = 0, + LAST_SON = 1, + BEFORE = 2, + AFTER = 3 +} +GDB_IN = protect( GDB_IN) +-- Costanti per riferimento in cui sono espressi i dati della funzione +GDB_RT = { + 'GDB_RT.', + GLOB = 0, -- globale + GRID = -3, -- griglia + LOC = -6 -- locale +} +GDB_RT = protect( GDB_RT) +-- Costanti per tipo di punto +GDB_PT = { + 'GDB_PT.', + STD = 0, + TG = 1, + PERP = 2, + MIND = 3 +} +GDB_PT = protect( GDB_PT) +-- Costanti per famiglie di oggetti +GDB_FY = { + 'GDB_FY.', + NONE = 0, + GEO_ZERODIM = 128, + GEO_CURVE = 256, + GEO_SURF = 512, + GEO_VOLUME = 1024, + GEO_EXTRA = 2048 +} +GDB_FY = protect( GDB_FY) +-- Costanti per tipo di oggetti +GDB_TY = { + 'GDB_TY.', + NONE = 0, + GROUP = 2, + GEO_VECTOR = 128, + GEO_POINT = 129, + GEO_FRAME = 130, + CRV_LINE = 256, + CRV_ARC = 257, + CRV_BEZ = 258, + CRV_COMPO = 259, + SRF_MESH = 512, + SRF_FRGN = 513, + SRF_BEZ = 514, + VOL_ZMAP = 1024, + EXT_TEXT = 2048, + EXT_DIMENSION = 2049 +} +GDB_TY = protect( GDB_TY) +-- Costanti per livello oggetti +GDB_LV = { + 'GDB_LV.', + USER = 1, + SYSTEM = 2, + TEMP = 3 +} +GDB_LV = protect( GDB_LV) +-- Costanti per modo oggetti +GDB_MD = { + 'GDB_MD.', + STD = 1, + LOCKED = 2, + HIDDEN = 3 +} +GDB_MD = protect( GDB_MD) +-- Costanti per stato oggetti +GDB_ST = { + 'GDB_ST.', + OFF = 0, + ON = 1, + SEL = 2 +} +GDB_ST = protect( GDB_ST) +-- Costanti per flag calcolo BBox3d +GDB_BB = { + 'GDB_BB.', + STANDARD = 0, + ONLY_VISIBLE = 1, + EXACT = 2, + IGNORE_TEXT = 4, + IGNORE_DIM = 8 +} +GDB_BB = protect( GDB_BB) +-- Costanti per info di sistema +GDB_SI = { + 'GDB_SI.', + SOURCE = "!SOU", + BASE = "!BAS", + LIST = "!LST", + COPY = "!COP", + MGRPONLY = "!MGO" +} +GDB_SI = protect( GDB_SI) +-- Costanti per tipologia di riferimento +GDB_FR = { + 'GDB_FR.', + TOP = 1, + BOTTOM = 2, + FRONT = 3, + BACK = 4, + LEFT = 5, + RIGHT = 6 +} +GDB_FR = protect( GDB_FR) +-- Costanti per posizione inserimento testo rispetto al punto di riferimento +GDB_TI = { + 'GDB_TI.', + TL = 1, + TC = 2, + TR = 3, + ML = 4, + MC = 5, + MR = 6, + BL = 7, + BC = 8, + BR = 9 +} +GDB_TI = protect( GDB_TI) +-- Costanti per interpolazione punti +GDB_PI = { + 'GDB_PI.', + ARCS = 0, + ARCS_CORNER = 1, + CUBICS = 2 +} +GDB_PI = protect( GDB_PI) +-- Costanti per approssimazione curve +GDB_CA = { + 'GDB_CA.', + LINES = 0, + SPECIAL_LINES = 10, + LEFT_LINES = 1, + LEFT_CONVEX_LINES = 11, + RIGHT_LINES = 2, + RIGHT_CONVEX_LINES = 12, + ARCS = 3 +} +GDB_CA = protect( GDB_CA) +-- Costanti per tipo offset di curve +GDB_OT = { + 'GDB_OT.', + FILLET = 0, + CHAMFER = 1, + EXTEND = 2 +} +GDB_OT = protect( GDB_OT) +-- Costanti per classificazione reciproca di regioni +GDB_RC = { + 'GDB_RC.', + NULL = 0, + IN1 = 1, + IN2 = 2, + SAME = 3, + OUT = 4, + INTERS = 5 +} +GDB_RC = protect( GDB_RC) +-- Costanti per classificazione curva rispetto a regione +GDB_CRC = { + 'GDB_CRC.', + NULL = 0, + IN = 1, + OUT = 2, + ON = 3, + INTERS = 4 +} +GDB_CRC = protect( GDB_CRC) +-- Costanti tipo punto intersezione Linea SurfTriMesh +GDB_SLT = { + 'GDB_SLT.', + NULL = 0, + IN = 1, + OUT = 2, + TG_INI = 3, + TG_FIN = 4, + TOUCH = 5 +} +GDB_SLT = protect( GDB_SLT) +-- Costanti tipo costruzione superficie rigata +GDB_RUL = { + 'GDB_RUL.', + ISOPAR = 'IP', + MINDIST = 'MD' +} +GDB_RUL = protect( GDB_RUL) +-- Costanti scena per tipo visualizzazione +SCE_SM = { + 'SCE_SM.', + WF = 0, + HL = 1, + SH = 2 +} +SCE_SM = protect( SCE_SM) +-- Costanti scena per tipo zoom +SCE_ZM = { + 'SCE_ZM.', + ALL = 1, + IN = 2, + OUT = 3 +} +SCE_ZM = protect( SCE_ZM) +-- Costanti scena per tipo vista +SCE_VD = { + 'SCE_VD.', + NONE = 0, + TOP = 1, + FRONT = 2, + RIGHT = 3, + BACK = 4, + LEFT = 5, + BOTTOM = 6, + ISO_SW = 7, + ISO_SE = 8, + ISO_NE = 9, + ISO_NW = 10, + GRID = 11 +} +SCE_VD = protect( SCE_VD) +-- Flag per import CNC +EIC_FL = { + 'EIC_FL.', + NONE = 0, + CHAIN = 1, + SKIP_ZEROMACH = 2, + SKIP_RAPID = 4 +} +EIC_FL = protect( EIC_FL) +-- Flag per import BTL +EIB_FL = { + 'EIB_FL.', + NONE = 0, + FLAT_POS = 1, + VERT_POS = 2, + SPECIAL_TRIM = 4, + TS3_POS = 8, + SORT = 16, + USEUATTR = 32 +} +EIB_FL = protect( EIB_FL) +-- Flag per export +EEX_FL = { + 'EEX_FL.', + NONE = 0, + COMP_LAYER = 1, + COL_BY_LAYER = 2, + ADV_NAMES = 4 +} +EEX_FL = protect( EEX_FL) +-- Costanti shortest path per tipo di percorso di ottimizzazione +SHP_TY = { + 'SHP_TY.', + NONE = 0, + CLOSED = 1, + OPEN = 2, + ZIGZAG_X = 3, + ZIGZAG_Y = 4, + ONEWAY_XP = 5, + ONEWAY_XM = 6, + ONEWAY_YP = 7, + ONEWAY_YM = 8 +} +SHP_TY = protect( SHP_TY) +-- Costanti shortest path per tipo estremo di percorso aperto +SHP_OB = { + 'SHP_OB.', + NONE = 0, + NEAR_PNT = 1, + XMIN = 2, + XMAX = 3, + YMIN = 4, + YMAX = 5 +} +SHP_OB = protect( SHP_OB) +-- Costanti nesting per interferenza lavorazione +NST_FMI = { + 'NST_FMI.', + NONE = 0, + LI = 1, + RM = 2, + LO = 4 +} +NST_FMI = protect( NST_FMI) +-- Costanti nesting automatico per corner di partenza +NST_CORNER = { + 'NST_CORNER.', + BL = 0, + TL = 1, + BR = 2, + TR = 3 +} +NST_CORNER = protect( NST_CORNER) +-- Costanti lavorazioni per tipo di tavola della macchina +MCH_TT = { + 'MCH_TT.', + FLAT = 1 +} +MCH_TT = protect( MCH_TT) +-- Costanti lavorazioni per tipo assi della macchina +MCH_AT = { + 'MCH_AT.', + LINEAR = 1, + ROTARY = 2 +} +MCH_AT = protect( MCH_AT) +-- Costanti lavorazioni per tipo teste della macchina (standard o multipla) +MCH_HT = { + 'MCH_HT.', + STD = 1, + MULTI = 2, + SPECIAL = 3 +} +MCH_HT = protect( MCH_HT) +-- Costanti lavorazioni per criterio scelta soluzione (Solution Choice Criterion) +-- STD e OPPOSITE si possono usare solo nelle operazioni (non nelle teste) +MCH_SCC = { + 'MCH_SCC.', + NONE = 0, + STD = 1, + OPPOSITE = 2, + ADIR_XP = 11, + ADIR_XM = 12, + ADIR_YP = 13, + ADIR_YM = 14, + ADIR_ZP = 15, + ADIR_ZM = 16, + ADIR_NEAR = 21, + ADIR_FAR = 22 +} +MCH_SCC = protect( MCH_SCC) +-- Costanti lavorazioni per posizionamento grezzo su corner +MCH_CR = { + 'MCH_CR.', + TL = 1, + TR = 2, + BL = 3, + BR = 4 +} +MCH_CR = protect( MCH_CR) +-- Costanti lavorazioni per posizionamento grezzo su centro +MCH_CE = { + 'MCH_CE.', + TC = 1, + ML = 2, + MR = 3, + BC = 4, + MC = 5 +} +MCH_CE = protect( MCH_CE) +-- Costanti lavorazioni per famiglia utensile +MCH_TF = { + 'MCH_TF.', + DRILLBIT = 256, + SAWBLADE = 512, + MILL = 1024, + MORTISE = 2048, + CHISEL = 4096, + WATERJET = 8192, + COMPO = 16384 +} +MCH_TF = protect( MCH_TF) +-- Costanti lavorazioni per tipologia utensile +MCH_TY = { + 'MCH_TY.', + NONE = 0, + DRILL_STD = 256, + DRILL_LONG = 257, + SAW_STD = 512, + SAW_FLAT = 513, + MILL_STD = 1024, + MILL_NOTIP = 1025, + MILL_POLISHING = 1026, + MORTISE_STD = 2048, + CHISEL_STD = 4096, + WATERJET = 8192, + COMPO = 16384 +} +MCH_TY = protect( MCH_TY) +-- Costanti lavorazioni per tipo parametri di utensili +MCH_TP = { + 'MCH_TP.', + ACTIVE = 4096, + CORR = 8192, + EXIT = 8193, + TYPE = 8194, + COOLANT = 8195, + CORNRAD = 16384, + DIAM = 16385, + TOTDIAM = 16386, + FEED = 16387, + ENDFEED = 16388, + STARTFEED = 16389, + TIPFEED = 16390, + LEN = 16391, + TOTLEN = 16392, + MAXMAT = 16393, + LONOFFSET = 16394, + RADOFFSET = 16395, + SPEED = 16396, + SIDEANG = 16397, + MAXSPEED = 16398, + THICK = 16399, + MAXABSORPTION = 16400, + MINFEED = 16401, + DRAW = 32768, + HEAD = 32769, + NAME = 32770, + SYSNOTES = 32771, + USERNOTES = 32772, + TCPOS = 32773, + UUID = 32774 +} +MCH_TP = protect( MCH_TP) +-- Costanti lavorazioni per tipologia operazione +MCH_OY = { + 'MCH_OY.', + NONE = 0, + DISP = 256, + DRILLING = 512, + SAWING = 1024, + MILLING = 2048, + POCKETING = 4096, + MORTISING = 8192, + SAWROUGHING = 16384, + SAWFINISHING = 32768, + GENMACHINING = 65536, + CHISELING = 131072, + SURFROUGHING = 262144, + SURFFINISHING = 524288, + WATERJETTING = 1048576 +} +MCH_OY = protect( MCH_OY) +-- Costanti lavorazioni per tipologia lavorazione +MCH_MY = { + 'MCH_MY.', + NONE = MCH_OY.NONE, + DRILLING = MCH_OY.DRILLING, + SAWING = MCH_OY.SAWING, + MILLING = MCH_OY.MILLING, + POCKETING = MCH_OY.POCKETING, + MORTISING = MCH_OY.MORTISING, + SAWROUGHING = MCH_OY.SAWROUGHING, + SAWFINISHING = MCH_OY.SAWFINISHING, + GENMACHINING = MCH_OY.GENMACHINING, + CHISELING = MCH_OY.CHISELING, + SURFROUGHING = MCH_OY.SURFROUGHING, + SURFFINISHING = MCH_OY.SURFFINISHING, + WATERJETTING = MCH_OY.WATERJETTING +} +MCH_MY = protect( MCH_MY) +-- Costanti lavorazioni per parametri generali delle lavorazioni +MCH_GP = { + 'MCH_GP.', + SPLITARCS = 8192, + SAFEZ = 16384, + EXTRALONCUTREG = 16385, + EXTRARONDRIREG = 16386, + HOLEDIAMTOLER = 16387, + EXTSAWARCMINRAD = 16388, + INTSAWARCMAXSIDEANG = 16389, + SAFEAGGRBOTTZ = 16390, + MAXDEPTHSAFE = 16391 +} +MCH_GP = protect( MCH_GP) +-- Costanti spezzatura archi +MCH_SPLAR ={ + 'MCH_SPLAR.', + NEVER = 0, + GEN_PLANE = 1, + NO_XY_PLANE = 2, + ALWAYS = 3 +} +MCH_SPLAR = protect( MCH_SPLAR) +-- Costanti lavorazioni per tipo parametri di lavorazione +MCH_MP = { + 'MCH_MP.', + INVERT = 4096, + LEAVETAB = 4097, + TOOLINVERT = 4098, + PROBING = 4099, + LIHOLE = 4100, + OSCENABLE = 4101, + TYPE = 8192, + WORKSIDE = 8193, + HEADSIDE = 8194, + LEADINTYPE = 8195, + EXTLINKTYPE = 8196, + LEADOUTTYPE = 8197, + CURVEUSE = 8198, + STEPTYPE = 8199, + SUBTYPE = 8200, + LEADLINKTYPE = 8201, + SCC = 8202, + FACEUSE = 8203, + EXTCORNERTYPE = 8204, + INTCORNERTYPE = 8205, + CORNERSLOWPERC = 8206, + LPTURNS = 8207, + HPTURNS = 8208, + TABMIN = 8209, + TABMAX = 8210, + SPEED = 16384, + TOOLSPEED = 16384, -- per compatibilità + FEED = 16385, + STARTFEED = 16386, + ENDFEED = 16387, + TIPFEED = 16388, + OFFSR = 16389, + OFFSL = 16390, + DEPTH = 16391, + SIDEANGLE = 16392, + APPROX = 16393, + STARTPOS = 16394, + STARTSLOWLEN = 16395, + ENDSLOWLEN = 16396, + THROUADDLEN = 16397, + STEP = 16398, + RETURNPOS = 16399, + OVERLAP = 16400, + TABLEN = 16401, + TABDIST = 16402, + TABHEIGHT = 16403, + TABANGLE = 16404, + LITANG = 16405, + LIPERP = 16406, + LIELEV = 16407, + LICOMPLEN = 16408, + LOTANG = 16409, + LOPERP = 16410, + LOELEV = 16411, + LOCOMPLEN = 16412, + STARTADDLEN = 16413, + ENDADDLEN = 16414, + OFFSET = 16415, + STEPEXTARC = 16416, + STEPINTARC = 16417, + SIDESTEP = 16418, + VERTFEED = 16419, + STEPSIDEANG = 16420, + OVERL = 16421, + STEPBACK = 16422, + STEPSIDEANGBACK = 16423, + BACKFEED = 16424, + LIHOLERAD = 16425, + FORWARDANGLE = 16426, + PROBINGMINDIST =16427, + PROBINGMAXDIST =16428, + CORNERSLOWLEN = 16429, + THICKREF = 16430, + OSCHEIGHT = 16431, + OSCRAMPLEN = 16432, + OSCFLATLEN = 16433, + SIDEANGFEED = 16434, + STEPLAST = 16435, + EPICYCLESRAD = 16436, + EPICYCLESDIST = 16437, + NAME = 32768, + TOOL = 32769, + DEPTH_STR = 32770, + TUUID = 32771, + UUID = 32772, + SYSNOTES = 32773, + USERNOTES = 32774, + OVERLAP_STR = 32775, + OFFSET_STR = 32776, + INITANGS= 32777, + BLOCKEDAXIS= 32778 +} +MCH_MP = protect( MCH_MP) +-- Costanti foratura per sottotipo lavorazione +MCH_DRI_SUB = { + 'MCH_DRI_SUB.', + STD = 0, + ALONG_CURVE = 1 +} +MCH_DRI_SUB = protect( MCH_DRI_SUB) +-- Costanti lavorazioni lama per lato di lavoro +MCH_SAW_WS = { + 'MCH_SAW_WS.', + CENTER = 0, + LEFT = 1, + RIGHT = 2 +} +MCH_SAW_WS = protect( MCH_SAW_WS) +-- Costanti lavorazioni lama per lato testa +MCH_SAW_HS = { + 'MCH_SAW_HS.', + LEFT = 1, + RIGHT = 2 +} +MCH_SAW_HS = protect( MCH_SAW_HS) +-- Costanti lavorazioni lama per tipo di step +MCH_SAW_ST = { + 'MCH_SAW_ST.', + ZIGZAG = 0, + ONEWAY = 1, + TOANDFROM = 2 +} +MCH_SAW_ST = protect( MCH_SAW_ST) +-- Costanti lavorazioni lama per tipo di attacco +MCH_SAW_LI = { + 'MCH_SAW_LI.', + CENT = 0, + STRICT = 1, + OUT = 2, + EXT_CENT = 3, + EXT_OUT = 4 +} +MCH_SAW_LI = protect( MCH_SAW_LI) +-- Costanti lavorazioni lama per link esterno +MCH_SAW_EL = { + 'MCH_SAW_EL.', + CENT = 0, + EXT_PREV = 1, + EXT_NEXT = 2, + EXT_BOTH = 3 +} +MCH_SAW_EL = protect( MCH_SAW_EL) +-- Costanti lavorazioni lama per tipo di uscita ( EXT conservato per compatibilità) +MCH_SAW_LO = { + 'MCH_SAW_LO.', + CENT = 0, + STRICT = 1, + EXT = 2, + EXT_CENT = 2, + OUT = 3, + EXT_OUT = 4 +} +MCH_SAW_LO = protect( MCH_SAW_LO) +-- Costanti lavorazioni lama per gestione curve +MCH_SAW_CRV = { + 'MCH_SAW_CRV.', + SKIP = 0, + APPROX = 1, + CONVEX = 2, + KEEP = 3 +} +MCH_SAW_CRV = protect( MCH_SAW_CRV) +-- Costanti lavorazioni fresa per lato di lavoro +MCH_MILL_WS = { + 'MCH_MILL_WS.', + CENTER = 0, + LEFT = 1, + RIGHT = 2 +} +MCH_MILL_WS = protect( MCH_MILL_WS) +-- Costanti lavorazioni fresa per tipo di step +MCH_MILL_ST = { + 'MCH_MILL_ST.', + ZIGZAG = 0, + ONEWAY = 1, + SPIRAL = 2 +} +MCH_MILL_ST = protect( MCH_MILL_ST) +-- Costanti lavorazioni fresa per tipo di attacco +MCH_MILL_LI = { + 'MCH_MILL_LI.', + NONE = 0, + LINEAR = 1, + TANGENT = 2, + GLIDE = 3, + ZIGZAG = 4, + HELIX = 5, + TG_PERP = 6 +} +MCH_MILL_LI = protect( MCH_MILL_LI) +-- Costanti lavorazioni fresa per tipo di uscita +MCH_MILL_LO = { + 'MCH_MILL_LO.', + NONE = 0, + LINEAR = 1, + TANGENT = 2, + GLIDE = 3, + AS_LI = 4, + PERP_TG = 5 +} +MCH_MILL_LO = protect( MCH_MILL_LO) +-- Costanti lavorazioni fresa per tipo lavorazione faccia +MCH_MILL_FU = { + 'MCH_MILL_FU.', + NONE = 0, + PARAL_DOWN = 1, + PARAL_TOP = 2, + PARAL_FRONT = 3, + PARAL_BACK = 4, + PARAL_LEFT = 5, + PARAL_RIGHT = 6, + ORTHO_DOWN = 33, + ORTHO_TOP = 34, + ORTHO_FRONT = 35, + ORTHO_BACK = 36, + ORTHO_LEFT = 37, + ORTHO_RIGHT = 38, + ORTHO_CONT = 39, + ORTUP_DOWN = 65, + ORTUP_TOP = 66, + ORTUP_FRONT = 67, + ORTUP_BACK = 68, + ORTUP_LEFT = 69, + ORTUP_RIGHT = 70, + ORTUP_CONT = 71 +} +MCH_MILL_FU = protect( MCH_MILL_FU) +-- Costanti lavorazioni svuotatura per sottotipo +MCH_POCK_SUB = { + 'MCH_POCK_SUB.', + ZIGZAG = 0, + ONEWAY = 1, + SPIRALIN = 2, + SPIRALOUT = 3 +} +MCH_POCK_SUB = protect( MCH_POCK_SUB) +-- Costanti lavorazioni svuotatura per tipo di attacco +MCH_POCK_LI = { + 'MCH_POCK_LI.', + NONE = 0, + GLIDE = 1, + ZIGZAG = 2, + HELIX = 3 +} +MCH_POCK_LI = protect( MCH_POCK_LI) +-- Costanti lavorazioni svuotatura per tipo di uscita +MCH_POCK_LO = { + 'MCH_POCK_LO.', + NONE = 0, + GLIDE = 1 +} +MCH_POCK_LO = protect( MCH_POCK_LO) +-- Costanti lavorazioni sgrossatura con lama per lato testa +MCH_SAWROU_HS = { + 'MCH_SAWROU_HS.', + LEFT = 1, + RIGHT = 2 +} +MCH_SAWROU_HS = protect( MCH_SAWROU_HS) +-- Costanti lavorazioni sgrossatura con lama per tipo di step +MCH_SAWROU_ST = { + 'MCH_SAWROU_ST.', + ZIGZAG = 0, + ONEWAY = 1 +} +MCH_SAWROU_ST = protect( MCH_SAWROU_ST) +-- Costanti lavorazioni sgrossatura con lama per tipo di attacco +MCH_SAWROU_LL = { + 'MCH_SAWROU_LL.', + CENT = 0, + OUT = 1 +} +MCH_SAWROU_LL = protect( MCH_SAWROU_LL) +-- Costanti lavorazioni finitura con lama per lato testa +MCH_SAWFIN_HS = { + 'MCH_SAWFIN_HS.', + LEFT = 1, + RIGHT = 2 +} +MCH_SAWFIN_HS = protect( MCH_SAWFIN_HS) +-- Costanti lavorazioni finitura con lama per tipo di step +MCH_SAWFIN_ST = { + 'MCH_SAWFIN_ST.', + ZIGZAG = 0, + ONEWAY = 1 +} +MCH_SAWFIN_ST = protect( MCH_SAWFIN_ST) +-- Costanti lavorazioni finitura con lama per tipo di attacco +MCH_SAWFIN_LL = { + 'MCH_SAWFIN_LL.', + CENT = 0, + OUT = 1 +} +MCH_SAWFIN_LL = protect( MCH_SAWFIN_LL) +-- Costanti lavorazioni scalpellatura per lato di lavoro +MCH_CHISEL_WS = { + 'MCH_CHISEL_WS.', + LEFT = 1, + RIGHT = 2 +} +MCH_CHISEL_WS = protect( MCH_CHISEL_WS) +-- Costanti lavorazioni mortasatura per lato di lavoro +MCH_MORTISE_WS = { + 'MCH_MORTISE_WS.', + LEFT = 1, + RIGHT = 2 +} +MCH_MORTISE_WS = protect( MCH_MORTISE_WS) +-- Costanti lavorazioni mortasatura per tipo di step +MCH_MORTISE_ST = { + 'MCH_MORTISE_ST.', + ZIGZAG = 0, + ONEWAY = 1 +} +MCH_MORTISE_ST = protect( MCH_MORTISE_ST) +-- Costanti lavorazioni fresa per tipo lavorazione faccia +MCH_MORTISE_FU = { + 'MCH_MORTISE_FU.', + NONE = 0, + PARAL_DOWN = 1, + PARAL_TOP = 2, + PARAL_FRONT = 3, + PARAL_BACK = 4, + PARAL_LEFT = 5, + PARAL_RIGHT = 6 +} +MCH_MORTISE_FU = protect( MCH_MORTISE_FU) +-- Costanti lavorazioni getto d'acqua per lato di lavoro +MCH_WJET_WS = { + 'MCH_WJET_WS.', + CENTER = 0, + LEFT = 1, + RIGHT = 2 +} +MCH_WJET_WS = protect( MCH_WJET_WS) +-- Costanti lavorazioni getto d'acqua per comportamento su angolo esterno +MCH_WJET_EC = { + 'MCH_WJET_EC.', + NONE = 0, + SLOW = 1, + LOOP = 2 +} +MCH_WJET_EC = protect( MCH_WJET_EC) +-- Costanti lavorazioni getto d'acqua per comportamento su angolo interno +MCH_WJET_IC = { + 'MCH_WJET_IC.', + NONE = 0, + SLOW = 1, +} +MCH_WJET_IC = protect( MCH_WJET_IC) +-- Costanti lavorazioni getto d'acqua per tipo di attacco +MCH_WJET_LI = { + 'MCH_WJET_LI.', + NONE = 0, + LINEAR = 1, + TANGENT = 2 +} +MCH_WJET_LI = protect( MCH_WJET_LI) +-- Costanti lavorazioni getto d'acqua per tipo di uscita +MCH_WJET_LO = { + 'MCH_WJET_LO.', + NONE = 0, + LINEAR = 1, + TANGENT = 2, + AS_LI = 4 +} +MCH_WJET_LO = protect( MCH_WJET_LO) +-- Costanti lavorazioni per stato simulazione +MCH_SIM = { + 'MCH_SIM.', + OK = 0, + END_STEP = 1, + END = 2, + STOP = 3, + OUTSTROKE = 4, + DIR_ERR = 5, + COLLISION = 6, + ERR = 7 +} +MCH_SIM = protect( MCH_SIM) +-- Costanti lavorazioni per stato utente di simulazione +MCH_UISIM = { + 'MCH_UISIM.', + NULL = 0, + STOP = 1, + PLAY = 2, + STEP = 3, + PAUSE = 4 +} +MCH_UISIM = protect( MCH_UISIM) +-- Costanti errore simulatore in cieco +MCH_SHE = { + 'MCH_SHE.', + NONE = 0, + INIT = 1, + OUTSTROKE = 2, + DIR_ERR = 3, + COLLISION = 4, + SPECIAL = 5, + GENERAL = 6 +} +MCH_SHE = protect( MCH_SHE) +-- Costanti per tipi oggetti per collisioni in simulatore +MCH_SIM_COB = { + 'MCH_SIM_COB.', + NONE = 0, + BOX = 1, + CYL = 2, + SPHE = 3, + CONE = 4 +} +MCH_SIM_COB = protect( MCH_SIM_COB) +--Costanti : stato visualizzazione macchina +MCH_LOOK = { + 'MCH_LOOK.', + TAB = 0, + TAB_TOOL = 1, + TAB_HEAD = 2, + ALL = 3 +} +MCH_LOOK = protect( MCH_LOOK) + +return EgtConst diff --git a/ProgramData/EgtCAM5/LuaLibs/EgtDimension.lua b/ProgramData/EgtCAM5/LuaLibs/EgtDimension.lua new file mode 100644 index 0000000..b93a347 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EgtDimension.lua @@ -0,0 +1,494 @@ +-- EgtDimension.lua by EgalTech s.r.l. 2019/032/31 +-- Creazione di una quota + +-- Tavola per definizione modulo (serve ma non usata) +local EgtDimension = {} + +EgtOutLog( 'EgtDimension started', 1) + +-- Intestazioni +require( 'EgtBase') + +-- Frecce agli estremi della linea di quotatura +function Arrows(nParentId, ptP1, ptP2, dLenArr, iFrame, cColor, bRadius) + + local Ang = atan2( (ptP2:getY() - ptP1:getY()), (ptP2:getX() - ptP1:getX())) + local iLine1 + local iLine2 + if not bRadius then + iLine1 = EgtLinePDL(nParentId, ptP1, Ang + 30, dLenArr, iFrame) + iLine2 = EgtLinePDL(nParentId, ptP1, Ang - 30, dLenArr, iFrame) + end + local iLine3 = EgtLinePDL(nParentId, ptP2, Ang + 150, dLenArr, iFrame) + local iLine4 = EgtLinePDL(nParentId, ptP2, Ang - 150, dLenArr, iFrame) + + if cColor then + if not bRadius then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + end + EgtSetColor( iLine3, cColor) + EgtSetColor( iLine4, cColor) + end +end + +-- Quota verticale (bSide: false sx, true dx) +function CreateLinearDimensionOnY( nParentId, ptP1, ptP2, sText, iTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor) + + if not iFrame then + iFrame = GDB_RT.LOC + end + + local ptSx -- punto a sinistra + local ptDx -- punto a destra + + if ptP1:getX() < ptP2:getX() - GEO.EPS_SMALL then + ptSx = Point3d(ptP1) + ptDx = Point3d(ptP2) + else + ptSx = Point3d(ptP2) + ptDx = Point3d(ptP1) + end + + if not bSide then -- Quotatura a sinistra + + if abs(ptSx:getY() - ptDx:getY()) < GEO.EPS_SMALL then -- Caso di quota nulla + + local Uvx = Vector3d(-1, 0, 0) + local iLine = EgtLinePVL(nParentId, ptDx, Uvx, dDistance + ptDx:getX() - ptSx:getX(), iFrame) + local pText = Point3d(ptSx:getX() - dDistance - dDistText, ptSx:getY(),0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.MR,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine, cColor) + EgtSetColor( TextId, cColor) + end + else -- Caso di quota non nulla + + local ptSx1 = Point3d(ptSx:getX() - dDistance, ptSx:getY(), 0) + local ptDx1 = Point3d(ptSx:getX() - dDistance, ptDx:getY(), 0) + + local iLine1 = EgtLine(nParentId, ptSx, ptSx1, iFrame) + local iLine2 = EgtLine(nParentId, ptDx, ptDx1, iFrame) + + local ptSx2 = Point3d(ptSx:getX() - (dDistance - 0.5 * dLenArr), ptSx:getY(), 0) + local ptDx2 = Point3d(ptSx:getX() - (dDistance - 0.5 * dLenArr), ptDx:getY(), 0) + + local iLine3 = EgtLine(nParentId, ptSx2, ptDx2, iFrame) + Arrows(nParentId, ptSx2, ptDx2, dLenArr, iFrame, cColor) + + local pText = Point3d(ptSx1:getX() - dDistText, (ptSx1:getY() + ptDx1:getY())/2,0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.MR) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end + end + else -- Quotatura a destra + + if abs(ptSx:getY() - ptDx:getY()) < GEO.EPS_SMALL then -- Caso di quota nulla + + local Uvx = Vector3d(1, 0, 0) + local iLine = EgtLinePVL(nParentId, ptSx, Uvx, dDistance + ptDx:getX() - ptSx:getX(), iFrame) + local pText = Point3d(ptDx:getX() + dDistance + dDistText, ptSx:getY(),0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.ML,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine, cColor) + EgtSetColor( TextId, cColor) + end + else -- Caso di quota non nulla + + local ptSx1 = Point3d(ptDx:getX() + dDistance, ptSx:getY(), 0) + local ptDx1 = Point3d(ptDx:getX() + dDistance, ptDx:getY(), 0) + + local iLine1 = EgtLine(nParentId, ptSx, ptSx1, iFrame) + local iLine2 = EgtLine(nParentId, ptDx, ptDx1, iFrame) + + local ptSx2 = Point3d(ptDx:getX() + (dDistance - 0.5 * dLenArr), ptSx:getY(), 0) + local ptDx2 = Point3d(ptDx:getX() + (dDistance - 0.5 * dLenArr), ptDx:getY(), 0) + + local iLine3 = EgtLine(nParentId, ptSx2, ptDx2, iFrame) + Arrows(nParentId, ptSx2, ptDx2, dLenArr, iFrame, cColor) + + local pText = Point3d(ptDx1:getX() + dDistText, (ptSx1:getY() + ptDx1:getY())/2,0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.ML,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end + end + end +end + +-- Quota orizzontale (bSide: false down, true up) +function CreateLinearDimensionOnX( nParentId, ptP1, ptP2, sText, iTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor, bRadius, bShiftLeft) + + if not iFrame then + iFrame = GDB_RT.LOC + end + + local ptDw -- punto in basso + local ptUp -- punto in alto + + if ptP1:getY() < ptP2:getY() - GEO.EPS_SMALL then + ptDw = Point3d( ptP1) + ptUp = Point3d( ptP2) + else + ptDw = Point3d( ptP2) + ptUp = Point3d( ptP1) + end + + -- Quotatura in basso + if not bSide then + + -- Caso di quota nulla + if abs(ptDw:getX() - ptUp:getX()) < GEO.EPS_SMALL then + + local UvY = Vector3d(0, -1, 0) + local iLine = EgtLinePVL(nParentId, ptUp, UvY, ptUp:getY() - ptDw:getY() + dDistance, iFrame) + local pText = Point3d(ptDw:getX(), ptDw:getY() - dDistance - dDistText,0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.TC,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + if bShiftLeft then + EgtMove( TextId, Vector3d(-dLenArr/2, dLenArr + abs(ptDw:getX() - ptUp:getX()) + 20, 0)) + end + if cColor then + EgtSetColor( iLine, cColor) + EgtSetColor( TextId, cColor) + end + + -- Caso di quota non nulla + else + local ptDw1 + local ptUp1 + local ptDw2 + local ptUp2 + local iLine1 + local iLine2 + + if not bRadius then + ptDw1 = Point3d(ptDw:getX(), ptDw:getY() - dDistance, 0) + ptUp1 = Point3d(ptUp:getX(), ptDw:getY() - dDistance, 0) + + iLine1 = EgtLine(nParentId, ptDw, ptDw1, iFrame) + iLine2 = EgtLine(nParentId, ptUp, ptUp1, iFrame) + + ptDw2 = Point3d(ptDw:getX(), ptDw:getY() - (dDistance - 0.5 * dLenArr), 0) + ptUp2 = Point3d(ptUp:getX(), ptDw:getY() - (dDistance - 0.5 * dLenArr), 0) + else + ptDw1 = Point3d(ptDw:getX(), ptDw:getY(), 0) + ptUp1 = Point3d(ptUp:getX(), ptDw:getY(), 0) + ptDw2 = Point3d(ptDw:getX(), ptDw:getY(), 0) + ptUp2 = Point3d(ptUp:getX(), ptDw:getY(), 0) + end + + local iLine3 = EgtLine(nParentId, ptDw2, ptUp2, iFrame) + Arrows(nParentId, ptDw2, ptUp2, dLenArr, iFrame, cColor, bRadius) + + local pText = Point3d((ptDw1:getX() + ptUp1:getX())/2, ptDw1:getY() - dDistText,0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.TC,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + if bShiftLeft then + EgtMove( TextId, Vector3d(-dLenArr/2, dLenArr + abs(ptDw:getX() - ptUp:getX()) + 20, 0)) + end + + if cColor then + if not bRadius then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + end + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end + end + + -- Quotatura in alto + else + + -- Caso di quota nulla + if abs( ptDw:getX() - ptUp:getX()) < GEO.EPS_SMALL then + + local UvY = Vector3d(0, 1, 0) + local iLine = EgtLinePVL(nParentId, ptDw, UvY, ptUp:getY() - ptDw:getY() + dDistance, iFrame) + local pText = Point3d(ptUp:getX(), ptUp:getY() + dDistance + dDistText,0) + local TextId = EgtTextAdv(nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.BC,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + if bShiftLeft then + EgtMove( TextId, Vector3d(-dLenArr/2, dLenArr + abs(ptDw:getX() - ptUp:getX()) + 20, 0)) + end + if cColor then + EgtSetColor( iLine, cColor) + EgtSetColor( TextId, cColor) + end + + -- Caso di quota non nulla + else + local ptDw1 + local ptUp1 + local ptDw2 + local ptUp2 + local iLine1 + local iLine2 + + if not bRadius then + + ptDw1 = Point3d( ptDw:getX(), ptUp:getY() + dDistance, 0) + ptUp1 = Point3d( ptUp:getX(), ptUp:getY() + dDistance, 0) + + iLine1 = EgtLine( nParentId, ptDw, ptDw1, iFrame) + iLine2 = EgtLine( nParentId, ptUp, ptUp1, iFrame) + + ptDw2 = Point3d( ptDw:getX(), ptUp:getY() + (dDistance - 0.5 * dLenArr), 0) + ptUp2 = Point3d( ptUp:getX(), ptUp:getY() + (dDistance - 0.5 * dLenArr), 0) + else + + ptDw1 = Point3d( ptDw:getX(), ptUp:getY(), 0) + ptUp1 = Point3d( ptUp:getX(), ptUp:getY(), 0) + ptDw2 = Point3d( ptDw:getX(), ptUp:getY(), 0) + ptUp2 = Point3d( ptUp:getX(), ptUp:getY(), 0) + end + + local iLine3 = EgtLine( nParentId, ptDw2, ptUp2, iFrame) + Arrows( nParentId, ptDw2, ptUp2, dLenArr, iFrame, cColor, bRadius) + + local pText = Point3d( ( ptDw1:getX() + ptUp1:getX()) / 2, ptUp1:getY() + dDistText, 0) + local TextId = EgtTextAdv( nParentId, pText, 0, sText,"", 400,"S", iTextSize, 1, 0, GDB_TI.BC,iFrame) + if bShiftLeft then + EgtMove( TextId, Vector3d( -dLenArr/2, dLenArr + abs( ptDw:getX() - ptUp:getX()) + 20, 0)) + end + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + if not bRadius then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + end + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end + end + end +end + +-- Quota allineata (bSide: false sx, true dx) +function CreateLinearDimensionAligned( nParentId, ptP1, ptP2, sText, dTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor) + + if not iFrame then + iFrame = GDB_RT.LOC + end + + -- Se punti coincidenti, esco + if AreSamePointApprox(ptP1,ptP2) then + return false + end + + -- Se quotatura orizzontale, uso questa + if abs(ptP1:getY() - ptP2:getY()) < GEO.EPS_SMALL then + -- adatto il lato + if ptP2:getX() > ptP1:getX() then + bSide = not bSide + end + CreateLinearDimensionOnX(nParentId, ptP1, ptP2, sText, dTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor) + return true + end + + local Vv = ptP2 - ptP1 + Vv:normalize() + + local AngText = atan2( Vv:getY(), Vv:getX()) + local bAngModif = false + if AngText > 90 then + AngText = AngText - 180 + bAngModif = true + elseif AngText < - 90 then + AngText = AngText + 180 + bAngModif = true + end + + if bSide then + Vv:rotate(Z_AX(),-90) + if bAngModif then + PointType = GDB_TI.BC + else + PointType = GDB_TI.TC + end + else + Vv:rotate(Z_AX(),90) + if bAngModif then + PointType = GDB_TI.TC + else + PointType = GDB_TI.BC + end + end + + local iLine1 = EgtLinePVL(nParentId,ptP1, Vv, dDistance, iFrame) + local iLine2 = EgtLinePVL(nParentId,ptP2, Vv, dDistance, iFrame) + + local ptP1M = ptP1 + (dDistance - 0.5 * dLenArr) * Vv + local ptP2M = ptP2 + (dDistance - 0.5 * dLenArr) * Vv + + local iLine3 = EgtLine(nParentId, ptP1M, ptP2M, iFrame) + Arrows(nParentId, ptP1M, ptP2M, dLenArr, iFrame, cColor) + + local ptText = 0.5 * ( ptP1 + ptP2) + ( dDistance + dDistText) * Vv + local TextId = EgtTextAdv(nParentId, ptText, AngText , sText,"", 400,"S", dTextSize, 1, 0, PointType,iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end +end + +-- Quota radiale (bSide: false sx, true dx) +function CreateRadialDimension( nParentId, ptC, ptP1, sText, dTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor) + + if not iFrame then + iFrame = GDB_RT.LOC + end + + -- Se punti coincidenti, esco + if AreSamePointApprox(ptC,ptP1) then + return false + end + + -- Se quotatura orizzontale, uso questa + if abs( ptC:getY() - ptP1:getY()) < GEO.EPS_SMALL then + -- adatto il lato + if ptP1:getX() > ptC:getX() then + bSide = not bSide + end + CreateLinearDimensionOnX( nParentId, ptC, ptP1, sText, dTextSize, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor, true) + return true + end + + local Vv = ptP1 - ptC + Vv:normalize() + + local AngText = atan2( Vv:getY(), Vv:getX()) + local bAngModif = false + if AngText > 90 then + AngText = AngText - 180 + bAngModif = true + elseif AngText < - 90 then + AngText = AngText + 180 + bAngModif = true + end + + local ptText + if bSide == nil then + AngText = 0 + Vv = - Vv + ptText = ptC + ( dDistText + 0.5 * dTextSize) * Vv + PointType = GDB_TI.MC + elseif bSide then + Vv:rotate( Z_AX(), -90) + ptText = 0.5 * ( ptC + ptP1) + ( dDistText) * Vv + PointType = EgtIf( bAngModif, GDB_TI.BC, GDB_TI.TC) + + else + Vv:rotate( Z_AX(), 90) + ptText = 0.5 * ( ptC + ptP1) + ( dDistText) * Vv + PointType = EgtIf( bAngModif, GDB_TI.TC, GDB_TI.BC) + end + + local iLine3 = EgtLine( nParentId, ptC, ptP1, iFrame) + Arrows( nParentId, ptC, ptP1, dLenArr, iFrame, cColor, true) + + local TextId = EgtTextAdv( nParentId, ptText, AngText , sText,"", 400,"S", dTextSize, 1, 0, PointType, iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine3, cColor) + EgtSetColor( TextId, cColor) + end +end + +-- Quota angolare (bSide: false = text external, true dx = text internal) +function CreateAngleDimension( nParentId, ptC, dDir, sText, dTextSize, dAngVal, dAmpArc, dDistance, dLenArr, dDistText, bSide, sVar, iFrame, cColor) + + if not iFrame then + iFrame = GDB_RT.LOC + end + + -- Se distanza quota nulla, esco + if abs(dAmpArc) < GEO.EPS_SMALL or abs(dAngVal) < GEO.EPS_SMALL then + return false + end + + -- disegno linee da quotare + local iLine1 = EgtLinePDL(nParentId, ptC, dDir, dAmpArc, iFrame) + local iLine2 = EgtLinePDL(nParentId, ptC, dDir+dAngVal, dAmpArc, iFrame) + -- prendo i punti finali delle due linee + local ptP1 = EgtEP(iLine1) + local ptP2 = EgtEP(iLine2) + -- allungo di nuovo le linee della distanza extra + EgtTrimExtendCurveByLen( iLine1, dDistance,ptP1) + EgtTrimExtendCurveByLen( iLine2, dDistance,ptP2) + -- arco + local iArc1 = EgtArcCPA( nParentId, ptC, ptP1, dAngVal, 0, iFrame) + local pPt3 = EgtMP(iArc1) + + -- frecce + local iLine3 + local ptP4 + local nNeg = -1 + if dAngVal > 0 then + nNeg = 1 + end + -- faccio linee che parte da punto di freccia perpendicolare a linea di quota + iLine3 = EgtLinePDL(nParentId, ptP1, dDir+(90*nNeg), dAmpArc, iFrame) + ptP4 = EgtEP(iLine3) + EgtErase(iLine3) + -- prima freccia sulla prima linea + Arrows( nParentId, ptP4, ptP1, dLenArr, iFrame, cColor, true) + + iLine3 = EgtLinePDL(nParentId, ptP2, dDir+dAngVal-(90*nNeg), dAmpArc, iFrame) + ptP4 = EgtEP(iLine3) + EgtErase(iLine3) + -- seconda freccia sulla seconda linea + Arrows( nParentId, ptP4, ptP2, dLenArr, iFrame, cColor, true) + + local Vv = ptP1 - ptC + Vv:normalize() + + local AngText = 0 + local bAngModif = false + + local ptText + if bSide == nil then + ptText = pPt3 + ( dDistText + 0.5 * dTextSize) * Vv + PointType = GDB_TI.MC + elseif bSide then + ptText = pPt3 + ( dDistText + 0.5 * dTextSize) * Vv + PointType = GDB_TI.MC + else + ptText = pPt3 - ( dDistText + 0.5 * dTextSize) * Vv + PointType = GDB_TI.MC + end + + local TextId = EgtTextAdv( nParentId, ptText, AngText , sText,"", 400,"S", dTextSize, 1, 0, PointType, iFrame) + EgtSetInfo( TextId, 'Var', sVar) + + if cColor then + EgtSetColor( iLine1, cColor) + EgtSetColor( iLine2, cColor) + EgtSetColor( iArc1, cColor) + EgtSetColor( TextId, cColor) + end +end + +return EgtDimension diff --git a/ProgramData/EgtCAM5/LuaLibs/EgtFrame3d.lua b/ProgramData/EgtCAM5/LuaLibs/EgtFrame3d.lua new file mode 100644 index 0000000..2c7c98d --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EgtFrame3d.lua @@ -0,0 +1,263 @@ +-- EgtFrame3d.lua by EgalTech s.r.l. 2020/09/29 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtFrame3d = {} + +EgtOutLog( 'EgtFrame3d started', 1) + +-- Include +require( 'EgtPoint3d') +--EnableDebug( false) + + +-- Definizione classe Frame3d +Frame3d = {{},{},{},{}} +Frame3d.__index = Frame3d + +-- funzione di utilita' per identificazione tipo +function isFrame3d( a) + return ( getmetatable( a) == Frame3d) +end + +local function New( a, b, c, d) + local f3d = setmetatable( {{0,0,0},{1,0,0},{0,1,0},{0,0,1}}, Frame3d) + local function SetVersors( type) + if type == GDB_FR.FRONT then + f3d[2] = X_AX() ; f3d[3] = Z_AX() ; f3d[4] = -Y_AX() + elseif type == GDB_FR.RIGHT then + f3d[2] = Y_AX() ; f3d[3] = Z_AX() ; f3d[4] = X_AX() + elseif type == GDB_FR.BACK then + f3d[2] = -X_AX() ; f3d[3] = Z_AX() ; f3d[4] = Y_AX() + elseif type == GDB_FR.LEFT then + f3d[2] = -Y_AX() ; f3d[3] = Z_AX() ; f3d[4] = -X_AX() + elseif type == GDB_FR.BOTTOM then + f3d[2] = X_AX() ; f3d[3] = -Y_AX() ; f3d[4] = -Z_AX() + else -- GDB_FR.TOP + f3d[2] = X_AX() ; f3d[3] = Y_AX() ; f3d[4] = Z_AX() + end + end + if not a then + f3d[1] = Point3d( 0, 0, 0) + SetVersors( GDB_FR.TOP) + elseif isFrame3d( a) then + f3d[1] = a[1] + f3d[2] = a[2] + f3d[3] = a[3] + f3d[4] = a[4] + elseif type(a) == 'table' and #a >= 4 and + type(a[1]) == 'table' and #a[1] >= 3 and + type(a[2]) == 'table' and #a[2] >= 3 and + type(a[3]) == 'table' and #a[3] >= 3 and + type(a[4]) == 'table' and #a[4] >= 3 then + f3d[1] = Point3d( a[1]) + f3d[2] = Vector3d( a[2]) + f3d[3] = Vector3d( a[3]) + f3d[4] = Vector3d( a[4]) + f3d[2]:normalize() + f3d[3]:normalize() + f3d[4]:normalize() + if not Frame3d.isValid( f3d) then + error( 'Error in FrameIsValid', 2) + end + elseif isPoint3d( a) and isVector3d( b) and isVector3d( c) and isVector3d( d) then + f3d[1] = a + f3d[2] = b + f3d[3] = c + f3d[4] = d + f3d[2]:normalize() + f3d[3]:normalize() + f3d[4]:normalize() + if not Frame3d.isValid( f3d) then + error( 'Error in FrameIsValid', 2) + end + elseif isPoint3d( a) and isVector3d( b) then + local bOk, Ocs = EgtFrameOCS( a, b) + if bOk then + f3d[1] = Point3d( Ocs[1]) + f3d[2] = Vector3d( Ocs[2]) + f3d[3] = Vector3d( Ocs[3]) + f3d[4] = Vector3d( Ocs[4]) + else + error( 'Error in EgtFrameOCS', 2) + end + elseif isPoint3d( a) and isPoint3d( b) and isPoint3d( c) then + local bOk, f3P = EgtFrameFrom3Points( a, b, c) + if bOk then + f3d[1] = Point3d( f3P[1]) + f3d[2] = Vector3d( f3P[2]) + f3d[3] = Vector3d( f3P[3]) + f3d[4] = Vector3d( f3P[4]) + else + error( 'Error in EgtFrameFrom3Points', 2) + end + elseif isPoint3d( a) then + f3d[1] = a + SetVersors( b) + elseif type(a) == 'number' and type( b) == 'number' and type( c) == 'number' then + f3d[1] = Point3d( a, b, c) + SetVersors( d) + else + error( 'A parameter is wrong', 2) + end + return f3d +end + +setmetatable( Frame3d, { __call = function( _, ...) return New( ...) end }) + +-- verifica validità +function Frame3d:isValid() + -- verifico che i versori siano normalizzati + if not self[2]:isNormalized() or + not self[3]:isNormalized() or + not self[4]:isNormalized() then + return false + end + -- verifico che i versori siano mutuamente ortogonali + if math.abs( self[2][1] * self[3][1] + self[2][2] * self[3][2] + self[2][3] * self[3][3]) > GEO.EPS_ZERO or + math.abs( self[3][1] * self[4][1] + self[3][2] * self[4][2] + self[3][3] * self[4][3]) > GEO.EPS_ZERO or + math.abs( self[4][1] * self[2][1] + self[4][2] * self[2][2] + self[4][3] * self[2][3]) > GEO.EPS_ZERO then + return false + end + -- verifico il senso destrorso della terna + if Vector3d.TripleProd( self[2], self[3], self[4]) < GEO.EPS_ZERO then + return false + end + -- tutto bene + return true +end + +-- traslazione +function Frame3d:move( m) + if not isFrame3d( self) then + return false + end + if isVector3d( m) then + self[1] = self[1] + m + return true + elseif type( m) == 'table' and #m >= 3 then + self[1] = self[1] + Vector3d( m) + return true + else + return false + end +end + +-- rotazione +function Frame3d:rotate( ptAx, vtAx, dAngDeg) + if not isFrame3d( self) or not isPoint3d( ptAx) or not isVector3d( vtAx) or type( dAngDeg) ~= 'number' then + return false + end + local bOk, fRot = EgtFrameRotate( self, ptAx, vtAx, dAngDeg) + if bOk then + self[1] = Point3d( fRot[1]) + self[2] = Vector3d( fRot[2]) + self[3] = Vector3d( fRot[3]) + self[4] = Vector3d( fRot[4]) + end + return bOk +end + +-- inversione (trasformazione inversa) +function Frame3d:invert() + if not isFrame3d( self) then + return false + end + local bOk, frInv = EgtFrameToLoc( Frame3d(), self) + if bOk then + self[1] = Point3d( frInv[1]) + self[2] = Vector3d( frInv[2]) + self[3] = Vector3d( frInv[3]) + self[4] = Vector3d( frInv[4]) + end + return bOk +end + +-- trasformazione di riferimento verso globale +function Frame3d:toGlob( fTool) + if not isFrame3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, fNew = EgtFrameToGlob( self, fTool) + if bOk then + self[1] = Point3d( fNew[1]) + self[2] = Vector3d( fNew[2]) + self[3] = Vector3d( fNew[3]) + self[4] = Vector3d( fNew[4]) + end + return bOk +end + +-- trasformazione di riferimento verso locale +function Frame3d:toLoc( fTool) + if not isFrame3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, fNew = EgtFrameToLoc( self, fTool) + if bOk then + self[1] = Point3d( fNew[1]) + self[2] = Vector3d( fNew[2]) + self[3] = Vector3d( fNew[3]) + self[4] = Vector3d( fNew[4]) + end + return bOk +end + +-- trasformazione di riferimento da locale a locale +function Frame3d:locToLoc( fOri, fDest) + if not isFrame3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then + return false + end + local bOk, fNew = EgtFrameLocToLoc( self, fOri, fDest) + if bOk then + self[1] = Point3d( fNew[1]) + self[2] = Vector3d( fNew[2]) + self[3] = Vector3d( fNew[3]) + self[4] = Vector3d( fNew[4]) + end + return bOk +end + +-- restituzione componenti +function Frame3d:getOrigin() + return self[1] +end + +function Frame3d:getVersX() + return self[2] +end + +function Frame3d:getVersY() + return self[3] +end + +function Frame3d:getVersZ() + return self[4] +end + +-- conversione in stringa (tostring) +function Frame3d:__tostring() + return '('.. tostring(self[1])..','..tostring(self[2])..','..tostring(self[3])..','..tostring(self[4]) ..')' +end + +-- Angoli di rotazione di Eulero da Frame +function GetRotCAC1FromFrame( frRef) + if not isFrame3d( frRef) then + return nil + end + return EgtFrameGetRotCAC1( frRef) +end + +-- Angoli di rotazione attorno ad assi XYZ fissi da Frame +function GetFixedAxesRotABCFromFrame( frRef) + if not isFrame3d( frRef) then + return nil + end + return EgtFrameGetFixedAxesRotABC( frRef) +end + +-- Riferimenti notevoli +function GLOB_FRM() + return Frame3d() +end + +return EgtFrame3d diff --git a/ProgramData/EgtCAM5/LuaLibs/EgtLinearDimension.lua b/ProgramData/EgtCAM5/LuaLibs/EgtLinearDimension.lua new file mode 100644 index 0000000..4d75062 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EgtLinearDimension.lua @@ -0,0 +1,15 @@ +-- EgtLinearDimension.lua by EgalTech s.r.l. 2018/12/22 +-- Creazione di una quota +-- 2018/12/22 DS Rinominato in EgtDimension, tenuto per compatibilità. + + + +-- Tavola per definizione modulo (serve ma non usata) +local EgtLinearDimension = {} + +require( 'EgtDimension') + +CreateLinearDimensionRadial = CreateRadialDimension +CreateAngleDimensionRadial = CreateAngleDimension + +return EgtLinearDimension diff --git a/ProgramData/EgtCAM5/LuaLibs/EgtMachine.lua.old b/ProgramData/EgtCAM5/LuaLibs/EgtMachine.lua.old new file mode 100644 index 0000000..b5c1cb5 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EgtMachine.lua.old @@ -0,0 +1,339 @@ +-- EgtMachine.lua by EgalTech s.r.l. 11/05/2015 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtMachine = {} + +print( 'EgtMachine started') + +-- Include +require( 'EgtBase') + +-- Funzioni ausiliarie +local function CalcSqrDiff( Ax, Vx, Vxpre) + local Diff = Vx - Vxpre + if Ax == 'C' or Ax == 'B' then + Diff = Diff * 10 + end + return Diff * Diff +end + +-- Movimento degli assi (da 1 a 5) +function MoveAxes( A1, V1, A2, V2, A3, V3, A4, V4, A5, V5) + local Len = 0 + local V1pre = 0 + if A1 and V1 then + V1pre = EgtGetAxisPos(A1) + Len = Len + CalcSqrDiff( A1, V1, V1pre) + end + local V2pre = 0 + if A2 and V2 then + V2pre = EgtGetAxisPos(A2) + Len = Len + CalcSqrDiff( A2, V2, V2pre) + end + local V3pre = 0 + if A3 and V3 then + V3pre = EgtGetAxisPos(A3) + Len = Len + CalcSqrDiff( A3, V3, V3pre) + end + if A4 and V4 then + V4pre = EgtGetAxisPos(A4) + Len = Len + CalcSqrDiff( A4, V4, V4pre) + end + if A5 and V5 then + V5pre = EgtGetAxisPos(A5) + Len = Len + CalcSqrDiff( A5, V5, V5pre) + end + Len = sqrt( Len) + local Steps = max( ceil( Len / 50), 1) + for i = 0, Steps do + local sOut = '' + local dFraz = i / Steps + if A1 and V1 then + local dPos1 = V1pre * ( 1 - dFraz) + V1 * dFraz + EgtSetAxisPos( A1, dPos1) + sOut = sOut .. ' ' .. A1 .. string.format('%10.3f',dPos1) + end + if A2 and V2 then + local dPos2 = V2pre * ( 1 - dFraz) + V2 * dFraz + EgtSetAxisPos( A2, dPos2) + sOut = sOut .. ' ' .. A2 .. string.format('%10.3f',dPos2) + end + if A3 and V3 then + local dPos3 = V3pre * ( 1 - dFraz) + V3 * dFraz + EgtSetAxisPos( A3, dPos3) + sOut = sOut .. ' ' .. A3 .. string.format('%10.3f',dPos3) + end + if A4 and V4 then + local dPos4 = V4pre * ( 1 - dFraz) + V4 * dFraz + EgtSetAxisPos( A4, dPos4) + sOut = sOut .. ' ' .. A4 .. string.format('%10.3f',dPos4) + end + if A5 and V5 then + local dPos5 = V5pre * ( 1 - dFraz) + V5 * dFraz + EgtSetAxisPos( A5, dPos5) + sOut = sOut .. ' ' .. A5 .. string.format('%10.3f',dPos5) + end + EgtDraw() + EgtTestBreak(0,0) + EgtOutText(sOut) + end +end + +-- Riporta gli assi alla posizione home istantaneamente +function ResetAllAxes() + EgtResetAxisPos( 'X') + EgtResetAxisPos( 'Y') + EgtResetAxisPos( 'Z') + EgtResetAxisPos( 'C') + EgtResetAxisPos( 'B') + EgtDraw() +end + +-- Salgo a Zmax +function MoveToZHome() + -- posizione home della Z + local Zhome = EgtGetAxisHomePos( 'Z') + -- risalita in Z + MoveAxes( 'Z', Zhome) +end + +-- Vado al cambio utensili +function MoveToToolChange() + -- posizioni home degli assi (tranne X) + local Yhome = EgtGetAxisHomePos( 'Y') + local Zhome = EgtGetAxisHomePos( 'Z') + local Chome = EgtGetAxisHomePos( 'C') + local Bhome = EgtGetAxisHomePos( 'B') + -- risalita in Z + MoveAxes( 'Z', Zhome) + -- altri assi + MoveAxes( 'Y', Yhome, 'C', Chome, 'B', Bhome) +end + +-- Riporta gli assi alla posizione home con movimento prima Z poi XYCB +function MoveToHome() + -- posizioni home degli assi + local Xhome = EgtGetAxisHomePos( 'X') + local Yhome = EgtGetAxisHomePos( 'Y') + local Zhome = EgtGetAxisHomePos( 'Z') + local Chome = EgtGetAxisHomePos( 'C') + local Bhome = EgtGetAxisHomePos( 'B') + -- risalita in Z + MoveAxes( 'Z', Zhome) + -- altri assi + MoveAxes( 'X', Xhome, 'Y', Yhome, 'C', Chome, 'B', Bhome) +end + +function SimuDrill( nId, dMaxMat) + + local bOkR, nStatR, dA1, dB1, dA2, dB2 + local bOkL, nStatL, dX, dY, dZ + local bOkS, nStatS + local vtV, vtIn + local ptP, ptOut, ptIn + + -- Recupero versore estrusione, versore profondità e punto foro + vtV = EgtCurveExtrusion( nId, GDB_ID.ROOT) + vtIn = EgtET( nId, GDB_ID.ROOT) + ptP = EgtCP( nId, GDB_ID.ROOT) + -- calcolo angoli macchina + bOkR, nStatR, dA1, dB1, dA2, dB2 = EgtGetCalcAngles( vtV) + -- punto fuori + ptOut = ptP + vtV * 80 + bOkL, nStatL, dX, dY, dZ = EgtGetCalcPositions( ptOut, dA1, dB1) + bOkS, nStatS = EgtVerifyOutstroke( dX, dY, dZ, dA1, dB1) + if not bOkS or nStatS ~= 0 then + if not EgtOutBox( "Out Of Stroke", '', 'Error') then + return false + end + end + MoveAxes( 'X', dX, 'Y', dY, 'C', dA1, 'B', dB1) + MoveAxes( 'Z', dZ) + EgtTestBreak(0,100) + -- se previsto massimo materiale, limito il punto dentro + if dMaxMat and vtIn:len() > dMaxMat then + vtIn = vtIn / vtIn:len() * dMaxMat + end + -- punto dentro + ptIn = ptP + vtIn + bOkL, nStatL, dX, dY, dZ = EgtGetCalcPositions( ptIn, dA1, dB1) + bOkS, nStatS = EgtVerifyOutstroke( dX, dY, dZ, dA1, dB1) + if not bOkS or nStatS ~= 0 then + if not EgtOutBox( "Out Of Stroke", '', 'Error') then + return false + end + end + MoveAxes( 'X', dX, 'Y', dY, 'Z', dZ) + EgtTestBreak(0,200) + -- ritorno fuori + bOkL, nStatL, dX, dY, dZ = EgtGetCalcPositions( ptOut, dA1, dB1) + MoveAxes( 'X', dX, 'Y', dY, 'Z', dZ) + EgtTestBreak(0,100) + return true +end + +function SimuUnderDrill( nId, dMaxMat, angOut, dLen) + + local bOkR, nStatR, dA1, dB1, dA2, dB2 + local bOkL, nStatL, dX, dY, dZ + local bOkS, nStatS + local vtV, vtIn + local ptP, ptOut, ptIn + + -- Recupero versore estrusione, versore profondità e punto foro + vtV = EgtCurveExtrusion( nId, GDB_ID.ROOT) + vtIn = EgtET( nId, GDB_ID.ROOT) + ptP = EgtCP( nId, GDB_ID.ROOT) + -- Verifico versore foro come Z- + if not AreSameVectorApprox( vtV, - Z_AX()) then + EgtOutBox( "Hole not from bottom", '', 'Error') + return false + end + -- calcolo angoli macchina + bOkR, nStatR, dA1, dB1, dA2, dB2 = EgtGetCalcAngles( vtV, VectorFromPolar( 1, angOut)) + -- punto di approccio + ptOut = ptP + vtV * 20 + ptAppr = ptOut + VectorFromPolar( dLen, angOut) + bOkL, nStatL, dX, dY, dZ = EgtGetCalcPositions( ptAppr, dA1, dB1) + bOkS, nStatS = EgtVerifyOutstroke( dX, dY, dZ, dA1, dB1) + if not bOkS or nStatS ~= 0 then + if not EgtOutBox( "Out Of Stroke", '', 'Error') then + return false + end + end + MoveAxes( 'X', dX, 'Y', dY, 'C', dA1, 'B', dB1) + MoveAxes( 'Z', dZ) + EgtTestBreak(0,100) + -- punto fuori + bOkL, nStatL, dX, dY, dZ = EgtGetCalcPositions( ptOut, dA1, dB1) + bOkS, nStatS = EgtVerifyOutstroke( dX, dY, dZ, dA1, dB1) + if not bOkS or nStatS ~= 0 then + if not EgtOutBox( "Out Of Stroke", '', 'Error') then + return false + end + end + MoveAxes( 'X', dX, 'Y', dY, 'Z', dZ) + EgtTestBreak(0,100) + -- se previsto massimo materiale, limito il punto dentro + if dMaxMat and vtIn:len() > dMaxMat then + vtIn = vtIn / vtIn:len() * dMaxMat + end + -- punto dentro + ptIn = ptP + vtIn + bOkL, nStatL, dX, dY, dZ = EgtGetCalcPositions( ptIn, dA1, dB1) + bOkS, nStatS = EgtVerifyOutstroke( dX, dY, dZ, dA1, dB1) + if not bOkS or nStatS ~= 0 then + if not EgtOutBox( "Out Of Stroke", '', 'Error') then + return false + end + end + MoveAxes( 'X', dX, 'Y', dY, 'Z', dZ) + EgtTestBreak(0,200) + -- ritorno fuori + bOkL, nStatL, dX, dY, dZ = EgtGetCalcPositions( ptOut, dA1, dB1) + MoveAxes( 'X', dX, 'Y', dY, 'Z', dZ) + EgtTestBreak(0,100) + -- ritorno approccio + bOkL, nStatL, dX, dY, dZ = EgtGetCalcPositions( ptAppr, dA1, dB1) + MoveAxes( 'X', dX, 'Y', dY, 'Z', dZ) + EgtTestBreak(0,100) + return true +end + +function SimuCut( nId, nCrv, dUnder, bHeadRight, bNotInvert, bOut, dAgg) + -- verifico sia una retta + --if EgtGetType( nId) ~= GDB_TY.CRV_LINE then + -- return + --end + -- estremi retta, versore tg, affondamento + local ptP1 = EgtUP( nId, ( nCrv - 1), GDB_ID.ROOT) + local ptP2 = EgtUP( nId, nCrv, GDB_ID.ROOT) + local vtTg = EgtUV( nId, nCrv, - 1, GDB_ID.ROOT) + local dAff = EgtCurveThickness( nId, GDB_ID.ROOT) + if dAff then + dAff = abs(dAff) + else + dAff = 0 + end + -- versore perpendicolare + local vtPerp = Vector3d( vtTg) + if bHeadRight then + vtPerp:rotate( Z_AX(), -90) + else + vtPerp:rotate( Z_AX(), 90) + end + -- se da invertire + if not bNotInvert then + local ptT = ptP1 + ptP1 = ptP2 + ptP2 = ptT + vtTg = - vtTg + end + + -- dati utensile + local Tool = EgtGetCalcTool() + EgtTdbSetCurrTool(Tool) + local dRad = EgtTdbGetCurrToolParam(MCH_TP.DIAM) / 2 + local dTh = EgtTdbGetCurrToolParam(MCH_TP.THICK) + + -- angoli macchina + local bOkR, nStatR, dA1, dB1, dA2, dB2 = EgtGetCalcAngles( vtPerp) + + local bOkL, nStatL, dX, dY, dZ + local bOkS, nStatS + + -- punto iniziale + local dSu = dRad - dAff - dUnder + local ptIni = ptP1 + Z_AX() * dSu + if not bHeadRight then + ptIni = ptIni - vtPerp * dTh + end + if bOut then + local dOut = sqrt( dRad * dRad - dSu * dSu) + ptIni = ptIni - vtTg * dOut + end + bOkL, nStatL, dX, dY, dZ = EgtGetCalcPositions( ptIni, dA1, dB1) + bOkS, nStatS = EgtVerifyOutstroke( dX, dY, dZ, dA1, dB1) + if not bOkS or nStatS ~= 0 then + if not EgtOutBox( "Out Of Stroke", '', 'Error') then + return false + end + end + -- verifico se mi muovo anche in Z + local bPause = false + local dOldZ = EgtGetAxisPos('Z') + if dOldZ then + if abs( dZ - dOldZ) > 100 * GEO.EPS_SMALL then + bPause = true + end + end + MoveAxes( 'X', dX, 'Y', dY, 'C', dA1, 'B', dB1) + if bPause then + EgtTestBreak(0,50) + end + MoveAxes( 'Z', dZ) + if bPause then + EgtTestBreak(0,50) + end + + -- punto finale + local ptFin = ptP2 + Z_AX() * dSu + if dAgg then + ptFin = ptFin + vtTg * dAgg + end + if not bHeadRight then + ptFin = ptFin - vtPerp * dTh + end + bOkL, nStatL, dX, dY, dZ = EgtGetCalcPositions( ptFin, dA1, dB1) + bOkS, nStatS = EgtVerifyOutstroke( dX, dY, dZ, dA1, dB1) + if not bOkS or nStatS ~= 0 then + if not EgtOutBox( "Out Of Stroke", '', 'Error') then + return false + end + end + MoveAxes( 'X', dX, 'Y', dY) + EgtTestBreak(0,5) + return true +end + +return EgtMachine diff --git a/ProgramData/EgtCAM5/LuaLibs/EgtPoint3d.lua b/ProgramData/EgtCAM5/LuaLibs/EgtPoint3d.lua new file mode 100644 index 0000000..254f7d7 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EgtPoint3d.lua @@ -0,0 +1,279 @@ +-- EgtPoint3d.lua by EgalTech s.r.l. 2019/03/31 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtPoint3d = {} + +EgtOutLog( 'EgtPoint3d started', 1) + +-- Include +require( 'EgtVector3d') +--EnableDebug( false) + + +-- Definizione classe Point3d +Point3d = {} +Point3d.__index = Point3d + +-- funzione di utilita' per identificazione tipo +function isPoint3d( a) + return ( getmetatable( a) == Point3d) +end + +local function New( x, y, z) + local p3d = setmetatable( {0,0,0}, Point3d) + if not x then + return nil + elseif isPoint3d( x) then + p3d[1] = x[1] + p3d[2] = x[2] + p3d[3] = x[3] + elseif type(x) == 'table' and #x >= 3 then + p3d[1] = x[1] + p3d[2] = x[2] + p3d[3] = x[3] + elseif type( x) == 'number' and type( y) == 'number' and type( z) == 'number' then + p3d[1] = x + p3d[2] = y + p3d[3] = z + else + error( 'A parameter is wrong', 2) + end + return p3d +end + +setmetatable( Point3d, { __call = function( _, ...) return New(...) end }) + +-- opposto di un punto (unary -) +function Point3d:__unm() + return New( - self[1], - self[2], - self[3]) +end + +-- somma di due punti o un punto e un vettore (+) +function Point3d.__add( a, b) + if ( isPoint3d( a) and ( isPoint3d( b) or isVector3d( b))) or + ( isPoint3d( b) and ( isPoint3d( a) or isVector3d( a))) then + return New( a[1] + b[1], a[2] + b[2], a[3] + b[3]) + else + error( 'A parameter is wrong', 2) + end +end + +-- sottrazione di due punti o un punto e un vettore, restituisce un vettore o un punto (-) +function Point3d.__sub( a, b) + if isPoint3d( a) and isPoint3d( b) then + return Vector3d( a[1] - b[1], a[2] - b[2], a[3] - b[3]) + elseif ( isPoint3d( a) and isVector3d( b)) or ( isVector3d( a) and isPoint3d( b)) then + return New( a[1] - b[1], a[2] - b[2], a[3] - b[3]) + else + error( 'A parameter is wrong', 2) + end +end + +-- moltiplicazione di un punto per un numero, di un numero per un punto (*) +function Point3d.__mul( a, b) + if type( a) == 'number' and isPoint3d( b) then + return New( a * b[1], a * b[2], a * b[3]) + elseif isPoint3d( a) and type( b) == 'number' then + return New( a[1] * b, a[2] * b, a[3] * b) + else + error( 'A parameter is wrong', 2) + end +end + +-- divisione di un punto per un numero (/) +function Point3d.__div( a, b) + if isPoint3d( a) and type( b) == 'number' then + return New( a[1] / b, a[2] / b, a[3] / b) + else + error( 'A parameter is wrong', 2) + end +end + +-- traslazione +function Point3d:move( m) + if not isPoint3d( self) then + return false + end + if isVector3d( m) or ( type( m) == 'table' and #m >= 3) then + self[1] = self[1] + m[1] + self[2] = self[2] + m[2] + self[3] = self[3] + m[3] + return true + else + return false + end +end + +-- rotazione +function Point3d:rotate( ptAx, vtAx, dAngDeg) + if not isPoint3d( self) or not isPoint3d( ptAx) or not isVector3d( vtAx) or not type( dAngDeg) == 'number' then + return false + end + local bOk, pRot = EgtPointRotate( self, ptAx, vtAx, dAngDeg) + if bOk then + self[1] = pRot[1] + self[2] = pRot[2] + self[3] = pRot[3] + end + return bOk +end + +-- mirror +function Point3d:mirror( ptOn, vtN) + if not isPoint3d( self) or not isPoint3d( ptOn) or not isVector3d( vtN) then + return false + end + local bOk, pMir = EgtPointMirror( self, ptOn, vtN) + if bOk then + self[1] = pMir[1] + self[2] = pMir[2] + self[3] = pMir[3] + end + return bOk +end + +-- trasformazione di riferimento verso globale +function Point3d:toGlob( fTool) + if not isPoint3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, pNew = EgtPointToGlob( self, fTool) + if bOk then + self[1] = pNew[1] + self[2] = pNew[2] + self[3] = pNew[3] + end + return bOk +end + +-- trasformazione di riferimento verso locale +function Point3d:toLoc( fTool) + if not isPoint3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, pNew = EgtPointToLoc( self, fTool) + if bOk then + self[1] = pNew[1] + self[2] = pNew[2] + self[3] = pNew[3] + end + return bOk +end + +-- trasformazione di riferimento da locale a locale +function Point3d:locToLoc( fOri, fDest) + if not isPoint3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then + return false + end + local bOk, pNew = EgtPointLocToLoc( self, fOri, fDest) + if bOk then + self[1] = pNew[1] + self[2] = pNew[2] + self[3] = pNew[3] + end + return bOk +end + +-- restituzione componenti +function Point3d:getX() + return self[1] +end + +function Point3d:getY() + return self[2] +end + +function Point3d:getZ() + return self[3] +end + +-- conversione in stringa (tostring) +function Point3d:__tostring() + return "(" .. EgtNumToString( self[1], 4) .. ", " + .. EgtNumToString( self[2], 4) .. ", " + .. EgtNumToString( self[3], 4) .. ")" +end + + +-- calcolo quadrato della distanza tra due punti +function sqdist( a, b) + if isPoint3d( a) and isPoint3d( b) then + return ( ( a[1] - b[1]) * ( a[1] - b[1]) + + ( a[2] - b[2]) * ( a[2] - b[2]) + + ( a[3] - b[3]) * ( a[3] - b[3])) + else + error( 'A parameter is not a Point3d', 2) + end +end + +-- calcolo distanza tra due punti +function dist( a, b) + if isPoint3d( a) and isPoint3d( b) then + return math.sqrt( ( a[1] - b[1]) * ( a[1] - b[1]) + + ( a[2] - b[2]) * ( a[2] - b[2]) + + ( a[3] - b[3]) * ( a[3] - b[3])) + else + error( 'A parameter is not a Point3d', 2) + end +end + +-- funzioni di confronto +function AreSamePointApprox( a, b) + if isPoint3d( a) and isPoint3d( b) then + return ( a - b):isSmall() + else + return false + end +end + +function AreSamePointExact( a, b) + if isPoint3d( a) and isPoint3d( b) then + return ( a - b):isZero() + else + return false + end +end + +function AreSamePointEpsilon( a, b, eps) + if isPoint3d( a) and isPoint3d( b) then + return sqdist( a, b) < eps * eps + else + return false + end +end + +-- Creazione di punti da stringhe di tre numeri +function PointFromString( sVal) + if not sVal then + return nil + end + local vsVal = EgtSplitString( sVal) + if not vsVal then + return nil + end + if #vsVal < 3 then + return nil + end + return Point3d( tonumber( vsVal[1]), tonumber( vsVal[2]), tonumber( vsVal[3])) +end + +-- Creazione di punti da info di entità GeomDB +function PointFromInfo( nId, sKey) + PointFromString( EgtGetInfo( nId, sKey)) +end + +-- Punti notevoli +function ORIG() + return Point3d(0,0,0) +end + +-- Punto con num aggiunto +function Point4d( P1, P2, P3, P4) + if isPoint3d( P1) and ( not P2 or type( P2) == 'number') then + return { P1[1], P1[2], P1[3], P2 or 0} + elseif type( P1) == 'number' and type( P2) == 'number' and type( P3) == 'number' and ( not P4 or type( P4) == 'number') then + return { P1, P2, P3, P4 or 0} + end +end + +return EgtPoint3d diff --git a/ProgramData/EgtCAM5/LuaLibs/EgtVector3d.lua b/ProgramData/EgtCAM5/LuaLibs/EgtVector3d.lua new file mode 100644 index 0000000..5d9f4d7 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EgtVector3d.lua @@ -0,0 +1,424 @@ +-- EgtVector3d.lua by EgalTech s.r.l. 2022/01/11 + +-- Tavola per definizione modulo (serve ma non usata) +local EgtVector3d = {} + +EgtOutLog( 'EgtVector3d started', 1) + +-- Include +require( 'EgtConst') +--EnableDebug( false) + + +-- Definizione classe Vector3d +Vector3d = {} +Vector3d.__index = Vector3d + +-- funzione di utilita' per identificazione tipo +function isVector3d( a) + return ( getmetatable( a) == Vector3d) +end + +local function New( x, y, z) + local v3d = setmetatable( {0,0,0}, Vector3d) + if not x then + return nil + elseif isVector3d( x) then + v3d[1] = x[1] + v3d[2] = x[2] + v3d[3] = x[3] + elseif type(x) == 'table' and #x >= 3 then + v3d[1] = x[1] + v3d[2] = x[2] + v3d[3] = x[3] + elseif type( x) == 'number' and type( y) == 'number' and type( z) == 'number' then + v3d[1] = x + v3d[2] = y + v3d[3] = z + else + error( 'A parameter is wrong', 2) + end + return v3d +end + +setmetatable( Vector3d, { __call = function( _, ...) return New(...) end }) + +-- opposto di un vettore (unary -) +function Vector3d:__unm() + return New( - self[1], - self[2], - self[3]) +end + +-- somma di due vettori (+) +function Vector3d.__add( a, b) + if isVector3d( a) and isVector3d( b) then + return New( a[1] + b[1], a[2] + b[2], a[3] + b[3]) + else + error( 'A parameter is not a Vector3d', 2) + end +end + +-- sottrazione di due vettori (-) +function Vector3d.__sub( a, b) + if isVector3d( a) and isVector3d( b) then + return New( a[1] - b[1], a[2] - b[2], a[3] - b[3]) + else + error( 'A parameter is not a Vector3d', 2) + end +end + +-- moltiplicazione di un vettore per uno scalare, di uno scalare per un vettore o prodotto scalare (*) +function Vector3d.__mul( a, b) + if type( a) == 'number' then + return New( a * b[1], a * b[2], a * b[3]) + elseif type( b) == 'number' then + return New( a[1] * b, a[2] * b, a[3] * b) + elseif isVector3d( a) and isVector3d( b) then + return ( a[1] * b[1] + a[2] * b[2] + a[3] * b[3]) + else + error( 'A parameter is wrong', 2) + end +end + +-- prodotto vettoriale (^) +function Vector3d.__pow( a, b) + if isVector3d( a) and isVector3d( b) then + return New( a[2] * b[3] - a[3] * b[2], + a[3] * b[1] - a[1] * b[3], + a[1] * b[2] - a[2] * b[1]) + else + error( 'A parameter is not a Vector3d', 2) + end +end + +-- divisione di un vettore per un numero (/) +function Vector3d.__div( a, b) + if isVector3d( a) and type( b) == 'number' then + return New( a[1] / b, a[2] / b, a[3] / b) + else + error( 'A parameter is wrong', 2) + end +end + +-- triplo prodotto (a ^ b) * c +function Vector3d.TripleProd( a, b, c) + if isVector3d( a) and isVector3d( b) and isVector3d( c) then + return ( a[1] * ( b[2] * c[3] - b[3] * c[2]) + + a[2] * ( b[3] * c[1] - b[1] * c[3]) + + a[3] * ( b[1] * c[2] - b[2] * c[1])) + else + error( 'A parameter is wrong', 2) + end +end + +-- verifica di vettore quasi nullo +function Vector3d:isSmall() + return (( self[1] * self[1] + self[2] * self[2] + self[3] * self[3]) < GEO.EPS_SMALL * GEO.EPS_SMALL) +end + +-- verifica di vettore nullo +function Vector3d:isZero() + return (( self[1] * self[1] + self[2] * self[2] + self[3] * self[3]) < GEO.EPS_ZERO * GEO.EPS_ZERO) +end + +-- verifica di vettore normalizzato +function Vector3d:isNormalized() + return ( math.abs( 1.0 - ( self[1] * self[1] + self[2] * self[2] + self[3] * self[3])) < 2.0 * GEO.EPS_ZERO) +end + +-- calcolo quadrato della lunghezza +function Vector3d:sqlen() + return ( self[1] * self[1] + self[2] * self[2] + self[3] * self[3]) +end + +-- calcolo lunghezza +function Vector3d:len() + return math.sqrt( self[1] * self[1] + self[2] * self[2] + self[3] * self[3]) +end + +-- normalizzazione +function Vector3d:normalize() + local sqlen = self[1] * self[1] + self[2] * self[2] + self[3] * self[3] + -- verifico se già normalizzato + if math.abs( 1.0 - sqlen) < 2.0 * GEO.EPS_ZERO then + return true + end + -- verifico se normalizzabile + if sqlen < GEO.EPS_SMALL * GEO.EPS_SMALL then + return false + end + -- eseguo la normalizzazione + local len = math.sqrt( sqlen) + local denom = 1 / len + self[1] = self[1] * denom + self[2] = self[2] * denom + self[3] = self[3] * denom + return true +end + +-- rotazione +function Vector3d:rotate( vtAx, dAngDeg) + if not isVector3d( self) or not isVector3d( vtAx) or not type( dAngDeg) == 'number' then + return false + end + local bOk, vRot = EgtVectorRotate( self, vtAx, dAngDeg) + if bOk then + self[1] = vRot[1] + self[2] = vRot[2] + self[3] = vRot[3] + end + return bOk +end + +-- mirror +function Vector3d:mirror( vtOn) + if not isVector3d( self) or not isVector3d( vtOn) then + return false + end + local bOk, vMir = EgtVectorMirror( self, vtOn) + if bOk then + self[1] = vMir[1] + self[2] = vMir[2] + self[3] = vMir[3] + end + return bOk +end + +-- trasformazione di riferimento verso globale +function Vector3d:toGlob( fTool) + if not isVector3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, vNew = EgtVectorToGlob( self, fTool) + if bOk then + self[1] = vNew[1] + self[2] = vNew[2] + self[3] = vNew[3] + end + return bOk +end + +-- trasformazione di riferimento verso locale +function Vector3d:toLoc( fTool) + if not isVector3d( self) or not isFrame3d( fTool) then + return false + end + local bOk, vNew = EgtVectorToLoc( self, fTool) + if bOk then + self[1] = vNew[1] + self[2] = vNew[2] + self[3] = vNew[3] + end + return bOk +end + +-- trasformazione di riferimento da locale a locale +function Vector3d:locToLoc( fOri, fDest) + if not isVector3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then + return false + end + local bOk, vNew = EgtVectorLocToLoc( self, fOri, fDest) + if bOk then + self[1] = vNew[1] + self[2] = vNew[2] + self[3] = vNew[3] + end + return bOk +end + +-- restituzione componenti +function Vector3d:getX() + return self[1] +end + +function Vector3d:getY() + return self[2] +end + +function Vector3d:getZ() + return self[3] +end + +-- assegnazione componenti +function Vector3d:setX( dX) + self[1] = dX +end + +function Vector3d:setY( dY) + self[2] = dY +end + +function Vector3d:setZ( dZ) + self[3] = dZ +end + +-- conversione in stringa (tostring) +function Vector3d:__tostring() + return "(" .. EgtNumToString( self[1], 6) .. ", " + .. EgtNumToString( self[2], 6) .. ", " + .. EgtNumToString( self[3], 6) .. ")" +end + +-- Alcune funzioni di confronto +function AreSameVectorApprox( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a - b):isSmall() + else + return false + end +end + +function AreSameVectorExact( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a - b):isZero() + else + return false + end +end + +function AreOppositeVectorApprox( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a + b):isSmall() + else + return false + end +end + +function AreOppositeVectorExact( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a + b):isZero() + else + return false + end +end + +function AreSameOrOppositeVectorApprox( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a - b):isSmall() or ( a + b):isSmall() + else + return false + end +end + +function AreSameOrOppositeVectorExact( a, b) + if isVector3d( a) and isVector3d( b) then + return ( a - b):isZero() or ( a + b):isZero() + else + return false + end +end + +-- Creazione di vettori da coordinate sferiche e polari +function VectorFromSpherical( dLen, dAngVertDeg, dAngOrizzDeg) + local dAngVertRad = math.rad( dAngVertDeg) + local dAngOrizzRad = math.rad( dAngOrizzDeg) + local dSinAngVert = math.sin( dAngVertRad) ; + return Vector3d( dLen * dSinAngVert * math.cos( dAngOrizzRad), + dLen * dSinAngVert * math.sin( dAngOrizzRad), + dLen * math.cos( dAngVertRad)) ; +end + +function VectorFromPolar( dLen, dAngDeg) + local dAngRad = math.rad( dAngDeg) + return Vector3d( dLen * math.cos( dAngRad), + dLen * math.sin( dAngRad), + 0) +end + +-- Creazione di vettore perpendicolare a dato e massimamente verso l'alto +function VectorFromUprightOrtho( vtV) + local vtAx = Vector3d( vtV) + if not vtAx then return nil end + -- se vettore nullo, imposto asse Z+ + if vtAx:isZero() then + return Z_AX() + end + -- se vettore coincidente con asse Z, imposto asse X+ + if AreSameOrOppositeVectorExact( vtAx, Z_AX()) then + return X_AX() + end + -- caso generico + vtAx:setZ( 0) + vtAx:normalize() + vtAx:rotate( Z_AX(), 90) + return ( vtV ^ vtAx) +end + +-- Creazione di vettore da altro vettore con rotazione +function VectorFromRotated( vtV, vtAx, dAngDeg) + local vtRot = Vector3d( vtV) + if not vtRot then return nil end + vtRot:rotate( vtAx, dAngDeg) + return vtRot +end + +-- Creazione di vettore da stringa di tre numeri +function VectorFromString( sVal) + if not sVal then + return nil + end + local vsVal = EgtSplitString( sVal) + if not vsVal then + return nil + end + if #vsVal < 3 then + return nil + end + return Vector3d( tonumber( vsVal[1]), tonumber( vsVal[2]), tonumber( vsVal[3])) +end + +-- Creazione di vettore da info di entità GeomDB +function VectorFromInfo( nId, sKey) + return VectorFromString( EgtGetInfo( nId, sKey)) +end + +-- Coordinate sferiche da vettore +function SphericalFromVector( vtV) + if not isVector3d( vtV) then + return nil + end + local dLen = vtV:len() + -- vettore nullo + if math.abs( dLen) < GEO.EPS_ZERO then + return 0, 0, 0 + end + -- vettore diretto come Z o -Z + if math.abs( vtV[1]) < GEO.EPS_ZERO and math.abs( vtV[2]) < GEO.EPS_ZERO then + if vtV[3] > 0 then + return dLen, 0, 0 + else + return dLen, 180, 0 + end + end + -- vettore nel piano XY + if math.abs( vtV[3]) < GEO.EPS_ZERO then + local dAngOri = math.deg( math.atan( vtV[2], vtV[1])) + if dAngOri < 0 then + dAngOri = dAngOri + 360 + end + return dLen, 90, dAngOri + end + -- caso generale + local dAngVert = math.deg( math.acos( vtV[3] / dLen)) + local dAngOri = math.deg( math.atan( vtV[2], vtV[1])) + if dAngOri < 0 then + dAngOri = dAngOri + 360 + end + return dLen, dAngVert, dAngOri +end + +-- Vettori notevoli +function V_NULL() + return Vector3d(0,0,0) +end +function X_AX() + return Vector3d(1,0,0) +end +function Y_AX() + return Vector3d(0,1,0) +end +function Z_AX() + return Vector3d(0,0,1) +end + + +return EgtVector3d diff --git a/ProgramData/EgtCAM5/LuaLibs/EmtGenerator.lua b/ProgramData/EgtCAM5/LuaLibs/EmtGenerator.lua new file mode 100644 index 0000000..9f94a93 --- /dev/null +++ b/ProgramData/EgtCAM5/LuaLibs/EmtGenerator.lua @@ -0,0 +1,987 @@ +-- EmtGenerator.lua by EgalTech s.r.l. 2021/12/28 +-- 2018/02/22 DS Funzioni bit32 sostituite con operatori sui bit. +-- 2018/08/16 DS Corretta ricorsione di SimulMoveAxis. +-- 2018/10/09 DS Controllo nDec anche in EmtLenToString. +-- 2019/03/19 DS Modificate SimulMoveAxis e SimulMoveAxes. +-- 2019/05/19 DS Aggiunta funzione SetToolForVmill. +-- 2019/08/06 DS Aggiunte funzioni AddToCollisionCheck, AddToolToCollisionCheck e DumpCollisionCheck. +-- 2020/02/04 DS Modifiche a SetToolForVmill per gestire frese con gambo piccolo. +-- 2020/02/05 DS Aggiunto parametro sCollGrp a AddToCollisionCheck e riportato nei dati successivi come Grp. +-- 2020/03/23 DS Aggiunta funzione per impostare il numero di decimali nell'emissione coordinate assi. +-- 2020/10/06 DS In AddToolToCollisionCheck ora si usano diametro e lunghezza totali, prima quelli di lavoro. +-- 2020/10/31 DS Corretta AddToCollisionCheck per riferimenti da calcolarsi in globale. +-- 2020/12/07 DS In SetToolForVmill aggiunta gestione WaterJet. +-- 2020/12/22 DS In AddToCollisionCheck per cilindri ora raggio precede altezza. +-- 2021/01/03 DS Aggiunta funzione AddToolToCollisionObj. In MoveAxis e MoveAxes aggiunta gestione delle collisioni. +-- 2021/01/19 DS In AddToolToCollisionCheck aggiunta gestione per mortasatrici/seghe a catena. +-- 2021/02/10 DS In SimulMoveAx* migliorata gestione segnalazione collisioni. +-- 2021/04/14 DS A AddToolToCollisionObj e AddToolToCollisionCheck aggiunto parametro opzionale bUseDiam. +-- 2021/05/24 DS Corretta AddToolToCollisionCheck perchè recuperava sempre l'utensile dell'uscita 1 della testa e uscita indicate. +-- Parametro bUseDiam eliminato perchè superato dalle modifiche. +-- 2021/06/25 DS In AddToolToCollisionCheck corretta gestione lame ora con lunghezza e spessore. +-- 2021/07/12 DS Migliorie a movimento asse/i per simulazione. +-- 2021/12/28 DS Anche a Centro e Punto Medio di Arco si sottrae EMT.ADDORI se definito. + +-- Tavola per definizione modulo (serve ma non usata) +local EmtGenerator = {} + +EgtOutLog( 'EmtGenerator started', 1) + +-- Include +require( 'EgtBase') + +--------------------------------------------------------------------- +-- *** Output *** +--------------------------------------------------------------------- +function EmtOutput( sOut, nId) + if EMT.NUM then + if not nId or nId == 1 then + EMT.LINENBR = EMT.LINENBR + EMT.LINEINC + if EMT.LINEMAX and EMT.LINENBR > EMT.LINEMAX then EMT.LINENBR = EMT.LINEINC end + EmtWrite( EMT.Nt .. EMT.LINENBR .. ' ' .. ( sOut or '')) + else + if not EMT.LINENBRS then EMT.LINENBRS = {} end + if not EMT.LINENBRS[nId] then EMT.LINENBRS[nId] = 0 end + EMT.LINENBRS[nId] = EMT.LINENBRS[nId] + EMT.LINEINC + if EMT.LINEMAX and EMT.LINENBRS[nId] > EMT.LINEMAX then EMT.LINENBRS[nId] = EMT.LINEINC end + OutFile( nId, EMT.Nt .. EMT.LINENBRS[nId] .. ' ' .. ( sOut or '')) + end + else + if not nId or nId == 1 then + EmtWrite( sOut or '') + else + OutFile( nId, sOut or '') + end + end +end + +----------------------------------------------------------------- +-- *** Other Files *** +----------------------------------------------------------------- + +local s_OutFh = {} + +----------------------------------------------------------------- +function OpenOutFile( nId, sFile) + s_OutFh[nId] = io.open( sFile, 'w') + return s_OutFh[nId] +end + +----------------------------------------------------------------- +function OutFile( nId, sOut) + if s_OutFh[nId] then + s_OutFh[nId]:write( sOut .. '\n') + end +end + +----------------------------------------------------------------- +function CloseOutFile( nId) + if s_OutFh[nId] then + s_OutFh[nId]:close() + s_OutFh[nId] = nil + end +end + +----------------------------------------------------------------- +-- *** Utilities *** +--------------------------------------------------------------------- +function EmtUpdatePrev() + EMT.L1p = EMT.L1 + EMT.L2p = EMT.L2 + EMT.L3p = EMT.L3 + EMT.R1p = EMT.R1 + EMT.R2p = EMT.R2 + EMT.R3p = EMT.R3 + EMT.R4p = EMT.R4 + EMT.L1op = EMT.L1o + EMT.L2op = EMT.L2o + EMT.L3op = EMT.L3o + if EMT.MOVE ~= 0 then + if EMT.F then + EMT.Fp = EMT.F + end + else + EMT.Fp = nil + end +end + +function EmtResetPrevLinear() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EMT.L1op = nil + EMT.L2op = nil + EMT.L3op = nil +end + +function EmtResetPrev() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EMT.R1p = nil + EMT.R2p = nil + EMT.R3p = nil + EMT.R4p = nil + EMT.L1op = nil + EMT.L2op = nil + EMT.L3op = nil + EMT.Fp = nil +end + +function EmtSetAdditionalOrig( dAddX, dAddY, dAddZ) + EMT.ADDORI = Point3d( dAddX, dAddY, dAddZ) +end + +function EmtAdjustLinearAxes() + -- salvo i valori rispetto a Zero macchina + EMT.L1o = EMT.L1 + EMT.L2o = EMT.L2 + EMT.L3o = EMT.L3 + -- se emetto rispetto all'origine 1 della tavola + if EMT.USETO1 then + -- sottraggo agli assi lineari l'origine 1 della tavola + if EMT.L1 then + EMT.L1 = EMT.L1 - EMT.TABORI1[1] + if EMT.ADDORI then + EMT.L1 = EMT.L1 - EMT.ADDORI[1] + end + end + if EMT.L2 then + EMT.L2 = EMT.L2 - EMT.TABORI1[2] + if EMT.ADDORI then + EMT.L2 = EMT.L2 - EMT.ADDORI[2] + end + end + if EMT.L3 then + EMT.L3 = EMT.L3 - EMT.TABORI1[3] + if EMT.ADDORI then + EMT.L3 = EMT.L3 - EMT.ADDORI[3] + end + end + end + -- se emetto rispetto a piano locale + if EMT.IPLGL then + local ptP = Point3d( EMT.L1, EMT.L2, EMT.L3) + ptP:toLoc( EMT.IPLGLFR) + EMT.L1 = ptP:getX() + EMT.L2 = ptP:getY() + EMT.L3 = ptP:getZ() + end +end + +function EmtAdjustRotaryAxes() + -- salvo i valori rispetto a Zero macchina + EMT.R1o = EMT.R1 + EMT.R2o = EMT.R2 + EMT.R3o = EMT.R3 + EMT.R4o = EMT.R4 +end + +function EmtAdjustCenterAxes() + -- salvo i valori rispetto a Zero macchina + EMT.C1o = EMT.C1 + EMT.C2o = EMT.C2 + EMT.C3o = EMT.C3 + -- se emetto rispetto all'origine 1 della tavola + if EMT.USETO1 then + -- sottraggo agli assi lineari l'origine 1 della tavola + if EMT.C1 then + EMT.C1 = EMT.C1 - EMT.TABORI1[1] + if EMT.ADDORI then + EMT.C1 = EMT.C1 - EMT.ADDORI[1] + end + end + if EMT.C2 then + EMT.C2 = EMT.C2 - EMT.TABORI1[2] + if EMT.ADDORI then + EMT.C2 = EMT.C2 - EMT.ADDORI[2] + end + end + if EMT.C3 then + EMT.C3 = EMT.C3 - EMT.TABORI1[3] + if EMT.ADDORI then + EMT.C3 = EMT.C3 - EMT.ADDORI[3] + end + end + end + -- se emetto rispetto a piano locale + if EMT.IPLGL then + local ptP = Point3d( EMT.C1, EMT.C2, EMT.C3) + ptP:toLoc( EMT.IPLGLFR) + EMT.C1 = ptP:getX() + EMT.C2 = ptP:getY() + EMT.C3 = ptP:getZ() + end +end + +function EmtAdjustMidPointAxes() + -- salvo i valori rispetto a Zero macchina + EMT.M1o = EMT.M1 + EMT.M2o = EMT.M2 + EMT.M3o = EMT.M3 + -- se emetto rispetto all'origine 1 della tavola + if EMT.USETO1 then + -- sottraggo agli assi lineari l'origine 1 della tavola + if EMT.M1 then + EMT.M1 = EMT.M1 - EMT.TABORI1[1] + if EMT.ADDORI then + EMT.M1 = EMT.M1 - EMT.ADDORI[1] + end + end + if EMT.M2 then + EMT.M2 = EMT.M2 - EMT.TABORI1[2] + if EMT.ADDORI then + EMT.M2 = EMT.M2 - EMT.ADDORI[2] + end + end + if EMT.M3 then + EMT.M3 = EMT.M3 - EMT.TABORI1[3] + if EMT.ADDORI then + EMT.M3 = EMT.M3 - EMT.ADDORI[3] + end + end + end + -- se emetto rispetto a piano locale + if EMT.IPLGL then + local ptP = Point3d( EMT.M1, EMT.M2, EMT.M3) + ptP:toLoc( EMT.IPLGLFR) + EMT.M1 = ptP:getX() + EMT.M2 = ptP:getY() + EMT.M3 = ptP:getZ() + end +end + +local function EmtToEmit( V, Vp) + if not V then + return false + end + if not EMT.MODAL or not Vp then + return true + end + return ( abs( V - Vp) > 0.001) +end + +function EmtGetAxis( Ax, bRotLikeLin) + local Axp = Ax .. 'p' + local Axt = Ax .. 't' + if EMT[Axt] and EmtToEmit( EMT[Ax], EMT[Axp]) then + local nDec = EMT.DECNUM or 3 + if not EMT.INCHES or (( Ax == 'R1' or Ax == 'R2' or Ax == 'R3' or Ax == 'R4') and not bRotLikeLin) then + return ' ' .. EMT[Axt] .. EgtNumToString( EMT[Ax], nDec), true + else + return ' ' .. EMT[Axt] .. EgtNumToString( EMT[Ax] / GEO.ONE_INCH, nDec + 1), true + end + end + return '', false +end + +function EmtGetRapidAxis( Ax, bRotLikeLin) + local MaskVal = {L1=1,L2=2,L3=4,R1=8,R2=16,R3=32,R4=64} -- per lua 5.2 {L1=0,L2=1,L3=2,R1=3,R2=4,R3=5,R4=6} + if ( EMT.MASK & MaskVal[Ax]) ~= 0 then -- per lua 5.2 bit32.extract(EMT.MASK,MaskVal[Ax]) ~= 0 + return EmtGetAxis( Ax, bRotLikeLin) + end + -- mascherato, sistemo attuale come precedente + local Axp = Ax .. 'p' + local Axt = Ax .. 't' + EMT[Ax] = EMT[Axp] + return '', false +end + +function EmtGetHomeAxis( Ax, bRotLikeLin) + local MaskVal = {L1=1,L2=2,L3=4,R1=8,R2=16,R3=32,R4=64} -- per lua 5.2 {L1=0,L2=1,L3=2,R1=3,R2=4,R3=5,R4=6} + if ( EMT.MASK & MaskVal[Ax]) ~= 0 then -- per lua 5.2 bit32.extract(EMT.MASK,MaskVal[Ax]) ~= 0 + local Axo = Ax .. 'o' + local Axt = Ax .. 't' + if EMT[Axt] then + local nDec = EMT.DECNUM or 3 + if not EMT.INCHES or (( Ax == 'R1' or Ax == 'R2' or Ax == 'R3' or Ax == 'R4') and not bRotLikeLin) then + return ' ' .. EMT[Axt] .. EgtNumToString( EMT[Axo], nDec), true + else + return ' ' .. EMT[Axt] .. EgtNumToString( EMT[Axo] / GEO.ONE_INCH, nDec + 1), true + end + end + end + return '', false +end + +function EmtGetHomeAxisByName( Ax, dOffset, bRotLikeLin) + local sToken = EgtGetAxisToken( Ax) + local bLinear = EgtGetAxisType( Ax) + local dVal = EgtGetAxisHomePos( Ax) + if dOffset then + dVal = dVal + dOffset + end + if sToken and bLinear ~= nil and dVal then + local nDec = EMT.DECNUM or 3 + if not EMT.INCHES or ( not bLinear and not bRotLikeLin) then + return ' ' .. sToken .. EgtNumToString( dVal, nDec), true + else + return ' ' .. sToken .. EgtNumToString( dVal / GEO.ONE_INCH, nDec + 1), true + end + else + return '', false + end +end + +function EmtGetFeed() + if EmtToEmit( EMT.F, EMT.Fp) then + if not EMT.INCHES then + return ' ' .. EMT.Ft .. EgtNumToString( EMT.F, 0) + else + return ' ' .. EMT.Ft .. EgtNumToString( EMT.F / GEO.ONE_INCH, 1) + end + end + return '' +end + +function EmtGetArcType( nMove, bInv) + if nMove == 2 then + if bInv then + return 3 + else + return 2 + end + elseif nMove == 3 then + if bInv then + return 2 + else + return 3 + end + else + return nil + end +end + +------------------------------------------------------------------------------- +function EmtGetAngO2( vtZ, vtX, dAngV, dAngO) + -- vettore X di riferimento + local vtRif = Vector3d( X_AX()) + -- lo ruoto prima attorno a Y poi attorno a Z + vtRif:rotate( Y_AX(), dAngV) + vtRif:rotate( Z_AX(), dAngO) + -- prodotto scalare tra vettore riferimento ruotato e vettore vtX + local dCos = vtRif * vtX + -- prodotto scalare tra vettore prodotto vettoriale dei due e vettore vtZ + local dSin = ( vtRif ^ vtX) * vtZ + -- restituisco l'angolo di rotazione richiesto + return atan2( dSin, dCos) +end + +------------------------------------------------------------------------------- +function EmtGetAngO3( vtZ, vtX, dAngV, dAngO) + -- vettore X di riferimento + local vtRif = Vector3d( X_AX()) + -- vettore asse di rotazione + local vtAx = Vector3d( - sin( dAngO), cos( dAngO), 0) + -- ruoto X di rif attorno a questo asse + vtRif:rotate( vtAx, dAngV) + -- prodotto scalare tra vettore riferimento ruotato e vettore vtX + local dCos = vtRif * vtX + -- prodotto scalare tra vettore prodotto vettoriale dei due e vettore vtZ + local dSin = ( vtRif ^ vtX) * vtZ + -- restituisco l'angolo di rotazione richiesto + return atan2( dSin, dCos) +end + +------------------------------------------------------------------------------- +function EmtLenToString( Val, nDec) + nDec = ( nDec or 3) + if not EMT.INCHES then + return EgtNumToString( Val, nDec) + else + return EgtNumToString( Val/GEO.ONE_INCH, nDec + 1) + end +end + +------------------------------------------------------------------------------- +function EmtNum3ToString( Tav, nDec) + nDec = ( nDec or 3) + return EgtNumToString( Tav[1], nDec) .. ",".. + EgtNumToString( Tav[2], nDec) .. ",".. + EgtNumToString( Tav[3], nDec) +end + +------------------------------------------------------------------------------- +function EmtLen3ToString( Tav, nDec) + nDec = ( nDec or 3) + return EmtLenToString( Tav[1], nDec) .. ",".. + EmtLenToString( Tav[2], nDec) .. ",".. + EmtLenToString( Tav[3], nDec) +end + +--------------------------------------------------------------------- +function EmtSecToHMS( dSec) + local nH = floor( dSec / 3600) + local nM = floor(( dSec - nH * 3600) / 60) + local nS = floor( dSec - nH * 3600 - nM * 60) + local sH = EgtIf( nH < 10, '0', '') .. tostring( nH) + local sM = EgtIf( nM < 10, '0', '') .. tostring( nM) + local sS = EgtIf( nS < 10, '0', '') .. tostring( nS) + return sH .. ':' .. sM .. ':' .. sS +end + +--------------------------------------------------------------------- +function EmtLenToMF( dLen) + local dOut + if EMT.INCHES then + dOut = dLen / 304.8 + else + dOut = dLen / 1000 + end + return EgtIf( dOut < 10, ' ', '') .. EgtNumToString( dOut, -1) +end + +--------------------------------------------------------------------- +-- *** Estimation functions *** +--------------------------------------------------------------------- +local s_TleTitle +local s_TleMach = {} +local s_TleTool = {} + +--------------------------------------------------------------------- +function EmtTleStart( sTitle) + -- inizializzazioni + s_TleTitle = sTitle + s_TleMach = {} + s_TleTool = {} +end + +--------------------------------------------------------------------- +function EmtTleAddMachining( sName, sTime, sLen, sTool) + table.insert( s_TleMach, { Name = sName, Time = sTime, Len = sLen, Tool = sTool}) +end + +--------------------------------------------------------------------- +function EmtTleAddTotal( sTotTime, sTotLen) + s_TleMach.Total = { Time = sTotTime, Len = sTotLen} +end + +--------------------------------------------------------------------- +function EmtTleAddTool( sName, sLen) + table.insert( s_TleTool, { Name = sName, Len = sLen}) +end + +--------------------------------------------------------------------- +function EmtTleEnd( sFormat) + -- se richiesto formato HTML + if sFormat:lower() == 'html' then + -- intestazione + EmtOutput( '') + EmtOutput( '') + EmtOutput( '') + EmtOutput( ' ') + EmtOutput( ' ' .. ( s_TleTitle or '') .. '') + EmtOutput( ' ') + EmtOutput( '') + EmtOutput( '') + -- tabella lavorazioni + if s_TleMach and #s_TleMach > 0 then + EmtOutput( ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' ') + for i = 1, #s_TleMach do + EmtOutput( ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' ') + end + EmtOutput( ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' ') + EmtOutput( '
Machinings
Time [h:m:s]Len ' .. EgtIf( EMT.INCHES, '[ft]', '[m]') .. 'Tool
' .. ( s_TleMach[i].Name or '') .. '' .. ( s_TleMach[i].Time or '') .. '' .. ( s_TleMach[i].Len or '') .. '' .. ( s_TleMach[i].Tool or '') .. '
TOTAL' .. ( s_TleMach.Total.Time or '') .. '' .. ( s_TleMach.Total.Len or '') .. '' .. '
') + end + -- tabella utensili + if s_TleTool and #s_TleTool > 0 then + EmtOutput( ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' ') + for i = 1, #s_TleTool do + EmtOutput( ' \r\n' .. + ' \r\n' .. + ' \r\n' .. + ' ') + end + EmtOutput( '
Tools
Len ' .. EgtIf( EMT.INCHES, '[ft]', '[m]') .. '
' .. ( s_TleTool[i].Name or '') .. '' .. ( s_TleTool[i].Len or '') .. '
') + end + -- conclusione + EmtOutput( '') + EmtOutput( '') + -- altrimenti formato testo + else + -- intestazione + EmtOutput( ' ' .. ( s_TleTitle or '') .. '\r\n \r\n') + -- tabella lavorazioni + if s_TleMach and #s_TleMach > 0 then + EmtOutput( ' Machinings') + EmtOutput( ' ==========') + EmtOutput( ' Time [h:m:s] Len ' .. EgtIf( EMT.INCHES, '[ft]', '[m]') .. ' Tool') + for i = 1, #s_TleMach do + local sName = ( s_TleMach[i].Name or '') + sName = sName .. string.rep( ' ', 18 - #sName) + EmtOutput( sName .. ( s_TleMach[i].Time or '') .. ' ' .. ( s_TleMach[i].Len or '') .. ' ' .. ( s_TleMach[i].Tool or '')) + end + end + EmtOutput( '-------------------------------------------------------') + EmtOutput( 'TOTAL ' .. ( s_TleMach.Total.Time or '') .. ' ' .. ( s_TleMach.Total.Len or '')) + -- tabella utensili + if s_TleTool and #s_TleTool > 0 then + EmtOutput( '\r\n\r\n Tools') + EmtOutput( ' =====') + EmtOutput( ' Len ' .. EgtIf( EMT.INCHES, '[ft]', '[m]')) + for i = 1, #s_TleTool do + local sName = ( s_TleTool[i].Name or '') + sName = sName .. string.rep( ' ', 19 - #sName) + EmtOutput( sName .. ( s_TleTool[i].Len or '')) + end + end + end +end + +--------------------------------------------------------------------- +-- *** Simulation functions *** +--------------------------------------------------------------------- +local function MyPrepareAxis( sName, dPos, dStep, nS) + if not sName then return nil, nS end + local dPrev = EgtGetAxisPos( sName) + if not dPrev then return nil, nS end + if abs( dStep) > GEO.EPS_SMALL then + local nSa = abs( ceil( ( dPos - dPrev) / dStep)) + nS = max( nS, nSa) + end + return dPrev, nS +end + +--------------------------------------------------------------------- +local function MySetAxisPos( sName, dPos) + local bOk, dNewPos = EgtSetAxisPos( sName, dPos) + return ( bOk and abs( dNewPos - dPos) < 10 * GEO.EPS_SMALL) +end + +--------------------------------------------------------------------- +function SimulMoveAxis( sName, dPos, dStep) + -- salvo step attuale + EMT.SIMSTEP = EMT.SIMSTEP or 20 + local dSimStep = EMT.SIMSTEP + -- preparazione asse + local dPrev, nS = MyPrepareAxis( sName, dPos, dStep, 1) + -- l'asse deve essere ben definito + if not dPrev then return false end + -- movimento + if nS > 0 then + for i = 1, nS do + local dCoeff = i / nS + local bOk = MySetAxisPos( sName, ( 1 - dCoeff) * dPrev + dCoeff * dPos) + EgtDraw() + local bCheckOk, nCdInd, nObjInd = EmtExecCollisionCheck() + if not bCheckOk then + local nPrevErr = EMT.ERR + local bCollOk, nErr = EmtOnCollision( nCdInd, nObjInd) + if not bCollOk and nErr == 11 then + if EgtGetEnableUI() then + EgtOutBox( 'Collisione!', 'AVVERTIMENTO', 'WARNING') + EMT.SIMUISTAT = MCH_UISIM.PAUSE + while EMT.SIMUISTAT == MCH_UISIM.PAUSE do + -- Param1 = -11 notifica al simulatore pausa per collisione + EgtProcessEvents( -11, 4) + end + end + else + EMT.ERR = nPrevErr + end + end + if not bOk then + return false + end + if EgtGetEnableUI() then + EgtProcessEvents( 0, 4) + while EMT.SIMUISTAT == MCH_UISIM.PAUSE do + EgtProcessEvents( 0, 4) + end + if EMT.SIMUISTAT == MCH_UISIM.STOP then + error( 'STOP') + end + -- se cambia lo step di simulazione richiesto in modo significativo ... + if abs( EMT.SIMSTEP - dSimStep) > 5 then + local dC = EMT.SIMSTEP / dSimStep + return SimulMoveAxis( sName, dPos, dC * dStep) + end + end + end + end + -- assegno valore finale esatto + return MySetAxisPos( sName, dPos) +end + +--------------------------------------------------------------------- +function SimulMoveAxes( sName, dPos, dStep, sName2, dPos2, dStep2, sName3, dPos3, dStep3, sName4, dPos4, dStep4, sName5, dPos5, dStep5) + -- salvo step attuale + EMT.SIMSTEP = EMT.SIMSTEP or 20 + local dSimStep = EMT.SIMSTEP + -- preparazione dei diversi assi + local dPrev, dPrev2, dPrev3, dPrev4, dPrev5 + local nS = 1 + dPrev, nS = MyPrepareAxis( sName, dPos, dStep, nS) + dPrev2, nS = MyPrepareAxis( sName2, dPos2, dStep2, nS) + dPrev3, nS = MyPrepareAxis( sName3, dPos3, dStep3, nS) + dPrev4, nS = MyPrepareAxis( sName4, dPos4, dStep4, nS) + dPrev5, nS = MyPrepareAxis( sName5, dPos5, dStep5, nS) + -- il primo asse deve essere ben definito + if not dPrev then return false end + -- movimento + if nS > 0 then + for i = 1, nS do + local dCoeff = i / nS + local bOk = MySetAxisPos( sName, ( 1 - dCoeff) * dPrev + dCoeff * dPos) + local bOk2 = not dPrev2 or MySetAxisPos( sName2, ( 1 - dCoeff) * dPrev2 + dCoeff * dPos2) + local bOk3 = not dPrev3 or MySetAxisPos( sName3, ( 1 - dCoeff) * dPrev3 + dCoeff * dPos3) + local bOk4 = not dPrev4 or MySetAxisPos( sName4, ( 1 - dCoeff) * dPrev4 + dCoeff * dPos4) + local bOk5 = not dPrev5 or MySetAxisPos( sName5, ( 1 - dCoeff) * dPrev5 + dCoeff * dPos5) + EgtDraw() + local bCheckOk, nCdInd, nObjInd = EmtExecCollisionCheck() + if not bCheckOk then + local nPrevErr = EMT.ERR + local bCollOk, nErr = EmtOnCollision( nCdInd, nObjInd) + if not bCollOk and nErr == 11 then + EMT.ERR = 11 + if EgtGetEnableUI() then + EgtOutBox( 'Collisione!', 'AVVERTIMENTO', 'WARNING') + EMT.SIMUISTAT = MCH_UISIM.PAUSE + while EMT.SIMUISTAT == MCH_UISIM.PAUSE do + -- Param1 = -11 notifica al simulatore pausa per collisione + EgtProcessEvents( -11, 4) + end + end + else + EMT.ERR = nPrevErr + end + end + if not ( bOk and bOk2 and bOk3 and bOk4 and bOk5) then + return false, bOk, bOk2, bOk3, bOk4, bOk5 + end + if EgtGetEnableUI() then + EgtProcessEvents( 0, 4) + while EMT.SIMUISTAT == MCH_UISIM.PAUSE do + EgtProcessEvents( 0, 4) + end + if EMT.SIMUISTAT == MCH_UISIM.STOP then + error( 'STOP') + end + -- se cambia lo step di simulazione richiesto in modo significativo ... + if abs( EMT.SIMSTEP - dSimStep) > 5 then + local dC = EMT.SIMSTEP / dSimStep + return SimulMoveAxes( sName, dPos, dC * dStep, + sName2, dPos2, dC * ( dStep2 or 0), sName3, dPos3, dC * ( dStep3 or 0), + sName4, dPos4, dC * ( dStep4 or 0), sName5, dPos5, dC * ( dStep5 or 0)) + end + end + end + end + -- assegno valore finale esatto + local bOk = MySetAxisPos( sName, dPos) + local bOk2 = not dPrev2 or MySetAxisPos( sName2, dPos2) + local bOk3 = not dPrev3 or MySetAxisPos( sName3, dPos3) + local bOk4 = not dPrev4 or MySetAxisPos( sName4, dPos4) + local bOk5 = not dPrev5 or MySetAxisPos( sName5, dPos5) + return ( bOk and bOk2 and bOk3 and bOk4 and bOk5), bOk, bOk2, bOk3, bOk4, bOk5 +end + +--------------------------------------------------------------------- +function SetToolForVmill( sTool, sHead, nExit, VMill) + -- se Vmill non definito, esco + if not VMill then return true end + -- se utensile, testa o uscita non definiti, reset ed esco + if not sTool or sTool == '' or not sHead or sHead == '' or not nExit then + EgtVolZmapResetTool( VMill) + return false + end + -- verifico che l'utensile sia corrente + local sOldTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + if sTool ~= sOldTool then + if not EgtTdbSetCurrTool( sTool) then return false end + end + -- dichiaro utensile per Vmill + local nType = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + local dLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) + local dDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) + local dCornR = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) + local dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) + local dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + -- ricerca dell'outline e del diametro gambo + local nExitId = EgtGetFirstNameInGroup( EgtGetHeadId( sHead) or GDB_ID.NULL, 'T' .. tostring( nExit)) + local nToolId = EgtGetFirstNameInGroup( nExitId or GDB_ID.NULL, sTool) + local nOutlineId = EgtGetFirstNameInGroup( nToolId or GDB_ID.NULL, 'Outline') + local dMaxStemDiam = EgtGetInfo( nToolId or GDB_ID.NULL, 'D_STEM', 'd') or dDiam + -- imposto profilo utensile per Vmill + if nOutlineId then + EgtVolZmapSetGenTool( VMill, sTool, nOutlineId) + elseif nType == MCH_TY.MORTISE_STD then + EgtVolZmapSetMortiserTool( VMill, sTool, dLen, dDiam, dThick, dCornR) + elseif nType == MCH_TY.SAW_STD or nType == MCH_TY.SAW_FLAT then + EgtVolZmapSetSawTool( VMill, sTool, dLen, dDiam, dThick, 0, dCornR) + elseif nType == MCH_TY.WATERJET then + EgtVolZmapSetStdTool( VMill, sTool, dLen + 50, dDiam, dCornR, dMaxMat) + elseif abs( dSideAng) < GEO.EPS_ANG_SMALL or abs( dThick) < GEO.EPS_ANG_SMALL then + if dDiam <= dMaxStemDiam then + EgtVolZmapSetStdTool( VMill, sTool, dLen, dDiam, dCornR, dMaxMat) + else + EgtVolZmapSetSawTool( VMill, sTool, dLen, dDiam, dMaxMat, 0, dCornR) + end + else + local bExtra = ( dThick > 0) + local dTipLen = abs( dThick) + local dTotLen = EgtIf( bExtra, dLen + dTipLen, dLen) + local dDelta + if dSideAng > 0 then + if dCornR < GEO.EPS_SMALL then + dDelta = 2 * dTipLen * tan( dSideAng) + else + dDelta = 2 * ( dCornR * cos( dSideAng) + ( dTipLen - dCornR + dCornR * sin( dSideAng)) * tan( dSideAng)) + end + else + dDelta = 2 * tan( dSideAng) * dTipLen + end + local dStemDiam = EgtIf( bExtra, dDiam, dDiam + dDelta) + local dTipDiam = EgtIf( bExtra, dDiam - dDelta, dDiam) + EgtVolZmapSetAdvTool( VMill, sTool, dTotLen, dStemDiam, dTipLen, dTipDiam, dCornR, dMaxMat) + end + -- se l'utensile non era corrente, ripristino il precedente + if sTool ~= sOldTool then + EgtTdbSetCurrTool( sOldTool) + end + return true +end + +--------------------------------------------------------------------- +local function AddGeomToCollisionCheck( CollGrpId, sClass, vColl) + if not CollGrpId then return false end + local sCollGrp = EgtGetName( CollGrpId) or '' + -- ricerca dei box + local BoxId = EgtGetFirstNameInGroup( CollGrpId, 'BOX') + while BoxId do + local FrameId = BoxId + ( EgtGetInfo( BoxId, 'Frame', 'i') or 0) + if FrameId ~= BoxId and EgtGetType( FrameId) == GDB_TY.GEO_FRAME then + local b3Box = EgtGetBBoxRef( BoxId, GDB_BB.STANDARD, EgtFR( FrameId, GDB_ID.ROOT)) + local vtDiag = b3Box:getMax() - b3Box:getMin() + local vtM = b3Box:getMin() - ORIG() + table.insert( vColl, { Cl=sClass, Grp=sCollGrp, Fr=FrameId, Ty=MCH_SIM_COB.BOX, Mv=vtM, P1=vtDiag:getX(), P2=vtDiag:getY(), P3=vtDiag:getZ()}) + BoxId = EgtGetNextName( BoxId, 'BOX') + end + end + -- ricerca dei cilindri + local CylId = EgtGetFirstNameInGroup( CollGrpId, 'CYL') + while CylId do + local FrameId = CylId + ( EgtGetInfo( CylId, 'Frame', 'i') or 0) + if FrameId ~= CylId and EgtGetType( FrameId) == GDB_TY.GEO_FRAME then + local b3Box = EgtGetBBoxRef( CylId, GDB_BB.STANDARD, EgtFR( FrameId, GDB_ID.ROOT)) + local dR = ( b3Box:getDimX() + b3Box:getDimY()) / 4 + local dH = b3Box:getDimZ() + local vtM = Vector3d( 0, 0, b3Box:getMin():getZ()) + table.insert( vColl, { Cl=sClass, Grp=sCollGrp, Fr=FrameId, Ty=MCH_SIM_COB.CYL, Mv=vtM, P1=dR, P2=dH, P3=0}) + CylId = EgtGetNextName( CylId, 'CYL') + end + end + -- ricerca delle sfere + local SphId = EgtGetFirstNameInGroup( CollGrpId, 'SPH') + while SphId do + local FrameId = SphId + ( EgtGetInfo( SphId, 'Frame', 'i') or 0) + if FrameId ~= SphId and EgtGetType( FrameId) == GDB_TY.GEO_FRAME then + local b3Box = EgtGetBBoxRef( SphId, GDB_BB.STANDARD, EgtFR( FrameId, GDB_ID.ROOT)) + local dR = ( b3Box:getDimX() + b3Box:getDimY() + b3Box:getDimZ()) / 6 + local vtM = b3Box:getCenter() - ORIG() + table.insert( vColl, { Cl=sClass, Grp=sCollGrp, Fr=FrameId, Ty=MCH_SIM_COB.SPHE, Mv=vtM, P1=dR, P2=0, P3=0}) + SphId = EgtGetNextName( SphId, 'SPH') + end + end + -- ricerca dei tronchi di cono + local ConId = EgtGetFirstNameInGroup( CollGrpId, 'CON') + while ConId do + local FrameId = ConId + ( EgtGetInfo( ConId, 'Frame', 'i') or 0) + if FrameId ~= ConId and EgtGetType( FrameId) == GDB_TY.GEO_FRAME then + local frRef = EgtFR( FrameId, GDB_ID.ROOT) + local vtZ = frRef:getVersZ() + local dRb, dRt, dOb, dOt + -- ricerca delle facce bottom e top + local nFacCnt = EgtSurfTmFacetCount( ConId) + for i = 0, nFacCnt - 1 do + local vtN = EgtSurfTmFacetNormVersor( ConId, i, GDB_ID.ROOT) + if AreSameVectorApprox( vtN, vtZ) then + local b3Box = EgtSurfTmGetFacetBBoxRef( ConId, i, GDB_BB.STANDARD, frRef) + dRt = ( b3Box:getDimX() + b3Box:getDimY()) / 4 + dOt = b3Box:getCenter():getZ() + elseif AreOppositeVectorApprox( vtN, vtZ) then + local b3Box = EgtSurfTmGetFacetBBoxRef( ConId, i, GDB_BB.STANDARD, frRef) + dRb = ( b3Box:getDimX() + b3Box:getDimY()) / 4 + dOb = b3Box:getCenter():getZ() + end + end + if dRb and dRt and dOb and dOt then + local vtM = Vector3d( 0, 0, dOb) + local dH = dOt - dOb + table.insert( vColl, { Cl=sClass, Grp=sCollGrp, Fr=FrameId, Ty=MCH_SIM_COB.CONE, Mv=vtM, P1=dRb, P2=dRt, P3=dH}) + end + ConId = EgtGetNextName( ConId, 'CON') + end + end + return true +end + +--------------------------------------------------------------------- +function AddToCollisionCheck( sName, sCollGrp, vColl) + if not vColl then return false end + -- ricerca del gruppo base + local GroupId = EgtGetHeadId( sName) + if not GroupId then GroupId = EgtGetAxisId( sName) end + if not GroupId then GroupId = EgtGetTableId( sName) end + if not GroupId then GroupId = EgtGetBaseId( sName) end + if not GroupId then return false end + -- ricerca del gruppo di collisione + local CAxCollId = EgtGetFirstNameInGroup( GroupId, sCollGrp) + if not CAxCollId then return false end + -- recupero della geometria di collisione + return AddGeomToCollisionCheck( CAxCollId, sName, vColl) +end + +--------------------------------------------------------------------- +function AddToolToCollisionCheck( sHeadName, nExit, vColl) + if not vColl then return false end + local sTool = EgtGetLoadedTool( sHeadName, nExit) + if not EgtTdbSetCurrTool( sTool or '') then return false end + local nType = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + local dTotRad = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) / 2 + local dTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + local HeadId = EgtGetHeadId( sHeadName) + local FrameId = EgtGetFirstNameInGroup( HeadId, '_T'..tostring( nExit)) + if nType == MCH_TY.SAW_STD or nType == MCH_TY.SAW_FLAT then + local vtM = Vector3d( 0, 0, -dTotLen) + local dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CYL, Mv=vtM, P1=dTotRad, P2=dThick, P3=0}) + elseif nType == MCH_TY.DRILL_STD or nType == MCH_TY.DRILL_LONG then + local dLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) + local vtMc = Vector3d( 0, 0, -dLen) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CYL, Mv=vtMc, P1=dTotRad, P2=dLen, P3=0}) + if dTotLen > dLen + 0.1 then + local vtMt = Vector3d( 0, 0, -dTotLen) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CONE, Mv=vtMt, P1=0, P2=dTotRad, P3=dTotLen-dLen}) + end + elseif nType ~= MCH_TY.MORTISE_STD then + local dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) + local dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) + if abs( dSideAng) < GEO.EPS_ANG_SMALL or abs( dThick) < GEO.EPS_ANG_SMALL then + local vtM = Vector3d( 0, 0, -dTotLen) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CYL, Mv=vtM, P1=dTotRad, P2=dTotLen, P3=0}) + else + local dLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) + local dDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local bExtra = ( dThick > 0) + local dTipLen = abs( dThick) + local dTotLen = EgtIf( bExtra, dLen + dTipLen, dLen) + local dDelta = 2 * dTipLen * tan( dSideAng) + local dStemRad = EgtIf( bExtra, dDiam, dDiam + dDelta) / 2 + local dTipRad = EgtIf( bExtra, dDiam - dDelta, dDiam) / 2 + local vtMs = Vector3d( 0, 0, -( dTotLen - dTipLen)) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CYL, Mv=vtMs, P1=dStemRad, P2=dTotLen-dTipLen, P3=0}) + local vtMt = Vector3d( 0, 0, -dTotLen) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=FrameId, Ty=MCH_SIM_COB.CONE, Mv=vtMt, P1=dTipRad, P2=dStemRad, P3=dTipLen}) + end + else + EgtErase( EgtGetFirstNameInGroup( HeadId, '_TT'..tostring( nExit)) or GDB_ID.NULL) + local frRef = EgtFR( FrameId) + local SpecFrId = EgtCopy( FrameId, FrameId, GDB_IN.AFTER) + EgtSetName( SpecFrId, '_TT'..tostring( nExit)) + EgtRotate( SpecFrId, frRef:getOrigin(), frRef:getVersY(), 90) + local dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) + local vtMb = Vector3d( 0, -dTotRad, 0) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=SpecFrId, Ty=MCH_SIM_COB.BOX, Mv=vtMb, P1=dTotLen-dTotRad, P2=2*dTotRad, P3=dThick}) + local vtMc = Vector3d( dTotLen-dTotRad, 0, 0) + table.insert( vColl, { Cl='T_'..sHeadName, Grp=sTool, Fr=SpecFrId, Ty=MCH_SIM_COB.CYL, Mv=vtMc, P1=dTotRad, P2=dThick, P3=0}) + end + return true +end + +--------------------------------------------------------------------- +function DumpCollisionCheck( vColl, sTitle, nDbgLev) + if not vColl then return false end + if EgtGetDebugLevel() < ( nDbgLev or 1) then return true end + if sTitle then EgtOutLog( sTitle, nDbgLev or 1) end + for i, Coll in ipairs( vColl) do + local sOut = ' Class='..Coll.Cl..' Group='..Coll.Grp..' FrId='..tostring( Coll.Fr)..' Type='..tostring( Coll.Ty)..' Mv='..tostring( Coll.Mv) + if Coll.Ty == MCH_SIM_COB.BOX then + sOut = sOut .. ' L='..EgtNumToString( Coll.P1, 3)..' W='..EgtNumToString( Coll.P2, 3)..' H='..EgtNumToString( Coll.P3, 3) + elseif Coll.Ty == MCH_SIM_COB.CYL then + sOut = sOut .. ' R='..EgtNumToString( Coll.P1, 3)..' H='..EgtNumToString( Coll.P2, 3) + elseif Coll.Ty == MCH_SIM_COB.SPHE then + sOut = sOut .. ' R='..EgtNumToString( Coll.P1, 3) + elseif Coll.Ty == MCH_SIM_COB.CONE then + sOut = sOut .. ' Rb='..EgtNumToString( Coll.P1, 3)..' Rt='..EgtNumToString( Coll.P2, 3)..' H='..EgtNumToString( Coll.P3, 3) + end + EgtOutLog( sOut, nDbgLev or 1) + end + return true +end + +--------------------------------------------------------------------- +function AddToolToCollisionObj( sTool, sHeadName, nExit, nInd) + local vToolColl = {} + AddToolToCollisionCheck( sHeadName, nExit, vToolColl) + if #vToolColl == 0 then return false end + DumpCollisionCheck( vToolColl, 'Tool Collision Objects :', 4) + -- aggiungo la geometria trovata + for i = 1, #vToolColl do + EmtAddCollisionObjEx( nInd, vToolColl[i].Fr, vToolColl[i].Ty, vToolColl[i].Mv, vToolColl[i].P1, vToolColl[i].P2, vToolColl[i].P3) + end + return true, vToolColl[1] +end + +--------------------------------------------------------------------- +function AddToolHolderToCollisionObj( sTool, sHeadName, nExit, nInd) + -- recupero il gruppo dell'utensile + local HeadId = EgtGetHeadId( sHeadName) + local ExitId = EgtGetFirstNameInGroup( HeadId, 'T'..tostring( nExit)) + local ToolId = EgtGetFirstInGroup( ExitId) + -- cerco la geometria di collisione in questo gruppo + local vThColl = {} + if not AddGeomToCollisionCheck( ToolId, 'TH_'..sHeadName, vThColl) then return false end + DumpCollisionCheck( vThColl, 'ToolHolder Collision Objects :', 4) + -- aggiungo la geometria trovata + for i = 1, #vThColl do + EmtAddCollisionObjEx( nInd, vThColl[i].Fr, vThColl[i].Ty, vThColl[i].Mv, vThColl[i].P1, vThColl[i].P2, vThColl[i].P3) + end + return true, #vThColl +end + +--------------------------------------------------------------------- +return EmtGenerator diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-90480027.ini b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-90480027.ini new file mode 100644 index 0000000..a59a999 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-90480027.ini @@ -0,0 +1,177 @@ +; Commento per evitare BOM con UTF-8 +[General] +Material=Beam +NCType=2 ; 1=Tpa, 2=Num Flexium + +[Axes] +; 1 = Type, Id, Name +; Type => l=linear;r=rotational +1=l,0,X +2=l,1,Y +3=l,2,Z +4=l,3,U +5=r,4,V +6=l,5,W +7=r,6,A +8=r,7,B +9=r,8,C + +[Channels] +1=0,Channel 1 +2=1,Channel 2 + +[MainVariables] +; 1 = Name, Variable Path, ReadType, Type +; ReadType => o=one time;c=continuous +; Type => plc;cn +1=P_Prod,E81295,c,cn +2=P_Machgroup,E81296,c,cn +3=P_Part,E81297,c,cn +4=P_State,E81298,c,cn +5=Reset_State,E80048,c,cn +6=ISO_Num,E80045,c,cn +7=ISO_Sent,E80046,c,cn +8=Running,E80047,c,cn +9=Start_State,Application.IOCONFIG_GLOBALS.Flexium_NCK.RCNC.General.Start,c,plc +10=Stop_State,Application.IOCONFIG_GLOBALS.Flexium_NCK.RCNC.General.Stop,c,plc +11=MachIndex,E80000,c,cn + +[Variables] +; 1 = Name, Variable Path, ReadType, Type +; ReadType => o=one time;c=continuous +; Type => plc;cn +;1=Ingresso1,Application.IoConfig_Globals_Mapping.A0,c,plc +;2=Ingresso2,Application.IoConfig_Globals_Mapping.A1,c,plc +;3=Ingresso3,Application.IoConfig_Globals_Mapping.A2,c,plc +;4=Ingresso4,Application.IoConfig_Globals_Mapping.A3,c,plc +;5=P_Prod,E81295,c,cn +;6=P_Machgroup,E81296,c,cn +;7=P_Part,E81297,c,cn +;8=P_State,E81298,c,cn +;9=Reset_State,E80048,c,cn +;10=Uscita1,Application.IoConfig_Globals_Mapping.E0,c,plc +;11=Uscita2,Application.IoConfig_Globals_Mapping.E1,c,plc +;12=Start_State,Application.IoConfig_Globals.Flexium_NCK.RCNC.General.Start,c,plc +;13=Stop_State,Application.IoConfig_Globals.Flexium_NKC.RCNC.General.Stop,c,plc + +[InputVariables] +; 1 = Name, Variable Path, ReadType, Type +; ReadType => o=one time;c=continuous +; Type => plc;cn +1=Uscita1,Application.IoConfig_Globals_Mapping.E0,c,plc +2=Uscita2,Application.IoConfig_Globals_Mapping.E1,c,plc +3=Uscita3,Application.IoConfig_Globals_Mapping.E2,c,plc +4=Uscita4,Application.IoConfig_Globals_Mapping.E3,c,plc + +[OutputVariables] +; 1 = Name, Variable Path, ReadType, Type +; ReadType => o=one time;c=continuous +; Type => plc;cn +1=Ingresso1,Application.IoConfig_Globals_Mapping.A12,c,plc +2=Ingresso2,Application.IoConfig_Globals_Mapping.A1,c,plc +3=Ingresso3,Application.IoConfig_Globals_Mapping.A2,c,plc +4=Ingresso4,Application.IoConfig_Globals_Mapping.A3,c,plc + +[MDI] +; 1 = Command, Description +1=M6T1,1 +2=M6T2,2 +3=M6T3,3 +4=M6T4,4 +5=M6T5,5 +6=M6T6,6 +7=M6T7,7 +8=M6T8,8 +9=M6T9,9 +10=M6T10,10 +11=M6T11,11 +12=M6T12,12 +13=M6T13,13 +14=M6T14,14 +15=M6T15,15 +16=M6T16,16 +17=M6T17,17 +18=M6T18,18 +19=M6T50,19 +20=M6T101,20 +21=M90,21 +22=M198T1,22 +23=M199T1,23 +24=M198T2,24 +25=M199T2,25 +26=M196,26 +27=M197,27 +28=M111,28 +29=M112,29 +30=M113,30 +31=M114,31 +32=M151,32 +33=M152,33 +34=M153,34 +35=M154,35 +36=M155,36 +37=E80001=0,37 + +[Languages] +Enable=0 +Language1=Italiano,Ita.txt +Language2=English,Eng.txt + +[Tools] +Drillbit=1 +Sawblade=1 +Mill=1 +Mortise=1 +Chisel=0 +DrillMaker=MakeWoodDrill.lua +SawbladeMaker=MakeSawblade.lua +MillMaker=MakeWoodCylMill.lua +MortiseMaker=MakeMortise.lua +ChiselMaker=MakeChisel.lua +Active=1 + +[ToolHolder] +H1.1=Standard.nge +H1.1:MILL_NOTIP=MillNoTip.nge +H2.1= +H3.1=ChainSaw.nge + +[Machinings] +Drilling=1 +Sawing=1 +Milling=1 +Pocketing=1 +Mortising=1 +Chiseling=0 +SawRoughing=0 +SawFinishing=0 + +[Machining] +InitScript=InitMach.lua +ExitScript=ExitMach.lua + +[Disposition] +;InitScript=InitDisp.lua + +[Heads] +; 5 axis head +H1=6608 +; 5 axis saw +H2=6615 +; Chainsaw +H3=6616 +; Horizontal drill +H5=6621 +; Opposite Horizontal drill +H6=6621 + +[SetUp] +Default=Standard + +[Estimations] +Enable=1 +WinPlace=0,514,138,628,810 + +[VMill] +Enable=1 +Save=0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-90480027.mlde b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-90480027.mlde new file mode 100644 index 0000000..4fda9c5 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-90480027.mlde @@ -0,0 +1,594 @@ +-- Descrizione macchina Essetre-90480027 by EgalTech s.r.l. 2022/02/02 +-- Macchina Wall. + +require( 'EmtGenerator') +EgtEnableDebug( false) + +PP_VER = '2.4b1' + +-- Parametri macchina +NumericalControl = 'NUM' -- NUM o TPA +MinY = 0.0 +MaxY = 18200.0 +MinX1 = -7910.0 +MaxX1 = 0.0 +MinZ1 = -1585.0 +MaxZ1 = 0.0 +MinB1 = -135.0 +MaxB1 = 135.0 +MinC1 = -275.0 +MaxC1 = 275.0 +MillOffs = 202.0 +ChSawLen = 101.0 +ParkC1 = 0 +ParkB1 = 0 +MinX2 = -6075.0 +MaxX2 = -770.0 +MinZ2 = -1180.0 +MaxZ2 = 0.0 +MinB2 = 0.0 +MaxB2 = 90.0 +MinC2 = -275.0 +MaxC2 = 275.0 +MinZ3 = 0 +MaxZ3 = 480 +HomeZ3 = 100 +MinX3 = 300 +MaxX3 = 2400 +HomeX3 = 2330 +MinZ4 = 0 +MaxZ4 = 480 +HomeZ4 = 100 +MinX4 = -2400 +MaxX4 = -300 +HomeX4 = -2330 +MinX5 = 0 +MaxX5 = 800 +HomeX5 = 0 +SawDeltaX = 347.5 +SawDeltaY = 0.0 +SawDeltaZ = -117.9 +SawOffs = 163.5 +DrillDeltaX = -306.35 +DrillDeltaY = -1149.285 +MchDrillDeltaY = -1149.285 +DrillDeltaZ = -971.0 +Drill2DeltaX = -306.35 +Drill2DeltaY = -4939.285 +MchDrill2DeltaY = -4939.285 +Drill2DeltaZ = -971.0 +DimTabX = 16800.0 +DimTabY = 3500.0 +DeltaTabX = 809.6 +DeltaTabY = -1294.3 - DimTabY +DeltaTabZ = -990.0 +CoeffVM = 0.75 +COLL_SAFE_DIST = 2 +SafeTableDown = - ( 7 + COLL_SAFE_DIST) + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Wall', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-90480027.data" +local sData = EgtGetSourceDir().."\\Wall\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end + +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine and Machine.Offsets then + local MchOffs = Machine.Offsets + NumericalControl = EgtIf( MchOffs.TIPO_CN ~= 1, 'NUM', 'TPA') + if MchOffs.MAX_Y then MinY = -MchOffs.MAX_Y end + if MchOffs.MIN_Y then MaxY = -MchOffs.MIN_Y end + MinX1 = MchOffs.MIN_X or MinX1 + MaxX1 = MchOffs.MAX_X or MaxX1 + MinZ1 = MchOffs.MIN_Z or MinZ1 + MaxZ1 = MchOffs.MAX_Z or MaxZ1 + MinB1 = MchOffs.MIN_B or MinB1 + MaxB1 = MchOffs.MAX_B or MaxB1 + MinC1 = MchOffs.MIN_C or MinC1 + MaxC1 = MchOffs.MAX_C or MaxC1 + MinX2 = MchOffs.MIN_U or MinX2 + MaxX2 = MchOffs.MAX_U or MaxX2 + MinZ2 = MchOffs.MIN_W or MinZ2 + MaxZ2 = MchOffs.MAX_W or MaxZ2 + MinB2 = MchOffs.MIN_V or MinB2 + MaxB2 = MchOffs.MAX_V or MaxB2 + MinC2 = MchOffs.MIN_A or MinC2 + MaxC2 = MchOffs.MAX_A or MaxC2 + MillOffs = MchOffs.PIVOT_MILL or MillOffs + SawOffs = MchOffs.PIVOT_SAW or SawOffs + if MchOffs.ZERO_Y_MILL then DeltaTabX = - MchOffs.ZERO_Y_MILL end + if MchOffs.ZERO_X_MILL then DeltaTabY = ( MchOffs.ZERO_X_MILL - DimTabY) end + DeltaTabZ = MchOffs.ZERO_Z_MILL or DeltaTabZ + if MchOffs.ZERO_Y_MILL and MchOffs.ZERO_Y_SAW then SawDeltaX = - ( MchOffs.ZERO_Y_MILL - MchOffs.ZERO_Y_SAW) end + if MchOffs.ZERO_X_MILL and MchOffs.ZERO_X_SAW then SawDeltaY = ( MchOffs.ZERO_X_MILL - MchOffs.ZERO_X_SAW) end + if MchOffs.ZERO_Z_MILL and MchOffs.ZERO_Z_SAW then SawDeltaZ = ( MchOffs.ZERO_Z_MILL - MchOffs.ZERO_Z_SAW) end + if MchOffs.ZERO_Y_MILL and MchOffs.ZERO_Y_DRILL then DrillDeltaX = - ( MchOffs.ZERO_Y_MILL - MchOffs.ZERO_Y_DRILL) end + if MchOffs.ZERO_X_MILL and MchOffs.ZERO_X_DRILL then MchDrillDeltaY = ( MchOffs.ZERO_X_MILL - MchOffs.ZERO_X_DRILL) end + if MchOffs.ZERO_Z_MILL and MchOffs.ZERO_Z_DRILL then DrillDeltaZ = ( MchOffs.ZERO_Z_MILL - MchOffs.ZERO_Z_DRILL) end + if MchOffs.ZERO_Y_MILL and MchOffs.ZERO_Y_DRILL2 then Drill2DeltaX = - ( MchOffs.ZERO_Y_MILL - MchOffs.ZERO_Y_DRILL2) end + if MchOffs.ZERO_X_MILL and MchOffs.ZERO_X_DRILL2 then MchDrill2DeltaY = ( MchOffs.ZERO_X_MILL - MchOffs.ZERO_X_DRILL2) end + if MchOffs.ZERO_Z_MILL and MchOffs.ZERO_Z_DRILL2 then Drill2DeltaZ = ( MchOffs.ZERO_Z_MILL - MchOffs.ZERO_Z_DRILL2) end + end +end + +-- Spostamenti della lama rispetto al disegno +local SawOffsX = SawDeltaX - 347.5 +local SawOffsY = SawDeltaY - 0 +local SawOffsZ = SawDeltaZ + 117.9 + +-- Spostamenti del foratore lato riferimenti rispetto al disegno +local DrillOffsX = DrillDeltaX + 306.35 +local DrillOffsY = DrillDeltaY + 1149.285 +local DrillOffsZ = DrillDeltaZ + 971.0 + +-- Spostamenti del foratore opposto ai riferimenti rispetto al disegno +local Drill2OffsX = Drill2DeltaX + 306.35 +local Drill2OffsY = Drill2DeltaY + 4939.285 +local Drill2OffsZ = Drill2DeltaZ + 971.0 + +EmtGeneral { + File='Essetre-90480027.nge', + Offset = Vector3d( -640.35, -3620.00, -1710.0), + AxisMaxAdjust = 9250, + ExitMaxAdjust = 9250, + Special = 'Essetre-WALL.mlse', + Processor = 'Essetre-WALL.mlpe'} +local BaseId = EmtBase { + Name = 'Base', + Geo='BASE/GEO', + Aux={'BASE/LOAD', 'BASE/MOD01', 'BASE/MOD02', 'BASE/MOD03', 'BASE/MOD04', 'BASE/MOD05', 'BASE/MOD06', 'BASE/MOD07', 'BASE/MOD08', 'BASE/REF', 'BASE/COLLISION'}} + local vtMove = Vector3d( DeltaTabX - 1029.65, DeltaTabY + 4794.3, DeltaTabZ + 990) + EgtMove( BaseId, vtMove, GDB_RT.GLOB) + local StmId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( BaseId, 'COLLISION'), 'STM') + EgtMove( StmId, Vector3d( 0, 0, SafeTableDown)) +-- Tavola +EmtTable { + Name = 'Tab', + Parent = 'Base', + Type = MCH_TT.FLAT, + Ref1 = Point3d( DeltaTabX, DeltaTabY, DeltaTabZ), + Geo = 'TABLE/GEO'} +-- Traversa +local YId = EmtAxis { + Name = 'Y', + Parent = 'Base', + Invert = true, + Type = MCH_AT.LINEAR, + Dir = X_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinY, MaxY}, + Home = 0, + Geo = 'Y_AXIS/GEO', + Aux = {'Y_AXIS/SOLID', 'Y_AXIS/TC', 'Y_AXIS/DRILL_BASE1', 'Y_AXIS/DRILL_BASE2', 'Y_AXIS/COLLISION'}} +EgtMove( EgtGetFirstNameInGroup( YId, 'DRILL_BASE1'), Vector3d( DrillOffsX, DrillOffsY, DrillOffsZ), GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( YId, 'DRILL_BASE2'), Vector3d( Drill2OffsX, Drill2OffsY, Drill2OffsZ), GDB_RT.GLOB) +-- Testa per frese +EmtAxis { + Name = 'X1', + Parent = 'Y', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinX1, MaxX1}, + Home = MaxX1, + Geo = 'X1_AXIS/GEO', + Aux = {'X1_AXIS/SOLID'}} +EmtAxis { + Name = 'Z1', + Parent = 'X1', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinZ1, MaxZ1}, + Home = 0, + Geo = 'Z1_AXIS/GEO', + Aux = {'Z1_AXIS/SOLID'}} +EmtAxis { + Name = 'C1', + Parent = 'Z1', + Token = 'C', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinC1, MaxC1}, + Home = ParkC1, + Geo = 'C1_AXIS/GEO', + Aux = {'C1_AXIS/SOLID', 'C1_AXIS/COLLISION'}} +EmtAxis { + Name = 'B1', + Parent = 'C1', + Token = 'B', + Type = MCH_AT.ROTARY, + Dir = -X_AX(), + Pos = Point3d( 0, 0, MillOffs), + Stroke = {MinB1, MaxB1}, + Home = ParkB1, + Geo = 'B1_AXIS/GEO', + Aux = {'B1_AXIS/SOLID', 'B1_AXIS/COLLISION'}} +EmtHead { + Name = 'H1', + Parent = 'B1', + HSet = 'H1', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, 0), + TDir = Z_AX(), + ADir = -Y_AX(), + Rot1W = 0.1, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H1_HEAD/GEO'} +-- Sega a catena +EmtAxis { + Name = 'A1', + Parent = 'B1', + Token = '**', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = { 0, 270}, + Home = 180, + Geo = 'A1_AXIS/GEO'} +local H3Id = EmtHead { + Name = 'H3', + Parent = 'A1', + HSet = 'H1', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, -ChSawLen), + TDir = Y_AX(), + ADir = Z_AX(), + Rot1W = 0.1, + SolCh = MCH_SCC.ADIR_NEAR, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H3_HEAD/GEO'} + EgtSetInfo( H3Id, 'ZSAFEDELTA', 60) +-- Testa per Lama +local X2Id = EmtAxis { + Name = 'X2', + Parent = 'Y', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinX2, MaxX2}, + Home = MinX2, + Geo = 'X2_AXIS/GEO', + Aux = {'X2_AXIS/SOLID'}} + EgtMove( EgtGetFirstNameInGroup( X2Id, 'SOLID'), Vector3d( SawOffsX, SawOffsY, 0), GDB_RT.GLOB) +local Z2Id = EmtAxis { + Name = 'Z2', + Parent = 'X2', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinZ2, MaxZ2}, + Home = 0, + Geo = 'Z2_AXIS/GEO', + Aux = {'Z2_AXIS/SOLID'}} + EgtMove( EgtGetFirstNameInGroup( Z2Id, 'SOLID'), Vector3d( SawOffsX, SawOffsY, SawOffsZ), GDB_RT.GLOB) +local C2Id = EmtAxis { + Name = 'C2', + Parent = 'Z2', + Token = 'C', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( SawDeltaX, SawDeltaY, 0), + Stroke = {MinC2, MaxC2}, + Home = 0, + Geo = 'C2_AXIS/GEO', + Aux = {'C2_AXIS/SOLID', 'C2_AXIS/COLLISION'}} + EgtMove( EgtGetFirstNameInGroup( C2Id, 'SOLID'), Vector3d( SawOffsX, SawOffsY, SawOffsZ), GDB_RT.GLOB) + EgtMove( EgtGetFirstNameInGroup( C2Id, 'COLLISION'), Vector3d( SawOffsX, SawOffsY, SawOffsZ), GDB_RT.GLOB) +local B2Id = EmtAxis { + Name = 'B2', + Parent = 'C2', + Token = 'B', + Type = MCH_AT.ROTARY, + Dir = -X_AX(), + Pos = Point3d( SawDeltaX, SawDeltaY, SawDeltaZ + SawOffs), + Stroke = {MinB2, MaxB2}, + Home = 90, + Geo = 'B2_AXIS/GEO', + Aux = {'B2_AXIS/SOLID', 'B2_AXIS/COLLISION'}} + EgtMove( EgtGetFirstNameInGroup( B2Id, 'SOLID'), Vector3d( SawOffsX, SawOffsY, SawOffsZ), GDB_RT.GLOB) + EgtMove( EgtGetFirstNameInGroup( B2Id, 'COLLISION'), Vector3d( SawOffsX, SawOffsY, SawOffsZ), GDB_RT.GLOB) +local H2Id = EmtHead { + Name = 'H2', + Parent = 'B2', + HSet = 'H2', + Type = MCH_HT.STD, + Pos = Point3d( SawDeltaX, SawDeltaY, SawDeltaZ), + TDir = Z_AX(), + ADir = -Y_AX(), + Rot1W = 0.2, + OthColl = {'B2/SOLID', 'C2/SOLID'}, + Geo = 'H2_HEAD/GEO'} +-- Foratore +local Z3Id = EmtAxis { + Name = 'Z3', + Parent = 'Y', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinZ3, MaxZ3}, + Home = HomeZ3, + Geo = 'Z3_AXIS/GEO', + Aux = {'Z3_AXIS/SOLID'}} +EgtMove( EgtGetFirstNameInGroup( Z3Id, 'SOLID'), Vector3d( DrillOffsX, DrillOffsY, DrillOffsZ), GDB_RT.GLOB) +local X3Id = EmtAxis { + Name = 'X3', + Parent = 'Z3', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinX3, MaxX3}, + Home = HomeX3, + Geo = 'X3_AXIS/GEO', + Aux = {'X3_AXIS/SOLID'}} +EgtMove( EgtGetFirstNameInGroup( X3Id, 'SOLID'), Vector3d( DrillOffsX, DrillOffsY, DrillOffsZ), GDB_RT.GLOB) +local H5Id = EmtHead { + Name = 'H5', + Parent = 'X3', + HSet = 'H5', + Type = MCH_HT.STD, + Pos = Point3d( DrillDeltaX, DrillDeltaY, DrillDeltaZ), + TDir = Y_AX(), + Geo = 'H5_HEAD/GEO'} +EgtSetInfo( H5Id, 'ABOVE', '0') +-- Foratore opposto +local Z4Id = EmtAxis { + Name = 'Z4', + Parent = 'Y', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinZ4, MaxZ4}, + Home = HomeZ4, + Geo = 'Z4_AXIS/GEO', + Aux = {'Z4_AXIS/SOLID'}} +EgtMove( EgtGetFirstNameInGroup( Z4Id, 'SOLID'), Vector3d( Drill2OffsX, Drill2OffsY, Drill2OffsZ), GDB_RT.GLOB) +local X4Id = EmtAxis { + Name = 'X4', + Parent = 'Z4', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinX4, MaxX4}, + Home = HomeX4, + Geo = 'X4_AXIS/GEO', + Aux = {'X4_AXIS/SOLID'}} +EgtMove( EgtGetFirstNameInGroup( X4Id, 'SOLID'), Vector3d( Drill2OffsX, Drill2OffsY, Drill2OffsZ), GDB_RT.GLOB) +local X5Id = EmtAxis { + Name = 'X5', + Parent = 'Z4', + Token = 'W', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinX5, MaxX5}, + Home = HomeX5, + Geo = 'X5_AXIS/GEO', + Aux = {'X5_AXIS/SOLID'}} +EgtMove( EgtGetFirstNameInGroup( X5Id, 'SOLID'), Vector3d( Drill2OffsX, Drill2OffsY, Drill2OffsZ), GDB_RT.GLOB) +local H6Id = EmtHead { + Name = 'H6', + Parent = 'X4', + HSet = 'H6', + Type = MCH_HT.STD, + Pos = Point3d( Drill2DeltaX, Drill2DeltaY, Drill2DeltaZ), + TDir = -Y_AX(), + Geo = 'H6_HEAD/GEO'} +EgtSetInfo( H6Id, 'ABOVE', '0') +-- ToolChanger +local ptTcA = Point3d( -480.6,-3377.7,17.0) +EmtTcPos { + Name = 'T10', + Parent = 'Y', + Pos = ptTcA, + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TA1'} +EmtTcPos { + Name = 'T11', + Parent = 'Y', + Pos = ptTcA + 120 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TA2'} +EmtTcPos { + Name = 'T12', + Parent = 'Y', + Pos = ptTcA + 240 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TA3'} +EmtTcPos { + Name = 'T13', + Parent = 'Y', + Pos = ptTcA + 360 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TA4'} +EmtTcPos { + Name = 'T14', + Parent = 'Y', + Pos = ptTcA + 480 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TA5'} +EmtTcPos { + Name = 'T15', + Parent = 'Y', + Pos = ptTcA + 600 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TA6'} +EmtTcPos { + Name = 'T16', + Parent = 'Y', + Pos = ptTcA + 720 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TA7'} +EmtTcPos { + Name = 'T17', + Parent = 'Y', + Pos = ptTcA + 840 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TA8'} +EmtTcPos { + Name = 'T18', + Parent = 'Y', + Pos = ptTcA + 960 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TA9'} +local ptTcB = Point3d( -480.6,-4726.7,17.0) +EmtTcPos { + Name = 'T1', + Parent = 'Y', + Pos = ptTcB, + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TB1'} +EmtTcPos { + Name = 'T2', + Parent = 'Y', + Pos = ptTcB + 120 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TB2'} +EmtTcPos { + Name = 'T3', + Parent = 'Y', + Pos = ptTcB + 240 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TB3'} +EmtTcPos { + Name = 'T4', + Parent = 'Y', + Pos = ptTcB + 360 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TB4'} +EmtTcPos { + Name = 'T5', + Parent = 'Y', + Pos = ptTcB + 480 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TB5'} +EmtTcPos { + Name = 'T6', + Parent = 'Y', + Pos = ptTcB + 600 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TB6'} +EmtTcPos { + Name = 'T7', + Parent = 'Y', + Pos = ptTcB + 720 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TB7'} +EmtTcPos { + Name = 'T8', + Parent = 'Y', + Pos = ptTcB + 840 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TB8'} +EmtTcPos { + Name = 'T9', + Parent = 'Y', + Pos = ptTcB + 960 * Y_AX(), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'Y_AXIS/TB9'} +EmtTcPos { + Name = 'T101', + Parent = 'Y', + Pos = Point3d(-568.3,-1312.4,9-92.8), + TDir = X_AX(), + ADir = Z_AX(), + Geo = 'Y_AXIS/TC1'} +--EmtTcPos { +-- Name = 'T201', +-- Parent = 'Y', +-- Pos = Point3d(-926.3,-1855.0,28), +-- TDir = Z_AX(), +-- ADir = X_AX(), +-- Geo = 'Y_AXIS/TC2'} + +--------------------------------------------------------------------- +-- Funzioni richiamate per modificare i dati macchina in casi particolari +--function OnSetTable() +--end + +--------------------------------------------------------------------- +function OnSetHead() + if EMC.HEAD == 'H1' then + EmtModifyAxisHome( 'X1', MaxX1) + EmtModifyAxisHome( 'Z1', MaxZ1) + EmtModifyAxisHome( 'C1', ParkC1) + elseif EMC.HEAD == 'H3' then + -- recupero valore asse A bloccato + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + local CSawPosA = EgtGetVal( sVal, 'A1', 'd') or 0 + EmtModifyAxisHome( 'X1', ( MinX1 + MaxX1) / 2) + EmtModifyAxisHome( 'Z1', GetChainSawZHomeFromVirtualAxis( CSawPosA)) + EmtModifyAxisHome( 'C1', GetChainSawCHomeFromVirtualAxis( CSawPosA)) + EmtModifyAxisHome( 'A1', CSawPosA) + end +end + +--------------------------------------------------------------------- +-- Funzione che calcola la posizione Home di Z per la sega a catena dal valore dell'asse virtuale +function GetChainSawZHomeFromVirtualAxis( dPosA) + -- quota fissa + return -150 +end + +--------------------------------------------------------------------- +-- Funzione che calcola l'angolo Home di C per la sega a catena dal valore dell'asse virtuale +function GetChainSawCHomeFromVirtualAxis( dPosA) + -- se A=0 -> T104 -> HomeC = 90 + if abs( dPosA) < 0.1 then + return 90 + -- altrimenti A=90 -> T101 -> HomeC = 0 + else + return 0 + end +end + +--------------------------------------------------------------------- +-- Funzione per resettare tutte le attivazioni della macchina +function OnResetMachine() + EmtUnlinkAllRawPartsFromGroups() + EmtUnlinkAllFixturesFromGroups() + -- nascondo Vmill + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nVmId = EgtGetFirstNameInGroup( nRawId, 'VMill') + local nId = EgtGetFirstInGroup( nRawId) + while nId do + EgtSetStatus( nId, EgtIf( nId ~= nVmId, GDB_ST.ON, GDB_ST.OFF)) + nId = EgtGetNext( nId) + end + nRawId = EgtGetNextRawPart( nRawId) + end + EgtSetStatus( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') or GDB_ID.NULL, GDB_ST.OFF) +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-90480027.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-90480027.nge new file mode 100644 index 0000000..5d15c54 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-90480027.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-WALL.NUM.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-WALL.NUM.mlpe new file mode 100644 index 0000000..548c961 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-WALL.NUM.mlpe @@ -0,0 +1,645 @@ +-- Processore macchina Essetre-WALL by EgalTech s.r.l. 2021/12/02 +-- Con controllo numerico NUM + +-- Variabili di modulo +local MLE_INFO = 'Essetre-WALL.NUM.mlpe ver.'..PP_VER..' by EgalTech s.r.l.' +local TEST_USE = false +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.FMAXPINZE = 154000 -- feed massima pinze +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Info da gruppo BtlInfo (se mancano prova dal gruppo di lavoro corrente) + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or EgtGetCurrMachGroup() or GDB_ID.NULL + EMT.ORIG = EgtGetInfo( BtlInfoId, 'REFPOS', 'i') or 1 + EMT.LOAD90 = EgtGetInfo( BtlInfoId, 'LOAD90', 'i') or 0 + -- Intestazioni + if not TEST_USE then + EMT.PRODID = EgtGetInfo( BtlInfoId, 'PRODID', 'i') or 0 + EMT.PATTID = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 0 + end + if EMT.PATTID and EMT.PATTID > 0 then + EmtOutput( '%' .. tostring( EMT.PATTID) .. '.0') + else + EmtOutput( '%40.0') + end + if EMT.INFO then + EmtOutput( '('..EMT.INFO..')') + else + EmtOutput( '(Program Start)') + end + EmtOutput( '('.. MLE_INFO..')') + -- Se modalità test vado in posizione sicura + if TEST_USE then + EmtOutput( 'G77 H9000 N1000 N2000') + end + -- Parametri macchina + local sOut = 'G114'..' EA'..EgtNumToString( DeltaTabY + DimTabY - SawDeltaY, 2)..' EB'..EgtNumToString( -DeltaTabX + SawDeltaX, 2).. + ' EC'..EgtNumToString( DeltaTabZ - SawDeltaZ, 2)..' ED'..EgtNumToString( SawOffs, -2)..' EE'..EgtNumToString( 0, 2).. + ' EF'..EgtNumToString( DeltaTabY + DimTabY, 2)..' EG'..EgtNumToString( -DeltaTabX, 2).. + ' EH'..EgtNumToString( DeltaTabZ, 2)..' EI'..EgtNumToString( MillOffs, 2).. + ' EL'..EgtNumToString( DeltaTabY + DimTabY - MchDrillDeltaY, 2)..' EM'..EgtNumToString( -DeltaTabX + DrillDeltaX, 2).. + ' EN'..EgtNumToString( DeltaTabZ - DrillDeltaZ, 2).. + ' EO'..EgtNumToString( DeltaTabY + DimTabY - MchDrill2DeltaY, 2)..' EP'..EgtNumToString( -DeltaTabX + Drill2DeltaX, 2).. + ' EQ'..EgtNumToString( DeltaTabZ - Drill2DeltaZ, 2) + EmtOutput( sOut) + -- Indice lavorazione + EMT.CNT = 0 + -- Non effettuate lavorazioni con sega a catena sul fianco + EMT.CSAWFIRST = true + -- Non effettuata pausa per rimozione sfridi + EMT.SCRAPFIRST = true + -- Cerco primo utensile su testa 1 + EMT.TOOL_1, EMT.TLEN_1 = FindFirstToolOnHead( 'H1') +end + +--------------------------------------------------------------------- +function OnProgramEnd() + EmtOutput( '( *** Program End *** )') + EmitCount() + -- Dichiarazione conclusione pezzi + if EMT.PRODID then + local sOut = 'G126 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( -1)..' ED2' + EmtOutput( sOut) + end + -- Arresto mandrino + EmtOutput( 'M05 E80000=1') + -- Gestione scarico + EmtOutput( 'M12 $PRESS START FOR CLEANING') + EmtOutput( 'M27 E30057=' .. EgtIf( EMT.LOAD90 == 1, '5', '1')) + -- Se modalità test, termino il programma + if TEST_USE then + EmtOutput( 'M02') + end +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensile (esclusa lama e sega a catena) + if EMT.HEAD == 'H1' then + -- cerco posizione di attrezzaggio del primo utensile di lavorazione + if EMT.TOOL == EMT.TOOL_1 and EMT.TLEN_1 < 215.5 then + EMT.TCPOS_1 = EMT.TCPOS + end + -- emissione dati sega a catena + elseif EMT.HEAD == 'H3' then + ; + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + --EmtOutput( '(Disposition '..EMT.DISPIND..' = '..EMT.DISPID..')') + EMT.OPEISDISP = true +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se prima disposizione + if EMT.PHASE == 1 then + -- Dimensioni grezzo + local b3Raw = EgtGetRawPartBBox( EMT.RAWID) + EMT.LP = b3Raw:getDimX() + EMT.HP = b3Raw:getDimY() + EMT.SP = b3Raw:getDimZ() + EmtOutput( 'E30050='..EgtNumToString( 1000 * EMT.HP, 0).. + ' E30051='..EgtNumToString( 1000 * EMT.LP, 0).. + ' E30052='..EgtNumToString( 1000 * EMT.SP, 0)) + -- Scelta origine + EmtOutput( 'M26 E30054='..EgtNumToString( EMT.ORIG, 0)) + -- Posizione cuffia + local dHCuff = b3Raw:getDimZ() + 32 + EmtOutput( 'E30039=' .. EgtNumToString( dHCuff * 1000, 0)) + -- Eventuale salto a lavorazione in corso + EmtOutput( 'G79 NE80000') + -- Dichiarazione inizio lavorazione pezzi + if EMT.PRODID then + EmitCount() + local sOut = 'G126 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( -1)..' ED1' + EmtOutput( sOut) + end + end + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOOLSEL = EMT.TCPOS..' M06' + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + --EMT.MCHLIBNAME = EgtGetMachiningParam( MCH_MP.NAME) + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam(MCH_MP.TYPE) + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + if not EMT.ZMAX then + EmtOutput( 'G103'..GetET()..' E80000='..tostring( EMT.CNT + 1)) + end + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStart() + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() +end + +--------------------------------------------------------------------- +function OnPathEnd() +end + +--------------------------------------------------------------------- +function OnRapid() + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmtOutput( '( *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** )') + EmitCount() + -- se lavorazione con sega a catena + if EMT.HEAD == 'H3' then + -- se prima lavorazione sui fianchi con sega a catena + if EMT.CSAWFIRST and string.sub( EMT.MCHNAME, 1, 5) == 'Csaw_' then + EMT.CSAWFIRST = false + -- pausa per rimozione sfridi + local b3Raw = EgtGetRawPartBBox( EMT.RAWID) + local ParkY = min( -( b3Raw:getMin():getX() - 2000), -MinY) + EmtOutput( 'G104 Y' .. EmtLenToString( ParkY, 3) .. ' ET1' .. GetEF()) + -- pre-posizionamento + EmitCount() + EmtResetPrev() + local sOut = 'G101' .. EmtGetAxis( 'R1') + local sET = GetET() + local sEU = GetEU() + local sEE = GetEE() + local sEF = GetEF() + local sEM = ' EM'..EgtIf( EMT.S > 0, '3', '4') + local sES = ' ES'..EgtNumToString( abs( EMT.S), 0) + local sEL = ' EL' .. EmtLenToString( ChSawLen, 3) + local sER = ' ER' .. EmtLenToString( EMT.TLEN, 3) + sOut = sOut .. sET .. sEU .. sEE .. sEF .. sEM .. sES .. sEL .. sER + EmtOutput( sOut) + end + -- altrimenti verifico se necessaria pausa + else + if EMT.SCRAPFIRST and EgtExistsInfo( EMT.MCHID, 'MOVE_AFTER') then + EMT.SCRAPFIRST = false + -- pausa per rimozione sfridi + local b3Raw = EgtGetRawPartBBox( EMT.RAWID) + local ParkY = min( -( b3Raw:getMin():getX() - 2000), -MinY) + EmtOutput( 'G104 Y' .. EmtLenToString( ParkY, 3) .. ' ET1' .. GetEF()) + end + end + -- primo posizionamento + EmtResetPrev() + if EMT.HEAD ~= 'H5' and EMT.HEAD ~= 'H6' then + local sOut = 'G101' .. EmtGetAxis( 'L1') .. EmtGetAxis( 'L2') .. EmtGetAxis( 'L3') .. + EmtGetAxis( 'R2') .. EmtGetAxis( 'R1') + if EMT.HEAD == 'H1' then + sOut = sOut .. ' U' .. EmtLenToString( MinX2, 3) .. ' W0 V90 A0' + elseif EMT.HEAD == 'H2' then + sOut = sOut .. ' U' .. EmtLenToString( MaxX1, 3) .. ' W0 V0 A0' + elseif EMT.HEAD == 'H3' then + sOut = sOut .. ' U' .. EmtLenToString( MinX2, 3) .. ' W0 V90 A0' + else + EmtSetLastError( 1211, "Unknown Head : " .. EMT.HEAD) + end + local sET = GetET() + local sEU = GetEU() + local sEE = GetEE() + local sEF = GetEF() + local sEM = ' EM'..EgtIf( EMT.S > 0, '3', '4') + local sES = ' ES'..EgtNumToString( abs( EMT.S), 0) + local sEL = ' EL' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TLEN, ChSawLen), 3) + local sER = ' ER' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TDIAM / 2, EMT.TLEN), 3) + sOut = sOut .. sET .. sEU .. sEE .. sEF .. sEM .. sES .. sEL .. sER + EmtOutput( sOut) + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + else -- H5 or H6 (foratori orizzontali) + -- rinvio l'emissione al prossimo movimento con Z del foro + EMT.FIRST_HDRILL = true + EMT.REFLOC = nil + EMT.MCHFIRST = false + end + -- se standard + elseif EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se prima emissione di foratura orizzontale + if EMT.FIRST_HDRILL then + EMT.FIRST_HDRILL = false + local sET = GetET() + local sEU = GetEU() + EMT.L1 = -EMT.L1 + local sOut = 'G101 X0' .. EmtGetAxis( 'L1') .. EmtGetAxis( 'L3')..' U0 V0 W0'..sET..sEU..' EF60000' + EmtOutput( sOut) + EMT.L1 = -EMT.L1 + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmtResetPrev() + local sEE = GetEE() + local sEF = ' EF20000' + local sEM = ' EM'..EgtIf( EMT.S > 0, '3', '4') + local sX = ' X30' + local sEX = ' EX0' + if EMT.HEAD == 'H6' then + sX = ' X-30' + sEX = ' EX' .. EmtLenToString( -EMT.HP) + end + sOut = 'G102' .. sX ..' Y0 Z0'..sEX..' EY'..EmtLenToString( EMT.L1)..' EZ'..EmtLenToString( EMT.L3) .. ' EA0 EB0 EC0 ED0' .. sET .. sEU .. sEE .. sEM .. sEF + EmtOutput( sOut) + EMT.ZMAX = false + -- se necessario, impostazione riferimento locale + elseif EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EMT.R1p = nil + EMT.R2p = nil + local sET = GetET() + local sEU = GetEU() + local sEE = GetEE() + local sEF = ' EF20000' + local sEM = ' EM'..EgtIf( EMT.S > 0, '3', '4') + local sES = ' ES'..EgtNumToString( abs( EMT.S), 0) + local sEL = ' EL' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TLEN, ChSawLen), 3) + local sER = ' ER' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TDIAM / 2, EMT.TLEN), 3) + EmtOutput( 'G102'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3')..EmtGetAxis('R2')..EmtGetAxis('R1')..EMT.IPLGLSTR..sET..sEU..sEE..sEF..sEM..sES..sEL..sER) + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + elseif EMT.HEAD ~= 'H5' and EMT.HEAD ~= 'H6' then + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + end + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + if EMT.REFLOC then + EMT.REFLOC = nil + EMT.IPLGL = false + EmtResetPrev() + -- dichiarazione fine lavorazione + EmtOutput( 'G103'..GetET()..' E80000='..tostring( EMT.CNT + 1)) + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + local sOut = 'G101' .. EmtGetAxis( 'L3') .. EmtGetAxis( 'R2') .. EmtGetAxis( 'R1') .. GetET() .. GetEE() .. GetEF() + EmtOutput( sOut) + EMT.ZMAX = true + elseif EMT.HEAD == 'H5' or EMT.HEAD == 'H6' then + EmtResetPrev() + EmtOutput( 'G103'..GetET()..' E80000='..tostring( EMT.CNT + 1)) + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.ZMAX = true + end + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- altrimenti errore + else + error( "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + local OldR1p = EMT.R1p + local OldR2p = EMT.R2p + -- imposto posizione precedente + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + EMT.R1p = nil + EMT.R2p = nil + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + local sET = GetET() + local sEU = GetEU() + local sEE = GetEE() + local sEF = ' EF20000' + local sEM = ' EM'..EgtIf( EMT.S > 0, '3', '4') + local sES = ' ES'..EgtNumToString( abs( EMT.S), 0) + local sEL = ' EL' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TLEN, ChSawLen), 3) + local sER = ' ER' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TDIAM / 2, EMT.TLEN), 3) + EmtOutput( 'G102'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3')..EmtGetAxis('R2')..EmtGetAxis('R1')..EMT.IPLGLSTR..sET..sEU..sEE..sEF..sEM..sES..sEL..sER) + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + EMT.R1p = OldR1p + EMT.R2p = OldR2p + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes + if EMT.HEAD ~= 'H5' and EMT.HEAD ~= 'H6' then + sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + else + sAxes = EmtGetAxis('L2') + end + -- se nulla da emettere, esco + if #sAxes == 0 then + return + end + -- aggiungo feed + local sFeed = EmtGetFeed() + -- emetto linea + EmtOutput( "G1"..sAxes..sFeed) + -- eventuale gestione fondo foro + if EMT.FLAG == 101 and ( EMT.HEAD == 'H5' or EMT.HEAD == 'H6') then + EmtOutput( 'M155') + end + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + -- non modale su archi + local dPrevZ = EMT.L3p + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString(EMT.RR,3) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- se elica, aggiungo il pitch + local sPitch = '' + local dDeltaZ = EMT.L3 - dPrevZ + if abs( dDeltaZ) > GEO.EPS_SMALL then + local dPitch = dDeltaZ * 360.0 / abs( EMT.AC) + sPitch = ' K' .. EmtLenToString( dPitch, 3) + end + -- emetto arco + EmtOutput( sArc..sAxes..sRad..sPitch..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + if EMT.REFLOC then + local vtDelta = V_NULL() + local vtE = V_NULL() + if EMT.HEAD == 'H1' then + local Len = EMT.TLEN + MillOffs + local LenRef = MillOffs + local vtTool = EgtGetCalcToolDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + vtE = vtTool * Len - Z_AX() * LenRef + elseif EMT.HEAD == 'H2' then + vtDelta = -Vector3d( SawDeltaX, SawDeltaY, SawDeltaZ) + local Len = EMT.TLEN + SawOffs + local LenRef = SawOffs + local vtTool = EgtGetCalcToolDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + vtE = vtTool * Len - Z_AX() * LenRef + elseif EMT.HEAD == 'H3' then + local Len = ChSawLen + MillOffs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + vtE = vtAux * Len - Z_AX() * LenRef + end + EMT.L1 = EMT.L1 - vtDelta:getX() - vtE:getX() + EMT.L2 = EMT.L2 - vtDelta:getY() - vtE:getY() + EMT.L3 = EMT.L3 - vtDelta:getZ() - DeltaTabZ - vtE:getZ() + elseif EMT.HEAD == 'H5' then + EMT.L1 = EMT.L1 - DeltaTabX + DrillDeltaX + EMT.L2 = EMT.L2 - DeltaTabY + DrillDeltaY - DimTabY - EMT.TLEN + EMT.L3 = EMT.L3 - DeltaTabZ + DrillDeltaZ + elseif EMT.HEAD == 'H6' then + EMT.L1 = EMT.L1 - DeltaTabX + Drill2DeltaX + EMT.L2 = EMT.L2 - DeltaTabY + Drill2DeltaY - DimTabY + EMT.HP + EMT.TLEN + EMT.L3 = EMT.L3 - DeltaTabZ + Drill2DeltaZ + end + + EmtAdjustLinearAxes() + + if not EMT.REFLOC then + EMT.L1 = - EMT.L1 + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + local yS = EMT.START[2] + local zS = 0 + local ptS = Point3d( xS, yS, zS) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H3' then + vtE = EgtGetCalcToolDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --EmtOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local _, dAngV, dAngO = SphericalFromVector( vtE) + local dAngO2 = EmtGetAngO2( EMT.IPLGLFR:getVersZ(), EMT.IPLGLFR:getVersX(), dAngV, dAngO) + dAngO = dAngO - 90 + while dAngO < 0 do + dAngO = dAngO + 360 + end + -- se rotazione solo attorno alla C allora si mette come rotazione finale + if abs( dAngV) < GEO.EPS_ANG_SMALL then + dAngO2 = dAngO2 + dAngO + while dAngO2 >= 360 do + dAngO2 = dAngO2 - 360 + end + dAngO = 0 + end + + local xOut = yS - DeltaTabY - DimTabY + local yOut = - ( xS - DeltaTabX) + local zOut = zS + if EMT.ORIG == 2 then + xOut = yS - DeltaTabY + yOut = - ( xS - DeltaTabX) + elseif EMT.ORIG == 3 then + xOut = yS - DeltaTabY - DimTabY + yOut = - ( xS - DeltaTabX - DimTabX) + elseif EMT.ORIG == 4 then + xOut = yS - DeltaTabY + yOut = - ( xS - DeltaTabX - DimTabX) + elseif EMT.ORIG == 5 then + xOut = yS - DeltaTabY - DimTabY + yOut = - ( xS - DeltaTabX - Orig5DeltaX) + elseif EMT.ORIG == 6 then + xOut = yS - DeltaTabY + yOut = - ( xS - DeltaTabX - Orig5DeltaX) + end + EMT.IPLGLSTR = ' EX'..EmtLenToString( xOut)..' EY'..EmtLenToString( yOut)..' EZ'..EmtLenToString( zOut).. + ' EA0'..' EB'..EgtNumToString( dAngV)..' EC'..EgtNumToString( dAngO)..' ED'..EgtNumToString( dAngO2) + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function GetET() + if EMT.HEAD == 'H1' or EMT.HEAD == 'H3' then + return ' ET2' + elseif EMT.HEAD == 'H2' then + return ' ET1' + elseif EMT.HEAD == 'H5' then + return ' ET3' + elseif EMT.HEAD == 'H6' then + return ' ET4' + end +end + +--------------------------------------------------------------------- +function GetEU() + local sEU + if EMT.HEAD == 'H1' then + sEU = ' EU'..string.sub( EMT.TCPOS, 2) + elseif EMT.HEAD == 'H2' then + sEU = ' EU0' + elseif EMT.HEAD == 'H3' then + if abs( EMT.R3 - 0) < 0.1 then + sEU = ' EU104' + elseif abs( EMT.R3 - 270) < 0.1 then + sEU = ' EU101' + elseif abs( EMT.R3 - 180) < 0.1 then + sEU = ' EU102' + elseif abs( EMT.R3 - 90) < 0.1 then + sEU = ' EU103' + else + EmtSetLastError( 1210, 'Chain saw orientation not allowed') + end + elseif EMT.HEAD == 'H5' or EMT.HEAD == 'H6' then + sEU = '' + else + sEU = '' + end + return sEU +end + +--------------------------------------------------------------------- +function GetEE() + return ' EE' .. EgtNumToString( EMT.ORIG, 0) +end + +--------------------------------------------------------------------- +function GetEF() + return ' EF60000' +end + +--------------------------------------------------------------------- +function EmitCount() + EMT.CNT = EMT.CNT + 1 + EmtOutput( 'N'..tostring( EMT.CNT)..' E80000='..tostring( EMT.CNT)) +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-WALL.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-WALL.mlpe new file mode 100644 index 0000000..1a8bd1c --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-WALL.mlpe @@ -0,0 +1,1042 @@ +-- Processore macchina Essetre-WALL by EgalTech s.r.l. 2022/01/30 +-- Funzioni generiche indipendenti dal controllo + +-- 2022/01/20 ver 2.4a3 DS In ExecScrapRemove migliorato calcolo centro di ogni parte del Vmill. +-- 2022/01/30 ver 2.4a4 DS In ExecScrapRemove esteso calcolo centri di ogni parte del Vmill. Migliorato controllo forature da sopra nel tavolo. + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +local sBaseDir = EgtGetSourceDir() +if NumericalControl == 'NUM' then + dofile( sBaseDir .. 'Essetre-WALL.NUM.mlpe') +elseif NumericalControl == 'TPA' then + error( 'Numerical Control error : TPA not yet managed') + --dofile( sBaseDir .. 'Essetre-WALL.TPA.mlpe') +else + error( 'Numerical Control error : unkwnown type') +end + +--------------------------------------------------------------------- +-- *** SIMULATION *** +--------------------------------------------------------------------- + +--------------------------------------------------------------------- +function OnSimulStart() + -- Carico gli utensili sulle barre portautensili + local vTcPos = EgtGetAllTcPosNames() + if vTcPos then + for i = 1, #vTcPos do + local vTools = EgtGetToolsInCurrSetupPos( vTcPos[i]) + if vTools and vTools[1] then + EgtLoadTool( vTcPos[i], 1, vTools[1]) + ShowToolInTcPos( vTcPos[i], true) + end + end + end + -- Se reset o home, esco + if EMT.SIM1ST then return end + -- Non effettuate lavorazioni con sega a catena sul fianco + EMT.CSAWFIRST = true + -- Non effettuata pausa per rimozione sfridi + EMT.SCRAPFIRST = true + -- Creo o svuoto gruppo per copia finale degli oggetti virtual milling + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + if nVmGrpId then + EgtSetStatus( nVmGrpId, GDB_ST.ON) + EgtEmptyGroup( nVmGrpId) + else + nVmGrpId = EgtGroup( GDB_ID.ROOT) + EgtSetName( nVmGrpId, 'VMill') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + -- Preparo lista oggetti da verificare per collisioni + EMT.COLLOBJ = {} + AddToCollisionCheck( 'B1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'B2', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C2', 'COLLISION', EMT.COLLOBJ) + DumpCollisionCheck( EMT.COLLOBJ, 'Collision Objects :', 4) + -- Preparo lista solidi macchina con cui possono collidere gli oggetti sopra riportati (in aggiunta a VMill) + EMT.MCODET = {} + EMT.MCODET[1] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'TRAV') + EMT.MCODET[2] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'COL1') + EMT.MCODET[3] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'COL2') + EMT.MCODET[4] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'TC1') + EMT.MCODET[5] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'TC2') + EMT.MCODET[6] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'CHSAW') + EMT.MCODET[7] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'STM') + EMT.MCODET[8] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'REF1') + EMT.MCODET[9] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'REF2') + EMT.MCODET[10] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'REF3') + EMT.MCODET[11] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'REF4') + EMT.MCODET[12] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'REF5') + for i = #EMT.MCODET, 1, -1 do + if not EMT.MCODET[i] then + table.remove( EMT.MCODET, i) + EgtOutLog( 'Warning : MCODET element (' .. tostring( i) .. ') is null') + end + end + -- Preparo lista collisioni vuota + EMT.COLLIDE = {} +end + +--------------------------------------------------------------------- +function OnSimulEnd() + if EMT.SCRAPFIRST then + EMT.SCRAPFIRST = false + ExecScrapRemove() + end + ExecUnloading() +end + +--------------------------------------------------------------------- +--function OnSimulDispositionStarting() +--end + +--------------------------------------------------------------------- +function OnSimulDispositionStart() + + EMT.OPEISDISP = true + + -- Se prima disposizione (dovrebbe essere l'unica) + if EMT.PHASE == 1 then + -- Determino dimensioni del grezzo + local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL + local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + EMT.LB = 0 + EMT.SB = 0 + EMT.HB = 0 + if b3Sol then + EMT.LB = b3Sol:getDimX() + EMT.SB = b3Sol:getDimY() + EMT.HB = b3Sol:getDimZ() + end + -- Carico primo utensile sulla testa 1 + local sTool = FindFirstToolOnHead( 'H1') + if sTool then + EMT.TOOL_1 = sTool + EgtLoadTool( 'H1', 1, EMT.TOOL_1) + EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1) + ShowToolInTcPos( EMT.TCPOS_1, false) + else + EgtUnloadTool( 'H1', 1) + end + end + + -- Nascondo tutte le lavorazioni + local nMchId = EgtGetFirstOperation() + while nMchId do + if EgtGetOperationType( nMchId) ~= MCH_OY.DISP then + EgtSetOperationStatus( nMchId, false) + end + nMchId = EgtGetNextOperation( nMchId) + end + + -- dati del grezzo + local nRawId = EgtGetFirstRawPart() + local b3Raw = EgtGetRawPartBBox( nRawId or GDB_ID.NULL) + + -- Se abilitato e trovato grezzo, creazione Zmap + if EgtGetInfo( EgtGetCurrMachGroup(), 'Vm', 'b') and nRawId then + -- Se vero inizio, creo Zmap + if not EMT.SIM1ST then + -- elimino eventuale vecchio Zmap + EgtErase( EgtGetFirstNameInGroup( nRawId, 'VMill') or GDB_ID.NULL) + -- recupero il solido + local nSolId = EgtGetFirstNameInGroup( nRawId, 'RawSolid') + -- determino la risoluzione dello Zmap + local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + local dArea = b3Sol:getDimX() * b3Sol:getDimY() + b3Sol:getDimX() * b3Sol:getDimZ() + b3Sol:getDimY() * b3Sol:getDimZ() + local dTol = 6.13 + if dArea < CoeffVM * 6.0e6 then + dTol = 2.81 + elseif dArea < CoeffVM * 12.0e6 then + dTol = 3.77 + elseif dArea < CoeffVM * 24.0e6 then + dTol = 5.03 + end + -- creo lo Zmap + EMT.VMILL = EgtVolZmapBox( nRawId, b3Raw:getMin(), b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol, true, GDB_RT.GLOB) + if EMT.VMILL then + EgtSetName( EMT.VMILL, 'VMill') + EgtSetLevel( EMT.VMILL, GDB_LV.TEMP) + EgtSetColor( EMT.VMILL, EgtGetColor( nSolId), false) + -- nascondo le altre geometrie + local nId = EgtGetFirstInGroup( nRawId) + while nId do + if nId ~= EMT.VMILL then + EgtSetStatus( nId, GDB_ST.OFF) + end + nId = EgtGetNext( nId) + end + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + -- imposto eventuale utensile corrente + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + end + end + end + -- se vero inizio, assegno solidi per verifica collisione + if not EMT.SIM1ST then + EMT.CODET = {} + for i = 1, #EMT.MCODET do + EMT.CODET[i] = EMT.MCODET[i] + end + if EMT.VMILL then + table.insert( EMT.CODET, EMT.VMILL) + end + end +end + +--------------------------------------------------------------------- +function OnSimulDispositionEnd() + if EMT.UNLOADING or EMT.FALL then + EMT.UNLOADING = false + EMT.FALL = false + end + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnSimulToolSelect() + -- se utensile non definito, è disposizione ed esco + if EMT.TOOL == '' then return end + -- recupero dati utensile + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOOLTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + -- se lama su sua testa, verifico che l'altra sia dalla parte opposta + if EMT.HEAD == 'H2' then + EgtSetAxisPos( 'X1', MaxX1) + -- se altrimenti utensile su testa 1, lo carico + elseif EMT.HEAD == 'H1' or EMT.HEAD == 'H3' then + -- se sega a catena, imposto subito angolo scelto per asse virtuale A + if EMT.HEAD == 'H3' then + -- recupero la lavorazione successiva + local NextMchId + if EMT.MCHID then + NextMchId = EgtGetNextActiveOperation( EMT.MCHID) + else + NextMchId = EgtGetFirstActiveOperation() + end + if EgtGetOperationType( NextMchId) == MCH_OY.DISP then + NextMchId = EgtGetNextActiveOperation( NextMchId) + end + EgtSetCurrMachining( NextMchId) + -- leggo e imposto il valore di A1 + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + local CSawPosA = EgtGetVal( sVal, 'A1', 'd') or 0 + EgtSetAxisPos( 'A1', CSawPosA) + EmtModifyAxisHome( 'A1', CSawPosA) + EgtSetAxisPos( 'C1', GetChainSawCHomeFromVirtualAxis( CSawPosA)) + end + -- breve pausa + EgtPause( 100) + EgtOutText( '') + EMT.TOOL_1 = EMT.TOOL + EMT.TCPOS_1 = EMT.TCPOS + -- lo nascondo sul portautensili + ShowToolInTcPos( EMT.TCPOS, false) + end + -- se attivo Vmill + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + -- se attivo Collision Check + EMT.SAFEDIST = COLL_SAFE_DIST + if EMT.COLLOBJ then + local nInd = EgtIf( EMT.HEAD ~= 'H2', 1001, 1011) + AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd) + AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd + 1) + for i, Coll in ipairs( EMT.COLLOBJ) do + EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3) + end + end +end + +--------------------------------------------------------------------- +function OnSimulToolDeselect() + -- Step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + local RapSimRotStep = RapSimStep / 10 + local CollSimRotStep = min( RapSimRotStep, 5) + -- porto la testa in home + if EMT.HEAD == 'H2' then + SimulMoveAxes( 'X2', MinX2, RapSimStep, 'C2', EgtGetAxisHomePos( 'C2'), CollSimRotStep, 'B2', EgtGetAxisHomePos( 'B2'), CollSimRotStep) + elseif EMT.NEXTHEAD == 'H2' then + local ParkX1 = EgtIf( EMT.HEAD == 'H3', ( MinX1 + MaxX1) / 2, MaxX1) + SimulMoveAxes( 'X1', ParkX1, RapSimStep, 'C1', EgtGetAxisHomePos( 'C1'), CollSimRotStep, 'B1', EgtGetAxisHomePos( 'B1'), CollSimRotStep) + end + -- se testa attuale è sega a catena devo depositarla + if EMT.HEAD == 'H3' then + ShowToolInTcPos( EMT.TCPOS_1, true) + EgtUnloadTool( 'H3', 1) + EMT.TOOL_1 = nil + EMT.TCPOS_1 = nil + end + -- deposito utensile se non lama su sua testa o foratori lunghi + if EMT.NEXTHEAD ~= 'H2' and EMT.NEXTHEAD ~= 'H5' and EMT.NEXTHEAD ~= 'H6' then + if EMT.NEXTTOOL ~= EMT.TOOL_1 then + EgtOutText( 'Tool change in progress...') + -- simulo movimento + SimulMoveAxes( 'B1', 0, CollSimRotStep, 'C1', 0, CollSimRotStep) + SimulMoveAxis( 'X1', MinX1, RapSimStep) + -- breve pausa + EgtPause( 100) + ShowToolInTcPos( EMT.TCPOS_1, true) + -- se segue sega a catena + if EMT.NEXTHEAD == 'H3' then + -- nascondo l'utensile corrente + EgtSetStatus( EgtGetHeadId( 'H1'), GDB_ST.OFF) + -- eseguo movimenti opportuni + SimulMoveAxis( 'X1', ( MinX1 + MaxX1) / 2, RapSimStep) + SimulMoveAxes( 'B1', 0, CollSimRotStep, 'C1', 90, CollSimRotStep) + end + else + EMT.TOOL_1 = nil + EMT.TCPOS_1 = nil + end + end +end + +--------------------------------------------------------------------- +function OnSimulMachiningStart() + -- recupero alcuni dati della lavorazione + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + EMT.VMRS = false + -- recupero CUTID e TASKID della feature lavorata + local vId = EgtGetMachiningGeometry() + if vId and #vId > 0 and #vId[1] > 0 then + local nPartId = EgtGetParent( EgtGetParent( vId[1][1]) or GDB_ID.NULL) + EMT.CUTID = EgtGetInfo( nPartId or GDB_ID.NULL, 'CUTID', 'i') or 0 + EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ; + else + EMT.CUTID = 0 + EMT.TASKID = 0 + end + -- eventuale pausa per rimozione sfridi + if EMT.SCRAPFIRST then + if ( EMT.HEAD == 'H3' and string.sub( EMT.MCHNAME, 1, 5) == 'Csaw_') or EgtExistsInfo( EMT.MCHID, 'MOVE_AFTER') then + EMT.SCRAPFIRST = false + EgtOutText( 'Pause for Scrap Remove') + ParkForScrapRemove() + ExecScrapRemove() + EgtPause( 500) + EgtOutText( '') + end + end + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true +end + +--------------------------------------------------------------------- +function OnSimulMachiningEnd() + if EMT.UNLOADING or EMT.FALL then + EMT.UNLOADING = false + EMT.FALL = false + end +end + +--------------------------------------------------------------------- +--function OnSimulPathStart() +--end + +--------------------------------------------------------------------- +function OnSimulPathEnd() + -- se attivo VMILL, lavorazione ed è richiesto di eliminare gli sfridi + if EMT.VMILL and not EMT.OPEISDISP and EMT.VMRS then + EgtOutLog( 'OnSimulPathEnd', 5) + local nPart = EgtVolZmapPartCount( EMT.VMILL) + if nPart > 1 then + -- ricerca del pezzo con massimo volume + local nPartMax = 0 + local dVolMax = 0 + for i = 1, nPart do + local dVol = EgtVolZmapPartVolume( EMT.VMILL, i - 1) + if dVol > dVolMax then + dVolMax = dVol + nPartMax = i + end + end + -- eliminazione di tutti i pezzi piccoli + for i = nPart, 1, -1 do + if i ~= nPartMax then + local b3Vmill = EgtVolZmapGetPartBBoxGlob( EMT.VMILL, i - 1, GDB_BB.STANDARD) + if b3Vmill:getDimX() < 1200 then + EgtRemoveVolZmapPart( EMT.VMILL, i - 1) + end + end + end + -- aggiorno visualizzazione + EgtDraw() + end + end +end + +--------------------------------------------------------------------- +function OnSimulPathStartAux() + --EgtOutLog( 'OnSimulPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + EgtOutLog( 'OnSimulPathStartAux', 5) + -- eseguo il comando + --ExecAuxCmd( EMT.AUX) +end + +--------------------------------------------------------------------- +function OnSimulPathEndAux() + --EgtOutLog( 'OnSimulPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + EgtOutLog( 'OnSimulPathEndAux', 5) + -- eseguo il comando + --ExecAuxCmd( EMT.AUX) +end + +--------------------------------------------------------------------- +function OnSimulMoveStart() + -- se posizionamento prima di lavorazione con foratore orizzontale + if EMT.MOVE == 0 and EMT.FLAG == 2 and ( EMT.HEAD == 'H5' or EMT.HEAD == 'H6') then + -- step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + -- porto gli assi Y e Z3 alla posizione finale + if EMT.HEAD == 'H5' then + SimulMoveAxes( 'Y', EMT.L1, RapSimStep, 'Z3', EMT.L3, RapSimStep) + else + SimulMoveAxes( 'Y', EMT.L1, RapSimStep, 'Z4', EMT.L3, RapSimStep) + end + end +end + +--------------------------------------------------------------------- +function OnSimulMoveEnd() + -- se Zmax dopo fine lavorazione con foratore orizzontale + if EMT.MOVE == 0 and EMT.FLAG == 3 and ( EMT.HEAD == 'H5' or EMT.HEAD == 'H6') then + -- step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + if EMT.HEAD == 'H5' then + -- porto l'asse X3 in home + SimulMoveAxis( 'X3', HomeX3, RapSimStep) + else + -- porto l'asse X4 in home + SimulMoveAxis( 'X4', HomeX4, RapSimStep) + end + end +end + +--------------------------------------------------------------------- +function OnSimulCollision() + -- se prima collisione della lavorazione, la segnalo + if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then + local Class = '' + if EMT.SIMCOBIND == 1001 or EMT.SIMCOBIND == 1011 then + Class = 'T_'..EMT.HEAD + elseif EMT.SIMCOBIND == 1002 or EMT.SIMCOBIND == 1012 then + Class = 'TH_'..EMT.HEAD + else + Class = EMT.COLLOBJ[EMT.SIMCOBIND].Cl + end + -- se foratura verticale ammetto discesa nel piano fino a 15 mm + if EMT.TOOLTYPE == MCH_TY.DRILL_STD and abs( EgtGetAxisPos( 'B1')) < 60.1 then + local PosZ = EgtGetAxisPos( 'Z1') + MillOffs - ( MillOffs + EMT.TOOLTOTLEN) * EMT.TDIR[3] + local DownZ = PosZ - DeltaTabZ + if DownZ > -15 then + EgtOutLog( 'Top Drill down table '..EgtNumToString( DownZ, 1), 1) + return + end + end + table.insert( EMT.COLLIDE, { Mc = EMT.MCHNAME, Cl = Class, Vm = EMT.SIMVMID}) + EMT.LAST_MCHNAME_COLLIDE = EMT.MCHNAME + EMT.ERR = 11 + local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Class='..Class..'; VMill='..EMT.SIMVMID + EmtSetLastError( 1221, sErr, true) + EgtOutLog( 'Collision : ' .. sErr, 1) + end +end + +--------------------------------------------------------------------- +function ParkForScrapRemove() + -- Step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + -- Quota di parcheggio + local b3Raw = EgtGetRawPartBBox( EgtGetFirstRawPart() or GDB_ID.NULL) + local ParkY = min( -( b3Raw:getMin():getX() - 2000), -MinY) + --Eseguo + SimulMoveAxis( 'Z1', EgtGetAxisHomePos( 'Z1'), RapSimStep) + SimulMoveAxis( 'Y', ParkY, RapSimStep) +end + +--------------------------------------------------------------------- +function ExecScrapRemove() + -- Se non c'è virtual milling attivo, esco + if not EMT.VMILL then return end + -- Se non ci sono almeno due parti nel virtual milling, esco + local nVmPart = EgtVolZmapPartCount( EMT.VMILL) + if nVmPart < 2 then return end + -- Recupero box e area dei pezzi + local vPart = {} + local nPartId = EgtGetFirstPartInRawPart( EgtGetFirstRawPart() or GDB_ID.NULL) + while nPartId do + -- box e area + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + local dPartArea = b3Part:getDimX() * b3Part:getDimY() + -- box espanso + local b3PartExp = BBox3d( b3Part) + b3PartExp:Add( b3PartExp:getMin() - Vector3d( 10, 10, 0)) + b3PartExp:Add( b3PartExp:getMax() + Vector3d( 10, 10, 0)) + -- salvo i dati + table.insert( vPart, { Box = b3Part, BoxExp = b3PartExp, Area = dPartArea}) + -- passo al successivo + nPartId = EgtGetNextPartInRawPart( nPartId) + end + -- Recupero box e area delle parti di Vmill + local vVmPart = {} + for i = 1, nVmPart do + -- recupero il box e calcolo l'area della parte come Vmill + local b3VmPart = EgtVolZmapGetPartBBoxGlob( EMT.VMILL, i - 1, GDB_BB.STANDARD) + local dVmPartArea = EgtVolZmapPartVolume( EMT.VMILL, i - 1) / b3VmPart:getDimZ() + -- box espanso + local b3VmPartExp = BBox3d( b3VmPart) + b3VmPartExp:Add( b3VmPart:getMin() - Vector3d( 100, 100, 0)) + b3VmPartExp:Add( b3VmPart:getMax() + Vector3d( 100, 100, 0)) + -- salvo i dati + table.insert( vVmPart, { Box = b3VmPart, BoxExp = b3VmPartExp, Area = dVmPartArea}) + end + -- Tengo solo le parti del Vmill che contengono almeno un box di un pezzo o che interferiscono e sono abbastanza grandi + local nValidCnt = 0 + for i = #vVmPart, 1, -1 do + -- verifiche per parte da eliminare + local bToRemove = true + -- se area abbastanza grande, allora da verificare + if vVmPart[i].Area > 1e4 then + -- verifico se sono sicuramente valide (i due box si equivalgono entro la tolleranza) + for j = 1, #vPart do + if EnclosesXY( vVmPart[i].BoxExp, vPart[j].Box) and EnclosesXY( vPart[j].BoxExp, vVmPart[i].Box) then + bToRemove = false + vVmPart[i].Part = j + nValidCnt = nValidCnt + 1 + break + end + end + -- verifico se sono molto probabilmente valide + for j = 1, #vPart do + if bToRemove and ( OverlapsXY( vVmPart[i].Box, vPart[j].Box) and vVmPart[i].Area > 0.49 * vPart[j].Area) then + bToRemove = false + break + end + end + end + -- se richiesta eliminazione, la eseguo + if bToRemove then + EgtRemoveVolZmapPart( EMT.VMILL, i - 1) + table.remove( vVmPart, i) + end + end + -- Se il numero delle parti sicuramente valide uguaglia il numero dei pezzi, elimino le altre ed ho finito + if nValidCnt == #vPart then + for i = #vVmPart, 1, -1 do + if not vVmPart[i].Part then + EgtRemoveVolZmapPart( EMT.VMILL, i - 1) + table.remove( vVmPart, i) + end + end + return + end + -- Calcolo punti interni alle parti di Vmill non già dichiarate valide + for i = 1, #vVmPart do + if not vVmPart[i].Part then + local vtDir = VectorFromRotated( X_AX(), Z_AX(), -15.0) + local ptP = vVmPart[i].Box:getCenter() - vtDir * ( vVmPart[i].Box:getRadius() + 10) + local bOk, vIntType, vIntDist = EgtLineVolZmapInters( ptP, vtDir, EMT.VMILL, GDB_RT.GLOB) + if bOk then + for j = 1, #vIntType do + -- se la corrente entra ed esiste la successiva che esce + if vIntType[j] == GDB_SLT.IN and j + 1 <= #vIntType and vIntType[j + 1] == GDB_SLT.OUT then + local ptC = ptP + vtDir * (( vIntDist[j] + vIntDist[j + 1]) / 2) + local nPart = EgtVolZmapGetPartMinDist( EMT.VMILL, ptC, GDB_RT.GLOB) + if nPart == i - 1 then + if not vVmPart[i].Cen then + vVmPart[i].Cen = ptC + elseif not vVmPart[i].Cen2 then + vVmPart[i].Cen2 = ptC + else + vVmPart[i].Cen3 = ptC + break + end + end + end + end + end + end + end + -- Verifico le parti di Vmill non già dichiarate valide + for i = #vVmPart, 1, -1 do + if not vVmPart[i].Part then + local bToRemove = true + if vVmPart[i].Cen then + for j = 1, #vPart do + if EnclosesPointXY( vPart[j].Box, vVmPart[i].Cen) then + bToRemove = false + break + elseif vVmPart[i].Cen2 and EnclosesPointXY( vPart[j].Box, vVmPart[i].Cen2) then + bToRemove = false + break + elseif vVmPart[i].Cen3 and EnclosesPointXY( vPart[j].Box, vVmPart[i].Cen3) then + bToRemove = false + break + end + end + for k = 1, #vVmPart do + if k ~= i then + local vExpBox = BBox3d( vVmPart[k].Box) + -- lo espando in XY per sicurezza + vExpBox:Add( vExpBox:getMin() - Vector3d( 100, 100, 0)) + vExpBox:Add( vExpBox:getMax() + Vector3d( 100, 100, 0)) + -- verifico contenimento + if EnclosesXY( vExpBox, vVmPart[i].Box) then + bToRemove = true + break + end + end + end + end + -- se richiesta eliminazione, la eseguo + if bToRemove then + EgtRemoveVolZmapPart( EMT.VMILL, i - 1) + table.remove( vVmPart, i) + end + end + end +end + +--------------------------------------------------------------------- +function ExecUnloading() + if EMT.VMILL then + -- gruppo dei Vmill + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + -- creo un nuovo layer e vi inserisco il nuovo pezzo + local nLayId = EgtGroup( nVmGrpId, EgtGetGlobFrame( EMT.VMILL)) + EgtRelocate( EMT.VMILL, nLayId) + EgtSetLevel( EMT.VMILL, GDB_LV.USER) + -- aggiungo gli spigoli + local nFirstId, nCount = EgtVolZmapGetEdges( EMT.VMILL, nLayId) + if nFirstId then + for nId = nFirstId, nFirstId + nCount - 1 do + EgtSetColor( nId, Color3d( 96, 96, 96)) + end + end + -- rilascio Vmill + EMT.VMILL = nil + -- aggiorno la visualizzazione + EgtDraw() + -- se finito + if EMT.PHASE == EgtGetPhaseCount() then + -- se impostato di salvare i Vmill, lo faccio + local sMachIni = EgtGetCurrMachineDir() .. '\\' .. EgtGetCurrMachineName() .. '.ini' + if EgtGetStringFromIni( 'VMill', 'Save', '', sMachIni) == '1' then + local sFile = EgtGetCurrFilePath() + if sFile then + local sDir, sName, sExt = EgtSplitPath( sFile) + if sExt and sExt:lower() == ".nge" then + sName = sName .. '_VM_' .. EgtGetMachGroupName( EgtGetCurrMachGroup()) + EgtSetLevel( nVmGrpId, GDB_LV.USER) + EgtSaveObjToFile( nVmGrpId, sDir .. sName .. '.Nge') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + end + end + end + end +end + +--------------------------------------------------------------------- +function ShowToolInTcPos( sTcPos, bShow) + -- recupero il gruppo dell'utensile + local TcExitId = EgtGetFirstNameInGroup( EgtGetTcPosId( sTcPos or '') or GDB_ID.NULL, 'T1') + if not TcExitId then return end + -- imposto lo stato di visualizzazione + EgtSetStatus( TcExitId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF)) +end + +--------------------------------------------------------------------- +function GetToolTcPos( sTool) + -- salvo stato iniziale + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- recupero la posizione di cambio utensile dell'utensile indicato + local sTcPos + if EgtTdbSetCurrTool( sTool) then + sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + end + -- ripristino stato iniziale + if CurrTool then + EgtTdbSetCurrTool( CurrTool) + else + EgtTdbSetCurrTool( '') + end + -- restituisco risultato + return sTcPos +end + + +--------------------------------------------------------------------- +-- *** ESTIMATION T&L *** +--------------------------------------------------------------------- +local RAPID_X_FEED = 75000 -- mm/min +local RAPID_Y_FEED = 100000 -- mm/min +local RAPID_Z_FEED = 50000 -- mm/min +local RAPID_C_FEED = 15000 -- deg/min +local RAPID_B_FEED = 15000 -- deg/min +local RAPID_MIN_T = 0.1 -- s +local LOAD_T = 2 -- s +local CHAR_ONE_MOVE_T = 1 -- s +local ROTATION_T = 40 -- s +local SPLIT_T = 6 -- s +local UNLOAD_T = 4 -- s +local FALL_T = 2 -- s + +--------------------------------------------------------------------- +function OnEstimStart() + EMT.INCHES = not EgtUiUnitsAreMM() -- unità di misura mm/inches +end + +--------------------------------------------------------------------- +function OnEstimEnd() +end + +--------------------------------------------------------------------- +function OnEstimProgramStart() + -- imposto inizio movimenti da Home + EMT.L1 = EgtGetAxisHomePos( 'Y') + EMT.L2 = EgtGetAxisHomePos( 'X1') + EMT.L3 = EgtGetAxisHomePos( 'Z1') + EMT.R1 = EgtGetAxisHomePos( 'C1') + EMT.R2 = EgtGetAxisHomePos( 'B1') + -- aggiorno valori come precedenti + EmtUpdatePrev() + -- totalizzatori tempi e lunghezze + EMT.TOTCUTLEN = 0 + EMT.TOTCUTTIME = 0 + EMT.TOTEXTLEN = 0 + EMT.TOTEXTTIME = 0 + -- variabile per lunghezza taglio utensili + EMT.TOOLCUTLEN = {} + -- intestazioni + EmtTleStart( EMT.INFO) +end + +--------------------------------------------------------------------- +function OnEstimProgramEnd() + -- stampa dei totali delle lavorazioni + EmtTleAddTotal( EmtSecToHMS( EMT.TOTCUTTIME + EMT.TOTEXTTIME), EmtLenToMF( EMT.TOTCUTLEN)) + -- stampa dei totali degli utensili + for i = 1, #EMT.TOOLCUTLEN do + local TCL = EMT.TOOLCUTLEN[i] + EmtTleAddTool( TCL.Name, EmtLenToMF( TCL.Len)) + end + -- completo il file + local _, _, sExt = EgtSplitPath( EMT.FILE) + EmtTleEnd( sExt:sub( 2)) + -- salvo i dati principali nel progetto + EgtSetInfo( EgtGetCurrMachGroup(), 'Ttot', EgtNumToString( EMT.TOTCUTTIME + EMT.TOTEXTTIME, 0)) + EgtSetInfo( EgtGetCurrMachGroup(), 'Ltot', EgtNumToString( EMT.TOTCUTLEN, 0)) +end + +--------------------------------------------------------------------- +function OnEstimDispositionStart() + -- inizio disposizione + EMT.OPEISDISP = true + -- sulla prima fase dichiaro carico barra + if EMT.PHASE == 1 then + EMT.LOAD = true + else + EMT.LOAD = false + end +end + +--------------------------------------------------------------------- +function OnEstimDispositionEnd() + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end + -- termine disposizione + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnEstimToolSelect() + -- reset indice utensile in tabella lunghezze + EMT.TCLIND = 0 + -- verifico che l'utensile sia definito + if #EMT.TOOL == 0 then return end + -- cerco l'utensile nella tabella + for i = 1, #EMT.TOOLCUTLEN do + if EMT.TOOLCUTLEN[i].Name == EMT.TOOL then + EMT.TCLIND = i + break + end + end + -- se non trovato, lo aggiungo + if EMT.TCLIND == 0 then + table.insert( EMT.TOOLCUTLEN, { Name = EMT.TOOL, Len = 0}) + EMT.TCLIND = #EMT.TOOLCUTLEN + end +end + +--------------------------------------------------------------------- +function OnEstimToolDeselect() +end + +--------------------------------------------------------------------- +function OnEstimMachiningStart() + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EgtOutLog( 'Mach : ' .. EMT.MCHNAME, 5) + -- reset contatori di lavorazione + EMT.MCHCUTLEN = 0 + EMT.MCHCUTTIME = 0 + EMT.MCHEXTLEN = 0 + EMT.MCHEXTTIME = 0 +end + +--------------------------------------------------------------------- +function OnEstimMachiningEnd() + -- nel caso di foratura devo dimezzare la lunghezza di taglio perchè comprende anche l'uscita + if EMT.MCHTYPE == MCH_MY.DRILLING then + EMT.MCHCUTLEN = EMT.MCHCUTLEN / 2 + end + local sName = EgtGetName( EMT.MCHID) + EmtTleAddMachining( sName, EmtSecToHMS( EMT.MCHCUTTIME + EMT.MCHEXTTIME), EmtLenToMF( EMT.MCHCUTLEN), EMT.TOOL) + -- aggiorno totali e utensili + EMT.TOTCUTLEN = EMT.TOTCUTLEN + EMT.MCHCUTLEN + EMT.TOTCUTTIME = EMT.TOTCUTTIME + EMT.MCHCUTTIME + EMT.TOTEXTLEN = EMT.TOTEXTLEN + EMT.MCHEXTLEN + EMT.TOTEXTTIME = EMT.TOTEXTTIME + EMT.MCHEXTTIME + EMT.TOOLCUTLEN[EMT.TCLIND].Len = EMT.TOOLCUTLEN[EMT.TCLIND].Len + EMT.MCHCUTLEN + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end +end + +--------------------------------------------------------------------- +function OnEstimPathStart() + EMT.AUXTYPE = nil + EMT.MCHMOVEFIRST = true +end + +--------------------------------------------------------------------- +function OnEstimPathEnd() + EMT.AUXTYPE = nil +end + +--------------------------------------------------------------------- +function OnEstimPathStartAux() + -- se richiesto, preparo il carico barra + if EMT.LOAD then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Loading', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.LOAD = false + end + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = ROTATION_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Rotation', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.POSTROT = false + end + -- altrimenti, spostamento carrelli + else + if EMT.AUXTOT > 2 and EMT.AUXIND == EMT.AUXTOT then + local dTime = ( EMT.AUXTOT - 2) * CHAR_ONE_MOVE_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Charriots move', EmtSecToHMS( dTime), ' - ', ' - ') + end + end +end + +--------------------------------------------------------------------- +function OnEstimPathEndAux() + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.AUXTYPE = 'F' + else + EMT.AUXTYPE = 'P' + end + end + end + -- per lo scarico della rimanenza + if EMT.AUXTYPE == 'R' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Remnant unloading' + EMT.TLE_TIME = dTime + end + -- per lo split + elseif EMT.AUXTYPE == 'S' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = SPLIT_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Splitting' + EMT.TLE_TIME = dTime + end + -- per lo scarico + elseif EMT.AUXTYPE == 'U' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Unloading' + EMT.TLE_TIME = dTime + end + -- per lo scarico a caduta + elseif EMT.AUXTYPE == 'F' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = FALL_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Fall' + EMT.TLE_TIME = dTime + end + -- per la pre-rotazione + elseif EMT.AUXTYPE == 'P' then + ; -- calcolato come parte della rotazione + end +end + +--------------------------------------------------------------------- +function OnEstimRapid() + -- dati movimento + local dL1 = EMT.L1 - ( EMT.L1p or 0) + local dL2 = EMT.L2 - ( EMT.L2p or 0) + local dL3 = EMT.L3 - ( EMT.L3p or 0) + local dR1 = 0 + if EMT.R1 and EMT.R1p then dR1 = EMT.R1 - EMT.R1p end + local dR2 = 0 + if EMT.R2 and EMT.R2p then dR2 = EMT.R2 - EMT.R2p end + -- se primo posizionamento della lavorazione il movimento di L1 è già conteggiato in quello dei carrelli + if EMT.MCHMOVEFIRST then + EMT.MCHMOVEFIRST = false + dL1 = 0 + end + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHEXTLEN = EMT.MCHEXTLEN + dLen + -- calcolo tempo + local dTime = RAPID_MIN_T + local dT1 = abs( dL1) / RAPID_X_FEED * 60 + if dT1 > dTime then dTime = dT1 end + local dT2 = abs( dL2) / RAPID_Y_FEED * 60 + if dT2 > dTime then dTime = dT2 end + local dT3 = abs( dL3) / RAPID_Z_FEED * 60 + if dT3 > dTime then dTime = dT3 end + local dT4 = abs( dR1) / RAPID_C_FEED * 60 + if dT4 > dTime then dTime = dT4 end + local dT5 = abs( dR2) / RAPID_B_FEED * 60 + if dT5 > dTime then dTime = dT5 end + EMT.MCHEXTTIME = EMT.MCHEXTTIME + dTime + EgtOutLog( string.format( ' G0 Len=%.0f Rot=%.0f° Time=%.2f', dLen, abs( dR1) + abs( dR2), dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimLinear() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G1 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimArc() + -- dati movimento + local dLxy = EMT.RR * abs( EMT.AC) * pi / 180 + local dLz = abs( ( Point3d( EMT.L1, EMT.L2, EMT.L3) - Point3d( EMT.L1p, EMT.L2p, EMT.L3p)) * Vector3d( EMT.EXTR)) + -- calcolo lunghezza + local dLen = sqrt( dLxy * dLxy + dLz * dLz) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G2 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +-- *** GENERAL *** +--------------------------------------------------------------------- +function FindFirstToolOnHead( sH1) + -- salvo stato iniziale + local CurrMachId = EgtGetCurrMachining() + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- cerco lavorazione con utensile su testa indicata + local sTool, nTlen + local OpId = EgtGetFirstActiveOperation() + while OpId do + local nType = EgtGetOperationType( OpId) + if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then + if EgtSetCurrMachining( OpId) then + local sTest = EgtGetMachiningParam( MCH_MP.TOOL) + if EgtTdbSetCurrTool( sTest) then + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if sHead and ( sHead == sH1) then + sTool = sTest + nTlen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + break + end + end + end + end + OpId = EgtGetNextActiveOperation( OpId) + end + -- ripristino stato iniziale + if CurrMachId then + EgtSetCurrMachining( CurrMachId) + else + EgtResetCurrMachining() + end + if CurrTool then + EgtTdbSetCurrTool( CurrTool) + else + EgtTdbSetCurrTool( '') + end + -- restituisco risultato + return sTool, nTlen +end + +--------------------------------------------------------------------- +-- *** END GENERAL *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-WALL.mlse b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-WALL.mlse new file mode 100644 index 0000000..51a7fc4 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Essetre-WALL.mlse @@ -0,0 +1,67 @@ +-- Special Operations macchina Essetre-WALL by EgalTech s.r.l. 2022/02/03 + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +EgtOutLog ( '** Essetre-WALL.mlse '..PP_VER..' **', 1) + +--------------------------------------------------------------------- +function OnSpecialMoveZup() + + -- Inizializzazioni + EMC.MODIF = false + EMC.ERR = 1 + + -- Se fresa + if EMC.HEAD == 'H1' then + if EMC.L3 > -300 then + EMC.R1 = EgtGetAxisHomePos( 'C1') + EMC.R2 = EgtGetAxisHomePos( 'B1') + EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2) + EMC.MODIF = true + end + -- se altrimenti sega a catena + elseif EMC.HEAD == 'H3' then + local L3New = EMC.L3 + local R1New = EMC.R1 + local R2New = EMC.R2 + if EMC.L3 > -300 then + L3New = min( EMC.L3, EgtGetAxisHomePos( 'Z1')) + R1New = EgtGetAxisHomePos( 'C1') + R2New = EgtGetAxisHomePos( 'B1') + EMC.MODIF = true + end + if EMC.L2 > -1400 then + R1New = 0 + EMC.MODIF = true + elseif EMC.L2 < -4700 then + R1New = 180 + EMC.MODIF = true + end + if EMC.MODIF then + EMC.L3 = L3New + EMC.R1 = R1New + EMC.R2 = R2New + EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2, EMC.R3) + end + -- se altrimenti lama + elseif EMC.HEAD == 'H2' then + if EMC.L3 > -200 then + EMC.R1 = EgtGetAxisHomePos( 'C2') + EMC.R2 = EgtGetAxisHomePos( 'B2') + EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2) + EMC.MODIF = true + end + -- se foratore orizzontale + elseif EMC.HEAD == 'H5' then + ; + -- se foratore orizzontale opposto + elseif EMC.HEAD == 'H6' then + ; + -- altrimenti errore + else + error( "Unknown Head") + end + EMC.ERR = 0 +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Machinings/Machinings.data b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Machinings/Machinings.data new file mode 100644 index 0000000..d4125d7 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Machinings/Machinings.data differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Machinings/Machinings.data.bak b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Machinings/Machinings.data.bak new file mode 100644 index 0000000..83f3704 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Machinings/Machinings.data.bak differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Messages/Eng.txt b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Messages/Eng.txt new file mode 100644 index 0000000..852a0fe --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Messages/Eng.txt @@ -0,0 +1,351 @@ +// English machine message file 2022/01/17 + +[MDI] +1=Take tool n° 1 +2=Take tool n° 2 +3=Take tool n° 3 +4=Take tool n° 4 +5=Take tool n° 5 +6=Take tool n° 6 +7=Take tool n° 7 +8=Take tool n° 8 +9=Take tool n° 9 +10=Take tool n° 10 +11=Take tool n° 11 +12=Take tool n° 12 +13=Take tool n° 13 +14=Take tool n° 14 +15=Take tool n° 15 +16=Take tool n° 16 +17=Take tool n° 17 +18=Take tool n° 18 +19=Head whitout tool +20=Take the Chainsaw +21=Activate tool magazine +22=Tool tool loader n°1 Forwards +23=Tool tool loader n°1 Backwards +24=Tool tool loader n°2 Forwards +25=Tool tool loader n°2 Backwards +26=Tool tool loader Chainsaw Forwards +27=Tool tool loader Chainsaw Backwards +28=Front zero reference ascent +29=Front zero reference descent +30=Lateral zero roller ascent +31=Lateral zero roller descent +32=Ability clockwise rotation right driller motor +33=Ability counterclockwise rotation right driller motor +34=Ability clockwise rotation left driller motor +35=Ability counterclockwise rotation left driller motor +36=Stop rotation of drilling spindles +37=Manual tool number assignment in the 5-axis head (E80001=1; E80001=2; E80001=3;ETC...) + +[PLC] +1=Machine off +2=Out of stroke axes +3=UPS Anomaly +4=Low UPS battery +5=Drive inverter suction not Ok +6=Setpoint axes B and C not executed +7=Check oil lubrication aggregates chainsaw +8=Thermal motors portal panel +9=Thermal motors cabinet on the ground +10=PROGRAM TRANSFER MESSAGE IN PROGRESS FROM SUPERVISOR +11=Suction cap out of position of Pom or not in position VERIFY +12=Minimum level grease +13=Defect in the lubrication system axes check grease level +14=Absence of lubricated compressed air +15=Overtemperature left cabinet +16=Overtemperature right cabinet +17=Cooler not ok +18=Front Zero reference not down +19=Lateral Zero rollers not down +20=Non-low rollers +21=Right drill not back +22=Left driller not back +23=Sovratemperatura armadio rulliere +24=X1 axis drive in alarm +25=Y1 axis drive in alarm +26=Z1 axis drive in alarm +27=B1 axis drive in alarm +28=C1 axis drive in alarm +29=X2 axis drive in alarm +30=Y2 axis drive in alarm +31=Z2 axis drive in alarm +32=X1 axis drive not enabled +33=Y1 axis drive not enabled +34=Z1 axis drive not enabled +35=B1 axis drive not enabled +36=C1 axis drive not enabled +37=X2 axis drive not enabled +38=Y2 axis drive not enabled +39=Z2 axis drive not enabled +40=B2 axis drive in alarm +41=B2 axis drive not enabled +42=C2 axis drive in alarm +43=C2 axis drive not enabled +44=Piano ribaltamento parete Whall FresaGraffe non a riposo !!! +45=*** MAINTENANCE CE *** +46=Left drilling tailstock further than the drill bit +47=Head position not Ok for side warehouse exit +48=Head position not Ok for chainsaw tool loader exit +49=Head position not Ok for output T201 +50=Head position not Ok for output T202 +51=Pre-alarm workbench safety zones +52=Alarm of safety zones workbench +53=Pre-alarm perimeter security zones +54=Right drilling axes locked with Z mill or Z saw blade low +55=Left drilling axes locked with Z mill or Z saw blade low +56=Problema su EV o sensore rullo 01 banco +57=Problema su EV o sensore rullo 02 banco +58=Problema su EV o sensore rullo 03 banco +59=Problema su EV o sensore rullo 04 banco +60=Problema su EV o sensore rullo 05 banco +61=Problema su EV o sensore rullo 06 banco +62=Problema su EV o sensore rullo 07 banco +63=Problema su EV o sensore rullo 08 banco +64=Problema su EV o sensore rullo 09 banco +65=Problema su EV o sensore rullo 10 banco +66=Problema su EV o sensore rullo 11 banco +67=Problema su EV o sensore rullo 12 banco +68=Problema su EV o sensore rullo 13 banco +69=Problema su EV o sensore rullo 14 banco +70=Problema su EV o sensore rullo 15 banco +71=Problema su EV o sensore rullo 16 banco +72=Problema su EV o sensore rullo 17 banco +73=Problema su EV o sensore rullo 18 banco +74=Problema su EV o sensore rullo 19 banco +75=Problema su EV o sensore rullo 20 banco +76=Problema su EV o sensore rullo 21 banco +77=Problema su EV o sensore rullo 22 banco +78=Problema su EV o sensore rullo 23 banco +79=Problema su EV o sensore rullo 24 banco +80=Anticollisione Portali Whall intervenuta !!! +81=Side tool loader not backwards program M90 and then M195 +82=Side tool loader not forward +83=Side tool loader not backwards +84=Chainsaw tool loader not backwards program M90 and then M195 +85=Chainsaw tool loader not forward +86=Chainsaw tool loader not backwards +87=T10-T18 tool loader not backwards program M90 and then M199T2 +88=T10-T18 tool loader not forward +89=T10-T18 tool loader not backwards +90=T1-T9 tool loader not forward +91=T1-T9 tool loader not backwards +92=Sensori contemporanei avanti-indietro cambio laterale +93=Sensori contemporanei avanti-indietro cambio Cu catena +94=T1-T9 tool loader not backwards program M90 and then M199T1 +95=Tuning inserted allowed only manual movements +96=Absence of dry compressed air +97=Remote control key is in manual +98= +99= +100= +101=Rotazione inverter fresa non Ok (Fcinv0=1) +102=Rotazione inverter lama non Ok (Fcinv0=2) +103= +104=Contemporary sensors tool loader T10-T18 forward-backward +105=Rotation Forbidden head without tools: check +106= +107=Contemporary sensors tool loader T1-T9 forward-backward +108=Wait for power +109=Press reset to CNC +110=Unload piece from the end of the output roller conveyor and press reset button +111=Mill inverter malfunction +112=Blade inverter malfunction +113=Problema su EV o sensore protezione anteriore alta +114=Problema su EV o sensore protezione posteriore alta +115=Overtemperature brake resistors mill inverter +116=Saw blade motor overtemperature +117=Mill motor overtemperature +118=Flow switch mill not Ok +119=Saw blade flow switch not Ok +120=Overcurrent mill inverter +121=Overcurrent saw blade inverter +122=Overtemperature brake resistors inverter saw blade +123=Turn on the remote control! +124=Almost empty battery: replace it as soon as possible! +125=Low suction cups with active vacuum +126=Inverter roller malfunction 01 (bench) +127=Inverter roller malfunction 02 (bench) +128=Inverter roller malfunction 03 (bench) +129=Inverter roller malfunction 04 (bench) +130=Inverter roller malfunction 05 (bench) +131=Inverter roller malfunction 06 (bench) +132=Inverter roller malfunction 07 (bench) +133=Inverter roller malfunction 08 (bench) +134=Inverter roller malfunction 09 (bench) +135=Inverter roller malfunction 10 (bench) +136=Inverter roller malfunction 11 (bench) +137=Inverter roller malfunction 12 (bench) +138=Inverter roller malfunction 13 (bench) +139=Inverter roller malfunction 14 (bench) +140=Inverter roller malfunction 15 (bench) +141=Inverter roller malfunction 16 (bench) +142=Inverter roller malfunction 17 (bench) +143=Inverter roller malfunction 18 (bench) +144=Inverter roller malfunction 19 (bench) +145=Inverter roller malfunction 20 (bench) +146=Inverter roller malfunction 21 (bench) +147=Inverter roller malfunction 22 (bench) +148=Inverter roller malfunction 23 (bench) +149=Inverter roller malfunction 24 (bench) +150=Pre-alarm spindle temperature mill +151=Milling head tool locking defect +152=Saw blade head tool locking defect +153=Tool on head with E80001=0 +154=Tool on T2 with E80002=0 +155=Head tool unlock defect +156=Difetto sbloccaggio utensile 2 +157=The vacuum pump does not go under pressure +158=Milling motor temperature alarm +159=Piston unlocking cone not at rest +160=Collision suction cap suction !!! +161=Problem on EV or side reference sensor 1 +162=Problem on EV or side reference sensor 2 +163=Problem on EV or side reference sensor 3 +164=Problem on EV or side reference sensor 4 +165=Problem on EV or side reference sensor 5 +166=Problem on EV or right front reference sensor +167=Problem on EV or LEFT front reference sensor +168=References blocked because the machine is not in power +169=Bench rollers blocked because the machine is not in power +170=Bench rollers stopped because the machine is not in power +171=Output rollers stopped because the machine is not in power +172=Parking roller inverter malfunction +173=Inverter roller malfunction 1 output +174=Inverter roller malfunction 2 output +175=Inverter roller malfunction 3 output +176=Inverter roller malfunction 4 output +177=Inverter roller malfunction 5 output +178=Inverter roller malfunction 6 output +179=Bench rollers blocked because the heads are not on top +180=Bench rollers blocked because the guards are not open +200=Defect on one or more EtherCAT modules: restart the machine +201=Function Block Safety in error - input signal discrepancy +202=Safety module communication defect +203=Safety output defect +204=Service Mode ON +205= +206=Stapler not ok to check !!! +207=Staple drawer in exhaustion +208=Axes B-C blocked button Grater not closed +209=B-C axes locked Non-high stapler +210=Waiting open button for ascent-descent Stapler +211=Waiting for B-C axes in position for ascent-descent Stapler +212=Stapler not on top +213=Non-pressure stapling machine in the workpiece +214=Non-low stapler +215=Right drilling inverter malfunction +216=Left drilling inverter malfunction + +501= +502=COMMAND WAITING +503=UNLOAD TOOL FROM MOTOR T1 +504=UNLOAD TOOL FROM MOTOR T2 +505=WAITING FOR THE END OF TOOL CHANGE T1 +506=WAITING FOR THE END OF TOOL CHANGE T2 +507=TOOL UNLOADING ON THE RIGHT SIDE +508=TOOL UNLOADING ON THE LEFT SIDE +509=WAITING ENGINE T1 STOPPED +510=WAITING ENGINE T2 STOPPED +511=TOOL UNLOADING CHAIN +512=MORTISE TOOL UNLOAD +513=WAITING E30010=0 +514=TOOL LOADING ON THE RIGHT SIDE +515=TOOL LOADING ON THE LEFT SIDE +516=TOOL LOADING CHAINSAW +517=TOOL LOADING MORTISE +518=WAITING FOR THE END OF UNLOADING OF THE PIECE +519=PLACE THE BEAM +520=WAITING UNLOADING GROUP GR6 FREE +521=AUTOMATIC CLAMPS +522=P1 NEG +523=P1 POS +524=P4 NEG +525=P4 POS +526=WAITING CLAMP 1 OPENED +527=WAITING E81145=0 +528=WAITING CLAMP 4 OPENED +529=WAITING X1 OUTSIDE THE WORK AREA +530=WAITING X2 OUTSIDE THE WORK AREA +531=WAITING OPEN P17 X2+ +532=LOAD BEAM +533=WAITING END M201 +534=BACKWARDS PIECE +535=RELOAD BEAM +536=UNLOADING PIECE ON LUNG ENTRANCE +537=UNLOAD BEAM +538=UNLOAD PIECE +539=WAITING FOR POSITIVE U-AXIS LIMIT OPENING +540=WAITING POSITIVE LIMIT READING X2 +541=WAITING FOR THE PIECE TO RETREAT +542=WAITING FOR THE START OF UNLOADING WORKPIECE +543=WAITING FOR U-AXIS LIMITS TO OPEN +544=WAITING FOR THE OPENING OF THE X+ T1 AXIS LIMITS +545=WAITING FOR THE OPENING OF THE X+ T2 AXIS LIMITS +546=WAITING FOR Y-AXIS LIMITS TO OPEN +547=WAITING WRITE P17 X1+ +548=WAITING WRITE P17 X2- +549=PRESS START FOR WORK +550=WAITING FOR WRITING P17 Y+ AND Y- +551=WAITING UNLOADING GROUP GR5 FREE +552=WAITING E81107=1 +553=WAITING FOR AUTOMATIC CLAMPS TO BE DEACTIVATED +554=WAITING UNLOADING PIECE MANUALLY +555=WAITING FOR THE END OF BEAM LOADING +556=WAITING FOR THE END OF BEAM TIPPING +557=WAITING FOR THE UNLOADING OF THE PIECE ON THE INCOMING LUNG +558=WAITING E81202=0 +559=LONG WORKZONE PRESS START FOR CONTINUE +560=WAITING E81201=0 +561=WAITING E81165=0 +562=WAITING E81203=0 +563=WAITING UNLOADING BEAM MANUALLY +564=WAITING E10006=1 +565=WAITING FOR AUTOMATIC CLAMPS TO ACTIVATE +566=WAITING FOR THE END OF BEAM RELOADING +567=WAITING E81196=0 +568=AUTOMATIC CLAMPS OUT OF AXES + +[CNC] +900=INVALID TOOL NUMBER M6T +901=TOOL NUMBER LOADED NOT OK +902=INVALID MOTOR TOOL NUMBER E80001 +903=SENSOR SETPOINT B MILLING NOT OK +904=SENSOR SETPOINT C MILLING NOT OK +905=SENSOR SETPOINT B SAW BLADE NOT OK +906=SENSOR SETPOINT C SAW BLADE NOT OK +907=UNLOAD CHAINSAW MANUALLY +908=WORK WITH 2 BLADES NOT POSSIBLE B<>90 OR C<>0 OR 180 +909=DEFINE TOOL NUMBER ENGINE SAW BLADE EU +910=G124 X REQUIRED +911=G124 Y REQUIRED +912=G124 B REQUIRED +913=G124 C REQUIRED +914=libero +915=libero +916=DEFINE SPINDLE NUMBER ET.. (1=BLADE 2=MILL 3=RIGHT DRILLER 4=LEFT DRILLER) +917=UNLOADING MOTOR TOOL +918=G104X.. REQUIRED +919=G104Y.. REQUIRED +920=G104Z.. REQUIRED +921=G104ET.. NOT OK (MANDATORY SCREWDRIVER NUMBER ET0-ET1-ET2-ET3) +922=G104EF.. NOT OK (REQUIRED LAYER NUMBER) +923=SETPOINT V SENSOR NOT OK +924=OFFSET X SAW BLADE NOT ALIGNED WITH CADCAM +925=OFFSET Y SAW BLADE NOT ALIGNED WITH CADCAM +926=OFFSET Z SAW BLADE NOT ALIGNED WITH CADCAM +927=PIVOT Z SAW BLADE NOT ALIGNED WITH CADCAM +928=PIVOT C SAW BLADE NOT ALIGNED WITH CADCAM +929=OFFSET X MILL NOT ALIGNED WITH CADCAM +930=OFFSET Y MILL NOT ALIGNED WITH CADCAM +931=OFFSET Z MILL NOT ALIGNED WITH CADCAM +932=PIVOT Z MILL NOT ALIGNED WITH CADCAM +933=MANDATORY X-U-W-Z PROGRAMMING WITH G102EH.. NON-ZERO +934=OFFSET X RIGHT DRILLER NOT ALIGNED WITH CADCAM +935=OFFSET Y RIGHT DRILLER NOT ALIGNED WITH CADCAM +936=OFFSET Z RIGHT DRILLER NOT ALIGNED WITH CADCAM +937=OFFSET X LEFT DRILLER NOT ALIGNED WITH CADCAM +938=OFFSET Y LEFT DRILLER NOT ALIGNED WITH CADCAM +939=OFFSET Z LEFT DRILLER NOT ALIGNED WITH CADCAM + diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Messages/Ita.txt b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Messages/Ita.txt new file mode 100644 index 0000000..7667ecc --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Messages/Ita.txt @@ -0,0 +1,349 @@ +// File dei messaggi macchina Italiano 2022/01/17 +[MDI] +1=Prendi utensile n° 1 +2=Prendi utensile n° 2 +3=Prendi utensile n° 3 +4=Prendi utensile n° 4 +5=Prendi utensile n° 5 +6=Prendi utensile n° 6 +7=Prendi utensile n° 7 +8=Prendi utensile n° 8 +9=Prendi utensile n° 9 +10=Prendi utensile n° 10 +11=Prendi utensile n° 11 +12=Prendi utensile n° 12 +13=Prendi utensile n° 13 +14=Prendi utensile n° 14 +15=Prendi utensile n° 15 +16=Prendi utensile n° 16 +17=Prendi utensile n° 17 +18=Prendi utensile n° 18 +19=Scarica utensili +20=Prendi Elettrosega +21=Attiva magazzino utensili +22=Magazzino utensili n°1 avanti +23=Magazzino utensili n°1 indietro +24=Magazzino utensili n°2 avanti +25=Magazzino utensili n°2 indietro +26=Magazzino utensili Elettrosega avanti +27=Magazzino utensili Elettrosega indietro +28=Salita rulli zero frontale +29=Discesa rulli zero frontale +30=Salita rulli zero laterale +31=Discesa rulli zero laterale +32=Abilita rotazione oraria motore foratore destro +33=Abilita rotazione antioraria motore foratore destro +34=Abilita rotazione oraria motore foratore sinistro +35=Abilita rotazione antioraria motore foratore sinistro +36=Stop rotazione mandrini foratori +37=Assegnazione manuale numero utensile nella testa a 5 assi (E80001=1; E80001=2;E80001=3;ETC...) + +[PLC] +1=Macchina spenta +2=Assi in extracorsa +3=Anomalia UPS +4=Batteria UPS scarica +5=Drive inverter cuffia aspirazione non Ok +6=POM assi B e C non eseguita +7=Verificare olio lubrificazione aggregati catena +8=Termici motori quadro portale +9=Termici motori quadro a terra +10=MESSAGGIO DI TRASFERIMENTO PROGRAMMA IN CORSO DA SUPERVISORE +11=Cuffia aspirazione fuori posizione di Pom o non in posizione VERIFICARE +12=Minimo livello grasso +13=Difetto impianto lubrificazione assi verificare livello grasso +14=Manca aria compressa lubrificata +15=Sovratemperatura armadio sinistro +16=Sovratemperatura armadio destro +17=Refrigeratore non ok +18=Riferimento frontale non basso +19=Riferimenti laterali non bassi +20=Rulli non bassi +21=Foratore destro non indietro +22=Foratore sinistro non indietro +23=Sovratemperatura armadio rulliere +24=Azionamento asse X1 in allarme +25=Azionamento asse Y1 in allarme +26=Azionamento asse Z1 in allarme +27=Azionamento asse B1 in allarme +28=Azionamento asse C1 in allarme +29=Azionamento asse X2 in allarme +30=Azionamento asse Y2 in allarme +31=Azionamento asse Z2 in allarme +32=Azionamento asse X1 non abilitato +33=Azionamento asse Y1 non abilitato +34=Azionamento asse Z1 non abilitato +35=Azionamento asse B1 non abilitato +36=Azionamento asse C1 non abilitato +37=Azionamento asse X2 non abilitato +38=Azionamento asse Y2 non abilitato +39=Azionamento asse Z2 non abilitato +40=Azionamento asse B2 in allarme +41=Azionamento asse B2 non abilitato +42=Azionamento asse C2 in allarme +43=Azionamento asse C2 non abilitato +44=Piano ribaltamento parete Whall FresaGraffe non a riposo !!! +45=*** MANUTENZIONE CE *** +46=Contropunta foratore sinistro piu avanti della punta +47=Posizione teste non Ok per uscita magazzino laterale +48=Posizione teste non Ok per uscita Cu catena +49=Posizione teste non Ok per uscita T201 +50=Posizione teste non Ok per uscita T202 +51=Pre-allarme zone di sicurezza banco di lavoro +52=Allarme zone di sicurezza banco di lavoro +53=Pre-allarme zone di sicurezza perimetrali +54=Assi foratore destro bloccati con ZFresa o ZLama bassi +55=Assi foratore sinistro bloccati con ZFresa o ZLama bassi +56=Problema su EV o sensore rullo 01 banco +57=Problema su EV o sensore rullo 02 banco +58=Problema su EV o sensore rullo 03 banco +59=Problema su EV o sensore rullo 04 banco +60=Problema su EV o sensore rullo 05 banco +61=Problema su EV o sensore rullo 06 banco +62=Problema su EV o sensore rullo 07 banco +63=Problema su EV o sensore rullo 08 banco +64=Problema su EV o sensore rullo 09 banco +65=Problema su EV o sensore rullo 10 banco +66=Problema su EV o sensore rullo 11 banco +67=Problema su EV o sensore rullo 12 banco +68=Problema su EV o sensore rullo 13 banco +69=Problema su EV o sensore rullo 14 banco +70=Problema su EV o sensore rullo 15 banco +71=Problema su EV o sensore rullo 16 banco +72=Problema su EV o sensore rullo 17 banco +73=Problema su EV o sensore rullo 18 banco +74=Problema su EV o sensore rullo 19 banco +75=Problema su EV o sensore rullo 20 banco +76=Problema su EV o sensore rullo 21 banco +77=Problema su EV o sensore rullo 22 banco +78=Problema su EV o sensore rullo 23 banco +79=Problema su EV o sensore rullo 24 banco +80=Anticollisione Portali Whall intervenuta !!! +81=Magazzino laterale non indietro programmare M90 e poi M195 +82=Avanti magazzino laterale non Ok +83=Indietro magazzino laterale non Ok +84=Cu catena non indietro programmare M90 e poi M197 +85=Avanti Cu catena non Ok +86=Indietro Cu catena non Ok +87=Cu T10-T18 non indietro programmare M90 e poi M199T2 +88=Avanti Cu T10-T18 non Ok +89=Indietro Cu T10-T18 non Ok +90=Avanti Cu T1-T9 non Ok +91=Indietro Cu T1-T9 non Ok +92=Sensori contemporanei avanti-indietro cambio laterale +93=Sensori contemporanei avanti-indietro cambio Cu catena +94=Cu T1-T9 non indietro programmare M90 e poi M199T1 +95=Messa a punto inserita permessi solo movimenti manuali +96=Manca aria compressa secca +97=Chiave pulsantiera in manuale +98= +99= +100= +101=Rotazione inverter fresa non Ok (Fcinv0=1) +102=Rotazione inverter lama non Ok (Fcinv0=2) +103= +104=Sensori contemporanei cambio T10-T18 avanti-indietro +105=Rotazione Testa proibita senza utensili: verificare +106= +107=Sensori contemporanei cambio T1-T9 avanti-indietro +108=Attendere inserzioni di potenza +109=Premere reset su CNC +110=Scaricare pezzo da fine rulliera uscita e premere pulsante reset +111=Malfunzionamento inverter fresa +112=Malfunzionamento inverter lama +113=Problema su EV o sensore protezione anteriore alta +114=Problema su EV o sensore protezione posteriore alta +115=Sovratemperatura resistenze di frenatura inverter fresa +116=Sovratemperatura motore lama +117=Sovratemperatura motore fresa +118=Flussostato Fresa non Ok +119=Flussostato Lama non Ok +120=Sovracorrente inverter fresa +121=Sovracorrente inverter lama +122=Sovratemperatura resistenze di frenatura inverter lama +123=Accendere tastiera! +124=Batteria quasi scarica: sostituirla quanto prima! +125=Ventose basse con vuoto attivo +126=Malfunzionamento inverter rullo 01 banco +127=Malfunzionamento inverter rullo 02 banco +128=Malfunzionamento inverter rullo 03 banco +129=Malfunzionamento inverter rullo 04 banco +130=Malfunzionamento inverter rullo 05 banco +131=Malfunzionamento inverter rullo 06 banco +132=Malfunzionamento inverter rullo 07 banco +133=Malfunzionamento inverter rullo 08 banco +134=Malfunzionamento inverter rullo 09 banco +135=Malfunzionamento inverter rullo 10 banco +136=Malfunzionamento inverter rullo 11 banco +137=Malfunzionamento inverter rullo 12 banco +138=Malfunzionamento inverter rullo 13 banco +139=Malfunzionamento inverter rullo 14 banco +140=Malfunzionamento inverter rullo 15 banco +141=Malfunzionamento inverter rullo 16 banco +142=Malfunzionamento inverter rullo 17 banco +143=Malfunzionamento inverter rullo 18 banco +144=Malfunzionamento inverter rullo 19 banco +145=Malfunzionamento inverter rullo 20 banco +146=Malfunzionamento inverter rullo 21 banco +147=Malfunzionamento inverter rullo 22 banco +148=Malfunzionamento inverter rullo 23 banco +149=Malfunzionamento inverter rullo 24 banco +150=Preallarme temperatura motore fresa +151=Difetto bloccaggio utensile testa fresa +152=Difetto bloccaggio utensile testa lama +153=Utensile presente su testa con E80001=0 +154=Utensile presente su T2 con E80002=0 +155=Difetto sbloccaggio utensile testa +156=Difetto sbloccaggio utensile 2 +157=La pompa del vuoto non va in pressione +158=Allarme temperatura motore fresa +159=Pistone sbloccaggio cono non a riposo +160=Collisione cuffia aspirazione !!! +161=Problema su EV o sensore riferimento laterale 1 +162=Problema su EV o sensore riferimento laterale 2 +163=Problema su EV o sensore riferimento laterale 3 +164=Problema su EV o sensore riferimento laterale 4 +165=Problema su EV o sensore riferimento laterale 5 +166=Problema su EV o sensore riferimento frontale destro +167=Problema su EV o sensore riferimento frontale sinistro +168=Riferimenti bloccati perch� la macchina non � in potenza +169=Rulli banco bloccati perch� la macchina non � in potenza +170=Rulli banco fermi perch� la macchina non � in potenza +171=Rulli uscita fermi perch� la macchina non � in potenza +172=Malfunzionamento inverter rullo parcheggio +173=Malfunzionamento inverter rullo 1 uscita +174=Malfunzionamento inverter rullo 2 uscita +175=Malfunzionamento inverter rullo 3 uscita +176=Malfunzionamento inverter rullo 4 uscita +177=Malfunzionamento inverter rullo 5 uscita +178=Malfunzionamento inverter rullo 6 uscita +179=Rulli banco bloccati perch� le teste non sono in cima +180=Rulli banco bloccati perch� le protezioni non sono aperte +200=Difetto su uno o pi� moduli EtherCAT: riavviare la macchina +201=Function Block Safety in errore - discrepanza segnali ingresso +202=Difetto di comunicazione moduli Safety +203=Difetto uscite Safety +204=Modo service ON +205= +206=Graffetatrice non ok verificare !!! +207=Cassetto Graffe in esaurimento +208=Assi B-C bloccati bottola Graffetatrice non chiusa +209=Assi B-C bloccati Graffetatrice non alta +210=Attesa bottola aperta per salita-discesa Graffetatrice +211=Attesa assi B-C in posizione per salita-discesa Graffetatrice +212=Graffetatrice non alta +213=Graffetatrice non in pressione nel pezzo +214=Graffetatrice non bassa +215=Malfunzionamento inverter foratore destro +216=Malfunzionamento inverter foratore sinistro + +501= +502=ATTESA COMANDO +503=SCARICARE UTENSILE DA MOTORE T1 +504=SCARICARE UTENSILE DA MOTORE T2 +505=ATTESA FINE CAMBIO UTENSILE T1 +506=ATTESA FINE CAMBIO UTENSILE T2 +507=SCARICO UTENSILE SU LATERALE DX +508=SCARICO UTENSILE SU LATERALE SX +509=ATTESA MOTORE T1 FERMO +510=ATTESA MOTORE T2 FERMO +511=SCARICO UTENSILE CATENA +512=SCARICO UTENSILE MORTASA +513=ATTESA E30010=0 +514=CARICO UTENSILE SU LATERALE DX +515=CARICO UTENSILE SU LATERALE SX +516=CARICO UTENSILE CATENA +517=CARICO UTENSILE MORTASA +518=ATTESA FINE SCARICO SPEZZONE +519=POSIZIONA TRAVE +520=ATTESA GRUPPO DI SCARICO GR6 LIBERO +521=PINZE AUTOMATICHE +522=P1 NEG +523=P1 POS +524=P4 NEG +525=P4 POS +526=ATTESA PINZA 1 APERTA +527=ATTESA E81145=0 +528=ATTESA PINZA 4 APERTA +529=ATTESA X1 FUORI AREA LAVORO +530=ATTESA X2 FUORI AREA LAVORO +531=ATTESA APERTURA P17 X2+ +532=CARICO TRAVE +533=ATTESA FINE M201 +534=ARRETRA SPEZZONE +535=RICARICO TRAVE +536=SCARICO SPEZZONE SU POLMONE ENTRATA +537=SCARICA PEZZO +538=SCARICA SPEZZONE +539=ATTESA APERTURA LIMITI POSITIVO ASSE U +540=ATTESA LETTURA LIMITE POSITIVO X2 +541=ATTESA FINE ARRETRAMENTO SPEZZONE +542=ATTESA INIZIO SCARICO PEZZO +543=ATTESA APERTURA LIMITI ASSE U +544=ATTESA APERTURA LIMITI ASSE X+ T1 +545=ATTESA APERTURA LIMITI ASSE X- T2 +546=ATTESA APERTURA LIMITI ASSE Y +547=ATTESA SCRITTURA P17 X1+ +548=ATTESA SCRITTURA P17 X2- +549=START PER INIZIO +550=ATTESA SCRITTURA P17 Y+ E Y- +551=ATTESA GRUPPO DI CARICO GR5 LIBERO +552=ATTESA E81107=1 +553=ATTESA DISATTIVAZIONE PINZE AUTOMATICHE +554=ATTESA SCARICO SPEZZONE MANUALE +555=ATTESA FINE CARICO TRAVE +556=ATTESA FINE RIBALTAMENTO TRAVE +557=ATTESA SCARICO SPEZZONE SU POLMONE ENTRATA +558=ATTESA E81202=0 +559=WKZONE LUNGA START PER CONTINUARE +560=ATTESA E81201=0 +561=ATTESA E81165=0 +562=ATTESA E81203=0 +563=ATTESA SCARICO PEZZO MANUALE +564=ATTESA E10006=1 +565=ATTESA ATTIVAZIONE PINZE AUTOMATICHE +566=ATTESA FINE RICARICO TRAVE +567=ATTESA E81196=0 +568=PINZE AUTOMATICHE FUORI CORSA + +[CNC] +900=NUMERO UTENSILE NON VALIDO M6T +901=NUMERO UTENSILE CARICATO NON OK +902=NUMERO UTENSILE SU MOTORE NON VALIDO E80001 +903=SENSORE POM B FRESA NON OK +904=SENSORE POM C FRESA NON OK +905=SENSORE POM B LAMA NON OK +906=SENSORE POM C LAMA NON OK +907=SCARICARE MOTOSEGA MANUALMENTE +908=LAVORO CON 2 LAME NON POSSIBILE B<>90 O C<>0 O 180 +909=DEFINIRE NUMERO UTENSILE LAMA MOTORE EU +910=G124 X OBBLIGATORIA +911=G124 Y OBBLIGATORIA +912=G124 B OBBLIGATORIA +913=G124 C OBBLIGATORIA +914=libero +915=libero +916=DEFINIRE NUMERO MANDRINO ET.. (1=LAMA 2=FRESA 3=FORATORE DX 4=FORATORE SX) +917=SCARICARE UTENSILE DA MOTORE +918=G104X.. OBBLIGATORIA +919=G104Y.. OBBLIGATORIA +920=G104Z.. OBBLIGATORIA +921=G104ET.. NON OK (NUMERO AVVITATORE OBBLIGATORIO ET0-ET1-ET2-ET3) +922=G104EF.. NON OK (NUMERO STRATO OBBLIGATORIO) +923=SENSORE POM V NON OK +924=OFFSET X LAMA NON ALLINEATO CON CADCAM +925=OFFSET Y LAMA NON ALLINEATO CON CADCAM +926=OFFSET Z LAMA NON ALLINEATO CON CADCAM +927=PIVOT Z LAMA NON ALLINEATO CON CADCAM +928=PIVOT C LAMA NON ALLINEATO CON CADCAM +929=OFFSET X FRESA NON ALLINEATO CON CADCAM +930=OFFSET Y FRESA NON ALLINEATO CON CADCAM +931=OFFSET Z FRESA NON ALLINEATO CON CADCAM +932=PIVOT Z FRESA NON ALLINEATO CON CADCAM +933=PROGRAMMAZIONE X-U-W-Z OBBLIGATORIA CON G102EH.. DIVERSO DA ZERO +934=OFFSET X FORATORE DESTRO NON ALLINEATO CON CADCAM +935=OFFSET Y FORATORE DESTRO NON ALLINEATO CON CADCAM +936=OFFSET Z FORATORE DESTRO NON ALLINEATO CON CADCAM +937=OFFSET X FORATORE SINISTRO NON ALLINEATO CON CADCAM +938=OFFSET Y FORATORE SINISTRO NON ALLINEATO CON CADCAM +939=OFFSET Z FORATORE SINISTRO NON ALLINEATO CON CADCAM diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Scripts/ExitMach.lua b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Scripts/ExitMach.lua new file mode 100644 index 0000000..18f86ad --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Scripts/ExitMach.lua @@ -0,0 +1,36 @@ +-- 2018/11/21 17:30:00 +-- Machining Exit for Essetre-FAST machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Uscita da Lavorazioni *** + +-- Nascondo il pezzo così marcato e le geometrie aggiunte, visualizzo il Box +local function ProcessPart( PartId) + -- visualizzo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.ON) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice (già chiusi tutti i gruppi di lavoro) +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +EgtZoom( SCE_ZM.ALL, false) + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Scripts/InitMach.lua b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Scripts/InitMach.lua new file mode 100644 index 0000000..6ac761b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Scripts/InitMach.lua @@ -0,0 +1,44 @@ +-- 2018/11/21 16:30:00 +-- Machining Init for Essetre-FAST machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Ingresso in Lavorazioni *** + +-- Rendo visibile il pezzo e le geometrie aggiunte, nascondo il Box +local function ProcessPart( PartId) + -- nascondo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.OFF) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +-- Processo i pezzi già nei gruppi di lavoro (quando appena lanciata Process) +local GhostId = EgtGetFirstGhostPart() +while GhostId do + local PartId = EgtGetInfo( GhostId, GDB_SI.SOURCE, 'i') + if PartId then + ProcessPart( PartId) + end + GhostId = EgtGetNextGhostPart( GhostId) +end + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Scripts/SetUp.lua b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Scripts/SetUp.lua new file mode 100644 index 0000000..fb0d5b5 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Scripts/SetUp.lua @@ -0,0 +1,210 @@ +-- 2020/11/13 +-- Gestione attrezzaggio per Essetre-FAST + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Tavola di passaggio valori +local STU = {} +STU.TUUID = "" +STU.TCPOS = "" +STU.HEAD = "" +STU.GROUP = "" +STU.POS = "" +STU.EXIT = 0 +STU.INDEX = 0 +STU.HEAD1 = "" +STU.HEAD2 = "" +STU.ISVALID = false +STU.ERR = 0 +_G.STU = STU + +local INVALIDPOS = "" +local POS = "Pos" + +-- Geom Set +local GS = {} + +-- Configurazione posizioni +local PositionTable={{Pos = "Pos1", TcPos = "T1", Head = "H1", Group = "G1"}, + {Pos = "Pos2", TcPos = "T2", Head = "H1", Group = "G1"}, + {Pos = "Pos3", TcPos = "T3", Head = "H1", Group = "G1"}, + {Pos = "Pos4", TcPos = "T4", Head = "H1", Group = "G1"}, + {Pos = "Pos5", TcPos = "T5", Head = "H1", Group = "G1"}, + {Pos = "Pos6", TcPos = "T6", Head = "H1", Group = "G1"}, + {Pos = "Pos7", TcPos = "T7", Head = "H1", Group = "G1"}, + {Pos = "Pos8", TcPos = "T8", Head = "H1", Group = "G1"}, + {Pos = "Pos9", TcPos = "T9", Head = "H1", Group = "G1"}, + {Pos = "Pos10", TcPos = "T10", Head = "H1", Group = "G2"}, + {Pos = "Pos11", TcPos = "T11", Head = "H1", Group = "G2"}, + {Pos = "Pos12", TcPos = "T12", Head = "H1", Group = "G2"}, + {Pos = "Pos13", TcPos = "T13", Head = "H1", Group = "G2"}, + {Pos = "Pos14", TcPos = "T14", Head = "H1", Group = "G2"}, + {Pos = "Pos15", TcPos = "T15", Head = "H1", Group = "G2"}, + {Pos = "Pos16", TcPos = "T16", Head = "H1", Group = "G2"}, + {Pos = "Pos17", TcPos = "T17", Head = "H1", Group = "G2"}, + {Pos = "Pos18", TcPos = "T18", Head = "H1", Group = "G2"}, + {Pos = "Pos19", TcPos = "T42", Head = "H2", Group = "G3"}, + {Pos = "Pos20", TcPos = "T101", Head = "H3", Group = "G3"}, + {Pos = "Pos21", TcPos = "T301", Head = "H5", Group = "G4"}, + {Pos = "Pos22", TcPos = "T401", Head = "H6", Group = "G4"}} + +local UsePositionHead = true + +local function IsInGeomSet( ToolHead, PosHead) + for GsIndex = 1, #GS do + local bToolHead = false + local bPosHead = false + for HIndex = 1, #GS[GsIndex] do + if GS[GsIndex][HIndex] == ToolHead then + bToolHead = true + elseif GS[GsIndex][HIndex] == PosHead then + bPosHead = true + end + if bToolHead and bPosHead then + return true + end + end + if bToolHead and bPosHead then + return true + end + end + return false +end + +function STU.IsCompatibleHeads() + STU.ISVALID = false + if IsInGeomSet(STU.HEAD1, STU.HEAD2) then + STU.ISVALID = true + else + STU.ISVALID = false + end +end + +function STU.GetValidHeadExitForPos() + -- se TUUID non valido restituisco errore + local ToolName = EgtTdbGetToolFromUUID( STU.TUUID) + if ToolName == nill then + STU.ERR = 1 + return + end + EgtTdbSetCurrTool( ToolName) + local CurrToolHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + STU.EXIT = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + -- recupero testa predefinita per la posizione corrente + local CurrPosHead + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + CurrPosHead = PositionTable[i].Head + break + end + end + -- verifico se la testa è quella della posizione predefinita + if CurrPosHead == CurrToolHead then + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + -- verifico se la testa è compatibile con quella della posizione predefinita + elseif IsInGeomSet( CurrToolHead, CurrPosHead) then + if UsePositionHead then + STU.HEAD = CurrPosHead + STU.ERR = 0 + return + else + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + end + -- la testa non è compatibile con quella della posizione predefinita + else + STU.HEAD = INVALIDPOS + STU.ERR = 0 + return + end +end + +function STU.IsValidTcPosFromHead() + STU.ISVALID = false + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + if PositionTable[i].Head == STU.HEAD then + STU.ISVALID = true + STU.ERR = 0 + return + elseif IsInGeomSet(PositionTable[i].Head, STU.HEAD) then + STU.ISVALID = true + STU.ERR = 0 + return + end + STU.ISVALID = false + STU.ERR = 0 + return + end + end +end + +function STU.GetTcPosHeadGroupFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.HEAD = PositionTable[i].Head + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.HEAD = INVALIDPOS + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetPosFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.POS = PositionTable[i].Pos + STU.ERR = 0 + return + end + end + STU.POS = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetGroupFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetHeadFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.HEAD = PositionTable[i].Head + STU.ERR = 0 + return + end + end + STU.HEAD = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetTcPosFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.ERR = 1 +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/SetUp/Standard.stu b/ProgramData/EgtCAM5/Machines/Essetre-90480027/SetUp/Standard.stu new file mode 100644 index 0000000..f3cdb26 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/SetUp/Standard.stu @@ -0,0 +1,24 @@ +; Commento per evitare BOM con UTF-8 +[General] +Pos1=T1;H1;1/A2177599-4D80-4C82-A675-CBA5C64C5023/DrillD10 +Pos2=T2;H1;1/CA0D193E-E12A-49E5-AE69-FD081BA7C958/DrillD6 +Pos3=T3;H1;1/951FD4FC-EB64-44E3-97E0-348DBBD79C68/Smusso45 +Pos4=T4;H1;1/D0575113-6666-40F5-9F8A-36BA8F9DDC2D/Fresa70x103 +Pos5=T5;H1;1/294F6AD8-E4BE-41BF-ACDA-A9F812413607/Smusso60 +Pos6=T6;H1;1/93231EB4-750C-46C3-8E33-8047754B75A6/Mill_350X50 +Pos7=T7;H1;1/05A6C13F-75A4-42CC-80A6-27BF09438AE4/Fresa20x50 +Pos8=T8;H1;1/0A54F32E-C48D-45DB-8502-953CA94FD7A0/Fresa25x130 +Pos9=T9;H1;1/89157C3F-9444-45CE-91B0-391C8AAD8693/Mill_200X63 +Pos10=T10;H1;1/59895C4A-B303-471F-BBAA-368A79D50F5D/Mill_350X25 +Pos11=T11;H1;1/E7F6A2BB-1F66-48B9-9561-496231C33403/FresaDT60x130 +Pos12=T12 +Pos13=T13 +Pos14=T14;H1;1/FFEC9345-19DC-4D26-88F2-E770FB6E973A/DrillD18 +Pos15=T15 +Pos16=T16 +Pos17=T17 +Pos18=T18 +Pos19=T42;H2;1/6CB00A83-DDCD-49E6-A301-E1A0482615CA/Lama1200 +Pos20=T101;H3;1/A6CFDA65-DABB-441E-990A-776B5C24C2E4/ChainSaw +Pos21=T301;H5;1/522528DD-E395-4FB9-9675-873FBA51AEA1/LongDrillD35 +Pos22=T401;H6;1/FC1B5898-08B0-4D9A-90E1-B76A6D72C76F/LongDrill2D35 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/ChainSaw.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/ChainSaw.nge new file mode 100644 index 0000000..7ad3b00 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/ChainSaw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/MillAsSaw.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/MillAsSaw.nge new file mode 100644 index 0000000..4e8c74b Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/MillAsSaw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/MillAsSaw2.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/MillAsSaw2.nge new file mode 100644 index 0000000..b37161e Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/MillAsSaw2.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/MillNoTip.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/MillNoTip.nge new file mode 100644 index 0000000..9ae3067 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/MillNoTip.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/Standard.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/Standard.nge new file mode 100644 index 0000000..cf86275 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/Standard.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/Standard_103.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/Standard_103.nge new file mode 100644 index 0000000..90ecc64 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/THolders/Standard_103.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/05A6C13F-75A4-42CC-80A6-27BF09438AE4.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/05A6C13F-75A4-42CC-80A6-27BF09438AE4.nge new file mode 100644 index 0000000..6f3b27c Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/05A6C13F-75A4-42CC-80A6-27BF09438AE4.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge new file mode 100644 index 0000000..f592b9c Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/294F6AD8-E4BE-41BF-ACDA-A9F812413607.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/294F6AD8-E4BE-41BF-ACDA-A9F812413607.nge new file mode 100644 index 0000000..33d1f37 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/294F6AD8-E4BE-41BF-ACDA-A9F812413607.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/522528DD-E395-4FB9-9675-873FBA51AEA1.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/522528DD-E395-4FB9-9675-873FBA51AEA1.nge new file mode 100644 index 0000000..83e22ce Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/522528DD-E395-4FB9-9675-873FBA51AEA1.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/59895C4A-B303-471F-BBAA-368A79D50F5D.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/59895C4A-B303-471F-BBAA-368A79D50F5D.nge new file mode 100644 index 0000000..b78270c Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/59895C4A-B303-471F-BBAA-368A79D50F5D.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge new file mode 100644 index 0000000..d413b4b Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/89157C3F-9444-45CE-91B0-391C8AAD8693.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/89157C3F-9444-45CE-91B0-391C8AAD8693.nge new file mode 100644 index 0000000..b2cf68a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/89157C3F-9444-45CE-91B0-391C8AAD8693.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/8A2B00DE-C8F3-4AE6-8C51-D9D6FAEC36F6.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/8A2B00DE-C8F3-4AE6-8C51-D9D6FAEC36F6.nge new file mode 100644 index 0000000..ba251fd Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/8A2B00DE-C8F3-4AE6-8C51-D9D6FAEC36F6.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/93231EB4-750C-46C3-8E33-8047754B75A6.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/93231EB4-750C-46C3-8E33-8047754B75A6.nge new file mode 100644 index 0000000..d022481 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/93231EB4-750C-46C3-8E33-8047754B75A6.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/951FD4FC-EB64-44E3-97E0-348DBBD79C68.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/951FD4FC-EB64-44E3-97E0-348DBBD79C68.nge new file mode 100644 index 0000000..a12908f Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/951FD4FC-EB64-44E3-97E0-348DBBD79C68.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/988C8FE5-70C2-418A-B8EA-53476324D1ED.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/988C8FE5-70C2-418A-B8EA-53476324D1ED.nge new file mode 100644 index 0000000..d6fc4e7 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/988C8FE5-70C2-418A-B8EA-53476324D1ED.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/A2177599-4D80-4C82-A675-CBA5C64C5023.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/A2177599-4D80-4C82-A675-CBA5C64C5023.nge new file mode 100644 index 0000000..27ae304 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/A2177599-4D80-4C82-A675-CBA5C64C5023.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/A3EA6C9C-F1B4-4520-BE09-D504168B811E.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/A3EA6C9C-F1B4-4520-BE09-D504168B811E.nge new file mode 100644 index 0000000..b1117ce Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/A3EA6C9C-F1B4-4520-BE09-D504168B811E.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge new file mode 100644 index 0000000..e805682 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/CA0D193E-E12A-49E5-AE69-FD081BA7C958.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/CA0D193E-E12A-49E5-AE69-FD081BA7C958.nge new file mode 100644 index 0000000..69a1a3d Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/CA0D193E-E12A-49E5-AE69-FD081BA7C958.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/D0575113-6666-40F5-9F8A-36BA8F9DDC2D.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/D0575113-6666-40F5-9F8A-36BA8F9DDC2D.nge new file mode 100644 index 0000000..86d0dc5 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/D0575113-6666-40F5-9F8A-36BA8F9DDC2D.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/D160E7EA-7A45-438E-AB9D-0DF54E173C98.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/D160E7EA-7A45-438E-AB9D-0DF54E173C98.nge new file mode 100644 index 0000000..ebd0fd8 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/D160E7EA-7A45-438E-AB9D-0DF54E173C98.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/E51AC36C-31A5-4C27-9517-E3E33AED5604.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/E51AC36C-31A5-4C27-9517-E3E33AED5604.nge new file mode 100644 index 0000000..dee5e5a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/E51AC36C-31A5-4C27-9517-E3E33AED5604.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge new file mode 100644 index 0000000..17e9c29 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/FC1B5898-08B0-4D9A-90E1-B76A6D72C76F.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/FC1B5898-08B0-4D9A-90E1-B76A6D72C76F.nge new file mode 100644 index 0000000..83e22ce Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/FC1B5898-08B0-4D9A-90E1-B76A6D72C76F.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/FFEC9345-19DC-4D26-88F2-E770FB6E973A.nge b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/FFEC9345-19DC-4D26-88F2-E770FB6E973A.nge new file mode 100644 index 0000000..525f022 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/FFEC9345-19DC-4D26-88F2-E770FB6E973A.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/Tools.data b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/Tools.data new file mode 100644 index 0000000..5f50a31 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/Tools.data differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/Tools.data.bak b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/Tools.data.bak new file mode 100644 index 0000000..9cc5949 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Tools/Tools.data.bak differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/CutData.lua b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/CutData.lua new file mode 100644 index 0000000..37cb415 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/CutData.lua @@ -0,0 +1,10 @@ +-- CutData.lua by Egaltech s.r.l. 04/11/2021 15:36:52 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local CutData = { + { On = true, Name = 'Cutting1200', Type = 'Standard'} +} + +--------------------------------------------------------------------- +return CutData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/DrillData.lua b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/DrillData.lua new file mode 100644 index 0000000..3c249e8 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/DrillData.lua @@ -0,0 +1,18 @@ +-- DrillData.lua by Egaltech s.r.l. 29/01/2022 09:25:55 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local DrillData = { + { On = true, Name = 'DrillD6', Type = 'Drill'}, + { On = true, Name = 'DrillD10', Type = 'Drill'}, + { On = true, Name = 'DrillD12', Type = 'Drill'}, + { On = true, Name = 'DrillD20', Type = 'Drill'}, + { On = true, Name = 'DrillD25', Type = 'Drill'}, + { On = true, Name = 'LongDrillD35', Type = 'Drill'}, + { On = true, Name = 'LongDrill2D35', Type = 'Drill'}, + { On = true, Name = 'DrillPockD40', Type = 'Pocket'}, + { On = true, Name = 'DrillPockD25', Type = 'Pocket'} +} + +--------------------------------------------------------------------- +return DrillData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/MachData.ini b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/MachData.ini new file mode 100644 index 0000000..f0e5ad5 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/MachData.ini @@ -0,0 +1,48 @@ +; PIndex = Type, PName, Default, Description +; Type : d=double, l=length, s=string + +[1] +Name=Offsets +1= l,MIN_X,-5310,MIN_X +2= l,MAX_X,0,MAX_X +3= l,MIN_Y,-20580,MIN_Y +4= l,MAX_Y,0,MAX_Y +5= l,MIN_Z,-1570,MIN_Z +6= l,MAX_Z,0,MAX_Z +7= d,MIN_B,-135,MIN_B +8= d,MAX_B,135,MAX_B +9= d,MIN_C,-275,MIN_C +10=d,MAX_C,275,MAX_C +11=l,MIN_U,-6075,MIN_U +12=l,MAX_U,-770,MAX_U +13=l,MIN_W,-1110,MIN_W +14=l,MAX_W,0,MAX_W +15=l,MIN_V,0,MIN_V +16=l,MAX_V,90,MAX_V +17=d,MIN_A,-275,MIN_A +18=d,MAX_A,275,MAX_A +19=l,ZERO_X_SAW,-1288.05,ZERO_X_SAW +20=l,ZERO_Y_SAW,-802.45,ZERO_Y_SAW +21=l,ZERO_Z_SAW,-900.55,ZERO_Z_SAW +22=l,PIVOT_SAW,163.15,PIVOT_SAW +23=l,ZERO_X_MILL,-1293.3,ZERO_X_MILL +24=l,ZERO_Y_MILL,-1151,ZERO_Y_MILL +25=l,ZERO_Z_MILL,-983.15,ZERO_Z_MILL +26=l,PIVOT_MILL,208.0,PIVOT_MILL +27=l,INTRULLI,1500,INTRULLI +28=d,TYPEWORK,1,TYPEWORK +29=l,ZERO_X_DRILL,-135.0,ZERO_X_DRILL +30=l,ZERO_Y_DRILL,-1456,ZERO_Y_DRILL +31=l,ZERO_Z_DRILL,40.0,ZERO_Z_DRILL +32=l,ZERO_X_DRILL2,3632.0,ZERO_X_DRILL2 +33=l,ZERO_Y_DRILL2,-1456,ZERO_Y_DRILL2 +34=l,ZERO_Z_DRILL2,40.0,ZERO_Z_DRILL2 + +[2] +Name=Trave +1=l,XMIN,20,XMIN +2=l,XMAX,3500,XMAX +3=l,YMIN,50,YMIN +4=l,YMAX,18000,YMAX +5=l,ZMIN,1,ZMIN +6=l,ZMAX,400,ZMAX diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/MachiningTypes.ini b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/MachiningTypes.ini new file mode 100644 index 0000000..78f8a3c --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/MachiningTypes.ini @@ -0,0 +1,25 @@ +[Cut] +1=Standard + +[Drill] +1=Drill +2=Pocket + +[Milling] +1=FreeContour +2=Side +3=SideGroove +4=DtMortise +5=Mark +6=Text +7=CleanCorner60 +8=CleanCorner30 +9=SideMill +10=Gorge + +[Pocketing] +1=Pocket +2=Mortise + +[Sawing] +1=Sawing diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/MillingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/MillingData.lua new file mode 100644 index 0000000..0623858 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/MillingData.lua @@ -0,0 +1,19 @@ +-- MillingData.lua by Egaltech s.r.l. 02/02/2022 16:46:13 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local MillingData = { + { On = true, Name = 'Mill_DtMrt60', Type = 'DtMortise'}, + { On = true, Name = 'Spig30x40', Type = 'CleanCorner30'}, + { On = true, Name = 'Spig60x70', Type = 'CleanCorner60'}, + { On = false, Name = 'Milling200x63', Type = 'Side'}, + { On = true, Name = 'SideMill_200x63', Type = 'SideMill'}, + { On = true, Name = 'SideMill_350x50', Type = 'SideMill'}, + { On = true, Name = 'SideMill_350x25', Type = 'SideMill'}, + { On = true, Name = 'SawM_480', Type = 'SideGroove'}, + { On = true, Name = 'Milling70x103', Type = 'Gorge'}, + { On = true, Name = 'Milling25x130', Type = 'FreeContour'} +} + +--------------------------------------------------------------------- +return MillingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/PocketingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/PocketingData.lua new file mode 100644 index 0000000..9ebad66 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/PocketingData.lua @@ -0,0 +1,12 @@ +-- PocketingData.lua by Egaltech s.r.l. 17/01/2022 20:36:14 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local PocketingData = { + { On = true, Name = 'Svuot70x103', Type = 'Pocket'}, + { On = true, Name = 'Svuot25x130', Type = 'Pocket'}, + { On = true, Name = 'Svuot20x50', Type = 'Pocket'} +} + +--------------------------------------------------------------------- +return PocketingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/SawingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/SawingData.lua new file mode 100644 index 0000000..7ef7340 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/SawingData.lua @@ -0,0 +1,10 @@ +-- SawingData.lua by Egaltech s.r.l. 18/02/2021 18:55:40 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local SawingData = { + { On = true, Name = 'TaglioCatena', Type = 'Sawing'} +} + +--------------------------------------------------------------------- +return SawingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/Ts3Data.lua b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/Ts3Data.lua new file mode 100644 index 0000000..e110197 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/Ts3Data.lua @@ -0,0 +1,48 @@ +local Offsets = { + MIN_X=-5310, + MAX_X=0, + MIN_Y=-20580, + MAX_Y=0, + MIN_Z=-1570, + MAX_Z=0, + MIN_B=-135, + MAX_B=135, + MIN_C=-275, + MAX_C=275, + MIN_U=-6075, + MAX_U=-770, + MIN_W=-1110, + MAX_W=0, + MIN_V=0, + MAX_V=90, + MIN_A=-275, + MAX_A=275, + ZERO_X_SAW=-1288.05, + ZERO_Y_SAW=-802.45, + ZERO_Z_SAW=-900.55, + PIVOT_SAW=163.15, + ZERO_X_MILL=-1293.3, + ZERO_Y_MILL=-1151, + ZERO_Z_MILL=-983.15, + PIVOT_MILL=208, + INTRULLI=1500, + TYPEWORK=1, + ZERO_X_DRILL=-135, + ZERO_Y_DRILL=-1456, + ZERO_Z_DRILL=40, + ZERO_X_DRILL2=3632, + ZERO_Y_DRILL2=-1456, + ZERO_Z_DRILL2=40, +} + +local Trave = { + XMIN=20, + XMAX=3500, + YMIN=50, + YMAX=18000, + ZMIN=1, + ZMAX=400, +} + +local Machine = { Offsets=Offsets, Trave=Trave} +return Machine diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/WallData.lua b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/WallData.lua new file mode 100644 index 0000000..03eb785 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/WallData.lua @@ -0,0 +1,102 @@ +-- WallData.lua by Egaltech s.r.l. 2022/02/03 +-- Raccolta dati generali per Pareti + +EgtOutLog( ' 90480027-WallData started', 1) + +-- Tabella per definizione modulo +local WallData = { + MIN_LENGTH = 100, -- lunghezza minima del grezzo + MIN_WIDTH = 100, -- larghezza minima del grezzo + MIN_HEIGHT = 10, -- altezza minima del grezzo + MAX_LENGTH = 16000, -- lunghezza massima del grezzo + MAX_WIDTH = 3500, -- larghezza massima del grezzo + MAX_HEIGHT = 300, -- altezza massima del grezzo + STD_RAW_LENGTH = 10000, -- lunghezza standard del grezzo + STD_RAW_WIDTH = 2600, -- larghezza standard del grezzo + OVM_HEAD = 60, -- sovramateriale testa + OVM_MID = 50, -- sovramateriale intermedio + COLL_SIC = 5, -- distanza di sicurezza per collisioni + CUT_SIC = 20, -- distanza di sicurezza per tagli + CUT_EXTRA = 1, -- affondamento extra standard per tagli di lama e fresature + NZ_MINA = 0.5, -- componente limite in Z normale di una faccia (-30deg) + NZ_MINB = -0.4, -- componente limite in Z normale di un insieme di facce (-23deg) + SAWGORGE_INTERAX = 100, -- interasse tra i tagli sfrido del gorge + PREDRILL_DIAM = 26, -- diametro del preforo + PREDRILL_MINANGLE = 0.707, -- minimo angolo che richiede il preforo con fresa (-30deg) + DRILL_TOL = 0.5, -- tolleranza tra diametro foro e diametro punta + DRILL_VZ_MIN = 0.49, -- componente limite in Z del versore di un foro + DRILL_OVERLAP = 5, -- sovrapposizione tra due mezze forature + MILL_OVERLAP = 5, -- sovrapposizione tra due mezze fresature + HOR_DRILL_Y_SPLIT = -3044.3, -- quota di split dei fori orizzontali speciali lungo Y (quota di metà tavola) + HOR_DRILL_Y_TABLE = 3500, -- dimensione di riferimento tavola in Y per fori orizzontali speciali lungo Y + HOR_DRILL_YNEG_MAXMIN = -3994.3, -- massimo minimo in Y per fori da Y negativo + HOR_DRILL_LEN = 1780, -- lunghezza della punta per fori orizzontali speciali lungo Y + HOR_DRILL_DIAM = 35, -- diametro della punta per fori orizzontali speciali lungo Y + HOR_DRILL_5AX = false, -- abilita lavorazione dei fori orizzontali (default true) + MINRAWY_HOR_DRILL = 2800, -- dimensione y minima del grezzo per fori orizzontali in vista + MAX_CLEAN_CRN30 = 60, -- massimo spessore per pulitura angolo con fresa 30deg + MIN_DIM_ALLOW_CLEAN = 200, -- apertura minima per lavorazione pulitura spigolo + MILL_MAX_DEPTH_AS_MAT = false, -- massimo affondamento frese uguale ad altezza tagliente (max materiale) + CHECK_MIN_Z_SAW = true, -- controlla la quota minima della lama rispetto alla tavola (default true) + MIN_Z_SAW = -6, -- quota minima rispetto alla tavola (default 0) + SIDEMILL_DIAM_UP = 65, -- diametro fresa che lavora lap joint sopra + SIDEMILL_DIAM_DOWN = 350, -- diametro fresa che lavora lap joint sotto + SIDEMILL_BEFORE = true, -- mette le lavorazioni di fresatura di fianco tra le prime + INSIDE_RAW_TOL = 30, -- tolleranza utilizzata per definire quando area di lavorazione è lontana dai bordi del grezzo + NEST_HOLE_MIN_AREA = 200000, -- area minima per inserire gli outlines interni come holes nel nesting + RAWCOL = { 255, 160, 32, 30}, -- colore del grezzo + SIMUL_VIEW_DIR = 3, -- direzione di vista predefinita per la simulazione (1=NW, 2=SW, 3=NE, 4=SE) + ORIG_CORNER = 'TL', -- angolo tavola per origine di battuta (BR (defualt), TR, BL, TL) + NESTING_CORNER = 'TL', -- angolo di origine del grezzo per posizionamento pezzi (BR (defualt), TR, BL, TL) + INTRULLI = 1200 -- distanza fra assi su cui poggia il grezzo (per non far cadere il pezzo) +} + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Wall', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-90480027.data" +local sData = EgtGetSourceDir().."\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Offsets then + WallData.HOR_DRILL_Y_SPLIT = Machine.Offsets.ZERO_X_MILL - WallData.HOR_DRILL_Y_TABLE / 2 + WallData.HOR_DRILL_YNEG_MAXMIN = Machine.Offsets.ZERO_X_MILL - WallData.HOR_DRILL_Y_TABLE + 800 + WallData.INTRULLI = Machine.Offsets.INTRULLI or WallData.INTRULLI + end + if Machine.Trave then + WallData.MIN_LENGTH = Machine.Trave.YMIN or WallData.MIN_LENGTH + WallData.MIN_WIDTH = Machine.Trave.XMIN or WallData.MIN_WIDTH + WallData.MIN_HEIGHT = Machine.Trave.ZMIN or WallData.MIN_HEIGHT + WallData.MAX_LENGTH = Machine.Trave.YMAX or WallData.MAX_LENGTH + WallData.MAX_WIDTH = Machine.Trave.XMAX or WallData.MAX_WIDTH + WallData.MAX_HEIGHT = Machine.Trave.ZMAX or WallData.MAX_HEIGHT + end + end +end + +local function GetChainSawBlockedAxis( nInd) + if nInd == 1 then + return 'A1=0' + else + return 'A1=90' + end +end +WallData.GetChainSawBlockedAxis = GetChainSawBlockedAxis + +local function GetChainSawStartAngs( vtN) + if not vtN or not isVector3d( vtN) then return end + if vtN:getZ() > 0.7 then + return '' + else + return 'C=-90;' + end +end +WallData.GetChainSawStartAngs = GetChainSawStartAngs + +--------------------------------------------------------------------- +return WallData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/WallTableTemplate.ini b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/WallTableTemplate.ini new file mode 100644 index 0000000..ccb02c1 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-90480027/Wall/WallTableTemplate.ini @@ -0,0 +1,9 @@ +-- %TABLE_NAME%.lua by Egaltech s.r.l. %DATE_TIME% +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local %TABLE_NAME% = { +} + +--------------------------------------------------------------------- +return %TABLE_NAME% diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/BeamData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/BeamData.lua new file mode 100644 index 0000000..cdcf899 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/BeamData.lua @@ -0,0 +1,114 @@ +-- BeamData.lua by Egaltech s.r.l. 2022/03/14 +-- Raccolta dati generali per Travi + +EgtOutLog( ' FAST-BeamData started', 1) + +-- Tabella per definizione modulo +local BeamData = { + GO_FAST = 0, -- flag abilitazione modalità veloce (0=no, 1=carrelli, 2=anche cambio utensili) + ROT90 = false, -- flag abilitazione rotazione 90 gradi + MIN_WIDTH = 40, -- larghezza minima del grezzo + MIN_HEIGHT = 40, -- altezza minima del grezzo + MAX_WIDTH = 240, -- larghezza massima del grezzo + MAX_HEIGHT = 625, -- altezza massima del grezzo + MAX_WIDTH2 = 305, -- seconda larghezza massima del grezzo + MAX_HEIGHT2 = 625, -- altezza massima per seconda larghezza massima del grezzo + LEN_SHORT_PART = 1200, -- lunghezza massima pezzo corto + LEN_VERY_SHORT_PART = 400, -- lunghezza massima pezzo molto corto (molto probabile lo scarico a caduta) + MAX_RAW = 30000, -- massima lunghezza grezzo (deve essere minore di LenTable - RAW_OFFSET) + STD_RAW = 14000, -- lunghezza standard della barra di grezzo + OVM_HEAD = 10, -- sovramateriale testa + OVM_MID = 5.4, -- sovramateriale intermedio (spessore lama) + MINRAW_S = 750, -- minimo grezzo in coda scaricabile per sezioni piccole + MINRAW_L = 1070, -- minimo grezzo in coda scaricabile per sezioni grandi + MAX_LEN_SCRAP = 270, -- massima lunghezza scarto di coda + MAX_LEN_SCRAP_START = 270, -- massima lunghezza scarto di testa + MAX_DIM_HTCUT = 200, -- larghezza massima taglio di testa o coda + MAX_DIM_HTCUT_HBEAM = 180, -- larghezza massima taglio di testa o coda con trave alta + MIN_DIM_HBEAM = 360, -- altezza minima di trave alta + MAX_DIM_DICE = 155, -- dimensione trasversale massima cubetto + MAX_LEN_DICE = 400, -- lunghezza massima cubetto + COLL_SIC = 5, -- distanza di sicurezza per collisioni + CUT_SIC = 20, -- distanza di sicurezza per tagli + CUT_EXTRA = 5, -- affondamento extra standard per tagli di lama e fresature + CUT_EXTRA_MIN = 1, -- affondamento extra ridotto per tagli di lama e fresature + NZ_MINA = -0.6, -- componente limite in Z normale di una faccia (-36.8deg) + NZ_MINB = -0.4, -- componente limite in Z normale di un insieme di facce (-23deg) + DRILL_TOL = 0.2, -- tolleranza tra diametro foro e diametro punta + DRILL_VZ_MIN = -0.51, -- componente limite in Z del versore di un foro + DRILL_VX_MAX = 0.867, -- componente limite in X del versore di un foro sulle facce laterali + DRILL_OVERLAP = 5, -- sovrapposizione tra due mezze forature + MILL_OVERLAP = 5, -- sovrapposizione tra due mezze fresature + MAX_DIST_HTFEA = 50.0, -- massima distanza di feature da testa o coda per essere considerata tale + MAX_LEN_HTFEA = 2000.0, -- massima lunghezza di feature di testa o coda + LONGCUT_ENDLEN = 600, -- lunghezza lavoro estremi iniziale e finale + LONGCUT_MAXLEN = 1200, -- lunghezza massima sezione di taglio longitudinale + MAX_LEN_RIDGELAP_FROM_BOTTOM = 141, -- massima lunghezza ridgelap lavorabile da sotto + MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM = 96, -- massima lunghezza ridgelap lavorabile da sotto con trave alta + DIM_TO_CENTER_STRIP = 0, -- larghezza minima trave per inseriemento codolo nel centro del trave; 0 = automatico + DIM_STRIP = -1, -- dimensione codolo sostegno parti lasciate su contorno libero o archi (-1 = da Q...) + DIM_STRIP_SMALL = 1, -- dimensione codolo piccolo (quando le parti sostenute sono sicuramente sulla parte sopra del pezzo) + RAWCOL = { 255, 160, 32, 30}, -- colore del grezzo + RAW_OFFSET = 2000, -- spostamento grezzo rimanente dopo split + VICE_MINH = 110, -- altezza minima della morsa + OFFSET_DRILL_TENON = 0, -- offset fori su tenoni verso base degli stessi (0=non fare) + USER_HOLE_DIAM = 0, -- diametro foro per L20 + MAX_TOOL_LEN_FOR_HOR_MACH = 311, -- massima lunghezza utensile per poter fare forature (fresature) oltre i 10 gradi dalla verticale + DRILL_VZ_MIN_LONG_TOOL = 0.984, -- componente limite per lavorazioni con punta lunga + MAX_TOOL_LEN_BACK_HOR_MACH = 250, -- massima lunghezza utensile per poter eseguire lavorazioni (forature/svuotature) da dietro (faccia 4) + MAX_HEIGHT_ROT_B_ABOVE = 500, -- massima altezza della trave che permette di ruotare l'asse B sopra la stessa senza collisioni + KIOTP = 3, -- coefficiente moltiplicativo per attacco/uscita lama tangente anzichè perpendicolare + MAXDIAM_POCK_CORNER = 30, -- diametro massimo utensile ammesso per tasche con angoli interni + ANG_TRASM = false -- presenza rinvio angolare per lavorazioni da sotto +} + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Beam', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-Fast.data" +local sData = EgtGetSourceDir().."\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Offsets then + BeamData.ANG_TRASM = ( Machine.Offsets.SECSUP and Machine.Offsets.SECSUP >= 2) + end + if Machine.Trave then + BeamData.MIN_WIDTH = Machine.Trave.XMIN or BeamData.MIN_WIDTH + BeamData.MIN_HEIGHT = Machine.Trave.ZMIN or BeamData.MIN_HEIGHT + BeamData.MAX_WIDTH = Machine.Trave.XMAX or BeamData.MAX_WIDTH + BeamData.MAX_HEIGHT = Machine.Trave.ZMAX or BeamData.MAX_HEIGHT + end + if Machine.User then + BeamData.OFFSET_DRILL_TENON = Machine.User.L040_OFFSET_P1 or BeamData.OFFSET_DRILL_TENON + if Machine.User.OPTIMIZATIONS_ENABLE_SLICES_F5 == 1 then + BeamData.MAX_LEN_SCRAP = Machine.User.OPTIMIZATIONS_LENGTH_SLICES or BeamData.MAX_LEN_SCRAP + else + BeamData.MAX_LEN_SCRAP = 100000 + end + if Machine.User.OPTIMIZATIONS_ENABLE_SLICES_F6 == 1 then + BeamData.MAX_LEN_SCRAP_START = Machine.User.OPTIMIZATIONS_LENGTH_SLICES or BeamData.MAX_LEN_SCRAP_START + else + BeamData.MAX_LEN_SCRAP_START = 100000 + end + BeamData.USER_HOLE_DIAM = Machine.User.L020_DIAM_HOLE or BeamData.USER_HOLE_DIAM + end + end +end + +--------------------------------------------------------------------- +local function GetMaxLenRidgeLapFromBottom( dHRaw) + if dHRaw < BeamData.MIN_DIM_HBEAM then + return BeamData.MAX_LEN_RIDGELAP_FROM_BOTTOM + 0.01 + else + return BeamData.MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM + 0.01 + end +end +BeamData.GetMaxLenRidgeLapFromBottom = GetMaxLenRidgeLapFromBottom + +--------------------------------------------------------------------- +return BeamData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/BeamTableTemplate.ini b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/BeamTableTemplate.ini new file mode 100644 index 0000000..ccb02c1 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/BeamTableTemplate.ini @@ -0,0 +1,9 @@ +-- %TABLE_NAME%.lua by Egaltech s.r.l. %DATE_TIME% +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local %TABLE_NAME% = { +} + +--------------------------------------------------------------------- +return %TABLE_NAME% diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/CutData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/CutData.lua new file mode 100644 index 0000000..68b6fa5 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/CutData.lua @@ -0,0 +1,12 @@ +-- CutData.lua by Egaltech s.r.l. 29/07/2019 17:05:59 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local CutData = { + { On = true, Name = 'MiSideInvSaw600', Type = 'HeadSide'}, + { On = true, Name = 'MiSideSaw600', Type = 'TailSide'}, + { On = true, Name = 'SplitSideSaw600', Type = 'SplitSide'} +} + +--------------------------------------------------------------------- +return CutData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/DrillData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/DrillData.lua new file mode 100644 index 0000000..e13354d --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/DrillData.lua @@ -0,0 +1,23 @@ +-- DrillData.lua by Egaltech s.r.l. 19/03/2022 13:24:05 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local DrillData = { + { On = true, Name = 'DrillD05_4', Type = 'Drill'}, + { On = true, Name = 'DrillD08', Type = 'Drill'}, + { On = true, Name = 'DrillD08_Long', Type = 'Drill'}, + { On = true, Name = 'DrillD10', Type = 'Drill'}, + { On = true, Name = 'DrillD12', Type = 'Drill'}, + { On = true, Name = 'DrillD12_Long', Type = 'Drill'}, + { On = true, Name = 'DrillD14', Type = 'Drill'}, + { On = true, Name = 'DrillD16', Type = 'Drill'}, + { On = true, Name = 'DrillD18', Type = 'Drill'}, + { On = true, Name = 'DrillD18_Short', Type = 'Drill'}, + { On = true, Name = 'DrillD20', Type = 'Drill'}, + { On = true, Name = 'DrillD25', Type = 'Drill'}, + { On = true, Name = 'DrillPockD20', Type = 'Pocket'}, + { On = true, Name = 'DrillPockD25', Type = 'Pocket'} +} + +--------------------------------------------------------------------- +return DrillData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/GetTs3Data.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/GetTs3Data.lua new file mode 100644 index 0000000..b43225d --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/GetTs3Data.lua @@ -0,0 +1,30 @@ +-- GetTs3Data.lua by Egaltech s.r.l. 2022/04/07 +-- Recupero dati da file Ts3Data.lua di macchina + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--GTSD = {} +--GTSD.TS3PATH = 'Essetre-FAST\\Ts3Data.lua' + +local sLog = 'GetTs3Data : ' .. GTSD.TS3PATH +EgtOutLog( sLog) + +if EgtExistsFile( GTSD.TS3PATH) then + local Machine = dofile( GTSD.TS3PATH) + -- Assegno valori di interesse + Offsets = Machine.Offsets + _G.Offsets = Offsets + Trave = Machine.Trave + _G.Trave = Trave + User = Machine.User + _G.User = User +end + +-- Tutto ok +GTSD.ERR = 0 + +EgtOutLog( ' +++ GetTs3Data completed') diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/MachData.ini b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/MachData.ini new file mode 100644 index 0000000..421b343 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/MachData.ini @@ -0,0 +1,51 @@ +; PIndex = Type, PName, Default, Description +; Type : d=double, l=length, s=string + +[1] +Name=Offsets +1=l,YCARICO,-1460.0,YCARICO +2=l,YSCARICO,1700.0,YSCARICO +3=l,OFFSETRIB,150.0,OFFSETRIB +4=l,PARKYY,480,PARKYY +5=l,PARKVV,-480,PARKVV +6=l,PIVOTFRESA,-177.0,PIVOTFRESA +7=l,PIVOTLAMA,242.0,PIVOTLAMA +8=l,OFFSETX,-900.0,OFFSETX +9=l,OFFSETZ,-1015.0,OFFSETZ +10=l,MIN_X,-1350,MIN_X +11=l,MAX_X,0,MAX_X +12=l,MIN_Y,110,MIN_Y +13=l,MAX_Y,3735,MAX_Y +14=l,MIN_Z,-1350,MIN_Z +15=l,MAX_Z,0,MAX_Z +16=d,MIN_B,-180,MIN_B +17=d,MAX_B,360,MAX_B +18=d,MIN_C,-360,MIN_C +19=d,MAX_C,360,MAX_C +20=l,MIN_V,-3735,MIN_V +21=l,MAX_V,-110,MAX_V +22=d,TIPO_CN,1,TIPO_CN +23=d,OFFSETCLAMA,0,OFFSETCLAMA +24=d,OFFSETBLAMA,0,OFFSETBLAMA +25=d,RIBCAR,0,RIBCAR +26=d,SECSUP,1,SECSUP +27=d,NOULOAD,0,NOULOAD +28=l,OFFSETX_RINV_1,150,OFFSETX_RINV_1 +29=l,OFFSETZ_RINV_1,347,OFFSETZ_RINV_1 +30=l,OFFSETX_RINV_2,150,OFFSETX_RINV_2 +31=l,OFFSETZ_RINV_2,347,OFFSETZ_RINV_2 + +[2] +Name=Trave +1=l,XMIN,29,XMIN +2=l,XMAX,305,XMAX +3=l,ZMIN,20,ZMIN +4=l,ZMAX,625,ZMAX + +[3] +Name=User +1=d,OPTIMIZATIONS_ENABLE_SLICES_F5,1,OPTIMIZATIONS_ENABLE_SLICES_F5 +2=d,OPTIMIZATIONS_ENABLE_SLICES_F6,1,OPTIMIZATIONS_ENABLE_SLICES_F6 +3=d,OPTIMIZATIONS_LENGTH_SLICES,100,OPTIMIZATIONS_LENGTH_SLICES +4=l,L020_DIAM_HOLE,20,L020_DIAM_HOLE +5=l,L040_OFFSET_P1,0,L040_OFFSET_P1 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/MachiningTypes.ini b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/MachiningTypes.ini new file mode 100644 index 0000000..6ecb633 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/MachiningTypes.ini @@ -0,0 +1,38 @@ +[Cut] +1=HeadSide +2=TailSide + +[Drill] +1=Drill +2=Pocket + +[Milling] +1=Prof +2=FreeContour +3=Tenon +4=DtTenon +5=DtMortise +6=DtMortise_AT +7=BirdsMouth +8=Chamfer +9=Mark +10=Text +11=Decor01 +12=Long2Cut +13=Long2CutDown +14=LongSmallCut +15=BHSideMill +16=CleanCorner +17=ProfTCone +18=Long2CutSide +19=SmallToolContour +20=AntiSplintMillCut + +[Pocketing] +1=Pocket +2=OpenPocket +3=Mortise +4=Mortise_AT + +[Sawing] +1=Sawing diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/MillingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/MillingData.lua new file mode 100644 index 0000000..a4b5dd2 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/MillingData.lua @@ -0,0 +1,35 @@ +-- MillingData.lua by Egaltech s.r.l. 20/03/2022 19:27:44 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local MillingData = { + { On = true, Name = 'Profiling25x130', Type = 'Prof'}, + { On = true, Name = 'FreeCont25x130', Type = 'FreeContour'}, + { On = true, Name = 'Mill_Tenon100x60', Type = 'Tenon'}, + { On = true, Name = 'Mill_Tenon100x150', Type = 'Tenon'}, + { On = true, Name = 'Mill_DtTen60x130', Type = 'DtTenon'}, + { On = true, Name = 'Mill_DtMrt60x130', Type = 'DtMortise'}, + { On = true, Name = 'Mill_DtMrt60x39_AT', Type = 'DtMortise_AT'}, + { On = false, Name = 'Mill_DtMrt40x120r', Type = 'DtMortise'}, + { On = true, Name = 'Mill_DtMrt35x130', Type = 'DtMortise'}, + { On = true, Name = 'Milling100x60', Type = 'BirdsMouth'}, + { On = false, Name = 'Chamfer25x130', Type = 'Chamfer'}, + { On = true, Name = 'Milling100x60', Type = 'Chamfer'}, + { On = true, Name = 'Text45x40', Type = 'Mark'}, + { On = true, Name = 'TextPenna', Type = 'Text'}, + { On = true, Name = 'Text45x40', Type = 'Decor01'}, + { On = true, Name = 'Mill_L2C100x60', Type = 'Long2Cut'}, + { On = false, Name = 'Mill_L2CD25x130', Type = 'Long2CutDown'}, + { On = true, Name = 'Mill_L2CD100x60', Type = 'Long2CutDown'}, + { On = false, Name = 'Mill_L2CD25x130', Type = 'Long2CutSide'}, + { On = true, Name = 'Mill_L2CD100x60', Type = 'Long2CutSide'}, + { On = true, Name = 'Milling25x130', Type = 'LongSmallCut'}, + { On = true, Name = 'MillOnSideBH', Type = 'BHSideMill'}, + { On = true, Name = 'Milling10x50', Type = 'SmallToolContour'}, + { On = true, Name = 'Milling25x130', Type = 'AntiSplintMillCut'}, + { On = true, Name = 'Clean35x40', Type = 'CleanCorner'}, + { On = true, Name = 'Mill_DTCone125x160', Type = 'ProfTCone'} +} + +--------------------------------------------------------------------- +return MillingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/PocketingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/PocketingData.lua new file mode 100644 index 0000000..6f591bd --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/PocketingData.lua @@ -0,0 +1,20 @@ +-- PocketingData.lua by Egaltech s.r.l. 01/12/2021 10:40:29 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local PocketingData = { + { On = true, Name = 'Svuot100x60', Type = 'OpenPocket'}, + { On = false, Name = 'Svuot100x150', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot60x80', Type = 'OpenPocket'}, + { On = false, Name = 'Svuot35x70', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot25x130', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot20x50', Type = 'OpenPocket'}, + { On = false, Name = 'Svuot35x70', Type = 'Pocket'}, + { On = true, Name = 'Svuot20x50', Type = 'Pocket'}, + { On = true, Name = 'Svuot25x130', Type = 'Pocket'}, + { On = true, Name = 'Mortiser38.89x130', Type = 'Mortise'}, + { On = true, Name = 'Svuot20x100_AT', Type = 'Mortise_AT'} +} + +--------------------------------------------------------------------- +return PocketingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/SawingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/SawingData.lua new file mode 100644 index 0000000..8232c0b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/SawingData.lua @@ -0,0 +1,10 @@ +-- SawingData.lua by Egaltech s.r.l. 29/07/2019 17:06:08 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local SawingData = { + { On = true, Name = 'TaglioCatena', Type = 'Sawing'} +} + +--------------------------------------------------------------------- +return SawingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/Ts3Data.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/Ts3Data.lua new file mode 100644 index 0000000..ab4c2db --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Beam/Ts3Data.lua @@ -0,0 +1,72 @@ +-- C:\TechnoEssetre7\EgtData\Essetre-FAST.data + +local Offsets = { + YCARICO=-1456.85, + YSCARICO=1700, + OFFSETRIB=200, + PARKYY=480, + PARKVV=-480, + PIVOTFRESA=-176.965, + PIVOTLAMA=241.61, + OFFSETX=-900.45, + OFFSETZ=-1014.4, + MIN_X=-1350, + MAX_X=0, + MIN_Y=110, + MAX_Y=3735, + MIN_Z=-1350, + MAX_Z=0, + MIN_B=-180, + MAX_B=360, + MIN_C=-360, + MAX_C=360, + MIN_V=-3735, + MAX_V=-110, + TIPO_CN=1, + OFFSETCLAMA=0, + OFFSETBLAMA=0, + RIBCAR=0, + SECSUP=1, + NOULOAD=0, + OFFSETX_RINV_1=150, + OFFSETZ_RINV_1=346.965, + OFFSETX_RINV_2=150, + OFFSETZ_RINV_2=346.965, + Zzz=1 +} + +local Trave = { + XMIN=30, + XMAX=300, + ZMIN=30, + ZMAX=625, + Zzz=1 +} + +local User = { + NESTING_MATERIAL=1, + NESTING_TYPEEXTERNALOP=1, + NESTING_FROM_BTL=0, + SAFETY_DISTANCE_ZSAVE=23, + OPTIMIZATIONS_ENABLE_SLICES_F5=1, + OPTIMIZATIONS_ENABLE_SLICES_F6=1, + OPTIMIZATIONS_LENGTH_SLICES=100, + L056_ACTIVE_AS=1, + L055_ADD_P13=0, + L055_ACTIVE_AS=1, + L050_ADDDEPTH=3, + L060_PEN_F2=2, + L060_PEN_F1=2, + L138_TOLLERANZA=0, + L037_TOOL_WIDTH=0, + L032_LENGTH_MIN_DIV=500, + T055_ACTIVE_AS=1, + L040_OFFSET_P1=0, + L040_TYPEDRILLING=1, + L020_DIAM_HOLE=14, + L030_AUM_DIM=0, + Zzz=1 +} + +local Machine = { Offsets=Offsets, Trave=Trave, User=User} +return Machine diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.NUM.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.NUM.mlpe new file mode 100644 index 0000000..039c04a --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.NUM.mlpe @@ -0,0 +1,1575 @@ +-- Processore macchina Essetre-FAST by EgalTech s.r.l. 2021/12/29 +-- Con controllo numerico NUM +-- 2021/04/23 DS ver 2.3d3 Se non c'è BtlInfo cerco il gruppo di lavoro corrente. +-- 2021/07/21 DS ver 2.3g5 Modifiche varie da TPA. +-- 2021/07/23 DS ver 2.3g6 Corretta gestione LOAD90. +-- 2021/07/23 DS ver 2.3g7 Completamento allineamento con TPA. +-- 2021/07/27 DS ver 2.3g8 Corretto carico senza taglio di testa per salto G79 N9. +-- 2021/07/27 DS ver 2.3g9 Nome in testa a CN (%NNNN.0) da PATTID di BtlInfo. +-- 2021/07/29 DS ver 2.3g10 Con testa H2 (lama) non si emettono assi rotanti nel corso della lavorazione. +-- 2021/08/03 DS ver 2.3h2 Nei commenti le parentesi sono sostituite con il carattere -. +-- 2021/08/05 DS ver 2.3h4 Nel rapido se non bHeadFirst ritardo anche l'emissione di G101 a dopo G112. +-- 2021/11/17 DS ver 2.3k1 Correzioni di Nicola su rotazioni verificate da GCT. +-- 2021/12/28 DS ver 2.3l2 Correzioni a G101 (ora sempre con EE ed ET). +-- 2021/12/29 DS ver 2.3l3 Altre correzioni a G101 (se già in alto EE3 e sempre ES). + +-- Variabili di modulo +local MLE_INFO = 'Essetre-FAST.NUM.mlpe ver.'..PP_VER..' by EgalTech s.r.l.' +local TEST_USE = false + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.FMAXPINZE = 154000 -- feed massima pinze +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Intestazioni + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or EgtGetCurrMachGroup() or GDB_ID.NULL + local nPatt = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 40 + EmtOutput( '%'..EgtNumToString( nPatt, 0)..'.0') + if EMT.INFO then + EmtOutput( '('..EMT.INFO..')') + else + EmtOutput( '(Program Start)') + end + EmtOutput( '('.. MLE_INFO..')\n') + -- Se modalità test, aggiungo linee per muovere tappeto e alzare la testa (in automatico viene fatto dal main residente) + if TEST_USE then + EmtOutput( 'M28') + EmtOutput( 'N1 G101 Z-100 L0=0') + EmtOutput( 'N1 G101 ET1001') + EmtOutput( 'N1 G101 ET2001\n') + end + -- Cerco primo utensile su testa 1 + EMT.TOOL_1, EMT.TLEN_1 = FindFirstToolOnHead( 'H1') + -- Dichiaro inizio + EMT.FIRST = true + EMT.TLAST = nil +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Arresto mandrino + EmtOutput( 'M05') + -- Emissione scarico + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' or EMT.AUXTYPE == 'R' then + EmtOutput( 'G111 ET1004') + EmtOutput( 'G111 ET2004') + elseif EMT.AUXTYPE == 'U' then + local sP1x = EgtIf( EMT.CHY_ON, '4', '2') + EmtOutput( 'G111 ET100'..sP1x) + EmtOutput( 'G111 ET200'..sP1x) + -- emissione conclusione pezzo precedente (se non si è in test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'G113 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( EMT.CUTID)..' ED2' + EmtOutput( sEnd) + end + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.RELOAD = nil + EMT.RELOAD2 = nil + -- Se modalità test, termino il programma + if TEST_USE then + EmtOutput( 'M02') + end +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensile (esclusa lama) + if EMT.HEAD == 'H1' then + -- output info + local sPos + if #EMT.TCPOS == 2 then + sPos = EMT.TCPOS:gsub( 'T', 'N30') + elseif #EMT.TCPOS == 3 then + sPos = EMT.TCPOS:gsub( 'T', 'N3') + else + sPos = EMT.TCPOS:gsub( 'T1', 'N4') + end + local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( EMT.TTOTLEN, 1)..' G76H9998.2'..sPos..sPos + EmtOutput( sOut) + -- cerco posizione di attrezzaggio del primo utensile di lavorazione + if EMT.TOOL == EMT.TOOL_1 and EMT.TLEN_1 < 215.5 then + EMT.TCPOS_1 = EMT.TCPOS + end + -- emissione dati sega a catena + elseif EMT.HEAD == 'H3' then + local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( ChSawLen, 1)..' G76H9998.2N401N404' + EmtOutput( sOut) + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + --EmtOutput( '(Disposition '..EMT.DISPIND..' = '..EMT.DISPID..')') + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') + EMT.YPOS = EgtGetInfo( EMT.DISPID, 'YPOS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- emissione dati di macchina + local sOut = 'G114 EA'..EmtLenToString( LoadT, 2)..' EB'..EmtLenToString( MinY, 2)..' EC'..EmtLenToString( MaxY, 2).. + ' ED'..EmtLenToString( MinV, 2)..' EE'..EmtLenToString( MaxV, 2)..' EF'..EmtLenToString( MillOffs, 2).. + ' EG'..EmtLenToString( SawOffs, 2)..' EI'..EmtLenToString( ParkY, 2)..' EL'..EmtLenToString( ParkV, 2).. + ' EM'..EmtLenToString( TurnerOffs, 2) + EmtOutput( '\n' .. sOut .. '\n') + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + if IsEnd2Phase( EMT.PHASE - 1) then + EMT.RELOAD = true + EMT.RELOAD2 = false + elseif IsStartPhase( EMT.PHASE) then + EMT.YDELTA = EMT.YPOS - LoadT + EMT.VDELTA = nil + end + end +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- reset recupero sovramateriale in X non più presente + EMT.X_OFF = nil + -- dati del grezzo + local LBarra = EMT.LB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- calcolo dati pinze + local MinAccPinze = 0.3 + local MaxAccPinze = 4 + local KgMtCubo= 550 -- densità legno in Kg / metro cubo + local Massa = ( HTrave * STrave * LBarra * KgMtCubo ) / 1000000000 + local FMaxPinze = EMT.FMAXPINZE + local ForzaAtrito = 700 / 2 -- Serve per regolare P32 (700 valore reale pistone) + local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAtrito) / 1000) + if ( TempoAcc < MinAccPinze) then TempoAcc = MinAccPinze end + if ( TempoAcc > MaxAccPinze) then TempoAcc = MaxAccPinze end + local AccPinze = FMaxPinze / ( 60 * TempoAcc) + local RidFeed = 100 / Massa * 100 + if ( RidFeed > 100) then RidFeed = 100 end + if IdTrave >= 0 then + local sOut = '( SN='..IdTrave..' LBarra='..EmtLenToString(LBarra,3)..' L='..EmtLenToString(LTrave,3).. + ' H='..EmtLenToString(HTrave,3)..' S='..EmtLenToString(STrave,3)..' Acc='..EmtLenToString(TempoAcc,1).. + ' RidFeed='..EmtLenToString(RidFeed,3)..' FeedMax='..EmtLenToString(FMaxPinze / 100 * RidFeed,3)..' )' + MyOutputNoNum( sOut) + sOut = 'E30049='..EmtLenToString(AccPinze,0)..' E30050=8555 E30051='..EmtLenToString(AccPinze,0).. + ' E30052=8555'..' E30054='..EmtLenToString(AccPinze,0)..' E30039='..EmtLenToString(RidFeed*1000,0).. + ' E30040='..EmtLenToString(RidFeed*1000,0)..' E30017=E80017'..' E30018=E80018'..' E10012=1' + MyOutputNoNum( sOut) + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or EgtGetCurrMachGroup() or GDB_ID.NULL + EMT.PRODID = EgtGetInfo( BtlInfoId, 'PRODID', 'i') or 0 + EMT.PATTID = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 0 + EMT.CUTID = EgtGetInfo( EMT.IDT, 'CUTID', 'i') or 0 + local sStart = '(G113 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( EMT.CUTID)..' ED1)' + -- da emettere solo se aggiorna PLC + EmtOutput( sStart) + else + MyOutputNoNum( '(REMAIN UNLOAD)') + EMT.PRODID = nil + EMT.PATTID = nil + EMT.CUTID = nil + end + -- se carico barra + if EMT.LOAD then + -- verifico se sezione già caricata + local sOut = 'IF E30033<'..EmtLenToString(HTrave*1000,0)..' OR E30036<'..EmtLenToString(STrave*1000,0)..' THEN' + EmtOutput( sOut) + sOut = 'M119' + EmtOutput( sOut) + sOut = 'M149' + EmtOutput( sOut) + sOut = 'ENDI' + EmtOutput( sOut) + -- assegnazione dati trave e barra + sOut = 'E30033='..EmtLenToString(HTrave*1000,0)..' E30036='..EmtLenToString(STrave*1000,0).. + ' E30069='..EmtLenToString(LBarra*1000,0) + EmtOutput( sOut) + -- preselezione prima fresa (della testa 1) + sOut = 'IF E30001=0 THEN' + EmtOutput( sOut) + sOut = 'M6' .. ( EMT.TCPOS_1 or 'T1') + -- va scritto 2 volte + EmtOutput( sOut) + EmtOutput( sOut) + sOut = 'ENDI' + EmtOutput( sOut) + -- ora abilito numerazione linee + EMT.NUM = true + EMT.LINENBR = 0 + -- se altrimenti ricarico barra dopo rotazione speciale + elseif EMT.RELOAD then + -- assegnazione dati trave e barra + sOut = 'E30033='..EmtLenToString(HTrave*1000,0)..' E30036='..EmtLenToString(STrave*1000,0).. + ' E30069='..EmtLenToString(LBarra*1000,0) + EmtOutput( sOut) + -- altrimenti recupero rimanenza + else + EmtOutput( 'G112 EC1'..' Y'..EmtLenToString( LoadT, 3).. ' EY'..EmtLenToString( EMT.YPOS, 3)..' EV'..EmtLenToString( ParkV, 3) ..' EF'..GetFmaxClamp()) + -- aggiorno dati aggancio carrelli alla trave + EMT.YDELTA = EMT.YPOS - LoadT + EMT.VDELTA = nil + end + -- eventuale preparazione per rotazione immediata + if IsStartPhase( EMT.PHASE) and EMT.AUXSTR then + -- emissione movimento carrelli per rotazione + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmtOutput( '(ROTATION)') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'G111 ET1004') + EmtOutput( 'G111 ET2004') + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se rotazioni diverse, emetto il comando e aggiorno lo stato + if VerifyEmitRotation() then + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- se altrimenti disposizione intermedia speciale con eventuale rotazione + elseif IsMid2Phase( EMT.PHASE) then + -- emissione movimento carrelli + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmtOutput( '(ROTATION)') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'G111 ET1004') + EmtOutput( 'G111 ET2004') + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + -- se rotazioni diverse, emetto il comando e aggiorno lo stato + if VerifyEmitRotation() then + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + MyOutputNoNum( '(PART UNLOAD)') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'G111 ET1002') + EmtOutput( 'G111 ET2002') + -- emissione conclusione pezzo precedente + if EMT.PRODID then + local sEnd= 'G113 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( EMT.CUTID)..' ED2' + EmtOutput( sEnd) + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + end + + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- se primo grezzo, reset lunghezza barra + if EMT.RAWIND == 1 then EMT.LB = 0 end + -- aggiungo la lunghezza del grezzo (solo se movimento in corner) + if EMT.RAWTYPE == 1 then + local b3Raw = EgtGetBBoxGlob( EgtGetFirstNameInGroup( EMT.RAWID, 'RawSolid'), GDB_BB.STANDARD) + local LBarra = b3Raw:getDimX() + EMT.LB = EMT.LB + LBarra + end + -- se primo grezzo, calcolo dati del pezzo + if EMT.RAWIND == 1 then + local PartId = EgtGetFirstPartInRawPart( EMT.RAWID) + if PartId then + EMT.IDT = PartId + EMT.IT = EgtGetInfo( PartId, 'PDN', 'i') or 0 + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box'), GDB_BB.STANDARD) + EMT.LT = b3Part:getDimX() + EMT.HT = b3Part:getDimY() + EMT.ST = b3Part:getDimZ() + EMT.HOVM = EgtGetInfo( EMT.RAWID, 'HOVM', 'd') or 0 + else + EMT.IDT = GDB_ID.NULL + EMT.IT = -1 + EMT.LT = 0 + EMT.HT = EMT.HT or 0 + EMT.ST = EMT.ST or 0 + EMT.HOVM = 0 + end + end + end +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOOLSEL = EMT.TCPOS..' M06' + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + --EMT.MCHNAME = EgtGetMachiningParam(MCH_MP.NAME) + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam(MCH_MP.TYPE) + EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + -- sistemazione speed + if EMT.HEAD == 'H2' then + EMT.S = EMT.S * 6 + end + -- determino subito se taglio di separazione di pezzo a caduta + EMT.PREFALLCUT = nil + if EMT.MCHUSERNOTES and EMT.MCHUSERNOTES:find( 'Split') then + local ClId = EgtGetFirstNameInGroup( EMT.MCHID, 'CL') + local P1Id = EgtGetFirstNameInGroup( ClId or GDB_ID.NULL, 'P1') + local sAE1 = EgtGetInfo( P1Id or GDB_ID.NULL, 'AE1') or '' + if sAE1 == '0,Fall' then + EMT.PREFALLCUT = true + end + end +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + --EmtOutput( ';Mach End') + -- Emissione split + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + MyOutputNoNum( '(PART SPLIT)') + elseif EMT.AUXTYPE == 'U' then + if not EMT.ZMAX then + EmitZmax() + EMT.ZMAX = true + end + MyOutputNoNum( '(PART UNLOAD)') + elseif EMT.AUXTYPE == 'P' then + if EMT.PREROT then + if not EMT.ZMAX then + EmitZmax() + EMT.ZMAX = true + end + MyOutputNoNum( '(PART ROTATION)') + elseif EMT.FALL then + if not EMT.ZMAX then + EmitZmax() + EMT.ZMAX = true + end + EmtOutput( '(FALL)') + else + if not EMT.ZMAX then + EmitZmax() + EMT.ZMAX = true + end + EmtOutput( '(SPLIT 2)') + end + end + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmtOutput( 'G111 ET1004') + EmtOutput( 'G111 ET2004') + elseif EMT.AUXTYPE == 'U' then + local sP1x = EgtIf( EMT.CHY_ON, '4', '2') + EmtOutput( 'G111 ET100'..sP1x) + EmtOutput( 'G111 ET200'..sP1x) + -- emissione conclusione pezzo precedente + if not TEST_USE and EMT.PRODID then + local sEnd= 'G113 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( EMT.CUTID)..' ED2' + EmtOutput( sEnd) + end + elseif EMT.AUXTYPE == 'P' then + EmtOutput( 'G111 ET1004') + EmtOutput( 'G111 ET2004') + if EMT.FALL then + EmtOutput( 'M155') + EmtOutput( 'M28') + -- emissione conclusione pezzo (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'G113 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( EMT.CUTID)..' ED2' + EmtOutput( sEnd) + end + elseif not EMT.PREROT then + EmtOutput( 'M77') + end + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStart() + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + + -- se richiesto, preparo il carico barra + if EMT.LOAD or EMT.RELOAD then + PrepareLoad( EMT.AUX, true) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( EMT.AUX) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnPathEndAux() + --EgtOutLog( 'OnPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif EgtGetInfo( EMT.DISPID, 'TYPE') == 'REST' then + EMT.AUXTYPE = 'R' + else + EMT.AUXTYPE = 'P' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'P' + if Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.FALL = true + end + end + elseif EMT.AUXTYPE == 'P' then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.CHY_ON = true + EMT.AUXTYPE = 'U' + end + end + end + -- preparo a seconda del tipo + if EMT.AUXTYPE == 'R' then + -- per il carico della rimanenza dopo rotazione speciale + if EMT.RELOAD and not EMT.RELOAD2 then + PrepareLoad( EMT.AUX, false) + -- per lo scarico della rimanenza + else + PrepareResidue( EMT.AUX) + end + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnRapid() + MyBackupAxes() + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + -- decido se muovere prima testa o carrelli (standard prima testa) + local bHeadFirst = true + local sLateG101 + if not ( EMT.LOAD or EMT.RELOAD) and not EMT.ZMAX then + local DeltaT = EMT.L1 - EMT.TLAST + if ( DeltaT < -GEO.EPS_SMALL and EMT.VDELTA) or ( DeltaT > GEO.EPS_SMALL and EMT.YDELTA) then bHeadFirst = false end + end + -- sistemo movimenti + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + if not ( EMT.LOAD or EMT.RELOAD) then + if not EMT.ZMAX and #EMT.AUXSTR > 0 then + EmitZmax() + EMT.ZMAX = true + end + end + if not EMT.LOAD then + local sOut = string.gsub( string.gsub( EMT.MCHNAME..'/'..EMT.TOOL, '%(', '-'), '%)', '-') + EmtOutput( '( *** ' .. sOut .. ' *** )') + end + -- primo posizionamento + EmtResetPrev() + local bZmax = ( #EMT.AUXSTR > 0 or EMT.TOOL ~= EMT.PREVTOOL or EMT.L3 > -1) + local sEE = ' EE' .. EgtIf( bZmax, '3', '4') + local sEL = ' EL' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TLEN, ChSawLen), 3) + local sER = ' ER' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TDIAM / 2, EMT.TLEN), 3) + local sET = GetET( EMT.HEAD, EMT.TCPOS, EMT.R3) + local sES = ' ES'..EgtNumToString( EMT.S, 0) + local sOut = 'G101' .. EmtGetAxis( 'L2') .. EmtGetAxis( 'L3') .. + EmtGetAxis( 'R2') .. EmtGetAxis( 'R1') .. sEE .. sEL .. sER .. sET .. sES + if EMT.LOAD or bHeadFirst then + sOut = sOut..' L0=0' + EmtOutput( sOut) + sOut = 'G101 ET1001' + EmtOutput( sOut) + else + -- va ritardata anche l'emissione del comando + sLateG101 = sOut..' L0=0' + end + -- se prima lavorazione + if EMT.LOAD then + local nJump = 9 + sOut = 'G79 E80060<>0 N' .. EgtNumToString( nJump, 0) .. ' E10015=0' + EmtOutput( sOut) + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + if #EMT.AUXSTR > 2 then + EmtOutput( EMT.AUXSTR[1] .. ' ET1') + EmtOutput( EMT.AUXSTR[2] .. 'ET1') + EmtOutput( 'G111 ET1001') + EmtOutput( 'G79 N' .. EgtNumToString( nJump, 0)) + EmtOutput( 'E80060=1') + EmtOutput( 'G111 ET2001') + for i = 3, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + EmtOutput( 'G111 ET1004') + EmtOutput( 'G111 ET2004') + else + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + EmtOutput( 'G111 ET1001') + EmtOutput( 'G79 N' .. EgtNumToString( nJump, 0)) + EmtOutput( 'E80060=1') + EmtOutput( 'G111 ET2001') + end + EMT.AUXSTR = {} + sOut = string.gsub( string.gsub( EMT.MCHNAME..'/'..EMT.TOOL, '%(', '-'), '%)', '-') + EmtOutput( '( *** ' .. sOut .. ' *** )') + sOut = 'G101 ET2001' + EmtOutput( sOut) + local sY, sA + if EMT.YDELTA then + sY = EmtLenToString( EMT.L1 + EMT.YDELTA) + sA = '1' + else + sY = EmtLenToString( ParkY) + sA = '2' + end + local sV, sB + if EMT.VDELTA then + sV = EmtLenToString( EMT.L1 + EMT.VDELTA) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + sOut = 'G112 EA'..sA..' EB'..sB..''..EmtGetAxis('L1')..' EY'..sY..' EV'..sV..' EF'..GetFmaxClamp() + EmtOutput( sOut) + EMT.LOAD = false + -- altrimenti lavorazione successiva + else + -- eventuale G111 + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if not ( EMT.POSTROT or EMT.RELOAD) then + EmtOutput( 'G111 ET1004') + EmtOutput( 'G111 ET2004') + else + EmtOutput( 'G111 ET1001') + EmtOutput( 'G111 ET2001') + end + end + EMT.AUXSTR = {} + local sY, sA + if EMT.YDELTA then + sY = EmtLenToString( EMT.L1 + EMT.YDELTA - ( EMT.X_OFF or 0)) + sA = '1' + else + sY = EmtLenToString( EgtIf( EMT.YPOS, EMT.YPOS, ParkY)) + sA = '2' + end + local sV, sB + if EMT.VDELTA then + sV = EmtLenToString( EMT.L1 + EMT.VDELTA - ( EMT.X_OFF or 0)) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + if bHeadFirst then + sOut = 'G101 ET2001' + EmtOutput( sOut) + end + sOut = 'G112 EA'..sA..' EB'..sB..EmtGetAxis('L1')..' EY'..sY..' EV'..sV..' EF'..GetFmaxClamp() + EmtOutput( sOut) + if not bHeadFirst then + EmtOutput( sLateG101) + sOut = 'G101 ET1001' + EmtOutput( sOut) + sOut = 'G101 ET2001' + EmtOutput( sOut) + end + EMT.POSTROT = false + EMT.RELOAD = false + EMT.RELOAD2 = nil + end + -- se taglio di separazione prima di scarico a caduta, emissione stop tappeto scarico trucioli + if EMT.PREFALLCUT then + EmtOutput( 'M29') + EMT.PREFALLCUT = nil + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se alto in Z (non serve l'avvicinamento finale) + if EMT.FLAG == 2 then + -- aggiorno valori come precedenti + EMT.TLAST = EMT.L1b + EmtUpdatePrev() + return + -- altrimenti ripristino i valori originali degli assi + else + MyRestoreAxes() + end + end + -- se standard + if EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EmtOutput( 'G102'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3')..EMT.IPLGLSTR) + else + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + end + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3') + if EMT.HEAD ~= 'H2' then sOut = sOut..EmtGetAxis('R2')..EmtGetAxis('R1') end + EmtOutput( sOut) + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmitZmax() + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- se altrimenti rotazione a Z max + elseif EMT.FLAG == 5 then + -- viene gestito all'inizio della lavorazione successiva + -- errore perchè caso non gestito su NUM + EmtSetLastError( 1212, "Rotate at Zmax not managed") + -- altrimenti errore + else + EmtSetLastError( 1212, "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EMT.TLAST = EMT.L1b + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + MyBackupAxes() + EMT.TLAST = EMT.L1 + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente (se presente devo annullare l'offset in X per sovramateriale di testa) + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + if EMT.X_OFF then EMT.L1 = EMT.L1 - EMT.X_OFF end + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EmtOutput( 'G102'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3')..EMT.IPLGLSTR) + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3') + if EMT.HEAD ~= 'H2' then sOut = sOut..EmtGetAxis('R2')..EmtGetAxis('R1') end + EmtOutput( sOut) + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3') + if EMT.HEAD ~= 'H2' then sAxes = sAxes..EmtGetAxis('R2')..EmtGetAxis('R1') end + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- aggiungo feed + local sFeed = EmtGetFeed() + -- emetto linea + EmtOutput( "G1"..sAxes..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + MyBackupAxes() + EMT.TLAST = EMT.L1 + -- non modale su archi + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3') + if EMT.HEAD ~= 'H2' then sAxes = sAxes..EmtGetAxis('R2')..EmtGetAxis('R1') end + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString(EMT.RR,3) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- emetto arco + EmtOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd, bSkipPress) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + elseif sCmd == '1' then + return '2' + -- chiuso con pressore attivato + elseif sCmd == '2' then + return EgtIf( bSkipPress, '2', '0') + end +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd, bStart) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = ' EA111' + EMT.SB = ' EB111' + EMT.SC = ' EC141' + EMT.SD = ' ED141' + EMT.SE = ' EE0' + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + if bStart then + EMT.RELOAD = false + else + EMT.RELOAD2 = true + end + for i = 1, #EMT.AUXSTR do + EMT.AUXSTR[i] = string.gsub( EMT.AUXSTR[i], 'ET1', '') + end + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut = 'G111 '..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.YPOS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sYTaking = ' Y'..EmtLenToString( Cmd[3] + TurnerOffs) + local sBeamRot = '0' + if StartRotation and EMT.LB >= AutoRotMinLen then + local nRot = GetPhaseRot( EMT.PHASE) + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or EgtGetCurrMachGroup() or GDB_ID.NULL + local nLoad90 = EgtGetInfo( BtlInfoId, 'LOAD90', 'i') or 0 + sBeamRot = tostring( nLoad90) + end + local sOut = 'G111'..sYTaking..' EA75'..EMT.SB..' EE0 EF'..EmtLenToString(EMT.FMAXPINZE,0)..' ET1 E80057='..sBeamRot..' E80058=0' + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', ' '..Cmd[2]..Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', ' '..Cmd[4]..Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', ' '..Cmd[6]..Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + local bPrevEA76 = ( #EMT.AUXSTR > 0 and EMT.AUXSTR[#EMT.AUXSTR]:find( 'EA76', 1, true)) + if #EMT.AUXSTR > 0 and not bPrevEA76 then + local sVal = ' EB11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + if not bPrevEA76 then + EMT.SA = ' EA11' .. CalcCharStatus( Cmd[2]) + end + EMT.SB = ' EB11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE1', ' EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' ED14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' EC14' .. CalcCharStatus( Cmd[2]) + EMT.SD = ' ED14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE2', ' EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + if not FindG111EA76( EMT.AUXSTR) then + local sYLoad = ' Y'..EmtLenToString( LoadT) + local sOut = 'G111'..sYLoad..' EA76'..EMT.SB..' EE0 EF'..EmtLenToString( EMT.FMAXPINZE, 0)..' ET1' + table.insert( EMT.AUXSTR, sOut) + end + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = EgtIf( EMT.YDELTA, ' EA112', ' EA111') + EMT.SB = EgtIf( EMT.YDELTA, ' EB112', ' EB111') + EMT.SC = EgtIf( EMT.VDELTA, ' EC142', ' EC141') + EMT.SD = EgtIf( EMT.VDELTA, ' ED142', ' ED141') + EMT.SE = EgtIf( EMT.YDELTA, ' EE1', ' EE2') + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut = 'G111 '..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.YPOS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', ' '..Cmd[2]..Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', ' '..Cmd[4]..Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', ' '..Cmd[2]..Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', ' '..Cmd[4]..Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', ' '..Cmd[6]..Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' EB11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' EA11' .. CalcCharStatus( Cmd[2]) + EMT.SB = ' EB11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE1', ' EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' ED14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' EC14' .. CalcCharStatus( Cmd[2]) + EMT.SD = ' ED14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE2', ' EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.YDELTA, ' EA112', ' EA111') + EMT.SB = EgtIf( EMT.YDELTA, ' EB112', ' EB111') + EMT.SC = EgtIf( EMT.VDELTA, ' EC142', ' EC141') + EMT.SD = EgtIf( EMT.VDELTA, ' ED142', ' ED141') + EMT.SE = EgtIf( EMT.YDELTA, ' EE1', ' EE2') + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + if not EMT.UNL then + sOut = 'G111 '..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + else + sOut = 'G111 '..Cmd[2]..Cmd[3]..' EC141 ED83 EE0 EF'..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', ' '..Cmd[2]..Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', ' '..Cmd[4]..Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', ' '..Cmd[2]..Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', ' '..Cmd[4]..Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', ' '..Cmd[6]..Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' EB11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' EA11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = ' EB11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE1', ' EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' ED14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' EC14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = ' ED14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE2', ' EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sOut = 'G111 '..Cmd[2]..Cmd[3]..' EA110 EB110 EC142 ED142 EE2 EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.YPOS = tonumber( Cmd[3]) + end + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sEE = EgtIf( EMT.PHASE == EgtGetPhaseCount(), '0', '1') + local sOut = 'G111 '..Cmd[2]..Cmd[3]..' EC141 ED83 EE'..sEE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[4] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sEAB = EgtIf( EMT.PHASE == EgtGetPhaseCount(), '111', '112') + local sOut = 'G111 '..Cmd[4]..Cmd[5]..' EA'..sEAB..' EB'..sEAB..' EC142 ED141 EE2 EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.U_STD = true + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + -- non interessa + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.YDELTA, ' EA112', ' EA111') + EMT.SB = EgtIf( EMT.YDELTA, ' EB112', ' EB111') + EMT.SC = EgtIf( EMT.VDELTA, ' EC142', ' EC141') + EMT.SD = EgtIf( EMT.VDELTA, ' ED142', ' ED141') + EMT.SE = EgtIf( EMT.YDELTA, ' EE1', ' EE2') + end + -- se è pre-rotazione + if Cmd[2] == 'Pre-Rotation' then + EMT.PREROT = true + elseif Cmd[2] == 'SplitRot' then + EMT.SPLITROT = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + if not EMT.PREROT then + sOut = 'G111 '..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + else + sOut = 'G111 '..Cmd[2]..Cmd[3]..' EA86 EB87 EC141 EE0 EF'..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', ' '..Cmd[2]..Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', ' '..Cmd[4]..Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', ' '..Cmd[2]..Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', ' '..Cmd[4]..Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', ' '..Cmd[6]..Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' EB11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + if EMT.SPLITROT then + EMT.SA = EgtIf( Cmd[2] ~= '0', ' EA11' .. CalcCharStatus( Cmd[2], true), ' EA86') + EMT.SB = EgtIf( Cmd[2] ~= '0', ' EB11' .. CalcCharStatus( Cmd[2], true), ' EB87') + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE1', ' EE2') + else + EMT.SA = ' EA11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = ' EB11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE1', ' EE2') + end + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' ED14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' EC14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = ' ED14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' EE2', ' EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = ' EB112' + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + EMT.POSTROT = false + for i = 1, #EMT.AUXSTR do + EMT.AUXSTR[i] = string.gsub( EMT.AUXSTR[i], 'ET1', '') + end + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + local sYTaking = ' Y'..EmtLenToString( Cmd[3] - EMT.HOVM) + local sOut = 'G111'..sYTaking..' EA75 EB112 EE0 EF'..EmtLenToString(EMT.FMAXPINZE,0)..' ET1 E80058=0' + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = ' EB11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + local sYLoad = ' Y'..EmtLenToString( LoadT) + local sOut = 'G111'..sYLoad..' EA76'..EMT.SB..' EE0 EF'..EmtLenToString( EMT.FMAXPINZE,0)..' ET1' + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function MyBackupAxes() + EMT.L1b = EMT.L1 + EMT.L2b = EMT.L2 + EMT.L3b = EMT.L3 + EMT.R1b = EMT.R1 + EMT.R2b = EMT.R2 + EMT.R3b = EMT.R3 + EMT.R4b = EMT.R4 + EMT.RRb = EMT.RR + EMT.C1b = EMT.C1 + EMT.C2b = EMT.C2 + EMT.C3b = EMT.C3 +end + +--------------------------------------------------------------------- +function MyRestoreAxes() + EMT.L1 = EMT.L1b + EMT.L2 = EMT.L2b + EMT.L3 = EMT.L3b + EMT.R1 = EMT.R1b + EMT.R2 = EMT.R2b + EMT.R3 = EMT.R3b + EMT.R4 = EMT.R4b + EMT.RR = EMT.RRb + EMT.C1 = EMT.C1b + EMT.C2 = EMT.C2b + EMT.C3 = EMT.C3b +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + local MyL1o = EMT.L1 + local MyL2o = EMT.L2 + local MyL3o = EMT.L3 + + if EMT.REFLOC then + local vtE + if EMT.HEAD ~= 'H3' then + local Len = EMT.TLEN + EgtIf( EMT.HEAD == 'H1', MillOffs, abs( SawOffs)) + local LenRef = MillOffs + vtE = Vector3d( EMT.EXTR) * Len - Z_AX() * LenRef + else + local LenAux = ChSawLen + MillOffs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + vtE = vtAux * LenAux - Z_AX() * LenRef + end + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - DeltaTabY - vtE:getY() + EMT.L3 = EMT.L3 - DeltaTabZ - vtE:getZ() + end + + if EMT.X_OFF then EMT.L1 = EMT.L1 + EMT.X_OFF end + + EmtAdjustLinearAxes() + + EMT.L1o = MyL1o + EMT.L2o = MyL2o + EMT.L3o = MyL3o + + if not EMT.REFLOC then + EMT.L2 = - EMT.L2 + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function MyOutputNoNum( sOut) + local bNum = EMT.NUM + EMT.NUM = false + EmtOutput( sOut) + EMT.NUM = bNum +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + LoadT + if EMT.X_OFF then xS = xS + EMT.X_OFF end + local ptS = Point3d( xS, 0, 0) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H3' then + vtE = Vector3d( EMT.EXTR) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --EmtOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local _, dAngV, dAngO = SphericalFromVector( vtE) + local dAngO2 = EmtGetAngO2( EMT.IPLGLFR:getVersZ(), EMT.IPLGLFR:getVersX(), dAngV, dAngO) + dAngO = dAngO + 90 + while dAngO >= 360 do + dAngO = dAngO - 360 + end + EMT.IPLGLSTR = ' EX0 EY'..EmtLenToString( xS)..' EZ0'.. + ' EA0'..' EB'..EgtNumToString(dAngV)..' EC'..EgtNumToString(dAngO)..' ED'..EgtNumToString(dAngO2) + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function VerifyEmitRotation() + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- se sono uguali non devo fare alcunchè + if nRot == nPrevRot then + return false + end + -- determino quanto ruotare + local nDeltaRot = nRot - nPrevRot + -- se rotazione automatica richiesta e possibile + if AutomaticRotation and EMT.LB >= AutoRotMinLen then + local sOut = 'M180 L0=' .. tostring( nDeltaRot) + EmtOutput( sOut) + else + local sOut + if nDeltaRot == 1 then + sOut = 'M151' + elseif nDeltaRot == 2 then + sOut = 'M152' + elseif nDeltaRot == 3 then + sOut = 'M153' + end + EmtOutput( sOut) + EmtOutput( 'M86') + EmtOutput( 'G4F.5') + end + return true +end + +--------------------------------------------------------------------- +function EmitZmax() + local sEE = ' EE4' + local sET = GetET( EMT.HEAD, EMT.TCPOS, EMT.R3) + local sES = ' ES'..EgtNumToString( EMT.S, 0) + local sOut = 'G101 X'..EmtLenToString( -EMT.L2o, 3)..' Z'..EgtGetAxisHomePos( 'Z').. + ' B'..EmtLenToString( EMT.R2o, 3)..' C'..EmtLenToString( EMT.R1o, 3)..sEE..sET..sES..' L0=0' + EmtOutput( sOut) + sOut = 'G101 ET1001' + EmtOutput( sOut) + sOut = 'G101 ET2001' + EmtOutput( sOut) +end + +--------------------------------------------------------------------- +function GetET( sHead, sTcPos, dAxR3) + if sHead == 'H1' then + return ' E'..sTcPos + elseif sHead == 'H2' then + return ' ET42' + elseif sHead == 'H3' then + if dAxR3 and abs( dAxR3 - 0) < 0.1 then + return ' ET101' + elseif dAxR3 and abs( dAxR3 - 270) < 0.1 then + return ' ET102' + elseif dAxR3 and abs( dAxR3 - 180) < 0.1 then + return ' ET103' + elseif dAxR3 and abs( dAxR3 - 90) < 0.1 then + return ' ET104' + else + EmtSetLastError( 1210, 'Chain saw orientation not allowed') + end + else + EmtSetLastError( 1211, "Unknown Head") + end +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE, 0) +end + +--------------------------------------------------------------------- +function FindG111EA76( vStr) + for i = 1, #vStr do + if vStr[i]:find( 'G111', 1, true) and vStr[i]:find( 'EA76', 1, true) then + return true + end + end + return false +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.TPA.PRINT.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.TPA.PRINT.mlpe new file mode 100644 index 0000000..fc7523c --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.TPA.PRINT.mlpe @@ -0,0 +1,1731 @@ +-- Processore macchina Essetre-FAST by EgalTech s.r.l. 2021/08/03 +-- Con controllo numerico TPA +-- 2020/03/23 DS ver.2.2c3 Nei movimenti interpolati si usano 5 decimali, nei G24 6 decimali. +-- 2020/04/27 DS ver.2.2d3 Aggiunta gestione scarico speciale senza spostamento finale pezzo. +-- 2020/04/30 DS ver.2.2d5 Modifiche a scarico manuale. +-- 2020/05/19 DS ver.2.2e2 Modifiche per rotazione 90 gradi. +-- 2020/05/27 DS ver.2.2e6 Aggiunta gestione ordine posizionamento iniziale testa e carrelli quando non è Zmax. +-- 2020/06/10 DS ver.2.2f1 Aggiunta emissione di pezzo finito (M113..) dopo pezzo caduto (M155). +-- 2020/06/11 DS ver 2.2f2 Nel contenuto dei commenti si sostituiscono le parentesi tonde con le quadre. +-- 2020/09/03 DS ver 2.2i1 A M114 aggiunti P11 e P12. Modificato M102 P1=. Modificati commenti. +-- 2020/09/16 DS ver 2.2i2 OFFSETX e OFFSETZ da TS3v7 ora devono contenere tutto lo spiazzamento non più solo il delta dal nominale. +-- 2020/09/17 DS ver 2.2i3 Correzione per il segno di OFFSETX. +-- 2021/01/08 DS ver 2.3a1 M115 esteso con P6 e usato per ogni pezzo. Eliminati 0 inutili. +-- 2021/04/07 DS ver 2.3d2 Gestione risalita Zmax (M116) anche allo scarico. +-- 2021/04/23 DS ver 2.3d3 Se non c'è BtlInfo cerco il gruppo di lavoro corrente. +-- 2021/05/25 DS ver 2.3e3 Aggiunta gestione rapido con Flag=5. +-- 2021/06/04 DS ver 2.3f2 Gestione parametro P12=1 su M101 per ruotare in alto quando necessario. +-- 2021/07/21 DS ver 2.3g5 Si imposta LOAD90 su tutti i pezzi di una barra tramite M115. Aggiunto M29 prima di taglio di pezzo a caduta. +-- 2021/08/03 DS ver 2.3h3 Aggiunto arresto preciso negli angoli (G9) in fresature con utensili di piccolo diametro. + +-- Variabili di modulo +local MLE_INFO = 'Essetre-FAST.TPA.mlpe ver.'..PP_VER..' by EgalTech s.r.l.' +local TEST_USE = false +local PRINT_USE = true + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.DECNUM = 5 -- numero di decimali dopo la virgola + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.FMAXPINZE = 154000 -- feed massima pinze +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Intestazioni + if EMT.INFO then + ParkLine( '('..EMT.INFO..')') + else + ParkLine( '(Program Start)') + end + ParkLine( '('.. MLE_INFO..')') + -- Se modalità test, aggiungo linee per muovere tappeto e alzare la testa (in automatico viene fatto dal main residente) + if TEST_USE then + ParkLine( 'M199') + end + -- Cerco primo utensile su testa 1 + EMT.TOOL_1, EMT.TLEN_1 = FindFirstToolOnHead( 'H1') + -- Dichiaro inizio + EMT.FIRST = true + EMT.TLAST = nil + -- Inizializzazioni varie + ParkLine( 'M6 T000000') + ParkLine( 'G49') + -- Inizio lista utensili + ParkLine( 'M993 (Tool List Start)') +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Arresto mandrino + MyOutput( 'M05') + -- Emissione scarico + --for i = 1, #EMT.AUXCMD do + -- MyOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + MyOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + MyOutput( 'M111 P1=20') + MyOutput( 'M111 P1=30') + elseif EMT.AUXTYPE == 'R' then + MyOutput( 'M111 P1=20') + MyOutput( 'M111 P1=30') + elseif EMT.AUXTYPE == 'U' then + local sP1x = EgtIf( EMT.CHY_ON, '0', '2') + MyOutput( 'M111 P1=2'..sP1x) + MyOutput( EgtIf( EMT.U_STD, ';', '')..'M111 P1=3'..sP1x) + -- emissione conclusione pezzo precedente (se non si è in test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.RELOAD = nil + EMT.RELOAD2 = nil + -- Termino il programma + MyOutput( 'M02') +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensili + if EMT.HEAD == 'H1' then + local sOut = 'M992 P1=' .. EMT.TCPOS:gsub( 'T', '') .. ' P2=' .. EmtLenToString( EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( EMT.TTOTLEN, 3) + ParkLine( sOut) + -- cerco posizione di attrezzaggio del primo utensile di lavorazione + if EMT.TOOL == EMT.TOOL_1 and EMT.TLEN_1 < 215.5 then + EMT.TCPOS_1 = EMT.TCPOS + end + -- emissione dati lama + elseif EMT.HEAD == 'H2' then + local sOut = 'M992 P1=' .. EMT.TCPOS:gsub( 'T', '') .. ' P2=' .. EmtLenToString( EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( EMT.TTOTLEN, 3) + ParkLine( sOut) + -- emissione dati sega a catena + elseif EMT.HEAD == 'H3' then + local sData = ' P2=' .. EmtLenToString( ChSawLen, 3) .. ' P3=' .. EmtLenToString( EMT.TLEN, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( ChSawLen, 3) + ParkLine( 'M992 P1=101' .. sData) + ParkLine( 'M992 P1=102' .. sData) + ParkLine( 'M992 P1=103' .. sData) + ParkLine( 'M992 P1=104' .. sData) + -- emissione dati rinvio + elseif EMT.HEAD == 'H5' or EMT.HEAD == 'H6' then + local nPos = EgtIf( EMT.HEAD == 'H5', 91, 93) + if EMT.EXIT == 2 then nPos = nPos + 1 end + local sOut = 'M992 P1=' .. EgtNumToString( nPos, 0) .. ' P2=' .. EmtLenToString( EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( EMT.TTOTLEN, 3) + ParkLine( sOut) + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + --MyOutput( '(Disposition '..EMT.DISPIND..' = '..EMT.DISPID..')') + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') + EMT.YPOS = EgtGetInfo( EMT.DISPID, 'YPOS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- terminazione lista utensili + ParkLine( 'G990 (Tool List End)') + -- abilito numerazione linee + EMT.NUM = false + EMT.LINENBR = 0 + ParkLine( 'M28') + -- emissione dati di macchina + local sOut = 'M114'..' P1='..EmtLenToString( LoadT, 2)..' P2='..EmtLenToString( MinY, 2)..' P3='..EmtLenToString( MaxY, 2).. + ' P4='..EmtLenToString( MinV, 2)..' P5='..EmtLenToString( MaxV, 2)..' P6='..EmtLenToString( MillOffs, 2).. + ' P7='..EmtLenToString( SawOffs, 2)..' P8='..EmtLenToString( ParkY, 2)..' P9='..EmtLenToString( ParkV, 2).. + ' P10='..EmtLenToString( TurnerOffs, 2)..' P11='..EmtLenToString( -DeltaTabY, 2)..' P12='..EmtLenToString( DeltaTabZ - MillOffs, 2) + if SecondSupport >= 2 then + sOut = sOut ..' P13='..EmtLenToString( AngTr1Len, 2) ..' P14='..EmtLenToString( AngTr1Offs + MillOffs,2) + --if SecondSupport == 3 then + -- sOut = sOut ..' P15='..EmtLenToString( AngTr2Len, 2) ..' P16='..EmtLenToString( AngTr2Offs + MillOffs,2) + --end + end + ParkLine( sOut) + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + if IsEnd2Phase( EMT.PHASE - 1) then + EMT.RELOAD = true + EMT.RELOAD2 = false + elseif IsStartPhase( EMT.PHASE) then + EMT.YDELTA = EMT.YPOS - LoadT + EMT.VDELTA = nil + end + end +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- reset recupero sovramateriale in X non più presente + EMT.X_OFF = nil + -- gruppo con info da BTL (se mancano prova dal gruppo di lavoro corrente) + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or EgtGetCurrMachGroup() or GDB_ID.NULL + -- dati del grezzo + local LBarra = EMT.LB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- calcolo dati pinze + local MinAccPinze = 0.3 + local MaxAccPinze = 4 + local KgMtCubo= 550 -- densità legno in Kg / metro cubo + local Massa = ( HTrave * STrave * LBarra * KgMtCubo ) / 1000000000 + local FMaxPinze = EMT.FMAXPINZE + local ForzaAtrito = 700 / 2 -- Serve per regolare P32 (700 valore reale pistone) + local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAtrito) / 1000) + if ( TempoAcc < MinAccPinze) then TempoAcc = MinAccPinze end + if ( TempoAcc > MaxAccPinze) then TempoAcc = MaxAccPinze end + local AccPinze = FMaxPinze / ( 60 * TempoAcc) + local RidFeed = 100 / Massa * 100 + if ( RidFeed > 100) then RidFeed = 100 end + if IdTrave >= 0 then + local sPrt = '( *** Part '.. EgtNumToString( IdTrave, 0) ..' ***)' + local sOut = '( SN=' .. IdTrave .. ' LBarra=' .. EmtLenToString( LBarra, 3) .. ' L='..EmtLenToString( LTrave, 3) .. + ' H=' .. EmtLenToString( HTrave, 3) .. ' S=' .. EmtLenToString( STrave, 3) .. ' )' + EMT.PRODID = EgtGetInfo( BtlInfoId, 'PRODID', 'i') or 0 + EMT.PATTID = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 0 + EMT.CUTID = EgtGetInfo( EMT.IDT, 'CUTID', 'i') or 0 + local sStart = 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=1' + if EMT.LOAD then + ParkLine( sPrt) + ParkLine( sOut) + if not TEST_USE then + ParkLine( sStart) + if PRINT_USE then + ParkLine( 'M12') + end + end + else + MyOutput( sPrt) + MyOutput( sOut) + if not TEST_USE then + MyOutput( sStart) + if PRINT_USE then + MyOutput( 'M12') + end + end + end + else + MyOutput( '(REMAIN UNLOAD)') + EMT.PRODID = nil + EMT.PATTID = nil + EMT.CUTID = nil + end + -- imposto dati pezzo + local nLoad90 = EgtGetInfo( BtlInfoId, 'LOAD90', 'i') or 0 + -- se carico barra + if EMT.LOAD or EMT.RELOAD then + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( HTrave, 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( nLoad90) .. ' P6=' .. EmtLenToString( LTrave, 2) + if EMT.LOAD then + ParkLine( sOut) + SetStartValue( 1, LBarra) + SetStartValue( 2, HTrave) + SetStartValue( 3, STrave) + SetStartValue( 6, HOverM) + else + MyOutput( sOut) + end + -- altrimenti recupero rimanenza + else + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( HTrave, 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( nLoad90) .. ' P6=' .. EmtLenToString( EgtIf( IdTrave >= 0, LTrave, LBarra), 2) + MyOutput( sOut) + MyOutput( 'M112'..' P1='..EmtLenToString( LoadT, 3).. ' P5=1 P6='..EmtLenToString( EMT.YPOS, 3)..' P7='..EmtLenToString( ParkV, 3) ..' P9='..GetFmaxClamp()) + -- aggiorno dati aggancio carrelli alla trave + EMT.YDELTA = EMT.YPOS - LoadT + EMT.VDELTA = nil + end + -- eventuale preparazione per rotazione immediata + if IsStartPhase( EMT.PHASE) and EMT.AUXSTR then + -- emissione movimento carrelli per rotazione + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + MyOutput( '( ** Rotation ** )') + end + for i = 1, #EMT.AUXSTR do + MyOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + MyOutput( 'M111 P1=20') + MyOutput( 'M111 P1=30') + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se rotazioni diverse, emetto il comando e aggiorno lo stato + if VerifyEmitRotation() then + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- se altrimenti disposizione intermedia speciale con eventuale rotazione + elseif IsMid2Phase( EMT.PHASE) then + -- emissione movimento carrelli + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + MyOutput( '( ** Rotation ** )') + end + for i = 1, #EMT.AUXSTR do + MyOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + MyOutput( 'M111 P1=20') + MyOutput( 'M111 P1=30') + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + -- se rotazioni diverse, emetto il comando e aggiorno lo stato + if VerifyEmitRotation() then + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + MyOutput( '( ** Unload ** )') + end + for i = 1, #EMT.AUXSTR do + MyOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + MyOutput( 'M111 P1=22') + -- se dopo c'è scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE + 1) then + MyOutput( 'M111 P1=32') + else + MyOutput( EgtIf( EMT.U_STD, ';', '')..'M111 P1=32') + end + -- emissione conclusione pezzo precedente (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + end + + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- se primo grezzo, reset lunghezza barra + if EMT.RAWIND == 1 then EMT.LB = 0 end + -- aggiungo la lunghezza del grezzo (solo se movimento in corner) + if EMT.RAWTYPE == 1 then + local b3Raw = EgtGetBBoxGlob( EgtGetFirstNameInGroup( EMT.RAWID, 'RawSolid'), GDB_BB.STANDARD) + local LBarra = b3Raw:getDimX() + EMT.LB = EMT.LB + LBarra + end + -- se primo grezzo, calcolo dati del pezzo + if EMT.RAWIND == 1 then + local PartId = EgtGetFirstPartInRawPart( EMT.RAWID) + if PartId then + EMT.IDT = PartId + EMT.IT = EgtGetInfo( PartId, 'PDN', 'i') or 0 + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box'), GDB_BB.STANDARD) + EMT.LT = b3Part:getDimX() + EMT.HT = b3Part:getDimY() + EMT.ST = b3Part:getDimZ() + EMT.HOVM = EgtGetInfo( EMT.RAWID, 'HOVM', 'd') or 0 + else + EMT.IDT = GDB_ID.NULL + EMT.IT = -1 + EMT.LT = 0 + EMT.HT = EMT.HT or 0 + EMT.ST = EMT.ST or 0 + EMT.HOVM = 0 + end + end + end +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOOLSEL = EMT.TCPOS..' M06' + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + --EMT.MCHNAME = EgtGetMachiningParam( MCH_MP.NAME) + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) + -- sistemazione speed + if EMT.HEAD == 'H2' then + EMT.S = EMT.S * 6 + elseif EMT.HEAD == 'H5' and EMT.EXIT == 1 then + EMT.S = -EMT.S + elseif EMT.HEAD == 'H6' and EMT.EXIT == 1 then + EMT.S = -EMT.S + end + -- determino subito se taglio di separazione di pezzo a caduta + EMT.PREFALLCUT = nil + if EMT.MCHUSERNOTES and EMT.MCHUSERNOTES:find( 'Split') then + local ClId = EgtGetFirstNameInGroup( EMT.MCHID, 'CL') + local P1Id = EgtGetFirstNameInGroup( ClId or GDB_ID.NULL, 'P1') + local sAE1 = EgtGetInfo( P1Id or GDB_ID.NULL, 'AE1') or '' + if sAE1 == '0,Fall' then + EMT.PREFALLCUT = true + end + end +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + --MyOutput( ';Mach End') + -- Emissione split + --for i = 1, #EMT.AUXCMD do + -- MyOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + MyOutput( '( ** Split ** )') + elseif EMT.AUXTYPE == 'U' then + if not EMT.ZMAX then + EmitZmax() + end + MyOutput( '( ** Unload ** )') + elseif EMT.AUXTYPE == 'P' then + if EMT.PREROT then + EmitZmax() + MyOutput( '( ** Rotation ** )') + elseif EMT.FALL then + if not EMT.ZMAX then + EmitZmax() + end + MyOutput( '( ** Fall ** )') + else + EmitZmax() + MyOutput( '( ** Split 2 ** )') + end + end + end + for i = 1, #EMT.AUXSTR do + MyOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + MyOutput( 'M111 P1=20') + MyOutput( 'M111 P1=30') + elseif EMT.AUXTYPE == 'U' then + local sP1x = EgtIf( EMT.CHY_ON, '0', '2') + MyOutput( 'M111 P1=2'..sP1x) + -- se dopo cè scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE +1) then + MyOutput( 'M111 P1=3'..sP1x) + else + MyOutput( EgtIf( EMT.U_STD, ';', '')..'M111 P1=3'..sP1x) + end + -- emissione conclusione pezzo precedente (se non è modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + elseif EMT.AUXTYPE == 'P' then + MyOutput( 'M111 P1=20') + MyOutput( 'M111 P1=30') + if EMT.FALL then + MyOutput( 'M155') + -- emissione conclusione pezzo (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + elseif not EMT.PREROT then + MyOutput( 'M77') + end + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStart() + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + EMT.MCHFIRSTFEED = true + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + if not EMT.ZMAX then + MyOutput( 'G27') + MyOutput( 'M6 T000000') + MyOutput( 'M99') + end + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + + -- se richiesto, preparo il carico barra + if EMT.LOAD or EMT.RELOAD then + PrepareLoad( EMT.AUX, true) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( EMT.AUX) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnPathEndAux() + --EgtOutLog( 'OnPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif EgtGetInfo( EMT.DISPID, 'TYPE') == 'REST' then + EMT.AUXTYPE = 'R' + else + EMT.AUXTYPE = 'P' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'P' + if Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.FALL = true + end + end + elseif EMT.AUXTYPE == 'P' then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.CHY_ON = true + EMT.AUXTYPE = 'U' + end + end + end + -- preparo a seconda del tipo + if EMT.AUXTYPE == 'R' then + -- per il carico della rimanenza dopo rotazione speciale + if EMT.RELOAD and not EMT.RELOAD2 then + PrepareLoad( EMT.AUX, false) + -- per lo scarico della rimanenza + else + PrepareResidue( EMT.AUX) + end + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnRapid() + MyBackupAxes() + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + -- decido se muovere prima testa o carrelli (standard prima testa) + local bHeadFirst = true + if not ( EMT.LOAD or EMT.RELOAD) and not EMT.ZMAX then + local DeltaT = EMT.L1 - EMT.TLAST + if ( DeltaT < -GEO.EPS_SMALL and EMT.VDELTA) or ( DeltaT > GEO.EPS_SMALL and EMT.YDELTA) then bHeadFirst = false end + end + -- sistemo movimenti + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + if not ( EMT.LOAD or EMT.RELOAD) then + if not EMT.ZMAX and #EMT.AUXSTR > 0 then + EmitZmax() + end + end + if not EMT.LOAD then + local sOut = string.gsub( string.gsub( EMT.MCHNAME..'/'..EMT.TOOL, '%(', '['), '%)', ']') + MyOutput( '( * ' .. sOut .. ' * )') + end + -- primo posizionamento + EmtResetPrev() + local bZmax = ( #EMT.AUXSTR > 0 or EMT.TOOL ~= EMT.PREVTOOL or EMT.L3 > -1) + local sOut = 'M101 P1=1' .. ' P2=' .. EmtLenToString( EMT.L2, 3) .. ' P3=' .. EmtLenToString( EMT.L3, 3) .. + ' P4=' .. EgtNumToString( EMT.R2, 3) .. ' P5=' .. EgtNumToString( EMT.R1, 3) .. + ' P6=' .. AdjustTcPos( false) .. ' P7=' .. EgtNumToString( EMT.S, 0) .. + ' P8=0' .. ' P9=0' .. ' P10=' .. EgtIf( bZmax, '3', '4') + if EMT.ST > BeamHeightForFixRot then + sOut = sOut .. ' P12=1' + end + if EMT.LOAD then + ParkLine( sOut) + else + MyOutput( sOut) + end + sOut = 'M101 P1=2' + if EMT.LOAD then + ParkLine( sOut) + else + if bHeadFirst then MyOutput( sOut) end + end + -- se prima lavorazione + if EMT.LOAD then + --for i = 1, #EMT.AUXCMD do + -- MyOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + local bOnlyCharY = true + for i = 1, #EMT.AUXSTR do + ParkLine( EMT.AUXSTR[i]) + if string.find( EMT.AUXSTR[i], 'P1=10', 1, true) then bOnlyCharY = false end + end + EMT.AUXSTR = {} + sOut = EgtIf( bOnlyCharY, 'M111 P1=21', 'M111 P1=20') + ParkLine( sOut) + sOut = EgtIf( bOnlyCharY, 'M111 P1=31', 'M111 P1=30') + ParkLine( sOut) + sOut = string.gsub( string.gsub( EMT.MCHNAME..'/'..EMT.TOOL, '%(', '['), '%)', ']') + ParkLine( '( * ' .. sOut ..' * )') + sOut = 'M101 P1=3' + ParkLine( sOut) + local sY, sA + if EMT.YDELTA then + sY = EmtLenToString( EMT.L1 + EMT.YDELTA) + sA = '1' + else + sY = EmtLenToString( ParkY) + sA = '2' + end + local sV, sB + if EMT.VDELTA then + sV = EmtLenToString( EMT.L1 + EMT.VDELTA) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + sOut = 'M112 P1='..EmtLenToString( EMT.L1, 3)..' P3='..sA..' P4='..sB..' P5=0 P6='..sY..' P7='..sV..' P9='..GetFmaxClamp() + ParkLine( sOut) + EMT.LOAD = false + -- emissione prime linee speciali e linee parcheggiate + EmitStartValues() + MyOutput( ';LISTA = ' .. tostring( EMT.PRODID)) + EmitParkedLines() + -- altrimenti lavorazione successiva + else + -- eventuale G111 + --for i = 1, #EMT.AUXCMD do + -- MyOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + MyOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if not ( EMT.POSTROT or EMT.RELOAD) then + MyOutput( 'M111 P1=20') + MyOutput( 'M111 P1=30') + else + MyOutput( 'M111 P1=21') + MyOutput( 'M111 P1=31') + end + end + EMT.AUXSTR = {} + local sY, sA + if EMT.YDELTA then + sY = EmtLenToString( EMT.L1 + EMT.YDELTA - ( EMT.X_OFF or 0)) + sA = '1' + else + sY = EmtLenToString( EgtIf( EMT.YPOS, EMT.YPOS, ParkY)) + sA = '2' + end + local sV, sB + if EMT.VDELTA then + sV = EmtLenToString( EMT.L1 + EMT.VDELTA - ( EMT.X_OFF or 0)) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + -- se taglio di coda senza residuo da scaricare, emetto M175 per accelerare il carico della barra successiva + if EMT.MCHUSERNOTES and EMT.MCHUSERNOTES:find( 'Cut') then + MyOutput( 'M175') + end + if bHeadFirst then + sOut = 'M101 P1=3' + MyOutput( sOut) + end + sOut = 'M112 P1=' .. EmtLenToString( EMT.L1, 3) ..' P3='..sA..' P4='..sB..' P6='..sY..' P7='..sV..' P9=' .. GetFmaxClamp() + MyOutput( sOut) + if not bHeadFirst then + sOut = 'M101 P1=2' + MyOutput( sOut) + sOut = 'M101 P1=3' + MyOutput( sOut) + end + EMT.POSTROT = false + EMT.RELOAD = false + EMT.RELOAD2 = nil + end + -- se taglio di separazione prima di scarico a caduta, emissione stop tappeto scarico trucioli + if EMT.PREFALLCUT then + MyOutput( 'M29') + EMT.PREFALLCUT = nil + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se alto in Z (non serve l'avvicinamento finale) + if EMT.FLAG == 2 then + -- aggiorno valori come precedenti + EMT.TLAST = EMT.L1b + EmtUpdatePrev() + return + -- altrimenti ripristino i valori originali degli assi + else + MyRestoreAxes() + end + end + -- se standard + if EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + MyOutput( 'M102 P1=' .. GetFaceCode()) + MyOutput( 'M98') + sOut = 'M6 T1' .. AdjustToolKinematic() .. AdjustTcPos( true) + MyOutput( sOut) + MyOutput( 'G24' .. EMT.IPLGLSTR) + -- forzo successiva emissione assi rotanti + EMT.R1p = nil + EMT.R2p = nil + else + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + end + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + MyOutput( sOut) + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmitZmax( true) + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- se altrimenti rotazione a Z max + elseif EMT.FLAG == 5 then + -- viene gestito all'inizio della lavorazione successiva + -- altrimenti errore + else + error( "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EMT.TLAST = EMT.L1b + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + MyBackupAxes() + EMT.TLAST = EMT.L1 + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente (se presente devo annullare l'offset in X per sovramateriale di testa) + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + if EMT.X_OFF then EMT.L1 = EMT.L1 - EMT.X_OFF end + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + MyOutput( 'M102 P1=' .. GetFaceCode()) + MyOutput( 'M98') + local sOut = 'M6 T1' .. AdjustToolKinematic() .. AdjustTcPos( true) + MyOutput( sOut) + MyOutput( 'G24' .. EMT.IPLGLSTR) + -- emissione movimento + EMT.R1p = nil + EMT.R2p = nil + sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + MyOutput( sOut) + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + MyOutput( 'M97') + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sL1, bL1 = EmtGetAxis( 'L1') + local sL2, bL2 = EmtGetAxis( 'L2') + local sL3, bL3 = EmtGetAxis( 'L3') + local sR1, bR1 = EmtGetAxis( 'R1') + local sR2, bR2 = EmtGetAxis( 'R2') + local sAxes = sL1 .. sL2 .. sL3 .. sR2 .. sR1 + -- se nulla da emettere, esco + if #sAxes == 0 then return end + -- aggiungo feed + local sFeed = EmtGetFeed() + -- emetto linea + MyOutput( "G1"..sAxes..sFeed) + + -- arresto preciso in angoli di fresature per utensili (non penne) di piccolo diametro + if EMT.MCHTYPE == MCH_MY.MILLING and EMT.TTOTDIAM < 15 and abs( EMT.S) > 1000 and ( bL1 or bL2) and not bL3 then + MyOutput( 'G9') + end + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + MyBackupAxes() + EMT.TLAST = EMT.L1 + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + MyOutput( 'M97') + end + + -- non modale su archi + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString( EMT.RR, EMT.DECNUM) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- emetto arco + MyOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd, bSkipPress) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + elseif sCmd == '1' then + return '2' + -- chiuso con pressore attivato + elseif sCmd == '2' then + return EgtIf( bSkipPress, '2', '0') + end +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd, bStart) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = ' P4=111' + EMT.SB = ' P5=112' + EMT.SC = ' P6=141' + EMT.SD = ' P7=141' + EMT.SE = ' P8=0' + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + if bStart then + EMT.RELOAD = false + else + EMT.RELOAD2 = true + end + for i = 1, #EMT.AUXSTR do + EMT.AUXSTR[i] = string.gsub( EMT.AUXSTR[i], 'P1=11', 'P1=10') + end + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..sPar2..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.YPOS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sYTaking = ' P2='..EmtLenToString( Cmd[3] + TurnerOffs) + local sOut = 'M111 P1=11' .. sYTaking .. ' P4=75 P5=110 P8=0 P9=' .. GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + SetStartValue( 4, Cmd[3] + TurnerOffs) + SetStartValue( 5, 110) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sPar6 = EgtIf( Cmd[6] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', sPar6 .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2]) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2]) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + if not FindM111P4EQ76( EMT.AUXSTR) then + local sYLoad = ' P2=' .. EmtLenToString( LoadT) + local sOut = 'M111 P1=11' .. sYLoad .. ' P4=76 P5=110 P8=0 P9=' .. GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = EgtIf( EMT.YDELTA, ' P4=112', ' P4=111') + EMT.SB = EgtIf( EMT.YDELTA, ' P5=112', ' P5=111') + EMT.SC = EgtIf( EMT.VDELTA, ' P6=142', ' P6=141') + EMT.SD = EgtIf( EMT.VDELTA, ' P7=142', ' P7=141') + EMT.SE = EgtIf( EMT.YDELTA, ' P8=1', ' P8=2') + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..sPar2..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.YPOS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sPar6 = EgtIf( Cmd[6] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', sPar6 .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2]) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2]) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd) + + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.YDELTA, ' P4=112', ' P4=111') + EMT.SB = EgtIf( EMT.YDELTA, ' P5=112', ' P5=111') + EMT.SC = EgtIf( EMT.VDELTA, ' P6=142', ' P6=141') + EMT.SD = EgtIf( EMT.VDELTA, ' P7=142', ' P7=141') + EMT.SE = EgtIf( EMT.YDELTA, ' P8=1', ' P8=2') + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + if not EMT.UNL then + sOut = 'M111 P1=10'..sPar2..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + else + sOut = 'M111 P1=10'..sPar2..Cmd[3]..' P6=141 P7=84 P8=0 P9='..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sPar6 = EgtIf( Cmd[6] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', sPar6 .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sOut = 'M111 P1=10'..' P2='..Cmd[3]..' P4=112 P5=112 P6=142 P7=142 P8=2 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.YPOS = tonumber( Cmd[3]) + end + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd) + + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sP1 = EgtIf( EMT.CHY_ON, '10', '12') + local sP7 = '84' + if not EMT.U_STD then + sP7 = EgtIf( EMT.U_MAN ~= 1, '85', '114') + EMT.U_MAN = EgtIf( EMT.U_MAN == 1, nil, 1) + end + local sP8 = EgtIf( EMT.PHASE == EgtGetPhaseCount() or IsEnd2Phase( EMT.PHASE), '0', '1') + local sOut = 'M111 P1='..sP1..' P3='..Cmd[3]..' P6=141 P7='..sP7..' P8='..sP8..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[4] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sP1 = EgtIf( EMT.CHY_ON, '10', '12') + local sP45 = EgtIf( EMT.PHASE == EgtGetPhaseCount() or IsEnd2Phase( EMT.PHASE), '111', '112') + local sOut = 'M111 P1='..sP1..' P3='..Cmd[5]..' P4=' .. sP45 .. ' P5=' .. sP45 .. ' P6=142 P7=141 P8=2 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.U_STD = true + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. EgtIf( Cmd[2] == '0', ' 0', ' 1') + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. EgtIf( Cmd[2] == '0', ' 0', ' 1') + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + -- non interessa + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.YDELTA, ' P4=112', ' P4=111') + EMT.SB = EgtIf( EMT.YDELTA, ' P5=112', ' P5=111') + EMT.SC = EgtIf( EMT.VDELTA, ' P6=142', ' P6=141') + EMT.SD = EgtIf( EMT.VDELTA, ' P7=142', ' P7=141') + EMT.SE = EgtIf( EMT.YDELTA, ' P8=1', ' P8=2') + end + -- se è pre-rotazione + if Cmd[2] == 'Pre-Rotation' then + EMT.PREROT = true + elseif Cmd[2] == 'SplitRot' then + EMT.SPLITROT = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + local sP23 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + if not EMT.PREROT then + sOut = 'M111'..' P1=10'..sP23..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + else + sOut = 'M111 P1=10'..sP23..Cmd[3]..' P4=86 P5=87 P6=141 P8=0 P9='..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sP2 = '' + local sP3 = '' + if Cmd[2] == 'Y' then + sP2 = ' P2=' .. Cmd[3] + elseif Cmd[4] == 'Y' then + sP2 = ' P2=' .. Cmd[5] + end + if Cmd[2] == 'V' then + sP3 = ' P3=' .. Cmd[3] + elseif Cmd[4] == 'V' then + sP3 = ' P3=' .. Cmd[5] + end + local sOut = 'M111 P1=10'..sP2..sP3..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sP2 = '' + local sP3 = '' + if Cmd[2] == 'Y' then + sP2 = ' P2=' .. Cmd[3] + elseif Cmd[4] == 'Y' then + sP2 = ' P2=' .. Cmd[5] + elseif Cmd[6] == 'Y' then + sP2 = ' P2=' .. Cmd[7] + end + if Cmd[2] == 'V' then + sP3 = ' P3=' .. Cmd[3] + elseif Cmd[4] == 'V' then + sP3 = ' P3=' .. Cmd[5] + elseif Cmd[6] == 'V' then + sP3 = ' P3=' .. Cmd[7] + end + local sOut = 'M111 P1=10'..sP2..sP3..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + if EMT.SPLITROT then + EMT.SA = EgtIf( Cmd[2] ~= '0', ' P4=11' .. CalcCharStatus( Cmd[2], true), ' P4=86') + EMT.SB = EgtIf( Cmd[2] ~= '0', ' P5=11' .. CalcCharStatus( Cmd[2], true), ' P5=87') + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + else + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + end + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = ' P5=112' + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + EMT.POSTROT = false + for i = 1, #EMT.AUXSTR do + EMT.AUXSTR[i] = string.gsub( EMT.AUXSTR[i], 'P1=11', 'P1=10') + end + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + -- su NUM si pone E80058=0, con TPA non sembra necessaria una equivalente impostazione + local sYTaking = ' P2='..EmtLenToString( Cmd[3] - EMT.HOVM) + local sOut = 'M111 P1=11'..sYTaking..' P4=75 P5=112 P8=0 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + local sYLoad = ' P2='..EmtLenToString( LoadT) + local sOut = 'M111 P1=11'..sYLoad..' P4=76'..EMT.SB..' P8=0 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function MyBackupAxes() + EMT.L1b = EMT.L1 + EMT.L2b = EMT.L2 + EMT.L3b = EMT.L3 + EMT.R1b = EMT.R1 + EMT.R2b = EMT.R2 + EMT.R3b = EMT.R3 + EMT.R4b = EMT.R4 + EMT.RRb = EMT.RR + EMT.C1b = EMT.C1 + EMT.C2b = EMT.C2 + EMT.C3b = EMT.C3 +end + +--------------------------------------------------------------------- +function MyRestoreAxes() + EMT.L1 = EMT.L1b + EMT.L2 = EMT.L2b + EMT.L3 = EMT.L3b + EMT.R1 = EMT.R1b + EMT.R2 = EMT.R2b + EMT.R3 = EMT.R3b + EMT.R4 = EMT.R4b + EMT.RR = EMT.RRb + EMT.C1 = EMT.C1b + EMT.C2 = EMT.C2b + EMT.C3 = EMT.C3b +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + if EMT.REFLOC then + local vtE + if EMT.HEAD == 'H1' or EMT.HEAD == 'H2' then + local Len = EMT.TLEN + EgtIf( EMT.HEAD == 'H1', MillOffs, abs( SawOffs)) + local LenRef = MillOffs + vtE = Vector3d( EMT.EXTR) * Len - Z_AX() * LenRef + elseif EMT.HEAD == 'H3' then + local LenAux = ChSawLen + MillOffs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + vtE = vtAux * LenAux - Z_AX() * LenRef + else -- 'H5' + local Len = EMT.TLEN + AngTr1Len + local LenAux = MillOffs + AngTr1Offs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2) + vtE = Vector3d( EMT.EXTR) * Len + vtAux * LenAux - Z_AX() * LenRef + end + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - DeltaTabY - vtE:getY() + EMT.L3 = EMT.L3 - DeltaTabZ - vtE:getZ() + end + + if EMT.X_OFF then EMT.L1 = EMT.L1 + EMT.X_OFF end + + EmtAdjustLinearAxes() + + if not EMT.REFLOC then + EMT.L2 = - EMT.L2 + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function AdjustToolKinematic() + if EMT.HEAD == 'H1' or EMT.HEAD == 'H3' then + return '01' + elseif EMT.HEAD == 'H2' then + return '02' + elseif EMT.HEAD == 'H5' then + return EgtIf( EMT.EXIT == 1, '11', '12') + elseif EMT.HEAD == 'H6' then + return EgtIf( EMT.EXIT == 1, '21', '22') + else + EmtSetLastError( 1211, 'Head not allowed') + end +end + +--------------------------------------------------------------------- +function AdjustTcPos( bLen3) + local sPos = EMT.TCPOS:gsub( 'T', '') + if sPos == '91' then + if EMT.EXIT == 2 then + sPos = '92' + end + elseif sPos == '93' then + if EMT.EXIT == 2 then + sPos = '94' + end + elseif sPos == '101' then + if abs( EMT.R3 - 0) < 0.1 then + sPos = '101' + elseif abs( EMT.R3 - 270) < 0.1 then + sPos = '102' + elseif abs( EMT.R3 - 180) < 0.1 then + sPos = '103' + elseif abs( EMT.R3 - 90) < 0.1 then + sPos = '104' + else + EmtSetLastError( 1210, 'Chain saw orientation not allowed') + end + end + if bLen3 then + if #sPos == 1 then + sPos = '00' .. sPos + elseif #sPos == 2 then + sPos = '0' .. sPos + end + end + return sPos +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + LoadT + if EMT.X_OFF then xS = xS + EMT.X_OFF end + local ptS = Point3d( xS, 0, 0) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H3' then + vtE = Vector3d( EMT.EXTR) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --MyOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local vtX = EMT.IPLGLFR:getVersX() + local vtY = EMT.IPLGLFR:getVersY() + local vtZ = EMT.IPLGLFR:getVersZ() + EMT.IPLGLSTR = ' X0 Y' .. EmtLenToString( xS, EMT.DECNUM) .. ' Z0' .. + ' A' .. EgtNumToString( - vtX:getY(), 6) .. ' B' .. EgtNumToString( vtX:getX(), 6) .. ' C' .. EgtNumToString( vtX:getZ(), 6) .. + ' I' .. EgtNumToString( - vtY:getY(), 6) .. ' J' .. EgtNumToString( vtY:getX(), 6) .. ' K' .. EgtNumToString( vtY:getZ(), 6) .. + ' P' .. EgtNumToString( - vtZ:getY(), 6) .. ' Q' .. EgtNumToString( vtZ:getX(), 6) .. ' R' .. EgtNumToString( vtZ:getZ(), 6) + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function VerifyEmitRotation() + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- se sono uguali non devo fare alcunchè + if nRot == nPrevRot then + return false + end + -- rotazione automatica o manuale (sempre con il medesimo comando) + local nDeltaRot = nRot - nPrevRot + local sOut = 'M180 P1=' .. tostring( nDeltaRot) + MyOutput( sOut) + return true +end + +--------------------------------------------------------------------- +function GetFaceCode() + if EMT.YDELTA and EMT.VDELTA then + return '3' + elseif EMT.YDELTA then + return '6' + else + return '5' + end +end + +--------------------------------------------------------------------- +function EmitZmax( bReset) + if bReset then + MyOutput( 'G27') + MyOutput( 'M6 T000000') + MyOutput( 'M99') + end + MyOutput( 'M116') +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE / 1000, 0) +end + +--------------------------------------------------------------------- +function FindM111P4EQ76( vStr) + for i = 1, #vStr do + if vStr[i]:find( 'M111', 1, true) and vStr[i]:find( 'P4=76', 1, true) then + return true + end + end + return false +end + +--------------------------------------------------------------------- +--------------------------------------------------------------------- +function MyOutput( sOut) + if not PRINT_USE then + EmtOutput( sOut) + else + local vsOut = { ';', '(', 'M6 T000000', 'G49', 'M993', 'M992', 'G990', 'M113', 'M12', 'M02'} + local bOut = false + for i = 1, #vsOut do + if sOut:find( vsOut[i], 1, true) == 1 then + bOut = true + break + end + end + if bOut then EmtOutput( sOut) end + end +end + +--------------------------------------------------------------------- +local ParkedLines = {} + +--------------------------------------------------------------------- +function ParkLine( sLine) + table.insert( ParkedLines, sLine) +end + +--------------------------------------------------------------------- +function EmitParkedLines() + for i = 1, #ParkedLines do + MyOutput( ParkedLines[i]) + end + ParkedLines = {} +end + +--------------------------------------------------------------------- +local StartValues = {} + +--------------------------------------------------------------------- +function SetStartValue( nI, dVal) + StartValues[nI] = dVal +end + +--------------------------------------------------------------------- +function EmitStartValues() + local sLine = '' + for i = 1, 10 do + sLine = sLine .. string.format( ';V%02d=', i) .. EgtNumToString( StartValues[i] or 0, 3) + end + MyOutput( sLine) +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.TPA.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.TPA.mlpe new file mode 100644 index 0000000..bf4756e --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.TPA.mlpe @@ -0,0 +1,1704 @@ +-- Processore macchina Essetre-FAST by EgalTech s.r.l. 2022/01/21 +-- Con controllo numerico TPA +-- 2020/03/23 DS ver.2.2c3 Nei movimenti interpolati si usano 5 decimali, nei G24 6 decimali. +-- 2020/04/27 DS ver.2.2d3 Aggiunta gestione scarico speciale senza spostamento finale pezzo. +-- 2020/04/30 DS ver.2.2d5 Modifiche a scarico manuale. +-- 2020/05/19 DS ver.2.2e2 Modifiche per rotazione 90 gradi. +-- 2020/05/27 DS ver.2.2e6 Aggiunta gestione ordine posizionamento iniziale testa e carrelli quando non è Zmax. +-- 2020/06/10 DS ver.2.2f1 Aggiunta emissione di pezzo finito (M113..) dopo pezzo caduto (M155). +-- 2020/06/11 DS ver 2.2f2 Nel contenuto dei commenti si sostituiscono le parentesi tonde con le quadre. +-- 2020/09/03 DS ver 2.2i1 A M114 aggiunti P11 e P12. Modificato M102 P1=. Modificati commenti. +-- 2020/09/16 DS ver 2.2i2 OFFSETX e OFFSETZ da TS3v7 ora devono contenere tutto lo spiazzamento non più solo il delta dal nominale. +-- 2020/09/17 DS ver 2.2i3 Correzione per il segno di OFFSETX. +-- 2021/01/08 DS ver 2.3a1 M115 esteso con P6 e usato per ogni pezzo. Eliminati 0 inutili. +-- 2021/04/07 DS ver 2.3d2 Gestione risalita Zmax (M116) anche allo scarico. +-- 2021/04/23 DS ver 2.3d3 Se non c'è BtlInfo cerco il gruppo di lavoro corrente. +-- 2021/05/25 DS ver 2.3e3 Aggiunta gestione rapido con Flag=5. +-- 2021/06/04 DS ver 2.3f2 Gestione parametro P12=1 su M101 per ruotare in alto quando necessario. +-- 2021/07/21 DS ver 2.3g5 Si imposta LOAD90 su tutti i pezzi di una barra tramite M115. Aggiunto M29 prima di taglio di pezzo a caduta. +-- 2021/08/03 DS ver 2.3h3 Aggiunto arresto preciso negli angoli (G9) in fresature con utensili di piccolo diametro. +-- 2022/01/21 DS ver 2.4a1 In V07 si imposta nLoad90. + +-- Variabili di modulo +local MLE_INFO = 'Essetre-FAST.TPA.mlpe ver.'..PP_VER..' by EgalTech s.r.l.' +local TEST_USE = false + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.DECNUM = 5 -- numero di decimali dopo la virgola + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.FMAXPINZE = 154000 -- feed massima pinze +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Intestazioni + if EMT.INFO then + ParkLine( '('..EMT.INFO..')') + else + ParkLine( '(Program Start)') + end + ParkLine( '('.. MLE_INFO..')') + -- Se modalità test, aggiungo linee per muovere tappeto e alzare la testa (in automatico viene fatto dal main residente) + if TEST_USE then + ParkLine( 'M199') + end + -- Cerco primo utensile su testa 1 + EMT.TOOL_1, EMT.TLEN_1 = FindFirstToolOnHead( 'H1') + -- Dichiaro inizio + EMT.FIRST = true + EMT.TLAST = nil + -- Inizializzazioni varie + ParkLine( 'M6 T000000') + ParkLine( 'G49') + -- Inizio lista utensili + ParkLine( 'M993 (Tool List Start)') +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Arresto mandrino + EmtOutput( 'M05') + -- Emissione scarico + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + elseif EMT.AUXTYPE == 'R' then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + elseif EMT.AUXTYPE == 'U' then + local sP1x = EgtIf( EMT.CHY_ON, '0', '2') + EmtOutput( 'M111 P1=2'..sP1x) + EmtOutput( EgtIf( EMT.U_STD, ';', '')..'M111 P1=3'..sP1x) + -- emissione conclusione pezzo precedente (se non si è in test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + EmtOutput( sEnd) + end + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.RELOAD = nil + EMT.RELOAD2 = nil + -- Termino il programma + EmtOutput( 'M02') +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensili + if EMT.HEAD == 'H1' then + local sOut = 'M992 P1=' .. EMT.TCPOS:gsub( 'T', '') .. ' P2=' .. EmtLenToString( EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( EMT.TTOTLEN, 3) + ParkLine( sOut) + -- cerco posizione di attrezzaggio del primo utensile di lavorazione + if EMT.TOOL == EMT.TOOL_1 and EMT.TLEN_1 < LONG_TOOL_MINLEN then + EMT.TCPOS_1 = EMT.TCPOS + end + -- emissione dati lama + elseif EMT.HEAD == 'H2' then + local sOut = 'M992 P1=' .. EMT.TCPOS:gsub( 'T', '') .. ' P2=' .. EmtLenToString( EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( EMT.TTOTLEN, 3) + ParkLine( sOut) + -- emissione dati sega a catena + elseif EMT.HEAD == 'H3' then + local sData = ' P2=' .. EmtLenToString( ChSawLen, 3) .. ' P3=' .. EmtLenToString( EMT.TLEN, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( ChSawLen, 3) + ParkLine( 'M992 P1=101' .. sData) + ParkLine( 'M992 P1=102' .. sData) + ParkLine( 'M992 P1=103' .. sData) + ParkLine( 'M992 P1=104' .. sData) + -- emissione dati rinvio + elseif EMT.HEAD == 'H5' or EMT.HEAD == 'H6' then + local nPos = EgtIf( EMT.HEAD == 'H5', 91, 93) + if EMT.EXIT == 2 then nPos = nPos + 1 end + local sOut = 'M992 P1=' .. EgtNumToString( nPos, 0) .. ' P2=' .. EmtLenToString( EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( EMT.TTOTLEN, 3) + ParkLine( sOut) + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + --EmtOutput( '(Disposition '..EMT.DISPIND..' = '..EMT.DISPID..')') + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') + EMT.YPOS = EgtGetInfo( EMT.DISPID, 'YPOS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- terminazione lista utensili + ParkLine( 'G990 (Tool List End)') + -- abilito numerazione linee + EMT.NUM = false + EMT.LINENBR = 0 + ParkLine( 'M28') + -- emissione dati di macchina + local sOut = 'M114'..' P1='..EmtLenToString( LoadT, 2)..' P2='..EmtLenToString( MinY, 2)..' P3='..EmtLenToString( MaxY, 2).. + ' P4='..EmtLenToString( MinV, 2)..' P5='..EmtLenToString( MaxV, 2)..' P6='..EmtLenToString( MillOffs, 2).. + ' P7='..EmtLenToString( SawOffs, 2)..' P8='..EmtLenToString( ParkY, 2)..' P9='..EmtLenToString( ParkV, 2).. + ' P10='..EmtLenToString( TurnerOffs, 2)..' P11='..EmtLenToString( -DeltaTabY, 2)..' P12='..EmtLenToString( DeltaTabZ - MillOffs, 2) + if SecondSupport >= 2 then + sOut = sOut ..' P13='..EmtLenToString( AngTr1Len, 2) ..' P14='..EmtLenToString( AngTr1Offs + MillOffs,2) + --if SecondSupport == 3 then + -- sOut = sOut ..' P15='..EmtLenToString( AngTr2Len, 2) ..' P16='..EmtLenToString( AngTr2Offs + MillOffs,2) + --end + end + ParkLine( sOut) + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + if IsEnd2Phase( EMT.PHASE - 1) then + EMT.RELOAD = true + EMT.RELOAD2 = false + elseif IsStartPhase( EMT.PHASE) then + EMT.YDELTA = EMT.YPOS - LoadT + EMT.VDELTA = nil + end + end +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- reset recupero sovramateriale in X non più presente + EMT.X_OFF = nil + -- gruppo con info da BTL (se mancano prova dal gruppo di lavoro corrente) + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or EgtGetCurrMachGroup() or GDB_ID.NULL + -- dati del grezzo + local LBarra = EMT.LB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- calcolo dati pinze + local MinAccPinze = 0.3 + local MaxAccPinze = 4 + local KgMtCubo= 550 -- densità legno in Kg / metro cubo + local Massa = ( HTrave * STrave * LBarra * KgMtCubo ) / 1000000000 + local FMaxPinze = EMT.FMAXPINZE + local ForzaAtrito = 700 / 2 -- Serve per regolare P32 (700 valore reale pistone) + local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAtrito) / 1000) + if ( TempoAcc < MinAccPinze) then TempoAcc = MinAccPinze end + if ( TempoAcc > MaxAccPinze) then TempoAcc = MaxAccPinze end + local AccPinze = FMaxPinze / ( 60 * TempoAcc) + local RidFeed = 100 / Massa * 100 + if ( RidFeed > 100) then RidFeed = 100 end + if IdTrave >= 0 then + local sPrt = '( *** Part '.. EgtNumToString( IdTrave, 0) ..' ***)' + local sOut = '( SN=' .. IdTrave .. ' LBarra=' .. EmtLenToString( LBarra, 3) .. ' L='..EmtLenToString( LTrave, 3) .. + ' H=' .. EmtLenToString( HTrave, 3) .. ' S=' .. EmtLenToString( STrave, 3) .. ' )' + EMT.PRODID = EgtGetInfo( BtlInfoId, 'PRODID', 'i') or 0 + EMT.PATTID = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 0 + EMT.CUTID = EgtGetInfo( EMT.IDT, 'CUTID', 'i') or 0 + local sStart = 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=1' + if EMT.LOAD then + ParkLine( sPrt) + ParkLine( sOut) + if not TEST_USE then ParkLine( sStart) end + else + EmtOutput( sPrt) + EmtOutput( sOut) + if not TEST_USE then EmtOutput( sStart) end + end + else + EmtOutput( '(REMAIN UNLOAD)') + EMT.PRODID = nil + EMT.PATTID = nil + EMT.CUTID = nil + end + -- imposto dati pezzo + local nLoad90 = EgtGetInfo( BtlInfoId, 'LOAD90', 'i') or 0 + -- se carico barra + if EMT.LOAD or EMT.RELOAD then + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( HTrave, 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( nLoad90) .. ' P6=' .. EmtLenToString( LTrave, 2) + if EMT.LOAD then + ParkLine( sOut) + SetStartValue( 1, LBarra) + SetStartValue( 2, HTrave) + SetStartValue( 3, STrave) + SetStartValue( 6, HOverM) + SetStartValue( 7, nLoad90) + else + EmtOutput( sOut) + end + -- altrimenti recupero rimanenza + else + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( HTrave, 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( nLoad90) .. ' P6=' .. EmtLenToString( EgtIf( IdTrave >= 0, LTrave, LBarra), 2) + EmtOutput( sOut) + EmtOutput( 'M112'..' P1='..EmtLenToString( LoadT, 3).. ' P5=1 P6='..EmtLenToString( EMT.YPOS, 3)..' P7='..EmtLenToString( ParkV, 3) ..' P9='..GetFmaxClamp()) + -- aggiorno dati aggancio carrelli alla trave + EMT.YDELTA = EMT.YPOS - LoadT + EMT.VDELTA = nil + end + -- eventuale preparazione per rotazione immediata + if IsStartPhase( EMT.PHASE) and EMT.AUXSTR then + -- emissione movimento carrelli per rotazione + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmtOutput( '( ** Rotation ** )') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se rotazioni diverse, emetto il comando e aggiorno lo stato + if VerifyEmitRotation() then + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- se altrimenti disposizione intermedia speciale con eventuale rotazione + elseif IsMid2Phase( EMT.PHASE) then + -- emissione movimento carrelli + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmtOutput( '( ** Rotation ** )') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + -- se rotazioni diverse, emetto il comando e aggiorno lo stato + if VerifyEmitRotation() then + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmtOutput( '( ** Unload ** )') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'M111 P1=22') + -- se dopo c'è scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE + 1) then + EmtOutput( 'M111 P1=32') + else + EmtOutput( EgtIf( EMT.U_STD, ';', '')..'M111 P1=32') + end + -- emissione conclusione pezzo precedente (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + EmtOutput( sEnd) + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + end + + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- se primo grezzo, reset lunghezza barra + if EMT.RAWIND == 1 then EMT.LB = 0 end + -- aggiungo la lunghezza del grezzo (solo se movimento in corner) + if EMT.RAWTYPE == 1 then + local b3Raw = EgtGetBBoxGlob( EgtGetFirstNameInGroup( EMT.RAWID, 'RawSolid'), GDB_BB.STANDARD) + local LBarra = b3Raw:getDimX() + EMT.LB = EMT.LB + LBarra + end + -- se primo grezzo, calcolo dati del pezzo + if EMT.RAWIND == 1 then + local PartId = EgtGetFirstPartInRawPart( EMT.RAWID) + if PartId then + EMT.IDT = PartId + EMT.IT = EgtGetInfo( PartId, 'PDN', 'i') or 0 + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box'), GDB_BB.STANDARD) + EMT.LT = b3Part:getDimX() + EMT.HT = b3Part:getDimY() + EMT.ST = b3Part:getDimZ() + EMT.HOVM = EgtGetInfo( EMT.RAWID, 'HOVM', 'd') or 0 + else + EMT.IDT = GDB_ID.NULL + EMT.IT = -1 + EMT.LT = 0 + EMT.HT = EMT.HT or 0 + EMT.ST = EMT.ST or 0 + EMT.HOVM = 0 + end + end + end +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOOLSEL = EMT.TCPOS..' M06' + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + --EMT.MCHNAME = EgtGetMachiningParam( MCH_MP.NAME) + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) + -- sistemazione speed + if EMT.HEAD == 'H2' then + EMT.S = EMT.S * 6 + elseif EMT.HEAD == 'H5' and EMT.EXIT == 1 then + EMT.S = -EMT.S + elseif EMT.HEAD == 'H6' and EMT.EXIT == 1 then + EMT.S = -EMT.S + end + -- determino subito se taglio di separazione di pezzo a caduta + EMT.PREFALLCUT = nil + if EMT.MCHUSERNOTES and EMT.MCHUSERNOTES:find( 'Split') then + local ClId = EgtGetFirstNameInGroup( EMT.MCHID, 'CL') + local P1Id = EgtGetFirstNameInGroup( ClId or GDB_ID.NULL, 'P1') + local sAE1 = EgtGetInfo( P1Id or GDB_ID.NULL, 'AE1') or '' + if sAE1 == '0,Fall' then + EMT.PREFALLCUT = true + end + end +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + --EmtOutput( ';Mach End') + -- Emissione split + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmtOutput( '( ** Split ** )') + elseif EMT.AUXTYPE == 'U' then + if not EMT.ZMAX then + EmitZmax() + end + EmtOutput( '( ** Unload ** )') + elseif EMT.AUXTYPE == 'P' then + if EMT.PREROT then + EmitZmax() + EmtOutput( '( ** Rotation ** )') + elseif EMT.FALL then + if not EMT.ZMAX then + EmitZmax() + end + EmtOutput( '( ** Fall ** )') + else + EmitZmax() + EmtOutput( '( ** Split 2 ** )') + end + end + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + elseif EMT.AUXTYPE == 'U' then + local sP1x = EgtIf( EMT.CHY_ON, '0', '2') + EmtOutput( 'M111 P1=2'..sP1x) + -- se dopo cè scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE +1) then + EmtOutput( 'M111 P1=3'..sP1x) + else + EmtOutput( EgtIf( EMT.U_STD, ';', '')..'M111 P1=3'..sP1x) + end + -- emissione conclusione pezzo precedente (se non è modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + EmtOutput( sEnd) + end + elseif EMT.AUXTYPE == 'P' then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + if EMT.FALL then + EmtOutput( 'M155') + -- emissione conclusione pezzo (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + EmtOutput( sEnd) + end + elseif not EMT.PREROT then + EmtOutput( 'M77') + end + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStart() + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + EMT.MCHFIRSTFEED = true + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + if not EMT.ZMAX then + EmtOutput( 'G27') + EmtOutput( 'M6 T000000') + EmtOutput( 'M99') + end + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + + -- se richiesto, preparo il carico barra + if EMT.LOAD or EMT.RELOAD then + PrepareLoad( EMT.AUX, true) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( EMT.AUX) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnPathEndAux() + --EgtOutLog( 'OnPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif EgtGetInfo( EMT.DISPID, 'TYPE') == 'REST' then + EMT.AUXTYPE = 'R' + else + EMT.AUXTYPE = 'P' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'P' + if Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.FALL = true + end + end + elseif EMT.AUXTYPE == 'P' then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.CHY_ON = true + EMT.AUXTYPE = 'U' + end + end + end + -- preparo a seconda del tipo + if EMT.AUXTYPE == 'R' then + -- per il carico della rimanenza dopo rotazione speciale + if EMT.RELOAD and not EMT.RELOAD2 then + PrepareLoad( EMT.AUX, false) + -- per lo scarico della rimanenza + else + PrepareResidue( EMT.AUX) + end + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnRapid() + MyBackupAxes() + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + -- decido se muovere prima testa o carrelli (standard prima testa) + local bHeadFirst = true + if not ( EMT.LOAD or EMT.RELOAD) and not EMT.ZMAX then + local DeltaT = EMT.L1 - EMT.TLAST + if ( DeltaT < -GEO.EPS_SMALL and EMT.VDELTA) or ( DeltaT > GEO.EPS_SMALL and EMT.YDELTA) then bHeadFirst = false end + end + -- sistemo movimenti + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + if not ( EMT.LOAD or EMT.RELOAD) then + if not EMT.ZMAX and #EMT.AUXSTR > 0 then + EmitZmax() + end + end + if not EMT.LOAD then + local sOut = string.gsub( string.gsub( EMT.MCHNAME..'/'..EMT.TOOL, '%(', '['), '%)', ']') + EmtOutput( '( * ' .. sOut .. ' * )') + end + -- primo posizionamento + EmtResetPrev() + local bZmax = ( #EMT.AUXSTR > 0 or EMT.TOOL ~= EMT.PREVTOOL or EMT.L3 > -1) + local sOut = 'M101 P1=1' .. ' P2=' .. EmtLenToString( EMT.L2, 3) .. ' P3=' .. EmtLenToString( EMT.L3, 3) .. + ' P4=' .. EgtNumToString( EMT.R2, 3) .. ' P5=' .. EgtNumToString( EMT.R1, 3) .. + ' P6=' .. AdjustTcPos( false) .. ' P7=' .. EgtNumToString( EMT.S, 0) .. + ' P8=0' .. ' P9=0' .. ' P10=' .. EgtIf( bZmax, '3', '4') + if EMT.ST > BeamHeightForFixRot then + sOut = sOut .. ' P12=1' + end + if EMT.LOAD then + ParkLine( sOut) + else + EmtOutput( sOut) + end + sOut = 'M101 P1=2' + if EMT.LOAD then + ParkLine( sOut) + else + if bHeadFirst then EmtOutput( sOut) end + end + -- se prima lavorazione + if EMT.LOAD then + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + local bOnlyCharY = true + for i = 1, #EMT.AUXSTR do + ParkLine( EMT.AUXSTR[i]) + if string.find( EMT.AUXSTR[i], 'P1=10', 1, true) then bOnlyCharY = false end + end + EMT.AUXSTR = {} + sOut = EgtIf( bOnlyCharY, 'M111 P1=21', 'M111 P1=20') + ParkLine( sOut) + sOut = EgtIf( bOnlyCharY, 'M111 P1=31', 'M111 P1=30') + ParkLine( sOut) + sOut = string.gsub( string.gsub( EMT.MCHNAME..'/'..EMT.TOOL, '%(', '['), '%)', ']') + ParkLine( '( * ' .. sOut ..' * )') + sOut = 'M101 P1=3' + ParkLine( sOut) + local sY, sA + if EMT.YDELTA then + sY = EmtLenToString( EMT.L1 + EMT.YDELTA) + sA = '1' + else + sY = EmtLenToString( ParkY) + sA = '2' + end + local sV, sB + if EMT.VDELTA then + sV = EmtLenToString( EMT.L1 + EMT.VDELTA) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + sOut = 'M112 P1='..EmtLenToString( EMT.L1, 3)..' P3='..sA..' P4='..sB..' P5=0 P6='..sY..' P7='..sV..' P9='..GetFmaxClamp() + ParkLine( sOut) + EMT.LOAD = false + -- emissione prime linee speciali e linee parcheggiate + EmitStartValues() + EmtOutput( ';LISTA = ' .. tostring( EMT.PRODID)) + EmitParkedLines() + -- altrimenti lavorazione successiva + else + -- eventuale G111 + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if not ( EMT.POSTROT or EMT.RELOAD) then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + else + EmtOutput( 'M111 P1=21') + EmtOutput( 'M111 P1=31') + end + end + EMT.AUXSTR = {} + local sY, sA + if EMT.YDELTA then + sY = EmtLenToString( EMT.L1 + EMT.YDELTA - ( EMT.X_OFF or 0)) + sA = '1' + else + sY = EmtLenToString( EgtIf( EMT.YPOS, EMT.YPOS, ParkY)) + sA = '2' + end + local sV, sB + if EMT.VDELTA then + sV = EmtLenToString( EMT.L1 + EMT.VDELTA - ( EMT.X_OFF or 0)) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + -- se taglio di coda senza residuo da scaricare, emetto M175 per accelerare il carico della barra successiva + if EMT.MCHUSERNOTES and EMT.MCHUSERNOTES:find( 'Cut') then + EmtOutput( 'M175') + end + if bHeadFirst then + sOut = 'M101 P1=3' + EmtOutput( sOut) + end + sOut = 'M112 P1=' .. EmtLenToString( EMT.L1, 3) ..' P3='..sA..' P4='..sB..' P6='..sY..' P7='..sV..' P9=' .. GetFmaxClamp() + EmtOutput( sOut) + if not bHeadFirst then + sOut = 'M101 P1=2' + EmtOutput( sOut) + sOut = 'M101 P1=3' + EmtOutput( sOut) + end + EMT.POSTROT = false + EMT.RELOAD = false + EMT.RELOAD2 = nil + end + -- se taglio di separazione prima di scarico a caduta, emissione stop tappeto scarico trucioli + if EMT.PREFALLCUT then + EmtOutput( 'M29') + EMT.PREFALLCUT = nil + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se alto in Z (non serve l'avvicinamento finale) + if EMT.FLAG == 2 then + -- aggiorno valori come precedenti + EMT.TLAST = EMT.L1b + EmtUpdatePrev() + return + -- altrimenti ripristino i valori originali degli assi + else + MyRestoreAxes() + end + end + -- se standard + if EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EmtOutput( 'M102 P1=' .. GetFaceCode()) + EmtOutput( 'M98') + sOut = 'M6 T1' .. AdjustToolKinematic() .. AdjustTcPos( true) + EmtOutput( sOut) + EmtOutput( 'G24' .. EMT.IPLGLSTR) + -- forzo successiva emissione assi rotanti + EMT.R1p = nil + EMT.R2p = nil + else + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + end + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmitZmax( true) + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- se altrimenti rotazione a Z max + elseif EMT.FLAG == 5 then + -- viene gestito all'inizio della lavorazione successiva + -- altrimenti errore + else + error( "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EMT.TLAST = EMT.L1b + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + MyBackupAxes() + EMT.TLAST = EMT.L1 + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente (se presente devo annullare l'offset in X per sovramateriale di testa) + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + if EMT.X_OFF then EMT.L1 = EMT.L1 - EMT.X_OFF end + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EmtOutput( 'M102 P1=' .. GetFaceCode()) + EmtOutput( 'M98') + local sOut = 'M6 T1' .. AdjustToolKinematic() .. AdjustTcPos( true) + EmtOutput( sOut) + EmtOutput( 'G24' .. EMT.IPLGLSTR) + -- emissione movimento + EMT.R1p = nil + EMT.R2p = nil + sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + EmtOutput( 'M97') + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sL1, bL1 = EmtGetAxis( 'L1') + local sL2, bL2 = EmtGetAxis( 'L2') + local sL3, bL3 = EmtGetAxis( 'L3') + local sR1, bR1 = EmtGetAxis( 'R1') + local sR2, bR2 = EmtGetAxis( 'R2') + local sAxes = sL1 .. sL2 .. sL3 .. sR2 .. sR1 + -- se nulla da emettere, esco + if #sAxes == 0 then return end + -- aggiungo feed + local sFeed = EmtGetFeed() + -- emetto linea + EmtOutput( "G1"..sAxes..sFeed) + + -- arresto preciso in angoli di fresature per utensili (non penne) di piccolo diametro + if EMT.MCHTYPE == MCH_MY.MILLING and EMT.TTOTDIAM < 15 and abs( EMT.S) > 1000 and ( bL1 or bL2) and not bL3 then + EmtOutput( 'G9') + end + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + MyBackupAxes() + EMT.TLAST = EMT.L1 + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + EmtOutput( 'M97') + end + + -- non modale su archi + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString( EMT.RR, EMT.DECNUM) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- emetto arco + EmtOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd, bSkipPress) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + elseif sCmd == '1' then + return '2' + -- chiuso con pressore attivato + elseif sCmd == '2' then + return EgtIf( bSkipPress, '2', '0') + end +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd, bStart) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = ' P4=111' + EMT.SB = ' P5=112' + EMT.SC = ' P6=141' + EMT.SD = ' P7=141' + EMT.SE = ' P8=0' + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + if bStart then + EMT.RELOAD = false + else + EMT.RELOAD2 = true + end + for i = 1, #EMT.AUXSTR do + EMT.AUXSTR[i] = string.gsub( EMT.AUXSTR[i], 'P1=11', 'P1=10') + end + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..sPar2..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.YPOS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sYTaking = ' P2='..EmtLenToString( Cmd[3] + TurnerOffs) + local sOut = 'M111 P1=11' .. sYTaking .. ' P4=75 P5=110 P8=0 P9=' .. GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + SetStartValue( 4, Cmd[3] + TurnerOffs) + SetStartValue( 5, 110) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sPar6 = EgtIf( Cmd[6] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', sPar6 .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2]) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2]) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + if not FindM111P4EQ76( EMT.AUXSTR) then + local sYLoad = ' P2=' .. EmtLenToString( LoadT) + local sOut = 'M111 P1=11' .. sYLoad .. ' P4=76 P5=110 P8=0 P9=' .. GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = EgtIf( EMT.YDELTA, ' P4=112', ' P4=111') + EMT.SB = EgtIf( EMT.YDELTA, ' P5=112', ' P5=111') + EMT.SC = EgtIf( EMT.VDELTA, ' P6=142', ' P6=141') + EMT.SD = EgtIf( EMT.VDELTA, ' P7=142', ' P7=141') + EMT.SE = EgtIf( EMT.YDELTA, ' P8=1', ' P8=2') + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..sPar2..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.YPOS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sPar6 = EgtIf( Cmd[6] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', sPar6 .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2]) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2]) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd) + + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.YDELTA, ' P4=112', ' P4=111') + EMT.SB = EgtIf( EMT.YDELTA, ' P5=112', ' P5=111') + EMT.SC = EgtIf( EMT.VDELTA, ' P6=142', ' P6=141') + EMT.SD = EgtIf( EMT.VDELTA, ' P7=142', ' P7=141') + EMT.SE = EgtIf( EMT.YDELTA, ' P8=1', ' P8=2') + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + if not EMT.UNL then + sOut = 'M111 P1=10'..sPar2..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + else + sOut = 'M111 P1=10'..sPar2..Cmd[3]..' P6=141 P7=84 P8=0 P9='..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sPar6 = EgtIf( Cmd[6] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', sPar6 .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sOut = 'M111 P1=10'..' P2='..Cmd[3]..' P4=112 P5=112 P6=142 P7=142 P8=2 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.YPOS = tonumber( Cmd[3]) + end + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd) + + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sP1 = EgtIf( EMT.CHY_ON, '10', '12') + local sP7 = '84' + if not EMT.U_STD then + sP7 = EgtIf( EMT.U_MAN ~= 1, '85', '114') + EMT.U_MAN = EgtIf( EMT.U_MAN == 1, nil, 1) + end + local sP8 = EgtIf( EMT.PHASE == EgtGetPhaseCount() or IsEnd2Phase( EMT.PHASE), '0', '1') + local sOut = 'M111 P1='..sP1..' P3='..Cmd[3]..' P6=141 P7='..sP7..' P8='..sP8..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[4] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sP1 = EgtIf( EMT.CHY_ON, '10', '12') + local sP45 = EgtIf( EMT.PHASE == EgtGetPhaseCount() or IsEnd2Phase( EMT.PHASE), '111', '112') + local sOut = 'M111 P1='..sP1..' P3='..Cmd[5]..' P4=' .. sP45 .. ' P5=' .. sP45 .. ' P6=142 P7=141 P8=2 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.U_STD = true + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. EgtIf( Cmd[2] == '0', ' 0', ' 1') + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. EgtIf( Cmd[2] == '0', ' 0', ' 1') + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + -- non interessa + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.YDELTA, ' P4=112', ' P4=111') + EMT.SB = EgtIf( EMT.YDELTA, ' P5=112', ' P5=111') + EMT.SC = EgtIf( EMT.VDELTA, ' P6=142', ' P6=141') + EMT.SD = EgtIf( EMT.VDELTA, ' P7=142', ' P7=141') + EMT.SE = EgtIf( EMT.YDELTA, ' P8=1', ' P8=2') + end + -- se è pre-rotazione + if Cmd[2] == 'Pre-Rotation' then + EMT.PREROT = true + elseif Cmd[2] == 'SplitRot' then + EMT.SPLITROT = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + local sP23 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + if not EMT.PREROT then + sOut = 'M111'..' P1=10'..sP23..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + else + sOut = 'M111 P1=10'..sP23..Cmd[3]..' P4=86 P5=87 P6=141 P8=0 P9='..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sP2 = '' + local sP3 = '' + if Cmd[2] == 'Y' then + sP2 = ' P2=' .. Cmd[3] + elseif Cmd[4] == 'Y' then + sP2 = ' P2=' .. Cmd[5] + end + if Cmd[2] == 'V' then + sP3 = ' P3=' .. Cmd[3] + elseif Cmd[4] == 'V' then + sP3 = ' P3=' .. Cmd[5] + end + local sOut = 'M111 P1=10'..sP2..sP3..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sP2 = '' + local sP3 = '' + if Cmd[2] == 'Y' then + sP2 = ' P2=' .. Cmd[3] + elseif Cmd[4] == 'Y' then + sP2 = ' P2=' .. Cmd[5] + elseif Cmd[6] == 'Y' then + sP2 = ' P2=' .. Cmd[7] + end + if Cmd[2] == 'V' then + sP3 = ' P3=' .. Cmd[3] + elseif Cmd[4] == 'V' then + sP3 = ' P3=' .. Cmd[5] + elseif Cmd[6] == 'V' then + sP3 = ' P3=' .. Cmd[7] + end + local sOut = 'M111 P1=10'..sP2..sP3..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + if EMT.SPLITROT then + EMT.SA = EgtIf( Cmd[2] ~= '0', ' P4=11' .. CalcCharStatus( Cmd[2], true), ' P4=86') + EMT.SB = EgtIf( Cmd[2] ~= '0', ' P5=11' .. CalcCharStatus( Cmd[2], true), ' P5=87') + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + else + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + end + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = ' P5=112' + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + EMT.POSTROT = false + for i = 1, #EMT.AUXSTR do + EMT.AUXSTR[i] = string.gsub( EMT.AUXSTR[i], 'P1=11', 'P1=10') + end + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + -- su NUM si pone E80058=0, con TPA non sembra necessaria una equivalente impostazione + local sYTaking = ' P2='..EmtLenToString( Cmd[3] - EMT.HOVM) + local sOut = 'M111 P1=11'..sYTaking..' P4=75 P5=112 P8=0 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + local sYLoad = ' P2='..EmtLenToString( LoadT) + local sOut = 'M111 P1=11'..sYLoad..' P4=76'..EMT.SB..' P8=0 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function MyBackupAxes() + EMT.L1b = EMT.L1 + EMT.L2b = EMT.L2 + EMT.L3b = EMT.L3 + EMT.R1b = EMT.R1 + EMT.R2b = EMT.R2 + EMT.R3b = EMT.R3 + EMT.R4b = EMT.R4 + EMT.RRb = EMT.RR + EMT.C1b = EMT.C1 + EMT.C2b = EMT.C2 + EMT.C3b = EMT.C3 +end + +--------------------------------------------------------------------- +function MyRestoreAxes() + EMT.L1 = EMT.L1b + EMT.L2 = EMT.L2b + EMT.L3 = EMT.L3b + EMT.R1 = EMT.R1b + EMT.R2 = EMT.R2b + EMT.R3 = EMT.R3b + EMT.R4 = EMT.R4b + EMT.RR = EMT.RRb + EMT.C1 = EMT.C1b + EMT.C2 = EMT.C2b + EMT.C3 = EMT.C3b +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + if EMT.REFLOC then + local vtE + if EMT.HEAD == 'H1' or EMT.HEAD == 'H2' then + local Len = EMT.TLEN + EgtIf( EMT.HEAD == 'H1', MillOffs, abs( SawOffs)) + local LenRef = MillOffs + vtE = Vector3d( EMT.EXTR) * Len - Z_AX() * LenRef + elseif EMT.HEAD == 'H3' then + local LenAux = ChSawLen + MillOffs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + vtE = vtAux * LenAux - Z_AX() * LenRef + else -- 'H5' + local Len = EMT.TLEN + AngTr1Len + local LenAux = MillOffs + AngTr1Offs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2) + vtE = Vector3d( EMT.EXTR) * Len + vtAux * LenAux - Z_AX() * LenRef + end + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - DeltaTabY - vtE:getY() + EMT.L3 = EMT.L3 - DeltaTabZ - vtE:getZ() + end + + if EMT.X_OFF then EMT.L1 = EMT.L1 + EMT.X_OFF end + + EmtAdjustLinearAxes() + + if not EMT.REFLOC then + EMT.L2 = - EMT.L2 + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function AdjustToolKinematic() + if EMT.HEAD == 'H1' or EMT.HEAD == 'H3' then + return '01' + elseif EMT.HEAD == 'H2' then + return '02' + elseif EMT.HEAD == 'H5' then + return EgtIf( EMT.EXIT == 1, '11', '12') + elseif EMT.HEAD == 'H6' then + return EgtIf( EMT.EXIT == 1, '21', '22') + else + EmtSetLastError( 1211, 'Head not allowed') + end +end + +--------------------------------------------------------------------- +function AdjustTcPos( bLen3) + local sPos = EMT.TCPOS:gsub( 'T', '') + if sPos == '91' then + if EMT.EXIT == 2 then + sPos = '92' + end + elseif sPos == '93' then + if EMT.EXIT == 2 then + sPos = '94' + end + elseif sPos == '101' then + if abs( EMT.R3 - 0) < 0.1 then + sPos = '101' + elseif abs( EMT.R3 - 270) < 0.1 then + sPos = '102' + elseif abs( EMT.R3 - 180) < 0.1 then + sPos = '103' + elseif abs( EMT.R3 - 90) < 0.1 then + sPos = '104' + else + EmtSetLastError( 1210, 'Chain saw orientation not allowed') + end + end + if bLen3 then + if #sPos == 1 then + sPos = '00' .. sPos + elseif #sPos == 2 then + sPos = '0' .. sPos + end + end + return sPos +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + LoadT + if EMT.X_OFF then xS = xS + EMT.X_OFF end + local ptS = Point3d( xS, 0, 0) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H3' then + vtE = Vector3d( EMT.EXTR) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --EmtOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local vtX = EMT.IPLGLFR:getVersX() + local vtY = EMT.IPLGLFR:getVersY() + local vtZ = EMT.IPLGLFR:getVersZ() + EMT.IPLGLSTR = ' X0 Y' .. EmtLenToString( xS, EMT.DECNUM) .. ' Z0' .. + ' A' .. EgtNumToString( - vtX:getY(), 6) .. ' B' .. EgtNumToString( vtX:getX(), 6) .. ' C' .. EgtNumToString( vtX:getZ(), 6) .. + ' I' .. EgtNumToString( - vtY:getY(), 6) .. ' J' .. EgtNumToString( vtY:getX(), 6) .. ' K' .. EgtNumToString( vtY:getZ(), 6) .. + ' P' .. EgtNumToString( - vtZ:getY(), 6) .. ' Q' .. EgtNumToString( vtZ:getX(), 6) .. ' R' .. EgtNumToString( vtZ:getZ(), 6) + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function VerifyEmitRotation() + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- se sono uguali non devo fare alcunchè + if nRot == nPrevRot then + return false + end + -- rotazione automatica o manuale (sempre con il medesimo comando) + local nDeltaRot = nRot - nPrevRot + local sOut = 'M180 P1=' .. tostring( nDeltaRot) + EmtOutput( sOut) + return true +end + +--------------------------------------------------------------------- +function GetFaceCode() + if EMT.YDELTA and EMT.VDELTA then + return '3' + elseif EMT.YDELTA then + return '6' + else + return '5' + end +end + +--------------------------------------------------------------------- +function EmitZmax( bReset) + if bReset then + EmtOutput( 'G27') + EmtOutput( 'M6 T000000') + EmtOutput( 'M99') + end + EmtOutput( 'M116') +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE / 1000, 0) +end + +--------------------------------------------------------------------- +function FindM111P4EQ76( vStr) + for i = 1, #vStr do + if vStr[i]:find( 'M111', 1, true) and vStr[i]:find( 'P4=76', 1, true) then + return true + end + end + return false +end + +--------------------------------------------------------------------- +local ParkedLines = {} + +--------------------------------------------------------------------- +function ParkLine( sLine) + table.insert( ParkedLines, sLine) +end + +--------------------------------------------------------------------- +function EmitParkedLines() + for i = 1, #ParkedLines do + EmtOutput( ParkedLines[i]) + end + ParkedLines = {} +end + +--------------------------------------------------------------------- +local StartValues = {} + +--------------------------------------------------------------------- +function SetStartValue( nI, dVal) + StartValues[nI] = dVal +end + +--------------------------------------------------------------------- +function EmitStartValues() + local sLine = '' + for i = 1, 10 do + sLine = sLine .. string.format( ';V%02d=', i) .. EgtNumToString( StartValues[i] or 0, 3) + end + EmtOutput( sLine) +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.ini b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.ini new file mode 100644 index 0000000..7fc9a91 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.ini @@ -0,0 +1,64 @@ +; Commento per evitare BOM con UTF-8 +[General] +Material=Beam + +[Tools] +Drillbit=1 +Sawblade=1 +Mill=1 +Mortise=1 +Chisel=0 +DrillMaker=MakeWoodDrill.lua +SawbladeMaker=MakeSawblade.lua +MillMaker=MakeWoodCylMill.lua +MortiseMaker=MakeMortise.lua +ChiselMaker=MakeChisel.lua +Active=1 + +[ToolHolder] +H1.1=Standard.nge +H1.1:MILL_NOTIP=MillNoTip.nge +H2.1=Saw.nge +H3.1=ChainSaw.nge +H5.1=AngTransm.nge +H5.2=AngTransm.nge +H6.1=AngTransm.nge +H6.2=AngTransm.nge + +[Machinings] +Drilling=1 +Sawing=1 +Milling=1 +Pocketing=1 +Mortising=1 +Chiseling=0 +SawRoughing=0 +SawFinishing=0 + +[Machining] +InitScript=InitMach.lua +ExitScript=ExitMach.lua + +[Disposition] +;InitScript=InitDisp.lua + +[Heads] +; 5 axis head +H1=6608 +; 5 axis saw +H2=6615 +; Chainsaw +H3=6616 +; Angular transmission +H5=6603 + +[SetUp] +Default=Standard + +[Estimations] +Enable=1 +WinPlace=0,458,111,669,906 + +[VMill] +Enable=1 +Save=0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.mlde b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.mlde new file mode 100644 index 0000000..5bb848f --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.mlde @@ -0,0 +1,539 @@ +-- Descrizione macchina Essetre-FAST by EgalTech s.r.l. 2022/04/07 +-- 2021/12/29 DS ver 2.3l4 Per NUM non va considerato MillOffs negli offset in Z. +-- 2022/01/27 DS ver 2.4a2 Modifiche per tagli testa/coda su pezzi alti. +-- 2022/02/10 DS ver 2.4a3 Ridotto di 10mm pinzaggio con pezzi alti ma sottili. +-- 2022/02/26 DS ver 2.4b1 Aggiunta verifica collisioni spalle per sega a catena. +-- 2022/03/19 DS ver 2.4c1 Unificazione con BH. + +require( 'EmtGenerator') +EgtEnableDebug( false) + +PP_VER = '2.4d1' + +-- Parametri macchina +NumericalControl = 'TPA' -- NUM o TPA +MinX = 0 +MaxX = 1350 +MinZ = -1350 +MaxZ = 0 +MinB = -180 +MaxB = 360 +MinC = -360 +MaxC = 360 +MinY = 110.0 +MaxY = 3760.0 +ParkY = 480.0 +MinV = -3760.0 +MaxV = -110.0 +ParkV = -480.0 +LoadT = 1454.2 +UnloadT = -1700 +MaxOpen = 305 +MillOffs = 177.35 +SawOffs = -242.68 +SawBOffs = 0 +SawCOffs = 0 +ChSawLen = 90.0 +AngTr1Offs = 170 +AngTr1Len = 150 +TurnerOffs = 200.0 +DeltaTabY = 898.0 +DeltaTabZ = -1017.8 + MillOffs -- per TPA : -1013.3 + MillOffs -- per NUM : -838.4 +DimTabY = 400 +DimTabX = 34000 +LenToPress = 900 +StartRotation = true +AutomaticRotation = true +AutoRotMinLen = 2600 +DefTcPos = 'T2' +SecondSupport = 0 +SpecialBH = false +MaxUnloadLen = 0 +BeamHeightForFixRot = 9999 -- per abilitare assegnare 500 +CoeffVM = 0.5 +NewTopC = true + +-- Aggiornamento con dati da BeamData.lua +local sBeamData = EgtGetSourceDir().."\\Beam\\BeamData.lua" +if EgtExistsFile( sBeamData) then + local BD = dofile( sBeamData) + if BD then + BeamHeightForFixRot = BD.MAX_HEIGHT_ROT_B_ABOVE or BeamHeightForFixRot + end +end + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Beam', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-Fast.data" +local sData = EgtGetSourceDir().."\\Beam\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Offsets then + NumericalControl = EgtIf( Machine.Offsets.TIPO_CN == 0, 'NUM', 'TPA') + if Machine.Offsets.MAX_X then MinX = - Machine.Offsets.MAX_X end + if Machine.Offsets.MIN_X then MaxX = - Machine.Offsets.MIN_X end + if Machine.Offsets.MIN_Z then MinZ = Machine.Offsets.MIN_Z end + if Machine.Offsets.MAX_Z then MaxZ = Machine.Offsets.MAX_Z end + if Machine.Offsets.MIN_B then MinB = Machine.Offsets.MIN_B end + if Machine.Offsets.MAX_B then MaxB = Machine.Offsets.MAX_B end + if Machine.Offsets.MIN_C then MinC = Machine.Offsets.MIN_C end + if Machine.Offsets.MAX_C then MaxC = Machine.Offsets.MAX_C end + MinY = Machine.Offsets.MIN_Y or Machine.Offsets.MINY or MinY + MaxY = Machine.Offsets.MAX_Y or Machine.Offsets.MAXY or MaxY + ParkY = Machine.Offsets.PARKYY or ParkY + MinV = Machine.Offsets.MIN_V or Machine.Offsets.MINV or MinV + MaxV = Machine.Offsets.MAX_V or Machine.Offsets.MAXV or MaxV + ParkV = Machine.Offsets.PARKVV or ParkV + if Machine.Offsets.YCARICO then LoadT = - Machine.Offsets.YCARICO end + if Machine.Offsets.YSCARICO then UnloadT = - Machine.Offsets.YSCARICO end + if Machine.Offsets.PIVOTFRESA then MillOffs = - Machine.Offsets.PIVOTFRESA end + if Machine.Offsets.PIVOTLAMA then SawOffs = - Machine.Offsets.PIVOTLAMA end + if Machine.Offsets.OFFSETBLAMA then SawBOffs = Machine.Offsets.OFFSETBLAMA end + if Machine.Offsets.OFFSETCLAMA then SawCOffs = Machine.Offsets.OFFSETCLAMA end + if Machine.Offsets.OFFSETZ_RINV_1 then AngTr1Offs = Machine.Offsets.OFFSETZ_RINV_1 - EgtIf( NumericalControl == 'TPA', MillOffs, 0) end + AngTr1Len = Machine.Offsets.OFFSETX_RINV_1 or AngTr1Len + --if Machine.Offsets.OFFSETZ_RINV_2 then AngTr2Offs = Machine.Offsets.OFFSETZ_RINV_2 - EgtIf( NumericalControl == 'TPA', MillOffs, 0) end + --AngTr2Len = Machine.Offsets.OFFSETX_RINV_2 or AngTr2Len + TurnerOffs = Machine.Offsets.OFFSETRIB or TurnerOffs + if Machine.Offsets.OFFSETX then DeltaTabY = - Machine.Offsets.OFFSETX end + if Machine.Offsets.OFFSETZ then DeltaTabZ = Machine.Offsets.OFFSETZ + EgtIf( NumericalControl == 'TPA', MillOffs, 0) end + if Machine.Offsets.SECSUP then SecondSupport = Machine.Offsets.SECSUP end + if Machine.Offsets.RIB_AUTO then AutomaticRotation = ( Machine.Offsets.RIB_AUTO == 1) end + if Machine.Offsets.NOULOAD then MaxUnloadLen = Machine.Offsets.NOULOAD end + end + end +end +if SpecialBH then SecondSupport = 0 end + +EmtGeneral { + File='Essetre-FAST.nge', + Offset = Vector3d( 0, 1150.16, -1500.0), + AxisMaxAdjust = 30, + AxisMaxRotAdj = 0.5, + ExitMaxAdjust = 30, + ExitMaxRotAdj = 0.5, + AngDeltaMinForHome = 165, + Special = 'Essetre-FAST.mlse', + Processor = 'Essetre-FAST.mlpe'} +local BaseId = EmtBase { + Name = 'Base', + Geo='BASE/GEO', + Aux={'BASE/SOLID', 'BASE/TC', 'BASE/SIGN', 'BASE/COLLISION'}} +local XId = EmtAxis { + Name = 'X', + Parent = 'Base', + Invert = true, + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( -639.5, 372.66, 945.7), + Stroke = {MinX, MaxX}, + Home = 0, + Geo = 'X_AXIS/GEO', + Aux = 'X_AXIS/SOLID'} +EmtAxis { + Name = 'Z', + Parent = 'X', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d( -19.25, -113.54, 790.0), + Stroke = {MinZ, MaxZ}, + Home = MaxZ, + Geo = 'Z_AXIS/GEO', + Aux = {'Z_AXIS/SOLID', 'Z_AXIS/COLLISION'}} +local CId = EmtAxis { + Name = 'C', + Parent = 'Z', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinC, MaxC}, + Home = 0, + Geo = 'C_AXIS/GEO', + Aux = {'C_AXIS/SOLID', 'C_AXIS/COLLISION'}} +if NewTopC then + local SolidTopId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( CId, 'SOLID'), 'TOP') + local CollTopId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( CId, 'COLLISION'), 'TOP') + EgtMove( { SolidTopId, CollTopId}, Vector3d( 65,0,0), GDB_RT.GLOB) + EgtSetName( CollTopId, 'BOX') +else + local CollTopId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( CId, 'COLLISION'), 'TOP') + EgtSetName( CollTopId, 'BOX') +end +EmtAxis { + Name = 'B', + Parent = 'C', + Type = MCH_AT.ROTARY, + Dir = X_AX(), + Pos = Point3d( 0, 0, MillOffs), + Stroke = {MinB, MaxB}, + Home = 0, + Geo = 'B_AXIS/GEO', + Aux = {'B_AXIS/SOLID', 'B_AXIS/COLLISION'}} +-- Frese +local H1Id = EmtHead { + Name = 'H1', + Parent = 'B', + HSet = 'H1', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, 0), + TDir = Z_AX(), + ADir = X_AX(), + Rot1W = 2, + OthColl = {'H2', 'B/SOLID', 'C/SOLID'}, + Geo = 'H1_HEAD/GEO'} +EgtSetInfo( H1Id, 'ZMAXONROT', '1,60') +if BeamHeightForFixRot < 1000 then + EgtSetInfo( H1Id, 'ROTATZMAX', '1') +end +-- Lama +local H2Id = EmtHead { + Name = 'H2', + Parent = 'B', + HSet = 'H2', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, (MillOffs-SawOffs)), + TDir = Vector3d( 0, -sin( SawBOffs), -cos( SawBOffs)), + ADir = X_AX(), + Rot1W = 0.2, + OthColl = {'H1', 'H3', 'B/SOLID', 'C/SOLID'}, + Geo = 'H2_HEAD/GEO'} +EgtSetInfo( H2Id, 'ZMAXONROT', '1,5') +if BeamHeightForFixRot < 1000 then + EgtSetInfo( H2Id, 'ROTATZMAX', '1') +end +-- Sega a catena +EmtAxis { + Name = 'A', + Parent = 'B', + Token = '**', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = { 0, 270}, + Home = 0, + Geo = 'A_AXIS/GEO'} +local H3Id = EmtHead { + Name = 'H3', + Parent = 'A', + HSet = 'H1', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, -ChSawLen), + TDir = X_AX(), + ADir = Z_AX(), + Rot1W = 0.2, + SolCh = MCH_SCC.ADIR_NEAR, + OthColl = {'H2', 'B/SOLID', 'C/SOLID'}, + Geo = 'H3_HEAD/GEO'} +EgtSetInfo( H3Id, 'ZMAXONROT', '1,5') +if BeamHeightForFixRot < 1000 then + EgtSetInfo( H3Id, 'ROTATZMAX', '1') +end +-- Dummy +EmtHead { + Name = 'H4', + Parent = 'B', + HSet = 'H4', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, 0), + TDir = Z_AX(), + ADir = X_AX(), + Rot1W = 0.2, + Geo = 'H4_HEAD/GEO'} +-- Eventuale rinvio angolare +if SecondSupport >= 2 then + local H5Id = EmtHead { + Name = 'H5', + Parent = 'B', + HSet = 'H1', + Type = MCH_HT.MULTI, + ExitNbr = 2, + Pos1 = Point3d( 0, -AngTr1Len, -AngTr1Offs), + TDir1 = Y_AX(), + Pos2 = Point3d( 0, AngTr1Len, -AngTr1Offs), + TDir2 = -Y_AX(), + ADir = Z_AX(), + Rot1W = 0.2, + Rot2Stroke = { -120, 120}, + OthColl = { 'H2', 'B/SOLID', 'C/SOLID'}, + Geo = 'H5_HEAD/GEO', + Aux = {'H5_HEAD/SOLID', 'H5_HEAD/COLLISION'}} + EgtSetInfo( H5Id, 'AGB_TYPE', '2') + EgtSetInfo( H5Id, 'AGB_DMAX', '220') + EgtSetInfo( H5Id, 'AGB_ENCH', '44') + EgtSetInfo( H5Id, 'AGB_ENCV', '380') + EgtSetInfo( H5Id, 'ZMAXONROT', '1,15') +end +-- Morse +local YId = EmtAxis { + Name = 'Y', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d( -953.0, 111.75, 1450.0), + Stroke = { MinY, MaxY}, + Home = ParkY, + Geo = 'Y_AXIS/GEO', + Aux = {'Y_AXIS/SOLID', 'Y_AXIS/COLLISION'}} +local PYId = EmtAxis { + Name = 'PY', + Parent = 'Y', + Type = MCH_AT.LINEAR, + Dir = -Y_AX(), + Pos = Point3d( -904.0, -276.5, 1449.0), + Stroke = { 0, MaxOpen}, + Home = MaxOpen, + Geo = 'PY_AXIS/GEO', + Aux = {'PY_AXIS/SOLID', 'PY_AXIS/COLLISION'}} +local VId = EmtAxis { + Name = 'V', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d( 953.0, 111.75, 1450.0), + Stroke = { MinV, MaxV}, + Home = ParkV, + Geo = 'V_AXIS/GEO', + Aux = {'V_AXIS/SOLID', 'V_AXIS/COLLISION'}} +local PVId = EmtAxis { + Name = 'PV', + Parent = 'V', + Type = MCH_AT.LINEAR, + Dir = -Y_AX(), + Pos = Point3d( 904.0, -276.5, 1449.0), + Stroke = { 0, MaxOpen}, + Home = MaxOpen, + Geo = 'PV_AXIS/GEO', + Aux = {'PV_AXIS/SOLID', 'PV_AXIS/COLLISION'}} +EmtAxis { + Name = 'T', + Parent = 'Base', + --Token = '**', + Type = MCH_AT.LINEAR, + Dir = - X_AX(), + Pos = Point3d( 0, 613.16, -830.037), + Stroke = { -30000, 30000}, + Home = LoadT, + Geo = 'T_AXIS/GEO'} +EmtTable { + Name = 'Tab', + Parent = 'T', + Type = MCH_TT.FLAT, + Ref1 = Point3d( -DimTabX, DeltaTabY - DimTabY, DeltaTabZ), + Scale = { DimTabX / 20000, DimTabY / 400, 1}, + Geo = 'TABLE/GEO', + Aux = 'TABLE/SOLID'} +-- ToolChanger +EmtTcPos { + Name = 'T1', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, 172.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T1'} +EmtTcPos { + Name = 'T2', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, 67.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T2'} +EmtTcPos { + Name = 'T3', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, -37.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T3'} +EmtTcPos { + Name = 'T4', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, -142.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T4'} +EmtTcPos { + Name = 'T5', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, -247.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T5'} +EmtTcPos { + Name = 'T6', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, -352.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T6'} +EmtTcPos { + Name = 'T7', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, -457.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T7'} +EmtTcPos { + Name = 'T8', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, -562.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T8'} +EmtTcPos { + Name = 'T9', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, -667.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T9'} +EmtTcPos { + Name = 'T10', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, -772.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T10'} +EmtTcPos { + Name = 'T11', + Parent = 'Base', + Pos = Point3d( 523.8, 88.0, -877.5), + TDir = -X_AX(), + ADir = -Y_AX(), + Geo = 'BASE/T11'} +if not SpecialBH then + EmtTcPos { + Name = 'T101', + Parent = 'Base', + Pos = Point3d( -510.4, 113.2, -160.8), + TDir = X_AX(), + ADir = Z_AX(), + Geo = 'BASE/T101'} +else + EmtTcPos { + Name = 'T101', + Parent = 'Base', + Pos = Point3d( -510.4, 113.2, -1160.8), + TDir = X_AX(), + ADir = Z_AX(), + Geo = 'BASE/T101S'} +end +if SecondSupport == 1 then + EmtTcPos { + Name = 'T111', + Parent = 'Base', + Pos = Point3d( -510.4, 113.2, -329.8), + TDir = Z_AX(), + ADir = X_AX(), + Geo = 'BASE/T111'} +end +if SpecialBH then + EmtTcPos { + Name = 'T111', + Parent = 'Base', + Pos = Point3d( -810.4, 113.2, -329.8), + TDir = Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T111S'} +end + +-- Aggiusto posizioni geometriche +local vtMove = Vector3d( 0, ( DeltaTabY - 913.16), ( DeltaTabZ + 830.037)) +local vtMoveX = Vector3d( 0, 0, ( DeltaTabZ + 830.037)) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SIGN'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( YId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( YId, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PYId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PYId, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( VId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( VId, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PVId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PVId, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( XId, 'SOLID'), vtMoveX, GDB_RT.GLOB) + +-- Assegno identificativi alle spie delle morse +PYLightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PYId, 'SOLID') or GDB_ID.NULL, 'Light') +PVLightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PVId, 'SOLID') or GDB_ID.NULL, 'Light') + +--------------------------------------------------------------------- +-- Funzioni richiamate per modificare i dati macchina in casi particolari +--function OnSetTable() +--end + +--------------------------------------------------------------------- +function OnSetHead() + -- se testa lama + if EMC.HEAD == 'H2' then + EmtModifyAxisDirection( 'B', Vector3d( cos( SawCOffs), -sin( SawCOffs), 0)) + -- altrimenti + else + EmtModifyAxisDirection( 'B', X_AX()) + end +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello Y +function SetPYLight( bClosed) + if not PYLightId then return end + EgtSetColor( PYLightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PYLightId, 'On', '1') + else + EgtRemoveInfo( PYLightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello Y +function GetPYLight() + if not PYLightId then return false end + return ( EgtGetInfo( PYLightId, 'On') == '1') +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello V +function SetPVLight( bClosed) + if not PVLightId then return end + EgtSetColor( PVLightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PVLightId, 'On', '1') + else + EgtRemoveInfo( PVLightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello V +function GetPVLight() + if not PVLightId then return false end + return ( EgtGetInfo( PVLightId, 'On') == '1') +end + +--------------------------------------------------------------------- +-- Funzione per resettare tutte le attivazioni della macchina +function OnResetMachine() + EmtUnlinkAllRawPartsFromGroups() + EmtUnlinkAllFixturesFromGroups() + SetPYLight( false) + SetPVLight( false) + -- nascondo Vmill + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nVmId = EgtGetFirstNameInGroup( nRawId, 'VMill') + local nId = EgtGetFirstInGroup( nRawId) + while nId do + EgtSetStatus( nId, EgtIf( nId ~= nVmId, GDB_ST.ON, GDB_ST.OFF)) + nId = EgtGetNext( nId) + end + nRawId = EgtGetNextRawPart( nRawId) + end + EgtSetStatus( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') or GDB_ID.NULL, GDB_ST.OFF) +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.mlpe new file mode 100644 index 0000000..1f36a97 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.mlpe @@ -0,0 +1,1446 @@ +-- Processore macchina Essetre-FAST by EgalTech s.r.l. 2022/03/19 +-- Funzioni generiche indipendenti dal controllo +-- 2020/09/22 DS ver 2.2i4 Distanza di sicurezza per collisioni da 2 a 4mm (inoltre allontanata flangia lama e aggiunto cilindro asse Z) +-- 2020/09/26 DS ver 2.2i5 Gestione cambio presa sega a catena tra due lavorazioni successive. +-- 2020/10/06 DS ver 2.2j1 Punta lunga da togliere basata su sua lunhezza totale e non più su T111. +-- 2021/01/08 DS ver 2.3a1 Gestione utensile di default da posizione e non da nome. +-- 2021/01/24 DS ver 2.3a2 Correzione deposito sega a catena con ripresa della stessa per angola A diverso. +-- 2021/01/31 DS ver 2.3a3 Altre correzioni per sega a catena. +-- 2021/03/15 DS ver 2.3c2 Aggiunta gestione lama su testa H1 e verifica collisione relativa (COLLISION3). +-- 2021/06/28 DS ver 2.3f5 Correzioni per scarico punte lunghe con pezzi alti. +-- 2021/07/12 DS ver 2.3g2 Correzioni per verifica collisioni durante scarico utensili. +-- 2021/07/20 DS ver 2.3g4 Aggiunta gestione rinvio angolare H5 (previsto anche H6). +-- 2021/12/01 DS ver 2.3l1 Corrette stime tempi per rotazione pezzi. + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +LONG_TOOL_MINLEN = 221 +BIG_TOOL_DIAM = 300 + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +local sBaseDir = EgtGetSourceDir() +if NumericalControl == 'NUM' then + dofile( sBaseDir .. 'Essetre-FAST.NUM.mlpe') +elseif NumericalControl == 'TPA' then + dofile( sBaseDir .. 'Essetre-FAST.TPA.mlpe') +else + error( 'Numerical Control error : unkwnown type') +end + +--------------------------------------------------------------------- +-- *** SIMULATION *** +--------------------------------------------------------------------- +local COLL_SAFE_DIST = 3 + +--------------------------------------------------------------------- +function OnSimulStart() + -- Carico gli utensili sulle barre portautensili + local vTcPos = EgtGetAllTcPosNames() + if vTcPos then + for i = 1, #vTcPos do + local vTools = EgtGetToolsInCurrSetupPos( vTcPos[i]) + if vTools and vTools[1] then + EgtLoadTool( vTcPos[i], 1, vTools[1]) + ShowToolInTcPos( vTcPos[i], true) + end + end + end + -- Se reset o home, esco + if EMT.SIM1ST then return end + -- Creo o svuoto gruppo per copia finale degli oggetti virtual milling + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + if nVmGrpId then + EgtSetStatus( nVmGrpId, GDB_ST.ON) + EgtEmptyGroup( nVmGrpId) + else + nVmGrpId = EgtGroup( GDB_ID.ROOT) + EgtSetName( nVmGrpId, 'VMill') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + -- Preparo lista oggetti da verificare per collisioni + EMT.COLLOBJ = {} + AddToCollisionCheck( 'Z', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'B', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'H5', 'COLLISION', EMT.COLLOBJ) + AddToolToCollisionCheck( 'H2', 1, EMT.COLLOBJ) + DumpCollisionCheck( EMT.COLLOBJ, 'Collision Objects :', 4) + -- Preparo lista solidi macchina con cui possono collidere gli oggetti sopra riportati (in aggiunta a VMill) + EMT.MCODET = {} + EMT.MCODET[1] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'VOL1') + EMT.MCODET[2] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'VOL2') + EMT.MCODET[3] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PY'), 'COLLISION'), 'VOL') + EMT.MCODET[4] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'V'), 'COLLISION'), 'VOL1') + EMT.MCODET[5] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'V'), 'COLLISION'), 'VOL2') + EMT.MCODET[6] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PV'), 'COLLISION'), 'VOL') + EMT.MCODET[7] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'SIDE1') + EMT.MCODET[8] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'SIDE2') + for i = #EMT.MCODET, 1, -1 do + if not EMT.MCODET[i] then + table.remove( EMT.MCODET, i) + EgtOutLog( ' Warning : MCODET element (' .. tostring( i) .. ') is null') + elseif EgtGetDebugLevel() >= 4 then + EgtOutLog( ' MCODET element (' .. tostring( i) .. ') is ok') + end + end + -- Preparo lista collisioni vuota + EMT.COLLIDE = {} +end + +--------------------------------------------------------------------- +--function OnSimulEnd() +--end + +--------------------------------------------------------------------- +function OnSimulDispositionStarting() + EmtUnlinkAllRawPartsFromGroups() + if EMT.PHASE > 1 then + if IsStartOrRestPhase( EMT.PHASE) then + EgtSetAxisPos( 'T', LoadT) + end + end +end + +--------------------------------------------------------------------- +function OnSimulDispositionStart() + EMT.OPEISDISP = true + + -- Se prima disposizione + if EMT.PHASE == 1 then + -- Determino dimensioni del grezzo + local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL + local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + EMT.LB = 0 + EMT.SB = 0 + EMT.HB = 0 + if b3Sol then + EMT.LB = b3Sol:getDimX() + EMT.SB = b3Sol:getDimY() + EMT.HB = b3Sol:getDimZ() + end + -- Carico primo utensile sulla testa 1 + local sTool, nTlen = FindFirstToolOnHead( 'H1') + if sTool and nTlen < LONG_TOOL_MINLEN then + EMT.TOOL_1 = sTool + else + EMT.TOOL_1 = GetDefaultToolName() + end + EgtLoadTool( 'H1', 1, EMT.TOOL_1) + EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1) + ShowToolInTcPos( EMT.TCPOS_1, false) + EMT.LOAD = true + -- Se vero inizio e abilitato creo gli Zmap + EMT.VMILL = {} + if not EMT.SIM1ST and EgtGetInfo( EgtGetCurrMachGroup(), 'Vm', 'b') then + local nLastOrd = GetPhaseOrd( EgtGetPhaseCount()) + local nPartRawId = EgtGetFirstRawPart() + while nPartRawId do + -- se è lo scarto finale tagliato a pezzi, esco + local nRawOrd = EgtGetInfo( nPartRawId, 'ORD', 'i') + if nRawOrd == nLastOrd + 1 then break end + -- elimino eventuale vecchio Zmap + EgtErase( EgtGetFirstNameInGroup( nPartRawId, 'VMill') or GDB_ID.NULL) + -- recupero il solido + local nSolId = EgtGetFirstNameInGroup( nPartRawId, 'RawSolid') + local b3Raw = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + -- aggiungo eventuale scrap successivo + if nRawOrd == nLastOrd then + local nScrapId = EgtGetNextRawPart( nPartRawId) + if nScrapId then + local nScrapSolId = EgtGetFirstNameInGroup( nScrapId, 'RawSolid') + local b3ScrapRaw = EgtGetBBoxGlob( nScrapSolId, GDB_BB.STANDARD) + if b3ScrapRaw then + b3Raw:Add( b3ScrapRaw) + end + end + end + -- determino la risoluzione dello Zmap + local dArea = b3Raw:getDimX() * b3Raw:getDimY() + b3Raw:getDimX() * b3Raw:getDimZ() + b3Raw:getDimY() * b3Raw:getDimZ() + local dTol = 4.71 + if dArea < CoeffVM * 0.15e6 then + dTol = 0.71 + elseif dArea < CoeffVM * 0.3e6 then + dTol = 1.01 + elseif dArea < CoeffVM * 0.6e6 then + dTol = 1.51 + elseif dArea < CoeffVM * 1.2e6 then + dTol = 1.97 + elseif dArea < CoeffVM * 2.4e6 then + dTol = 2.81 + elseif dArea < CoeffVM * 4.8e6 then + dTol = 3.77 + end + -- creo lo Zmap + local VMillId = EgtVolZmapBox( nPartRawId, b3Raw:getMin(), b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol, true, GDB_RT.GLOB) + if VMillId then + EgtSetName( VMillId, 'VMill') + EgtSetLevel( VMillId, GDB_LV.TEMP) + EgtSetColor( VMillId, EgtGetColor( nSolId), false) + -- nascondo le altre geometrie + local nId = EgtGetFirstInGroup( nPartRawId) + while nId do + if nId ~= VMillId then + EgtSetStatus( nId, GDB_ST.OFF) + end + nId = EgtGetNext( nId) + end + table.insert( EMT.VMILL, VMillId) + end + nPartRawId = EgtGetNextRawPart( nPartRawId) + end + -- imposto eventuale utensile corrente + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + end + -- fasi successive + else + EMT.LOAD = false + end + + -- Nascondo tutte le lavorazioni + local nMchId = EgtGetFirstOperation() + while nMchId do + if EgtGetOperationType( nMchId) ~= MCH_OY.DISP then + EgtSetOperationStatus( nMchId, false) + end + nMchId = EgtGetNextOperation( nMchId) + end + + -- Se fase inizio o rimanenza, aggancio grezzi della fase alla tavola + if IsStartOrRestPhase( EMT.PHASE) then + -- se fase inizio, segnalo giacitura del grezzo + if IsStartPhase( EMT.PHASE) then + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= 0 then + EgtOutText( tostring( -90 * nRot) .. '° rotated bar') + else + EgtOutText( 'Not rotated bar') + end + end + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + local nScrapOrd = GetPhaseOrd( EgtGetPhaseCount()) + 1 + local b3Raw = BBox3d() + local nPartRawId, nScrapRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + b3Raw = EgtGetRawPartBBox( nRawId) + nPartRawId = nRawId + elseif nRawOrd == nOrd + 1 and nRawOrd == nScrapOrd then + local b3Tmp = EgtGetRawPartBBox( nRawId) or BBox3d() + b3Raw:Add( b3Tmp) + nScrapRawId = nRawId + end + end + nRawId = nNextRawId + end + -- gestione eventuale scarto affettato successivo + if EMT.VMILL and #EMT.VMILL > 0 then + EMT.SCRAP = nScrapRawId + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + else + EMT.SCRAP = nil + end + -- recupero CutId del pezzo in lavorazione + EMT.CUTID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + EMT.YSPEC = nil + -- se vero inizio, assegno solidi per verifica collisione + if not EMT.SIM1ST then + EMT.CODET = {} + for i = 1, #( EMT.MCODET or {}) do + EMT.CODET[i] = EMT.MCODET[i] + end + for i = 1, #( EMT.VMILL or {}) do + table.insert( EMT.CODET, EMT.VMILL[i]) + end + end + -- se altrimenti fase intermedia, aggancio grezzi della fase alla tavola + elseif IsMidPhase( EMT.PHASE) then + -- se cambiata giacitura, lo segnalo + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= nPrevRot then + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- eseguo aggancio + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + end + nRawId = nNextRawId + end + -- se Vmill, nascondo eventuale scrap + if EMT.VMILL then + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + end + -- se altrimenti fasi intermedia o finale speciali, aggancio primo grezzo alla tavola e gli altri in posizione pre-carico + elseif IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se cambiata giacitura, lo segnalo + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= nPrevRot then + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + -- ricerco vettore movimento per i successivi + local vtMove = Vector3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then + vtMove = Vector3d( - LoadT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then + EmtLinkRawPartToGroup( nRawId, 'Tab') + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EgtSetStatus( nRawId, GDB_ST.OFF) + end + end + nRawId = nNextRawId + end + -- altrimenti fase finale, aggancio primo grezzo alla tavola e gli altri in posizione carico al carro Y + else + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + -- ricerco vettore movimento per i successivi + local vtMove = Vector3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then + vtMove = Vector3d( - LoadT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then + EmtLinkRawPartToGroup( nRawId, 'Tab') + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EmtLinkRawPartToGroup( nRawId, 'Y') + end + end + nRawId = nNextRawId + end + end + -- Indicazione angolo rotazione pezzo + EMT.ROT = EgtGetInfo( EMT.DISPID, 'ROT', 'i') or 0 + local SignId = EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'SIGN') + EgtSetStatus( EgtGetFirstNameInGroup( SignId, '0'), EgtIf( EMT.ROT == 0, GDB_ST.ON, GDB_ST.OFF)) + EgtSetStatus( EgtGetFirstNameInGroup( SignId, '90'), EgtIf( EMT.ROT == -1, GDB_ST.ON, GDB_ST.OFF)) + EgtSetStatus( EgtGetFirstNameInGroup( SignId, '180'), EgtIf( EMT.ROT == -2, GDB_ST.ON, GDB_ST.OFF)) +end + +--------------------------------------------------------------------- +function OnSimulDispositionEnd() + if EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + end + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnSimulToolSelect( dPosA) + -- se utensile non definito, è disposizione ed esco + if EMT.TOOL == '' then return end + -- recupero dati utensile + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + EMT.TOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + -- se non è chiamato da altro script (non c'è parametro) + if not dPosA then + -- se attivo Vmill + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + -- se attivo Collision Check + EMT.SAFEDIST = COLL_SAFE_DIST + if EMT.COLLOBJ then + for i, Coll in ipairs( EMT.COLLOBJ) do + EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3) + end + if EMT.HEAD ~= 'H2' then + AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1001) + AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1002) + else + AddToolToCollisionObj( nil, 'H1', 1, 1001) + AddToolHolderToCollisionObj( nil, 'H1', 1, 1002) + end + end + -- dichiaro assi ausiliari da visualizzare + EMT.AuxAxes = 2 + EMT.A1n = 'Y' + EMT.A2n = 'V' + end + -- carico utensile se non lama su sua testa o dummy + if EMT.HEAD ~= 'H2' and EMT.HEAD ~= 'H4' then + -- se sega a catena, imposto subito angolo scelto per asse virtuale A + if EMT.HEAD == 'H3' then + if not dPosA then + -- recupero la lavorazione successiva + local NextMchId + if EMT.MCHID then + NextMchId = EgtGetNextActiveOperation( EMT.MCHID) + else + NextMchId = EgtGetFirstActiveOperation() + end + while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do + NextMchId = EgtGetNextActiveOperation( NextMchId) + end + EgtSetCurrMachining( NextMchId) + -- recupero il valore dell'asse virtuale bloccato A + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + dPosA = tonumber( sVal:sub( 3)) + end + -- imposto il valore di A + EgtSetAxisPos( 'A', dPosA) + if abs( dPosA) < 0.1 then + EgtSetAxisPos( 'C', 0) + end + EgtSetAxisPos( 'B', 0) + end + -- breve pausa + EgtPause( 100) + EgtOutText( '') + EMT.TOOL_1 = EMT.TOOL + EMT.TCPOS_1 = EMT.TCPOS + -- lo nascondo sul portautensili + ShowToolInTcPos( EMT.TCPOS, false) + end +end + +--------------------------------------------------------------------- +function OnSimulToolDeselect() + -- se prossimo utensile non definito, è disposizione ed esco + if EMT.NEXTTOOL == '' then return end + -- se sega a catena o rinvio o punta lunga o utensile di grosso diametro, devo cambiare + if EMT.HEAD == 'H3' or EMT.HEAD == 'H5' or ( EMT.HEAD == 'H1' and ( EMT.TOTLEN > LONG_TOOL_MINLEN or EMT.TOTDIAM > BIG_TOOL_DIAM)) then + EgtOutText( 'Tool change in progress...') + local RapSimStep = 4 * EMT.SIMSTEP + local RapSimRotStep = RapSimStep / 10 + local CollSimRotStep = min( RapSimRotStep, 5) + -- movimento scarico sega a catena + if EMT.HEAD == 'H3' then + local dPosA = EgtGetAxisPos( 'A') + if abs( dPosA) < 0.1 then + SimulMoveAxes( 'B', 0, CollSimRotStep, 'C', 0, CollSimRotStep) + else + SimulMoveAxes( 'B', 0, CollSimRotStep, 'C', -90, CollSimRotStep) + end + SimulMoveAxis( 'X', 0, RapSimStep) + -- movimento scarico rinvio + elseif EMT.HEAD == 'H5' then + SimulMoveAxes( 'B', 0, CollSimRotStep, 'C', -90, CollSimRotStep) + SimulMoveAxis( 'X', 0, RapSimStep) + -- movimento scarico punta lunga su T111 + elseif EMT.TOTLEN > LONG_TOOL_MINLEN then + -- se su cambio utensile T111 + if EMT.TCPOS == 'T111' then + local dPosB = EgtGetAxisPos( 'B') + local dNewB = EgtIf( dPosB < 0, -90, 90) + SimulMoveAxes( 'B', dNewB, CollSimRotStep, 'C', 0, CollSimRotStep) + SimulMoveAxis( 'X', 0, RapSimStep) + SimulMoveAxis( 'B', 0, CollSimRotStep) + -- altrimenti posizioni standard rastrelliera + else + SimulMoveAxis( 'X', 0, RapSimStep) + SimulMoveAxes( 'B', 90, CollSimRotStep, 'C', -90, CollSimRotStep) + end + -- movimento scarico utensile di grosso diametro (su T111) + else + local dPosB = EgtGetAxisPos( 'B') + local dNewB = EgtIf( dPosB < 0, -90, 90) + SimulMoveAxes( 'B', dNewB, CollSimRotStep, 'C', 0, CollSimRotStep) + SimulMoveAxis( 'X', 0, RapSimStep) + end + -- breve pausa + EgtPause( 100) + -- nascondo utensile su testa e lo visualizzo su TcPos + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF) + ShowToolInTcPos( EMT.TCPOS_1, true) + -- movimento per carico utensile + if EMT.NEXTHEAD ~= 'H3' and EMT.NEXTHEAD ~= 'H5' then + SimulMoveAxes( 'B', 90, RapSimRotStep, 'C', -90, RapSimRotStep) + else + SimulMoveAxes( 'B', 0, RapSimRotStep, 'C', -90, RapSimRotStep) + end + -- se segue lama, carico utensile di default + if EMT.NEXTHEAD == 'H2' then + local sDefTool = GetDefaultToolName() + EgtLoadTool( 'H1', 1, sDefTool) + EMT.TOOL_1 = sDefTool + EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1) + -- lo nascondo sul portautensili + ShowToolInTcPos( EMT.TCPOS_1, false) + end + EgtOutText( '') + -- deposito utensile se prossimo non lama su sua testa o dummy + elseif EMT.NEXTHEAD ~= 'H2' and EMT.NEXTHEAD ~= 'H4' then + if EMT.NEXTTOOL ~= EMT.TOOL_1 then + EgtOutText( 'Tool change in progress...') + local RapSimStep = 4 * EMT.SIMSTEP + local RapSimRotStep = RapSimStep / 10 + local CollSimRotStep = min( RapSimRotStep, 10) + -- simulo movimento + SimulMoveAxes( 'B', 90, CollSimRotStep, 'C', -90, CollSimRotStep) + SimulMoveAxis( 'X', 0, RapSimStep) + -- breve pausa + EgtPause( 100) + ShowToolInTcPos( EMT.TCPOS_1, true) + -- se segue sega a catena + if EMT.NEXTHEAD == 'H3' or EMT.NEXTHEAD == 'H5' then + -- se non lama, nascondo l'utensile corrente + if EMT.HEAD ~= 'H2' then + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF) + end + -- eseguo movimento opportuno + SimulMoveAxes( 'B', 0, RapSimRotStep, 'C', -90, RapSimRotStep) + -- se altrimenti lama su cambio utensile + elseif EMT.NEXTHEAD == 'H1' and SpecialBH and EMT.NEXTTCPOS == 'T111' then + -- se non lama, nascondo l'utensile corrente + if EMT.HEAD ~= 'H2' then + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF) + end + -- eseguo movimento opportuno + SimulMoveAxes( 'B', -90, RapSimRotStep, 'C', 0, RapSimRotStep) + end + else + EMT.TOOL_1 = nil + EMT.TCPOS_1 = nil + end + end +end + +--------------------------------------------------------------------- +function OnSimulMachiningStart() + -- se lavorazione attuale e precedente con sega a catena con angolo A diverso, devo scaricare e ricaricare + if EMT.HEAD == 'H3' and EMT.HEAD == EMT.PREVHEAD then + local dPrevA = EgtGetAxisPos( 'A') + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + local dPosA = tonumber( sVal:sub( 3)) + if abs( dPosA - dPrevA) > 1 then + OnSimulToolDeselect() + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON) + OnSimulToolSelect( dPosA) + end + end + -- recupero alcuni dati della lavorazione + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + EMT.VMRS = ( EMT.MCHTYPE ~= MCH_MY.DRILLING and not ( sNotes and sNotes:find( 'VMRS=0;', 1, true))) + -- recupero TASKID della feature lavorata + local vId = EgtGetMachiningGeometry() + if vId and #vId > 0 and #vId[1] > 0 then + EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ; + else + EMT.TASKID = 0 + end + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true +end + +--------------------------------------------------------------------- +function OnSimulMachiningEnd() + if EMT.LOAD then + EMT.LOAD = false + elseif EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + end + EMT.PREVHEAD = EMT.HEAD + EMT.PREVEXIT = EMT.EXIT +end + +--------------------------------------------------------------------- +--function OnSimulPathStart() +--end + +--------------------------------------------------------------------- +function OnSimulPathEnd() + -- se attivo VMILL, lavorazione ed è richiesto di eliminare gli sfridi + if EMT.VMILL and #EMT.VMILL > 0 and not EMT.OPEISDISP and EMT.VMRS then + EgtOutLog( 'OnSimulPathEnd', 5) + local vMillId = EMT.VMILL[1] + local nPart = EgtVolZmapPartCount( vMillId) + if nPart > 1 then + -- ricerca del pezzo con massimo volume + local nPartMax = 0 + local dVolMax = 0 + for i = 1, nPart do + local dVol = EgtVolZmapPartVolume( vMillId, i - 1) + if dVol > dVolMax then + dVolMax = dVol + nPartMax = i + end + end + -- eliminazione di tutti i pezzi piccoli + for i = nPart, 1, -1 do + if i ~= nPartMax then + local b3Vmill = EgtVolZmapGetPartBBoxGlob( vMillId, i - 1, GDB_BB.STANDARD) + if b3Vmill:getDimX() < 1200 then + EgtRemoveVolZmapPart( vMillId, i - 1) + end + end + end + -- aggiorno visualizzazione + EgtDraw() + end + end +end + +--------------------------------------------------------------------- +function OnSimulPathStartAux() + --EgtOutLog( 'OnSimulPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + EgtOutLog( 'OnSimulPathStartAux', 5) + -- eseguo il comando + ExecAuxCmd( EMT.AUX) +end + +--------------------------------------------------------------------- +function OnSimulPathEndAux() + --EgtOutLog( 'OnSimulPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + EgtOutLog( 'OnSimulPathEndAux', 5) + -- eseguo il comando + ExecAuxCmd( EMT.AUX) +end + +--------------------------------------------------------------------- +function OnSimulMoveStart() + -- Recupero la posizione corrente dei carrelli + local Yp = EgtGetAxisPos( 'Y') + local Vp = EgtGetAxisPos( 'V') + -- Imposto movimento carrelli insieme con la tavola : + -- entrambe le pinze + if EMT.YDELTA and EMT.VDELTA then + EMT.AuxAxes = 2 + EMT.A1n = 'Y' + EMT.A1m = 'T' + EMT.A1 = EMT.L1 + EMT.YDELTA + EMT.A2n = 'V' + EMT.A2m = 'T' + EMT.A2 = EMT.L1 + EMT.VDELTA + -- solo pinza Y + elseif EMT.YDELTA then + EMT.AuxAxes = 2 + EMT.A1n = 'Y' + EMT.A1m = 'T' + EMT.A1 = EMT.L1 + EMT.YDELTA + EMT.A2n = 'V' + EMT.A2m = nil + EMT.A2 = ParkV + -- solo pinza V + elseif EMT.VDELTA then + EMT.AuxAxes = 2 + EMT.A1n = 'Y' + EMT.A1m = nil + EMT.A1 = EgtIf( EMT.YSPEC, Yp, ParkY) + EMT.A2n = 'V' + EMT.A2m = 'T' + EMT.A2 = EMT.L1 + EMT.VDELTA + end + -- Controllo scorrimento pinze chiuse Y e V + if EMT.YDELTA then + local dYDeltaP = Yp - EMT.L1p + if abs( EMT.YDELTA - dYDeltaP) > 0.1 then + EMT.ERR = 2 + local sErr = 'Y slide : ' .. EmtLenToString( dYDeltaP, 3) .. ' -> ' .. EmtLenToString( EMT.YDELTA, 3) + EmtSetLastError( 1202, sErr) + end + end + if EMT.VDELTA then + local dVDeltaP = Vp - EMT.L1p + if abs( EMT.VDELTA - dVDeltaP) > 0.1 then + EMT.ERR = 2 + local sErr = 'V slide : ' .. EgtNumToString( dVDeltaP, 3) .. ' -> ' .. EgtNumToString( EMT.VDELTA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Controllo corse assi Y e V + VerifyYStroke( EMT.A1) + VerifyVStroke( EMT.A2) + -- se inizio lavorazione + if EMT.MCHFIRST then + EgtOutText( '') + EMT.MCHFIRST = false + -- con pezzi alti aggiorno gli assi rotanti prima di muovermi sopra il pezzo + if not EMT.LOAD and EMT.MOVE == 0 and EMT.HB > BeamHeightForFixRot then + local RapSimStep = 4 * EMT.SIMSTEP + SimulMoveAxes( 'C', EMT.R1, RapSimStep/10, 'B', EMT.R2, RapSimStep/10) + end + end +end + +--------------------------------------------------------------------- +--function OnSimulMoveEnd() +--end + +--------------------------------------------------------------------- +function OnSimulCollision() + -- se prima collisione della lavorazione, la segnalo + if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then + local Class = '' + if EMT.SIMCOBIND == 1001 then + Class = 'T_H1' + elseif EMT.SIMCOBIND == 1002 then + Class = 'TH_H1' + else + Class = EMT.COLLOBJ[EMT.SIMCOBIND].Cl + end + table.insert( EMT.COLLIDE, { Mc = EMT.MCHNAME, Cl = Class, Vm = EMT.SIMVMID}) + EMT.LAST_MCHNAME_COLLIDE = EMT.MCHNAME + EMT.ERR = 1 + local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Class='..Class..'; VMill='..EMT.SIMVMID + EmtSetLastError( 1221, sErr, true) + EgtOutLog( 'Collision : ' .. sErr, 1) + end +end + +--------------------------------------------------------------------- +function ExecAuxCmd( sCmd) + local RapSimStep = 4 * EMT.SIMSTEP + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + if Cmd[2] == 'Unloading' then + EMT.UNLOADING = true + elseif Cmd[2] == 'Fall' then + EMT.FALL = true + end + EgtOutText( EgtIf( Cmd[3], Cmd[3], Cmd[2])) + elseif Cmd[1] == '1' then + if not SimulMoveAxis( Cmd[2], tonumber( Cmd[3]), RapSimStep) then + if VerifyYVStroke( Cmd[2], tonumber( Cmd[3])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + end + elseif Cmd[1] == '2' then + -- Verifico movimento carrello con trave agganciata + VerifyOneChariotSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5]) + -- Eseguo il movimento + local _, bOk, bOk2 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), RapSimStep, + Cmd[4], tonumber( Cmd[5]), RapSimStep) + if not ( bOk and bOk2) then + local nI = EgtIf( not bOk, 2, 4) + if VerifyYVStroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + end + elseif Cmd[1] == '3' then + -- Verifico movimento carrelli con trave agganciata + VerifyTwoChariotsSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5], Cmd[6], Cmd[7]) + -- Eseguo il movimento + local _, bOk, bOk2, bOk3 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), RapSimStep, + Cmd[4], tonumber( Cmd[5]), RapSimStep, + Cmd[6], tonumber( Cmd[7]), RapSimStep) + if not ( bOk and bOk2 and bOk3) then + local nI = EgtIf( not bOk, 2, EgtIf( not bOk2, 4, 6)) + if VerifyYVStroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + end + elseif Cmd[1] == '11' then + local dPY = MaxOpen + if Cmd[2] ~= '0' then + dPY = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB) + end + SimulMoveAxis( 'PY', dPY, RapSimStep) + SetPYLight( Cmd[2] ~= '0') + elseif Cmd[1] == '12' then + local dPV = MaxOpen + if Cmd[2] ~= '0' then + dPV = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB) + end + SimulMoveAxis( 'PV', dPV, RapSimStep) + SetPVLight( Cmd[2] ~= '0') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0.01 and nVDelta > 0.01 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0.01 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0.01 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + elseif Cmd[1] == '31' then + local nRawId = tonumber( Cmd[2]) + EmtUnlinkRawPartFromGroup( nRawId) + EmtLinkRawPartToGroup( nRawId, Cmd[3]) + EMT.YSPEC = true + end +end + +--------------------------------------------------------------------- +function ExecUnloading() + if EMT.VMILL and #EMT.VMILL > 0 then + local vMillId = EMT.VMILL[1] + -- gruppo dei Vmill + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + -- li sposto per lasciare spazio al nuovo pezzo + local nId = EgtGetFirstInGroup( nVmGrpId) + while nId do + EgtMove( nId, Vector3d( 0, -( EMT.SB + 50.0), 0), GDB_RT.GLOB) + nId = EgtGetNext( nId) + end + -- creo un nuovo layer e vi inserisco il nuovo pezzo + local nLayId = EgtGroup( nVmGrpId, EgtGetGlobFrame( vMillId)) + EgtRelocate( vMillId, nLayId) + local vtMove = Vector3d( 0, -450, 0) + if EMT.FALL then vtMove = Vector3d( -500, 0, -750) end + EgtMove( nLayId, vtMove, GDB_RT.GLOB) + EgtSetLevel( vMillId, GDB_LV.USER) + -- aggiungo gli spigoli + local nFirstId, nCount = EgtVolZmapGetEdges( vMillId, nLayId) + if nFirstId then + for nId = nFirstId, nFirstId + nCount - 1 do + EgtSetColor( nId, Color3d( 96, 96, 96)) + end + end + -- rilascio Vmill + table.remove( EMT.VMILL, 1) + -- aggiorno la visualizzazione + EgtDraw() + -- se finito + if EMT.PHASE == EgtGetPhaseCount() then + -- se impostato di salvare i Vmill, lo faccio + local sMachIni = EgtGetCurrMachineDir() .. '\\' .. EgtGetCurrMachineName() .. '.ini' + if EgtGetStringFromIni( 'VMill', 'Save', '', sMachIni) == '1' then + local sFile = EgtGetCurrFilePath() + if sFile then + local sDir, sName, sExt = EgtSplitPath( sFile) + if sExt and sExt:lower() == ".nge" then + sName = sName .. '_VM_' .. EgtGetMachGroupName( EgtGetCurrMachGroup()) + EgtSetLevel( nVmGrpId, GDB_LV.USER) + EgtSaveObjToFile( nVmGrpId, sDir .. sName .. '.Nge') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + end + end + end + end +end + +--------------------------------------------------------------------- +function VerifyYSlide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello Y + if sName1 == 'T' and sName2 == 'Y' and GetPYLight() then + local dYDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'Y') + local dYDeltaA = tonumber( dVal1) - tonumber( dVal2) + EgtOutLog( string.format( 'YDeltaP=%.3f YDeltaA=%.3f', dYDeltaP, dYDeltaA), 5) + if abs( dYDeltaA - dYDeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'Y slide : ' .. EmtLenToString( dYDeltaP, 3) .. ' -> ' .. EmtLenToString( dYDeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Tutto bene + return true +end + +--------------------------------------------------------------------- +function VerifyVSlide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello V + if sName1 == 'T' and sName2 == 'V' and GetPVLight() then + local dVDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'V') + local dVDeltaA = tonumber( dVal1) - tonumber( dVal2) + EgtOutLog( string.format( 'VDeltaP=%.3f VDeltaA=%.3f', dVDeltaP, dVDeltaA), 5) + if abs( dVDeltaA - dVDeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'V slide : ' .. EmtLenToString( dVDeltaP, 3) .. ' -> ' .. EmtLenToString( dVDeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + return true +end + +--------------------------------------------------------------------- +function VerifyOneChariotSlide( sName1, dVal1, sName2, dVal2) + -- Metto in prima posizione la trave + if sName2 == 'T' then + sName1, sName2 = sName2, sName1 + dVal1, dVal2 = dVal2, dVal1 + end + -- Eseguo verifica + if sName2 == 'Y' then + return VerifyYSlide( sName1, dVal1, sName2, dVal2) + elseif sName2 == 'V' then + return VerifyVSlide( sName1, dVal1, sName2, dVal2) + end + return true +end + +--------------------------------------------------------------------- +function VerifyTwoChariotsSlide( sName1, dVal1, sName2, dVal2, sName3, dVal3) + -- Metto in prima posizione la trave + if sName2 == 'T' then + sName1, sName2 = sName2, sName1 + dVal1, dVal2 = dVal2, dVal1 + elseif sName3 == 'T' then + sName1, sName3 = sName3, sName1 + dVal1, dVal3 = dVal3, dVal1 + end + -- Eseguo verifica + if sName2 == 'Y' then + return VerifyYSlide( sName1, dVal1, sName2, dVal2) and VerifyVSlide( sName1, dVal1, sName3, dVal3) + elseif sName2 == 'V' then + return VerifyVSlide( sName1, dVal1, sName2, dVal2) and VerifyYSlide( sName1, dVal1, sName3, dVal3) + end + return true +end + +--------------------------------------------------------------------- +function VerifyYStroke( dY) + if dY < MinY then + EmtSetOutstrokeInfo( 'Y', 'Y', true, dY - MinY, ' (L1-)') + EMT.ERR = 1 + local sErr = 'Y axis outstroke ' .. EgtNumToString( dY - MinY, 3) + EgtOutLog( sErr) + return false + elseif dY > MaxY then + EmtSetOutstrokeInfo( 'Y', 'Y', true, dY - MaxY, ' (L1+)') + EMT.ERR = 1 + local sErr = 'Y axis outstroke ' .. EgtNumToString( dY - MaxY, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyVStroke( dV) + if dV > MaxV then + EmtSetOutstrokeInfo( 'V', 'V', true, dV - MaxV, ' (L1+)') + EMT.ERR = 1 + local sErr = 'V axis outstroke ' .. EgtNumToString( dV - MaxV, 3) + EgtOutLog( sErr) + return false + elseif dV < MinV then + EmtSetOutstrokeInfo( 'V', 'V', true, dV - MinV, ' (L1-)') + EMT.ERR = 1 + local sErr = 'V axis outstroke ' .. EgtNumToString( dV - MinV, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyYVStroke( sName, dVal) + if sName == 'Y' then + return VerifyYStroke( dVal) + elseif sName == 'V' then + return VerifyVStroke( dVal) + else + return nil + end +end + +--------------------------------------------------------------------- +function ShowToolInTcPos( sTcPos, bShow) + -- recupero il gruppo dell'utensile + local TcExitId = EgtGetFirstNameInGroup( EgtGetTcPosId( sTcPos or '') or GDB_ID.NULL, 'T1') + if not TcExitId then return end + -- imposto lo stato di visualizzazione + EgtSetStatus( TcExitId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF)) +end + +--------------------------------------------------------------------- +function GetToolTcPos( sTool) + -- salvo stato iniziale + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- recupero la posizione di cambio utensile dell'utensile indicato + local sTcPos + if EgtTdbSetCurrTool( sTool) then + sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + end + -- ripristino stato iniziale + if CurrTool then + EgtTdbSetCurrTool( CurrTool) + else + EgtTdbSetCurrTool( '') + end + -- restituisco risultato + return sTcPos +end + + +--------------------------------------------------------------------- +-- *** ESTIMATION T&L *** +--------------------------------------------------------------------- +local RAPID_X_FEED = 75000 -- mm/min +local RAPID_Y_FEED = 100000 -- mm/min +local RAPID_Z_FEED = 50000 -- mm/min +local RAPID_C_FEED = 15000 -- deg/min +local RAPID_B_FEED = 15000 -- deg/min +local RAPID_MIN_T = 0.1 -- s +local LOAD_T = 2 -- s +local CHAR_ONE_MOVE_T = 1 -- s +local ROTATION_T = 40 -- s +local SPLIT_T = 6 -- s +local UNLOAD_T = 4 -- s +local FALL_T = 2 -- s + +--------------------------------------------------------------------- +function OnEstimStart() + EMT.INCHES = not EgtUiUnitsAreMM() -- unità di misura mm/inches +end + +--------------------------------------------------------------------- +function OnEstimEnd() +end + +--------------------------------------------------------------------- +function OnEstimProgramStart() + -- imposto inizio movimenti da Home + EMT.L1 = EgtGetAxisHomePos( 'T') + EMT.L2 = EgtGetAxisHomePos( 'X') + EMT.L3 = EgtGetAxisHomePos( 'Z') + EMT.R1 = EgtGetAxisHomePos( 'C') + EMT.R2 = EgtGetAxisHomePos( 'B') + -- aggiorno valori come precedenti + EmtUpdatePrev() + -- totalizzatori tempi e lunghezze + EMT.TOTCUTLEN = 0 + EMT.TOTCUTTIME = 0 + EMT.TOTEXTLEN = 0 + EMT.TOTEXTTIME = 0 + -- variabile per lunghezza taglio utensili + EMT.TOOLCUTLEN = {} + -- intestazioni + EmtTleStart( EMT.INFO) +end + +--------------------------------------------------------------------- +function OnEstimProgramEnd() + -- stampa dei totali delle lavorazioni + EmtTleAddTotal( EmtSecToHMS( EMT.TOTCUTTIME + EMT.TOTEXTTIME), EmtLenToMF( EMT.TOTCUTLEN)) + -- stampa dei totali degli utensili + for i = 1, #EMT.TOOLCUTLEN do + local TCL = EMT.TOOLCUTLEN[i] + EmtTleAddTool( TCL.Name, EmtLenToMF( TCL.Len)) + end + -- completo il file + local _, _, sExt = EgtSplitPath( EMT.FILE) + EmtTleEnd( sExt:sub( 2)) + -- salvo i dati principali nel progetto + EgtSetInfo( EgtGetCurrMachGroup(), 'Ttot', EgtNumToString( EMT.TOTCUTTIME + EMT.TOTEXTTIME, 0)) + EgtSetInfo( EgtGetCurrMachGroup(), 'Ltot', EgtNumToString( EMT.TOTCUTLEN, 0)) +end + +--------------------------------------------------------------------- +function OnEstimDispositionStart() + -- inizio disposizione + EMT.OPEISDISP = true + -- sulla prima fase dichiaro carico barra + if EMT.PHASE == 1 then + EMT.LOAD = true + else + EMT.LOAD = false + end +end + +--------------------------------------------------------------------- +function OnEstimDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + ; + -- se altrimenti disposizione intermedia o finale dopo separazione e rotazione, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) or IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- verifico se sono diverse + if nRot ~= nPrevRot then + -- imposto stato post-rotazione + EMT.POSTROT = true + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + ; + end + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end + -- termine disposizione + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnEstimToolSelect() + -- reset indice utensile in tabella lunghezze + EMT.TCLIND = 0 + -- verifico che l'utensile sia definito + if #EMT.TOOL == 0 then return end + -- cerco l'utensile nella tabella + for i = 1, #EMT.TOOLCUTLEN do + if EMT.TOOLCUTLEN[i].Name == EMT.TOOL then + EMT.TCLIND = i + break + end + end + -- se non trovato, lo aggiungo + if EMT.TCLIND == 0 then + table.insert( EMT.TOOLCUTLEN, { Name = EMT.TOOL, Len = 0}) + EMT.TCLIND = #EMT.TOOLCUTLEN + end +end + +--------------------------------------------------------------------- +function OnEstimToolDeselect() +end + +--------------------------------------------------------------------- +function OnEstimMachiningStart() + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EgtOutLog( 'Mach : ' .. EMT.MCHNAME, 5) + -- reset contatori di lavorazione + EMT.MCHCUTLEN = 0 + EMT.MCHCUTTIME = 0 + EMT.MCHEXTLEN = 0 + EMT.MCHEXTTIME = 0 +end + +--------------------------------------------------------------------- +function OnEstimMachiningEnd() + -- nel caso di foratura devo dimezzare la lunghezza di taglio perchè comprende anche l'uscita + if EMT.MCHTYPE == MCH_MY.DRILLING then + EMT.MCHCUTLEN = EMT.MCHCUTLEN / 2 + end + local sName = EgtGetName( EMT.MCHID) + EmtTleAddMachining( sName, EmtSecToHMS( EMT.MCHCUTTIME + EMT.MCHEXTTIME), EmtLenToMF( EMT.MCHCUTLEN), EMT.TOOL) + -- aggiorno totali e utensili + EMT.TOTCUTLEN = EMT.TOTCUTLEN + EMT.MCHCUTLEN + EMT.TOTCUTTIME = EMT.TOTCUTTIME + EMT.MCHCUTTIME + EMT.TOTEXTLEN = EMT.TOTEXTLEN + EMT.MCHEXTLEN + EMT.TOTEXTTIME = EMT.TOTEXTTIME + EMT.MCHEXTTIME + EMT.TOOLCUTLEN[EMT.TCLIND].Len = EMT.TOOLCUTLEN[EMT.TCLIND].Len + EMT.MCHCUTLEN + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end +end + +--------------------------------------------------------------------- +function OnEstimPathStart() + EMT.AUXTYPE = nil + EMT.MCHMOVEFIRST = true +end + +--------------------------------------------------------------------- +function OnEstimPathEnd() + EMT.AUXTYPE = nil +end + +--------------------------------------------------------------------- +function OnEstimPathStartAux() + -- se richiesto, preparo il carico barra + if EMT.LOAD then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Loading', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.LOAD = false + end + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = ROTATION_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Rotation', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.POSTROT = false + end + -- altrimenti, spostamento carrelli + else + if EMT.AUXTOT > 2 and EMT.AUXIND == EMT.AUXTOT then + local dTime = ( EMT.AUXTOT - 2) * CHAR_ONE_MOVE_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Charriots move', EmtSecToHMS( dTime), ' - ', ' - ') + end + end +end + +--------------------------------------------------------------------- +function OnEstimPathEndAux() + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.AUXTYPE = 'F' + else + EMT.AUXTYPE = 'P' + end + end + end + -- per lo scarico della rimanenza + if EMT.AUXTYPE == 'R' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Remnant unloading' + EMT.TLE_TIME = dTime + end + -- per lo split + elseif EMT.AUXTYPE == 'S' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = SPLIT_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Splitting' + EMT.TLE_TIME = dTime + end + -- per lo scarico + elseif EMT.AUXTYPE == 'U' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Unloading' + EMT.TLE_TIME = dTime + end + -- per lo scarico a caduta + elseif EMT.AUXTYPE == 'F' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = FALL_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Fall' + EMT.TLE_TIME = dTime + end + -- per la pre-rotazione + elseif EMT.AUXTYPE == 'P' then + ; -- calcolato come parte della rotazione + end +end + +--------------------------------------------------------------------- +function OnEstimRapid() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + local dR1 = 0 + if EMT.R1 and EMT.R1p then dR1 = EMT.R1 - EMT.R1p end + local dR2 = 0 + if EMT.R2 and EMT.R2p then dR2 = EMT.R2 - EMT.R2p end + -- se primo posizionamento della lavorazione il movimento di L1 è già conteggiato in quello dei carrelli + if EMT.MCHMOVEFIRST then + EMT.MCHMOVEFIRST = false + dL1 = 0 + end + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHEXTLEN = EMT.MCHEXTLEN + dLen + -- calcolo tempo + local dTime = RAPID_MIN_T + local dT1 = abs( dL1) / RAPID_X_FEED * 60 + if dT1 > dTime then dTime = dT1 end + local dT2 = abs( dL2) / RAPID_Y_FEED * 60 + if dT2 > dTime then dTime = dT2 end + local dT3 = abs( dL3) / RAPID_Z_FEED * 60 + if dT3 > dTime then dTime = dT3 end + local dT4 = abs( dR1) / RAPID_C_FEED * 60 + if dT4 > dTime then dTime = dT4 end + local dT5 = abs( dR2) / RAPID_B_FEED * 60 + if dT5 > dTime then dTime = dT5 end + EMT.MCHEXTTIME = EMT.MCHEXTTIME + dTime + EgtOutLog( string.format( ' G0 Len=%.0f Rot=%.0f° Time=%.2f', dLen, abs( dR1) + abs( dR2), dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimLinear() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G1 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimArc() + -- dati movimento + local dLxy = EMT.RR * abs( EMT.AC) * pi / 180 + local dLz = abs( ( Point3d( EMT.L1, EMT.L2, EMT.L3) - Point3d( EMT.L1p, EMT.L2p, EMT.L3p)) * Vector3d( EMT.EXTR)) + -- calcolo lunghezza + local dLen = sqrt( dLxy * dLxy + dLz * dLz) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G2 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +-- *** GENERAL *** +--------------------------------------------------------------------- +function FindFirstToolOnHead( sH1) + -- salvo stato iniziale + local CurrMachId = EgtGetCurrMachining() + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- cerco lavorazione con utensile su testa indicata + local sTool, nTlen + local OpId = EgtGetFirstActiveOperation() + while OpId do + local nType = EgtGetOperationType( OpId) + if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then + if EgtSetCurrMachining( OpId) then + local sTest = EgtGetMachiningParam( MCH_MP.TOOL) + if EgtTdbSetCurrTool( sTest) then + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if sHead and ( sHead == sH1) then + sTool = sTest + nTlen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + break + end + end + end + end + OpId = EgtGetNextActiveOperation( OpId) + end + -- ripristino stato iniziale + if CurrMachId then + EgtSetCurrMachining( CurrMachId) + else + EgtResetCurrMachining() + end + if CurrTool then + EgtTdbSetCurrTool( CurrTool) + else + EgtTdbSetCurrTool( '') + end + -- restituisco risultato + return sTool, nTlen +end + +--------------------------------------------------------------------- +function GetDefaultToolName() + local vTools = EgtGetToolsInCurrSetupPos( DefTcPos) + if vTools and vTools[1] and #vTools[1] > 0 then + return vTools[1] + else + local sErr = 'Missing tool in Default Position ' .. DefTcPos + EgtOutLog( 'Error : ' .. sErr) + if EMT.VER and EMT.VER >= '2.3a2' and EMT.SIM1ST then + EgtOutBox( sErr, 'ERROR', 'ERROR') + end + return '' + end +end + +--------------------------------------------------------------------- +function IsStartPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START') +end + +--------------------------------------------------------------------- +function IsRestPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'REST') +end + +--------------------------------------------------------------------- +function IsStartOrRestPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START' or sVal == 'REST') +end + +--------------------------------------------------------------------- +function IsMidPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'MID') +end + +--------------------------------------------------------------------- +function IsMid2Phase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'MID2') +end + +--------------------------------------------------------------------- +function IsEnd2Phase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'END2') +end + +--------------------------------------------------------------------- +function GetPhaseType( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '') +end + +--------------------------------------------------------------------- +function GetPhaseOrd( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ORD', 'i') or 0) +end + +--------------------------------------------------------------------- +function GetPhaseRot( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) +end + +--------------------------------------------------------------------- +-- *** END GENERAL *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.mlse b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.mlse new file mode 100644 index 0000000..c2e8ed4 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.mlse @@ -0,0 +1,3855 @@ +-- Special Operations macchina Essetre-FAST by EgalTech s.r.l. 2022/04/07 +-- 2020/05/15 DS ver.2.2e1 Correzione a SpecAdjustCarrC3 per bFixedDelta. +-- 2020/05/16 DS ver 2.2e2 Aggiunta gestione rotazione 90deg. +-- 2020/05/21 DS ver 2.2e3 Aggiunto a SpecAdjustCarrC3 parametro bFixedPos (per lavorazioni Split e Cut precedute da Pre). +-- 2020/05/26 DS ver 2.2e4 Nuova gestione dei pezzi a caduta. +-- 2020/05/27 DS ver 2.2e5 Corretto blocco pinza V su presplit e precut. +-- 2020/05/28 DS ver 2.2e7 Correzione per mancanza EMC.HOVM allo scarico. +-- 2020/06/18 DS ver 2.2f3 Aumento ingombro fresatura opposta a cerrello per evitare extracorsa. +-- 2020/07/02 DS ver 2.2g1 Correzione quota di presa al carico per casi senza tagli in testa e lavorazioni solo in coda. +-- 2020/09/03 DS ver 2.2i1 Correzione in Load dopo rotazione deve tener conto dell'ingombro delle lavorazioni in coda. +-- 2020/09/09 DS ver 2.2i2 Nel calcolo pinzaggi ora si tiene conto anche della larghezza della sezione della barra. +-- 2020/09/25 DS ver 2.2i5 Migliorato calcolo ingombro lama con testa opposta al carrello. +-- 2020/09/29 DS ver 2.2i6 Migliorato calcolo ingombro fresa su tagli longitudinali di fianco. +-- 2020/10/13 DS ver 2.2j2 Aggiunta gestione sezione molto piccola (Very Small) per presa minima. Corretta gestione ingombri con fori a 30 deg. +-- 2020/12/09 DS ver 2.2l1 Migliorato calcolo ingombro con lama verticale inclinata di +/-45deg rispetto a X. +-- 2021/01/24 DS ver 2.3a2 Migliorato controllo assi rotanti definiti con sega a catena per SpecialCalcMachiningEncumbrance. +-- 2021/02/02 DS ver 2.3b1 Migliorato calcolo ingombro tagli di lama quasi verticale angolata. +-- 2021/02/17 DS ver 2.3b2 Corretta B3Ys-xs1 per accentrare V e T bisogna sottrarre dExtraY che è negativo e non sommare. +-- 2021/04/02 DS ver 2.3d1 Corretto calcolo ingombro con lama per non andare in extracorsa con le pinze quando lavorazione vicino a Y0. +-- 2021/06/01 DS ver 2.3f1 Aggiunta segnalazione pezzo scaricato a caduta. +-- 2021/06/25 DS ver 2.3f5 Corretta segnalazione tipo di scarico del pezzo. +-- 2021/07/20 DS ver 2.3g4 Aggiunta gestione rinvio per lavorazioni da sotto. +-- 2021/08/02 DS ver 2.3h1 Per spessori piccoli ridotta tolleranza di presa (limiti _V). +-- 2021/10/12 DS ver 2.3j1 Lame standard (Lt > L) gestite come lame piatte (MCH_TY.SAW_STD e MCH_TY.SAW_FLAT). +-- 2021/10/12 DS ver 2.4c3 Corretti errori di scrittura nomi variabili alle linee 2714 (YDeltaTol) e 2717 (dCorsaYTr e dCorsaVr). +-- 2022/04/07 DS ver 2.4d1 Aumentato ingombro lavorazione per evitare extracorsa interno Y e V (da 260 a 280). + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +-- Carico i dati globali +local sBaseDir = EgtGetSourceDir() +local BD = dofile( sBaseDir .. 'Beam\\BeamData.lua') + +EgtOutLog ( '** Essetre-FAST '..PP_VER..' **', 1) + +---------------------- OnSpecialMoveZup ----------------------------- +--------------------------------------------------------------------- +function OnSpecialMoveZup() + --EgtOutLog( 'OnSpecialMoveZup : ' .. EMC.HEAD .. '.' .. tostring( EMC.EXIT)) + + -- Inizializzazioni + EMC.ERR = 0 + EMC.MODIF = false + + -- se sega a catena + if EMC.HEAD == 'H3' then + + + end + +end + +---------- OnSpecialApplyDisposition & OnPostApplyMachining --------- +----------------------- Costanti ------------------------------------ +local DELTA_TOL_V = 110 +local DELTA_TOL_S = 210 +local DELTA_TOL_L = 410 +local DELTA_TOL_FIXED = 50 +local DeltaTol = DELTA_TOL_S +local DELTA_SIC = 1 +local AGG_LOAD = 50 +local AGG_B_SPLIT = 0 +local MIN_JOIN_VV = 75 +local MIN_JOIN_SS = 100 +local MIN_JOIN_LS = 290 +local MIN_JOIN_SL = 100 +local MIN_JOIN_LL = 400 +local MinJoin = MIN_JOIN_SS +local MinOther = abs( MinY) + abs( MaxV) + MinJoin + +----------------------- Variabili ----------------------------------- +local Test = false + +--------------------------------------------------------------------- +local function PrepareClGroup( nParentId) + + local nClId = EgtGetFirstNameInGroup( nParentId, 'CL') + -- se non c'è, lo aggiunge + if not nClId then + nClId = EgtGroup( EMC.DISPID) + if not nClId then + return nil + end + EgtSetName( nClId, 'CL') + -- altrimenti lo svuoto + else + EgtEmptyGroup( nClId) + end + + return nClId +end + +--------------------------------------------------------------------- +local function IsStartOrRestPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'START' or sVal == 'REST') +end + +--------------------------------------------------------------------- +local function IsMidPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'MID') +end + +--------------------------------------------------------------------- +local function IsEndPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'END') +end + +--------------------------------------------------------------------- +local function IsMid2Phase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'MID2') +end + +--------------------------------------------------------------------- +local function IsEnd2Phase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'END2') +end + +--------------------------------------------------------------------- +local function GetNextStartOrRestPhase( nPhase) + local nNextPhase = nPhase + 1 + while nNextPhase <= EgtGetPhaseCount() do + if IsStartOrRestPhase( nNextPhase) then + break ; + end + nNextPhase = nNextPhase + 1 + end + return nNextPhase +end + +--------------------------------------------------------------------- +local function GetPhaseRot( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) +end + +--------------------------------------------------------------------- +local function IsLastOperationBeforeRotation( nOperId) + -- se ultima fase o ultima fase del pezzo, ritorno risultato negativo + if EMC.PHASE == EgtGetPhaseCount() or IsEndPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) then + return false + end + -- recupero la successiva operazione attiva + local nNextOperId = EgtGetNextActiveOperation( nOperId) + -- se non esiste o non è una disposizione, ritorno risultato negativo + if not nNextOperId or EgtGetOperationType( nNextOperId) ~= MCH_OY.DISP then + return false + end + -- recupero le rotazioni della fase corrente e della prossima fase + local nRot = GetPhaseRot( EMC.PHASE) + local nNextRot = GetPhaseRot( EMC.PHASE + 1) + -- ritorno se sono diverse + return ( nRot ~= nNextRot) +end + +--------------------------------------------------------------------- +local function IsFirstMachiningAfterRotation( nMchId) + -- se prima fase o prima fase del pezzo, ritorno risultato negativo + if EMC.PHASE == 1 or IsStartOrRestPhase( EMC.PHASE) then + return false + end + -- recupero la precedente operazione attiva + local nPrevOperId = EgtGetPrevActiveOperation( nMchId) + -- se non esiste o non è una disposizione, ritorno risultato negativo + if not nPrevOperId or EgtGetOperationType( nPrevOperId) ~= MCH_OY.DISP then + return false + end + -- recupero le rotazioni della fase corrente e della fase precedente + local nRot = GetPhaseRot( EMC.PHASE) + local nPrevRot = GetPhaseRot( EMC.PHASE - 1) + -- ritorno se sono diverse + return ( nRot ~= nPrevRot) +end + +--------------------------------------------------------------------- +local function UpdateMinJoinDeltaTol() + local L_SMALL = 800 + local H_V = 90 + local H_S = 200 + local H_L = 400 + local W_V = 90 + local W_S = 150 + local W_L = 250 + if EMC.SB <= W_V and EMC.HB <= H_V then + MinJoin = MIN_JOIN_VV + DeltaTol = DELTA_TOL_V + elseif EMC.LB <= L_SMALL then + MinJoin = MIN_JOIN_SS + DeltaTol = DELTA_TOL_S + else + local dMinJoinS + local dMinJoinL + if EMC.SB <= W_S then + dMinJoinS = MIN_JOIN_SS + dMinJoinL = MIN_JOIN_LS + elseif EMC.SB <= W_L then + local Coeff = ( EMC.SB - W_S) / ( W_L - W_S) + dMinJoinS = ( 1 - Coeff) * MIN_JOIN_SS + Coeff * MIN_JOIN_SL + dMinJoinL = ( 1 - Coeff) * MIN_JOIN_LS + Coeff * MIN_JOIN_LL + else + dMinJoinS = MIN_JOIN_SL + dMinJoinL = MIN_JOIN_LL + end + if EMC.HB <= H_S then + MinJoin = dMinJoinS + DeltaTol = DELTA_TOL_S + elseif EMC.HB <= H_L then + local Coeff = ( EMC.HB - H_S) / ( H_L - H_S) + MinJoin = ( 1 - Coeff) * dMinJoinS + Coeff * dMinJoinL + DeltaTol = ( 1 - Coeff) * DELTA_TOL_S + Coeff * DELTA_TOL_L + else + MinJoin = dMinJoinL + DeltaTol = DELTA_TOL_L + end + if EMC.SB < W_V then + DeltaTol = DELTA_TOL_V + end + end + MinOther = abs( MinY) + abs( MaxV) + MinJoin +end + +--------------------------------------------------------------------- +local function GetCUTID() + -- recupero CUTID del pezzo in lavoro + local nOrd = GetPhaseOrd( EMC.PHASE) + local nPartRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + nPartRawId = nRawId + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + local CutID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + return CutID +end + +--------------------------------------------------------------------- +local function EnsureZmax( bZmaxOk, vCmd) + if not bZmaxOk then table.insert( vCmd, { 1, 'Z', EgtGetAxisHomePos( 'Z')}) end + return true +end + +--------------------------------------------------------------------- +local function EmitComment( vCmd, sOut) + EgtOutLog( ' ' .. sOut, 1) + if Test then + table.insert( vCmd, { 0, sOut}) + end +end + +--------------------------------------------------------------------- +function OnSpecialApplyDisposition() + + EgtOutLog( ' *** Fase : ' .. EgtNumToString( EMC.PHASE, 0) .. ' ***', 1) + + -- Inizializzo codice di errore + EMC.ERR = 0 + + -- Campi obbligatori ma non usati + EMC.HEAD = "H4" + EMC.EXIT = 1 + EMC.TCPOS = "" + EMC.SHIFTS = 0 + EMC.SBH = false + + -- Se disposizione da saltare non devo fare alcunché + if EgtExistsInfo( EMC.DISPID, 'SKIP') then return end + + -- Assegno flag di pezzo separato dal resto del grezzo + local bSplit = IsEndPhase( EMC.PHASE) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) + + -- Recupero il tipo dell'operazione successiva + local nNextOpeType = EgtGetOperationType( EgtGetNextActiveOperation( EMC.DISPID) or GDB_ID.NULL) + + -- Se ci sono lavorazioni successive non devo fare alcunché + if nNextOpeType ~= MCH_OY.NONE and nNextOpeType ~= MCH_OY.DISP then return end + + -- Imposto gruppo e path di movimento + local nClId = PrepareClGroup( EMC.DISPID) + if not nClId then + EMC.ERR = 3 + return + end + local nPathId = EgtGroup( nClId) + if not nPathId then + EMC.ERR = 6 + return + end + EgtSetName( nPathId, 'Empty') + EMC.PATHID = nPathId + EMC.SHIFTS = -1 + + -- Se l'operazione successiva è una disposizione con rotazione, devo preparare il pezzo alla rotazione + if IsLastOperationBeforeRotation( EMC.DISPID) then + -- aggiornamento posizioni + if IsStartPhase( EMC.PHASE) then + -- carico le posizioni + local dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd') + local dPosY = EgtGetInfo( EMC.DISPID, 'YPOS', 'd') + EMC.TPOS = dPosT + EMC.YDELTA = dPosY - dPosT + EMC.VDELTA = nil + EMC.CNT = 1 + else + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + end + -- Determinazione delle dimensioni del grezzo in lavoro + local b3Raw = BBox3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + b3Raw = EgtGetRawPartBBox( nRawId) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + -- Assegno sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 + EMC.HCING = 0 + EMC.TCING = EgtGetInfo( nRawId, 'TCING', 'd') or 0 + -- Eseguo preparazione alla rotazione + local vCmd = SpecCalcPreRot() + SpecOutputCmds( vCmd, true) + return + end + + -- Se l'operazione successiva è ancora una disposizione, devo scaricare il pezzo + if nNextOpeType == MCH_OY.DISP and bSplit and not IsEnd2Phase( EMC.PHASE) then + -- aggiornamento posizioni + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + -- Determinazione delle dimensioni del grezzo in lavoro + local b3Raw = BBox3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) and not EgtVerifyRawPartPhase( nRawId, EMC.PHASE + 1) then + b3Raw = EgtGetRawPartBBox( nRawId) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + EMC.HOVM = EgtGetInfo( nRawId or GDB_ID.NULL, 'HOVM', 'd') or 0 + -- Eseguo scarico + local vCmd = SpecCalcUnload() + SpecOutputCmds( vCmd, true) + return + end + + -- Verifico ci sia un solo grezzo nella fase corrente + local nRawCount = 0 + local nCurrRawId = GDB_ID.NULL + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + nRawCount = nRawCount + 1 + nCurrRawId = nRawId + end + nRawId = EgtGetNextRawPart( nRawId) + end + + -- Determinazione delle sue dimensioni + local b3Raw = EgtGetRawPartBBox( nCurrRawId) + if b3Raw:isEmpty() then + EMC.ERR = 11 + return + end + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + EMC.SB = b3Raw:getDimY() + EMC.HB = b3Raw:getDimZ() + EMC.ZMIN = b3Raw:getMin():getZ() + + -- Aggiorno limiti di presa e tolleranza + UpdateMinJoinDeltaTol() + + -- Assegno sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = 0 + EMC.HCING = 0 + EMC.TCING = 0 + + -- Devo scaricare il grezzo rimasto (deve essere unico) + -- Posizione trave + local dPosT + + -- Se fase 1 o dopo rotazione eseguo carico con carrello Y + local vCmd = {} + if EMC.PHASE == 1 or IsEnd2Phase( EMC.PHASE) then + dPosT = LoadT + if IsEnd2Phase( EMC.PHASE) then dPosT = dPosT + TurnerOffs end + vCmd = SpecCalcLoad( dPosT, 0, min( EMC.LB - MinOther - AGG_LOAD, MaxY - dPosT)) + -- se altrimenti fase successiva alla prima di tipo inizio o rimanenza + elseif IsStartOrRestPhase( EMC.PHASE) then + -- recupero posizione trave e quota di aggancio carrello + dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd') + local dPosY = EgtGetInfo( EMC.DISPID, 'YPOS', 'd') + -- se carrello agganciato + if dPosY then + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dPosY - dPosT, 0}) + -- recupero CNT + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + if EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP and EgtExistsInfo( nPrevOpeId, 'SKIP') then + nPrevOpeId = EgtGetPrevActiveOperation( nPrevOpeId) + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + -- altrimenti è grezzo scaricato al carico e devo ricaricarlo + else + vCmd = SpecCalcLoad( dPosT, 0, min( EMC.LB - MinOther - AGG_LOAD, MaxY - dPosT)) + end + -- altrimenti fase successiva pari + else + local dPosV = EgtGetInfo( EMC.DISPID, 'VPOS', 'd') + EMC.VDELTA = dPosV + end + -- Se fase inizio o rimanenza, eseguo scambio per avere solo pinza V + local vCmd2 = {} + if IsStartOrRestPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) then + EMC.TPOS = dPosT + SpecSetCarrPosFromCmds( vCmd) + local dDistFront = EgtIf( EMC.LB < abs( MinV - UnloadT), MinJoin, EMC.LB - abs( MinV - UnloadT) + MinJoin + DeltaTol) + vCmd2 = SpecCalcCarriages( dDistFront, 0) + if vCmd and #vCmd > 1 and vCmd2 and #vCmd2 > 1 then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + end + -- eseguo scarico + SpecSetCarrPosFromCmds( vCmd2) + local vCmd3 = SpecCalcUnload() + -- unisco ed emetto i comandi + vCmd = EgtJoinTables( vCmd, vCmd2) + vCmd = EgtJoinTables( vCmd, vCmd3) + SpecOutputCmds( vCmd, true) +end + +--------------------------------------------------------------------- +function OnPostApplyMachining() + + EgtOutLog( ' Lavorazione : ' .. EgtGetName( EMC.MCHID), 1) + + -- Inizializzo codice di errore + EMC.ERR = 0 + + -- Recupero la posizione della trave e dei carrelli al termine della precedente operazione + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID) + -- se precedente operazione non esiste, errore + if not nPrevOpeId then + EMC.ERR = 1 + return + -- se precedente operazione è disposizione + elseif EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP then + if EMC.PHASE == 1 or IsFirstMachiningAfterRotation( EMC.MCHID) then + -- posizioni home + EMC.TPOS = nil + EMC.YDELTA = nil + EMC.VDELTA = nil + EMC.HCING_IGNORE = true + elseif IsStartOrRestPhase( EMC.PHASE) then + -- carico le posizioni + local dPosT = EgtGetInfo( nPrevOpeId, 'TPOS', 'd') + local dPosY = EgtGetInfo( nPrevOpeId, 'YPOS', 'd') + -- se carrello agganciato + if dPosY then + EMC.TPOS = dPosT + EMC.YDELTA = dPosY - dPosT + EMC.VDELTA = nil + -- altrimenti è grezzo scaricato al carico e devo ricaricarlo + else + EMC.TPOS = nil + EMC.YDELTA = nil + EMC.VDELTA = nil + end + EMC.HCING_IGNORE = true + else + -- aggiornamento posizioni (da lavorazione precedente a disposizione) + local nPrev2OpeId = EgtGetPrevActiveOperation( nPrevOpeId) + if not nPrev2OpeId then + EMC.ERR = 1 + return + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrev2OpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + end + EMC.CNT = nil + -- altrimenti precedente operazione è lavorazione + else + -- aggiornamento posizioni + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + end + + -- Verifico se ultima lavorazione della fase + local nNextOpeId = EgtGetNextActiveOperation( EMC.MCHID) + local bMchLast = ( not nNextOpeId or EgtGetOperationPhase( nNextOpeId) ~= EMC.PHASE) + + -- Verifico se ultima lavorazione prima di una rotazione + local bPreRotMch = IsLastOperationBeforeRotation( EMC.MCHID) + + -- Verifico flag di separazione e fase di scarico + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + local bPreSplit = ( sNotes:find( 'Presplit') ~= nil) + local bSplitting = ( sNotes:find( 'Split') ~= nil) + local bPreCut = ( sNotes:find( 'Precut') ~= nil) + local bCutting = ( sNotes:find( 'Cut') ~= nil) + local bUnload = IsEndPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) + if bPreSplit or bPreCut then + EgtSetInfo( EMC.MCHID, 'IS_PRE', '1') + else + EgtRemoveInfo( EMC.MCHID, 'IS_PRE') + end + + -- Agisco sui diversi percorsi della lavorazione + local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EMC.MCHID, 'CL') or GDB_ID.NULL) + while nPathId do + -- assegno id percorso da elaborare + EMC.PATHID = nPathId + -- recupero id del successivo + nPathId = EgtGetNext( nPathId) + -- verifico se ultimo percorso di ultima lavorazione della fase + local bLast = ( bMchLast and ( not nPathId)) + -- se ultimo, elimino ritorno in home + if bLast then EgtRemoveOperationHome( EMC.MCHID) end + -- salvo lo stato di trave e carrelli + local OriTPos = EMC.TPOS + local OriYDelta = EMC.YDELTA + local OriVDelta = EMC.VDELTA + local OriCnt = EMC.CNT + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) + -- se separazione, verifico il risultato + if bSplitting then + -- recupero CUTID del pezzo in lavoro + local CutID = GetCUTID() + -- in caso di errore mancato pinzaggio uscita riprovo dopo aver disabilitato le lavorazioni finali + if EMC.ERR == 18 then + -- segnalazione warning + EMC.ERR = -101 + EMC.MSG = 'Warning : skipped final processes (WRN=101,CUTID='..tostring( CutID)..')' + -- ripristino lo stato originale di trave e carrelli + EMC.TPOS = OriTPos + EMC.YDELTA = OriYDelta + EMC.VDELTA = OriVDelta + EMC.CNT = OriCnt + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) + -- pinzaggio ancora impossibile, pezzo a caduta + if EMC.ERR == 18 then + -- segnalazione warning + EMC.ERR = -102 + EMC.MSG = 'Warning : skipped final processes and unload by fall (WRN=102,CUTID='..tostring( CutID)..')' + end + -- scarico standard + elseif EMC.ERR == 0 then + -- segnalazione warning + EMC.ERR = -100 + EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' + end + -- se taglio del residuo finale, scarico standard + elseif bCutting then + -- recupero CUTID del pezzo in lavoro + local CutID = GetCUTID() + -- se non ci sono errori, segnalazione warning + if EMC.ERR == 0 then + EMC.ERR = -100 + EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' + end + end + if EMC.ERR > 0 then return end + -- determino la posizione finale della trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + end + +end + +--------------------------------------------------------------------- +function SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bUnload, bPreRotMch) + + -- Assegno flag di pezzo separato dal resto del grezzo + local bSplit = IsEndPhase( EMC.PHASE) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) + + -- Assegno flag di pezzo in separazione + local bFixedDelta = ( bPreSplit or bSplitting or bPreCut or bCutting) + + -- Se separazione o taglio del grezzo finale, verifico se precedente era una preparazione + local bFixedPos = false + if bPreSplit or bSplitting or bPreCut or bCutting then + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID) + bFixedPos = EgtExistsInfo( nPrevOpeId or GDB_ID.NULL, 'IS_PRE') + end + + -- Determinazione delle dimensioni totali dei grezzi e del grezzo in lavoro + local b3Tot = BBox3d() + local b3Raw = BBox3d() + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + local nCurrRawId = GDB_ID.NULL + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + local b3Tmp = EgtGetRawPartBBox( nRawId) + b3Tot:Add( b3Tmp) + if EgtGetPartInRawPartCount( nRawId) > 0 and not EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + b3Raw = b3Tmp + nCurrRawId = nRawId + end + end + nRawId = EgtGetNextRawPart( nRawId) + end + if b3Tot:isEmpty() then + EMC.ERR = 11 + return + end + EMC.LB = EgtIf( bSplit, b3Raw:getDimX(), b3Tot:getDimX()) + 10 * GEO.EPS_SMALL + EMC.SB = b3Tot:getDimY() + EMC.HB = b3Tot:getDimZ() + EMC.LR = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + EMC.YMIN = b3Raw:getMin():getY() + EMC.ZMIN = b3Raw:getMin():getZ() + + -- Aggiorno limiti di presa e tolleranza + UpdateMinJoinDeltaTol() + + -- Recupero sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = EgtGetInfo( nCurrRawId, 'HOVM', 'd') or 0 + EMC.HCING = EgtGetInfo( nCurrRawId, 'HCING', 'd') or 0 + EMC.TCING = EgtGetInfo( nCurrRawId, 'TCING', 'd') or 0 + + -- Calcolo dell'ingombro della lavorazione + local dDistFront, dDistBack = SpecialCalcMachiningEncumbrance( EMC.MCHID, bPreCut) + if not dDistFront or not dDistBack then return end + if bPreSplit or bSplitting then + local dDistF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + local dNextHOVM = EgtGetInfo( EgtGetNextRawPart( nCurrRawId) or GDB_ID.NULL, 'HOVM', 'd') or 0 + dDistBack = dDistBack - AGG_B_SPLIT - max( dNextHOVM - 300, 0) + elseif bPreCut or bCutting then + local dDistF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + dDistBack = 0.0 + end + + -- Verifico lunghezza pezzo + if not bSplit and not VerifyPartLength() then + return + end + + -- Se inizio o appena dopo rotazione, eseguo il carico + if not EMC.TPOS then + local dPosT = LoadT + if IsFirstMachiningAfterRotation( EMC.MCHID) then dPosT = dPosT + TurnerOffs end + local vCmd = SpecCalcLoad( dPosT, dDistFront, max( dDistBack, MinJoin)) + local vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos) + if vCmd2 and #vCmd2 > 1 then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + EgtJoinTables( vCmd, vCmd2) + SpecOutputCmds( vCmd) + + -- Se altrimenti carri entrambi diponibili, eseguo calcoli per carrelli + elseif not IsEndPhase( EMC.PHASE) then + local vCmd = SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos) + -- Se non ci sono spostamenti, confermo i parametri di aggancio + if SpecTestOnlyRemarkInCmds( vCmd) then + table.insert( vCmd, { 21, EgtIf( EMC.YDELTA, EMC.YDELTA, 0), EgtIf( EMC.VDELTA, EMC.VDELTA, 0)}) + end + SpecOutputCmds( vCmd) + + -- Altrimenti, non muovo i carrelli rispetto alla trave + else + local vCmd = {} + SpecOutputCmds( vCmd) + end + EMC.HCING_IGNORE = nil + + -- Se taglio di separazione + local vCmd = {} + if bSplitting then + -- rimuovo eventuale vecchia info di Skip + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) or GDB_ID.NULL + EgtRemoveInfo( NextDispId, 'SKIP') + -- verifico se separazione con caduta + if not EMC.VDELTA then + EgtOutLog( ' Warning SPLITTING -> separazione con caduta pezzo') + if IsEndPhase( EMC.PHASE + 1) then + EgtSetInfo( NextDispId, 'SKIP', '1') + local NextOpeId = EgtGetNextOperation( NextDispId) + while NextOpeId and EgtGetOperationPhase( NextOpeId) == EMC.PHASE + 1 do + EgtSetOperationMode( NextOpeId, false) + NextOpeId = EgtGetNextOperation( NextOpeId) + end + end + EMC.ERR = 18 + -- verifico che la barra sia agganciata ad entrambi i carrelli + elseif not EMC.YDELTA or not EMC.VDELTA then + EMC.ERR = 19 + EMC.MSG = ' Error SPLIT : Y or V not clamped' + return false + end + -- eseguo la separazione ( standard o di pezzo ruotato) + if not IsMid2Phase( EMC.PHASE + 1) then + vCmd = SpecCalcSplit( b3Raw:getDimX()) + else + vCmd = SpecCalcSplitRot( b3Raw:getDimX()) + end + end + -- Se taglio finale di grezzo a perdere + if bCutting then + -- salvo distanza carrello V da inizio grezzo rimasto nella disposizione della prossima fase + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if NextDispId then + EgtSetInfo( NextDispId, 'VPOS', EMC.VDELTA) + end + end + + -- Se previsto scarico, lo eseguo + if bUnload then + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + local vCmdTmp = SpecCalcUnload() + vCmd = EgtJoinTables( vCmd, vCmdTmp) + end + + -- Se ritorno al carico per rotazione + if bPreRotMch then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + -- eseguo movimento prima di rotazione + local vCmdTmp = SpecCalcPreRot() + vCmd = EgtJoinTables( vCmd, vCmdTmp) + end + + -- Emetto eventuali comandi di separazione e/o scarico + if #vCmd > 0 then + SpecOutputCmds( vCmd, true) + end + +end --SpecApplyPath( bLast) + +--------------------------------------------------------------------- +function SpecialCalcMachiningEncumbrance( nMchId, bPreCut) + -- gruppi della lavorazione + local nClId = EgtGetFirstNameInGroup( nMchId, 'CL') + local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) + if not nPathId then + EMC.ERR = 12 + return + end + -- recupero ptMin ptMax della lavorazione + local ptMin = EgtGetInfo( nClId, 'MMIN', 'p') + local ptMax = EgtGetInfo( nClId, 'MMAX', 'p') + if not ptMin or not ptMax then + EMC.ERR = 13 + return + end + -- se pre-taglio, aggiorno ptMax con quello del taglio finale + if bPreCut then + local ptFinMax = GetFinalCutPmax( nMchId) + if ptFinMax then + ptMax = ptFinMax + end + end + -- Recupero del vettore estrusione (coincide con il vettore utensile) + local vtTool = EgtGetInfo( nPathId, 'EXTR', 'v') + if not vtTool then + EMC.ERR = 14 + return + end + -- Recupero testa + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + -- Calcolo del vettore ausiliario + local vAxes = EmtGetAxesPos( EgtGetFirstInGroup( nPathId)) + if not vAxes or #vAxes < 5 or ( sHead == 'H3' and #vAxes < 6) then + EMC.ERR = 15 + return + end + local vtAux = EgtGetCalcAuxDirFromAngles( vAxes[4], vAxes[5], vAxes[6]) + if not vtAux then + EMC.ERR = 16 + return + end + -- Recupero dei dati dell'utensile + local nToolType = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + local bSaw = ( nToolType == MCH_TY.SAW_STD or nToolType == MCH_TY.SAW_FLAT) + local bChain = ( nToolType == MCH_TY.MORTISE_STD) + local bAngTrasm = ( sHead == 'H5' or sHead == 'H6') + local dTLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + -- Se sega a catena, devo correggere il versore Aux per farlo coincidere con la direzione del braccio C + if bChain then + if abs( vAxes[6] or 0) < 1 then + vtAux = vtTool + else + vtAux = vtTool ^ vtAux + end + end + -- Se rinvio da sotto, devo correggere il versore Aux per farlo coincidere con la direzione del braccio C + if bAngTrasm then + local nExit = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + vtAux = vtTool ^ vtAux + if nExit == 2 then vtAux = -vtAux end + end + -- Calcolo limiti derivanti dalla lavorazione + local dDistFront, dDistBack = SpecCalcEncumbrance( vtTool, vtAux, ptMin, ptMax, bSaw, bChain, dTLen, dTDiam) + return dDistFront, dDistBack +end + +--------------------------------------------------------------------- +function SpecialCalcPhaseEncumbrance( nPhase) + -- Deve essere la fase finale di lavorazione di un pezzo (già staccato dal resto della trave) + local dDistFront = EMC.LB + local dDistBack = EMC.LB + -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine + local nOrigMchId = EgtGetCurrMachining() + local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + local sOrigHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local nOrigExit = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + -- Ciclo sulle lavorazioni + local nMchId = EgtGetNextActiveOperation( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL) + while nMchId and EgtGetOperationPhase( nMchId) == nPhase do + -- imposto lavorazione e utensile correnti + EgtSetCurrMachining( nMchId) + local sTool = EgtGetMachiningParam( MCH_MP.TOOL) + if not EgtTdbSetCurrTool( sTool) then + local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID) + sTool = EgtTdbGetToolFromUUID( sTuuid) + EgtTdbSetCurrTool( sTool) + end + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local nExit = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + if sTool and sHead and nExit then EgtSetCalcTool( sTool, sHead, nExit) end + -- calcolo ingombri + local dDistF, dDistB = SpecialCalcMachiningEncumbrance( nMchId) + if dDistF and dDistB then + dDistFront = min( dDistFront, dDistF) + dDistBack = min( dDistBack, dDistB) + end + nMchId = EgtGetNextActiveOperation( nMchId) + end + -- Ripristino lavorazione e utensile correnti + if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end + if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end + if sOrigTool and sOrigHead and nOrigExit then EgtSetCalcTool( sOrigTool, sOrigHead, nOrigExit) end + -- Restituisco gli ingombri trovati + return dDistFront, dDistBack +end + +--------------------------------------------------------------------- +function GetFinalCutPmax( nMchId) + local nFinalCutId + local nId = EgtGetNextActiveOperation( nMchId) + while nId and EgtGetOperationPhase( nId) == EMC.PHASE do + nFinalCutId = nId + nId = EgtGetNextActiveOperation( nId) + end + if not nFinalCutId then return end + local nCLId = EgtGetFirstNameInGroup( nFinalCutId, 'CL') + if not nCLId then return end + return EgtGetInfo( nCLId, 'MMAX', 'p') +end + +--------------------------------------------------------------------- +function SpecCalcEncumbrance( vtTool, vtArm, ptMin, ptMax, bSaw, bChain, dTLen, dTDiam) + -- Quota in Z dal punto di inclinazione dei carrelli + local dCompZ = sqrt( 1 - vtTool:getZ() * vtTool:getZ()) + local dZup = ptMin:getZ() - 0.5 * dCompZ * dTDiam - ( EMC.ZMIN + 130) + -- Ingombro a sinistra + local dDistBack = EMC.LB + ptMin:getX() + LoadT + local dHeadBack = 350 + if bSaw then + if vtTool:getX() > 0 and abs( vtTool:getY()) < 0.088 and abs( vtTool:getZ()) < 0.088 then + dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.35 then + dHeadBack = EgtIf( vtArm:getX() < 0, 540, 350) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.71 then + if vtArm:getX() < 0 then + dHeadBack = 450 + else + dHeadBack = EgtIf( vtTool:getX() > 0, 50, 90) + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + elseif ( vtTool:getX() > 0.7 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + 0.9 * EMC.HB) then + if vtTool:getZ() > 0 then + dHeadBack = max( 50, 90 - 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + else + dHeadBack = max( 50, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + end + if ptMax:getZ() < EMC.ZMIN + BD.VICE_MINH then + dHeadBack = dHeadBack + BD.VICE_MINH + end + elseif ( vtTool:getX() > 0.2 and abs( vtTool:getZ()) < 0.5) then + dHeadBack = max( 90, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + elseif abs( vtTool:getZ()) < 0.93 then + if vtTool:getX() > 0 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + BD.VICE_MINH then + dHeadBack = 180 + elseif vtTool:getX() > -0.05 then + dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif vtTool:getX() > -0.3 then + dHeadBack = 250 + elseif vtTool:getX() > -0.707 then + dHeadBack = 350 + elseif vtTool:getX() > -0.8667 then + dHeadBack = 450 + else + dHeadBack = 650 + end + else + dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + else + if ( vtTool:getX() > -0.1 and vtArm:getX() > -0.1) or + ( abs( vtTool:getX()) < 0.1 and abs( vtTool:getZ()) < 0.1) then + dHeadBack = EgtIf( EMC.CNT == 1, 180, 130) + elseif ( vtTool:getX() > -0.1 and vtArm:getX() > -0.95) then + dHeadBack = 180 + elseif ( vtTool:getX() < -0.8) then + dHeadBack = 675 + elseif ( vtTool:getX() < -0.75) then + dHeadBack = 650 + elseif ( vtTool:getX() < -0.5) then + dHeadBack = 450 + end + if vtTool:getX() < -0.25 then + dHeadBack = dHeadBack + max( dTLen - 130, 0) * abs( vtTool:getX()) + elseif vtTool:getX() < 0 then + dHeadBack = dHeadBack + ( dTLen + 180) * abs( vtTool:getX()) + end + if vtTool:getX() > 0.866 then + dHeadBack = 50 + elseif vtTool:getX() >= 0 and dZup > 0 then + dHeadBack = max( EgtIf( EMC.CNT == 1, 180, 130), dHeadBack - dZup) + end + if abs( vtTool:getX()) < 0.5 and abs( vtTool:getZ()) > 0.259 and dZup < 0 then + if vtArm:getX() < -0.259 then + dHeadBack = 510 + else + dHeadBack = 280 + end + end + -- pre fresature longitudinali con utensile di fianco + if abs( vtTool:getX()) < 0.1 and vtTool:getZ() < 0.707 and vtArm:getX() < -0.5 then + dHeadBack = 500 + end + -- per sega a catena di fianco + if bChain and vtTool:getX() < 0.5 and vtTool:getZ() < 0.5 and vtArm:getX() < -0.5 then + dHeadBack = max( dHeadBack, 510) + end + -- per interferenza con triangolo di rinforzo sulla pinza Y + if vtTool:getZ() < 0.25 and vtTool:getX() < 0.10 and vtTool:getY() > 0 and vtArm:getX() < -0.707 then + dHeadBack = dHeadBack + 90 + end + end + -- Ingombro a destra + local dDistFront = - ptMax:getX() - LoadT + local dHeadFront = 350 + if bSaw then + if vtTool:getX() < 0 and abs( vtTool:getY()) < 0.088 and abs( vtTool:getZ()) < 0.088 then + dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.35 then + dHeadFront = EgtIf( vtArm:getX() > 0, 540, 350) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.71 then + if vtArm:getX() > 0 then + dHeadFront = 450 + else + dHeadFront = EgtIf( vtTool:getX() < 0, 50, 90) + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + elseif ( vtTool:getX() < - 0.7 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + 0.9 * EMC.HB) then + if vtTool:getZ() > 0 then + dHeadFront = max( 50, 90 - 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + else + dHeadFront = max( 50, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + end + if ptMax:getZ() < EMC.ZMIN + BD.VICE_MINH then + dHeadFront = dHeadFront + BD.VICE_MINH + end + elseif ( vtTool:getX() < -0.2 and abs( vtTool:getZ()) < 0.5) then + dHeadFront = max( 90, 40 + 0.5 * dTDiam * sqrt( vtTool:getY() * vtTool:getY() + vtTool:getZ() * vtTool:getZ())) + elseif abs( vtTool:getZ()) < 0.93 then + if vtTool:getX() < 0 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + BD.VICE_MINH then + dHeadFront = 180 + elseif vtTool:getX() < 0.05 then + dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif vtTool:getX() < 0.3 then + dHeadFront = 250 + elseif vtTool:getX() < 0.707 then + dHeadFront = 350 + elseif vtTool:getX() < 0.8667 then + dHeadFront = 450 + else + dHeadFront = 650 + end + else + dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + else + if ( vtTool:getX() < -0.5 and vtArm:getX() < 0.1) then + dHeadFront = max( 50, dTDiam / 2 * abs( vtTool:getZ()) + 20) + elseif ( vtTool:getX() < 0.1 and vtArm:getX() < 0.1) or + ( abs( vtTool:getX()) < 0.1 and abs( vtTool:getZ()) < 0.1) then + dHeadFront = 130 + elseif ( vtTool:getX() < 0.1 and vtArm:getX() < 0.95) then + dHeadFront = 180 + elseif ( vtTool:getX() > 0.8) then + dHeadFront = 675 + elseif ( vtTool:getX() > 0.75) then + dHeadFront = 650 + elseif ( vtTool:getX() > 0.5) then + dHeadFront = 450 + end + if vtTool:getX() > 0.25 then + dHeadFront = dHeadFront + max( dTLen - 130, 0) * vtTool:getX() + elseif vtTool:getX() > 0 then + dHeadFront = dHeadFront + ( dTLen + 180) * vtTool:getX() + end + if vtTool:getX() < -0.866 then + dHeadFront = 50 + elseif vtTool:getX() <= 0 and dZup > 0 then + dHeadFront = max( 130, dHeadFront - dZup) + end + if abs( vtTool:getX()) < 0.5 and abs( vtTool:getZ()) > 0.259 and dZup < 0 then + if vtArm:getX() > 0.259 then + dHeadFront = 510 + else + dHeadFront = 280 + end + end + -- pre fresature longitudinali con utensile di fianco + if abs( vtTool:getX()) < 0.1 and vtTool:getZ() < 0.707 and vtArm:getX() > 0.5 then + dHeadFront = 500 + end + -- per sega a catena di fianco + if bChain and vtTool:getX() > -0.5 and vtTool:getZ() < 0.5 and vtArm:getX() > 0.5 then + dHeadFront = max( dHeadFront, 510) + end + -- per interferenza con triangolo di rinforzo sulla pinza V + if vtTool:getZ() < 0.25 and vtTool:getX() > -0.10 and vtTool:getY() > 0 and vtArm:getX() > 0.707 then + dHeadFront = dHeadFront + 90 + end + end + -- Stampe debug + EgtOutLog( ' Tdir=' .. tostring( vtTool) .. ' Adir=' .. tostring( vtArm) .. ' Zup=' .. EgtNumToString( dZup), 3) + EgtOutLog( ' DistFront=' .. EgtNumToString( dDistFront) .. ' DistBack=' .. EgtNumToString( dDistBack) .. + ' HeadFront=' .. EgtNumToString( dHeadFront) .. ' HeadBack=' .. EgtNumToString( dHeadBack), 3) + -- Restituisco ingombri effettivi + return ( dDistFront - dHeadFront), ( dDistBack - dHeadBack) +end + +--------------------------------------------------------------------- +function VerifyPartLength() + + -- Verifico lunghezza pezzo + if EMC.LB < MinJoin + MinOther + AGG_LOAD + EMC.HCING + EMC.HOVM then + EgtOutLog( ' Error CLAMP -> pezzo troppo corto') + EMC.ERR = 17 + return false + end + + return true +end + +--------------------------------------------------------------------- +function SpecCalcLoad( dPosT, dDistFront, dDistBack) + --[L] + local dMinDistBack= max( dDistBack, MinJoin + EgtIf( IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE), EMC.TCING, 0)) + local dNewYDelta = max( EMC.LB - dMinDistBack, MinOther + AGG_LOAD + EMC.HCING + EMC.HOVM) + local dNewVDelta = nil + local dNewY = dPosT + TurnerOffs + dNewYDelta + local vCmd = {} + EgtOutLog( ' *[L]', 1) + -- [L-1] + if dNewY - MaxY > 0 then + dNewYDelta = min( EMC.LB - MinJoin + AGG_LOAD, MaxY - dPosT - TurnerOffs) + EgtOutLog( ' *[L1]', 1) + end --[L-2] + if EMC.LB - dNewYDelta < MinJoin then + dNewYDelta = min( EMC.LB - MinJoin + AGG_LOAD, MaxY - dPosT - TurnerOffs) + EgtOutLog( ' *[L2]', 1) + end + -- Commento + table.insert( vCmd, { 0, 'Loading'}) + -- risalita testa a Zmax + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- Apro entrambe le morse + table.insert( vCmd, { 11, 0}) + table.insert( vCmd, { 12, 0}) + -- Sposto il carrello Y per il carico + table.insert( vCmd, { 2, 'Y', dPosT + dNewYDelta, 'V', ParkV}) + -- Chiudo morsa Y + table.insert( vCmd, { 11, EgtIf( EMC.LB - dNewYDelta < LenToPress, 1, 2)}) + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dNewYDelta, 0}) + -- Inizializzo contatore globale + EMC.CNT = 1 + SpecOutputCNT() + -- Assegno stato corrente + EMC.TPOS = dPosT + EMC.YDELTA = dNewYDelta + EMC.VDELTA = nil + -- Restituisco i comandi + return vCmd +end -- SpecAdjustLoad [L] + +--------------------------------------------------------------------- +function SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos) + + local MinFrontJoin = MinJoin + EMC.HCING + EMC.HOVM + local MinBackJoin = MinJoin + EgtIf( IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE), EMC.TCING, 0) + local MyMinOther = MinOther + EgtIf( EMC.CNT == 1, AGG_LOAD, 0) + + local dDistFrontEff = min( dDistFront, EMC.LB - MyMinOther - EMC.TCING) + if bFixedDelta and IsMid2Phase( EMC.PHASE + 1) then + dDistFrontEff = min( dDistFrontEff, EMC.LR - MinOther - EMC.TCING) + end + local dDistBackEff = min( dDistBack, EMC.LB - MyMinOther - EMC.HCING - EMC.HOVM) + + EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBackEff, 1) .. '/' .. EgtNumToString( MinBackJoin, 1) .. + ' Front=' .. EgtNumToString( dDistFrontEff, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1) .. + ' Fixed : Delta=' .. EgtIf( bFixedDelta, 'T', 'F') .. ' Pos=' .. EgtIf( bFixedPos, 'T', 'F'), 3) + + -- [A] se posso mettere solo carrello Y + if dDistFrontEff < MinFrontJoin and dDistBackEff > MinBackJoin - GEO.EPS_SMALL then + + local dPosT = EMC.TPOS + local dYDelta = EMC.YDELTA + local dVDelta = EMC.VDELTA + + local dNewPosT = nil + local dNewYDelta = EMC.LB - dDistBackEff + local dNewVDelta = nil + + return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos) + + -- [B] se altrimenti posso mettere entrambi i carrelli Y e V + elseif dDistBackEff > MinBackJoin - GEO.EPS_SMALL and + dDistFrontEff > MinFrontJoin - GEO.EPS_SMALL then + + local dPosT = EMC.TPOS + local dYDelta = EMC.YDELTA + local dVDelta = EMC.VDELTA + + local dNewPosT = nil + local dNewYDelta = EMC.LB - dDistBackEff + local dNewVDelta = dDistFrontEff + + return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos) + + -- [C] se altrimenti posso mettere solo carrello V + elseif dDistBackEff < MinBackJoin and dDistFrontEff > MinFrontJoin - GEO.EPS_SMALL then + + local dPosT = EMC.TPOS + local dYDelta = EMC.YDELTA + local dVDelta = EMC.VDELTA + + local dNewPosT = nil + local dNewYDelta = nil + local dNewVDelta = dDistFrontEff + + return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos) + + -- altrimenti errore + else + if EgtGetDebugLevel() < 3 then + EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBackEff, 1) .. '/' .. EgtNumToString( MinBackJoin, 1) .. + ' Front=' .. EgtNumToString( dDistFrontEff, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1)) + end + EgtOutLog( ' Error CLAMP impossible') + EMC.ERR = 18 + return {} + end + +end + +--------------------------------------------------------------------- +function SpecCalcSplit( dLenRaw) + local vCmd = {} + EgtOutLog( ' *[S]', 1) + table.insert( vCmd, { 0, EgtIf( EMC.VDELTA, 'Split', 'Fall')}) + -- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari) + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + table.insert( vCmd, { 31, nRawId, 'Y'}) + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- riporto il carrello Y al carico con il resto della trave + local dLDelta = EMC.YDELTA - dLenRaw + table.insert( vCmd, { 1, 'Y', LoadT + dLDelta}) + table.insert( vCmd, { 21, 0, EMC.VDELTA or 0}) + -- imposto subito Y non più attaccato al trave in lavoro + EMC.YDELTA = nil + -- salvo posizione carrello Y in disposizione del pezzo dopo split + local PostDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if PostDispId then + EgtSetInfo( PostDispId, 'YPOS', LoadT + dLDelta) + end + -- salvo posizione grezzo rimasto e posizione carrello Y nella disposizione iniziale del pezzo succ (prossima fase dispari) + local NextDispId = EgtGetPhaseDisposition( nNextOddPhase) + if NextDispId then + EgtSetInfo( NextDispId, 'TPOS', LoadT) + EgtSetInfo( NextDispId, 'YPOS', LoadT + dLDelta) + end + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcSplitRot( dLenRaw) + local vCmd = {} + EgtOutLog( ' *[SR]', 1) + table.insert( vCmd, { 0, 'SplitRot'}) + -- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari) + local vRaw = {} + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + table.insert( vRaw, nRawId) + end + nRawId = EgtGetNextRawPart( nRawId) + end + for _, nId in ipairs( vRaw) do + table.insert( vCmd, { 31, nId, 'Y'}) + end + -- riporto il carrello Y al carico con il resto della trave + local dLDelta = EMC.YDELTA - dLenRaw + table.insert( vCmd, { 1, 'Y', LoadT + TurnerOffs + dLDelta}) + table.insert( vCmd, { 21, 0, EMC.VDELTA}) + -- imposto subito Y non più attaccato alla trave in lavoro + EMC.YDELTA = nil + -- apro il carrello Y + table.insert( vCmd, { 11, 0}) + -- sgancio i grezzi dal carrello Y + for _, nId in ipairs( vRaw) do + table.insert( vCmd, { 31, nId, ''}) + end + -- lo porto in parcheggio + table.insert( vCmd, { 1, 'Y', ParkY}) + -- salvo posizione grezzo rimasto nella disposizione iniziale del pezzo succ (prossima fase dispari) + local NextDispId = EgtGetPhaseDisposition( nNextOddPhase) + if NextDispId then + EgtSetInfo( NextDispId, 'TPOS', LoadT) + end + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcUnload() + local vCmdPre = {} + EgtOutLog( ' *[U]', 1) + -- Se pinza Y chiusa , devo effettuare uno scambio + if EMC.YDELTA then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + -- imposto quote aggancio per avere solo pinza V + local dDistFront = EMC.LB - MinOther - EMC.TCING - 10 * GEO.EPS_SMALL + local dDistBack = 0 + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack) + if EMC.ERR ~= 0 then + return {} + end + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' *[U1]', 1) + end + local vCmd = {} + -- Tipo di scarico + local bStdUl = ( MaxUnloadLen < 1 or EMC.LB - EMC.HOVM < MaxUnloadLen + 1) + -- Commento + table.insert( vCmd, { 0, 'Unloading', EgtIf( bStdUl, 'Unloading', 'Manual Unloading')}) + -- risalita testa a Zmax + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- Se pinza Y chiusa, la apro + if EMC.YDELTA then + table.insert( vCmd, { 11, 0}) + end + -- Se non supero la lunghezza massima di scarico, sposto il pezzo in posizione di scarico + if bStdUl then + local dFinT = UnloadT - EMC.LB + local dFinV = dFinT + EMC.VDELTA + table.insert( vCmd, { 2, 'T', dFinT, 'V', dFinV}) + else + table.insert( vCmd, { 1, 'V', MaxV}) + end + -- apro la morsa + table.insert( vCmd, { 12, 0}) + -- riporto il carrello in home + table.insert( vCmd, { 1, 'V', ParkV}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcPreRot() + local vCmdPre = {} + EgtOutLog( ' *[PR]', 1) + -- Se pinza V chiusa , devo effettuare uno scambio + if EMC.VDELTA then + -- imposto quote aggancio per avere solo pinza Y + local dDistFront = 0 + local dDistBack = EMC.LB - MinOther - EMC.HOVM + 10 * GEO.EPS_SMALL + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack) + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' *[PR1]', 1) + end + -- porto il pezzo alla zona di rotazione con il carro Y + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Pre-Rotation'}) + -- risalita testa a Zmax + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- Se pinza V chiusa, la apro + if EMC.VDELTA then + table.insert( vCmd, { 12, 0}) + end + -- riporto la trave al carico + local RotT = LoadT + TurnerOffs + table.insert( vCmd, { 2, 'Y', RotT + EMC.YDELTA, 'T', RotT}) + -- apro la morsa + table.insert( vCmd, { 11, 0}) + -- riporto il carrello in home + table.insert( vCmd, { 1, 'Y', ParkY}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecAdjustCarriages( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos) + + -- [A] richiesto solo carrello Y + if dYDeltaF and ( not dVDeltaF) then + -- [A1] rimango sul carrello Y + if dYDeltaI and ( not dVDeltaI) then + return SpecAdjustCarrA1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + -- [A2] torno da entrambi + elseif dYDeltaI and dVDeltaI then + return SpecAdjustCarrA2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + -- [A3] torno da carrello V + elseif dVDeltaI and (not dYDeltaI) then + return SpecAdjustCarrA3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + else + EgtOutLog( ' Error CLAMP NULL-> Y impossibile') + error( 'Error CLAMP NULL-> Y impossibile') + end + + -- (B) richiesti entrambi i carrelli + elseif dYDeltaF and dVDeltaF then + -- [B1] passo da carrello Y a entrambi + if dYDeltaI and ( not dVDeltaI) then + return SpecAdjustCarrB1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [B2] continuo con entrambi i carrelli + elseif dYDeltaI and dVDeltaI then + return SpecAdjustCarrB2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [B3] passo da carrello V a entrambi + elseif dVDeltaI and (not dYDeltaI) then + return SpecAdjustCarrB3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + else + EgtOutLog( ' Error CLAMP NULL-> Y+V impossibile') + error( 'Error CLAMP NULL-> Y+V impossibile') + end + + -- [C] richiesto solo carrello V + elseif ( not dYDeltaF) and dVDeltaF then + -- [C1] provengo da solo carrello Y + if dYDeltaI and ( not dVDeltaI) then + return SpecAdjustCarrC1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [C2] provengo da carrelli Y e V + elseif dYDeltaI and dVDeltaI then + return SpecAdjustCarrC2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [C3] rimango sul carrello V + elseif ( not dYDeltaI) and dVDeltaI then + return SpecAdjustCarrC3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos) + else + EgtOutLog( ' Error CLAMP NULL-> V impossibile') + error( 'Error CLAMP NULL-> V impossibile') + end + + end + +end + +--------------------------------------------------------------------- +local function CalcCharStatus( sType, dDelta) + -- se per carrello Y + if sType == 'Y' then + return EgtIf( EMC.LB - dDelta < LenToPress, 1, 2) + -- altrimenti per carrello V + else + return EgtIf( dDelta < LenToPress, 1, 2) + end +end + +--------------------------------------------------------------------- +local function GetDeltaTol( dLenPresa, TCING, HCING, HOVM, Carr, bFixedDelta) + local dDeltaTolEff = DELTA_SIC + if Carr == 'Y' then + local dLenPreEff = dLenPresa - TCING + if dLenPreEff < MinJoin + DeltaTol then + dDeltaTolEff = max( DELTA_SIC, dLenPreEff - MinJoin + 10 * GEO.EPS_SMALL) + else + if BD.GO_FAST and BD.GO_FAST ~= 0 then + if bFixedDelta == false then + dDeltaTolEff = min( EMC.LB + 700, dLenPreEff, 3200) + else + dDeltaTolEff = 900 + end + else + dDeltaTolEff = DeltaTol + end + end + elseif Carr == 'V' then + local dLenPreEff = dLenPresa - HCING - HOVM + if dLenPreEff < MinJoin + DeltaTol then + dDeltaTolEff = max( DELTA_SIC, dLenPreEff - MinJoin + 10 * GEO.EPS_SMALL) + else + dDeltaTolEff = DeltaTol + end + end + return EgtIf( bFixedDelta, min( dDeltaTolEff, DELTA_TOL_FIXED), dDeltaTolEff) +end + +--------------------------------------------------------------------- +local function GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistN, sSide) + local dRecTotn = min( dDistN, dCorsaYfc+ dCorsaVfc) -- recupero possibile al netto di dCorsa..TrA) + local dCorsaYd, dCorsaYTd, dCorsaVd, dCorsaVTd + if sSide == 'Fr' then + if dRecTotn / 2 <= dCorsaYfc then + if dRecTotn / 2 <= dCorsaVfc then + dCorsaYTd = dRecTotn / 2 + dCorsaVd = dRecTotn / 2 + else + dCorsaVd = dCorsaVfc + dCorsaYTd = min( dCorsaYfc, dRecTotn - dCorsaVd) + end + else + dCorsaYTd = dCorsaYfc + dCorsaVd = min( dCorsaVfc, dRecTotn - dCorsaYTd) + end + dCorsaY = dCorsaYTd + dCorsaV = dCorsaVd + else + if dRecTotn / 2 <= dCorsaVfc then + if dRecTotn / 2 <= dCorsaYfc then + dCorsaVTd = dRecTotn / 2 + dCorsaYd = dRecTotn / 2 + else + dCorsaYd = dCorsaYfc + dCorsaVTd = min( dCorsaVfc, dRecTotn - dCorsaYd) + end + else + dCorsaVTd = dCorsaVfc + dCorsaYd = min( dCorsaYfc, dRecTotn - dCorsaVTd) + end + dCorsaY = dCorsaYd + dCorsaV = dCorsaVTd + end + return dCorsaY, dCorsaV +end + +--------------------------------------------------------------------- +local function PosxExtraYV( dYPosA, dVPosA, dTPosA, dMinY, dMaxV, sYV) + -- svolge la predisposizione iniziale di trave e carrelli in caso di situazione iniziale con un solo carrello chiuso + -- con un solo carrello chiuso per l'aggancio del carrello aperto + local dYPos, dVPos, dTPos + -- per aggancio del carrello V + if sYV == 'V' then + dTPos = min( dTPosA, dVPosA - MinJoin - EgtIf( EMC.HCING_IGNORE, 0, EMC.HCING) - EMC.HOVM) + dYPos = dYPosA + ( dTPos - dTPosA) + if dYPos < dMinY then + dVPos = dVPosA + ( dMinY - dYPos) + if dVPos > dMaxV + GEO.EPS_SMALL then + EmitComment( vCmd, ' Error CLAMP V') + error( 'Error CLAMP V') + return + elseif dVPos > dMaxV - GEO.EPS_SMALL then + dVPos = dMaxV + end + dYPos = dMinY + dTPos = dTPosA + ( dYPos - dYPosA) + else + --dYPos = dMinY + --dYPos = dYPos! + --dTPos = dTPosA + ( dYPos - dYPosA) + --dTPos = dTPos! + dVPos = dVPosA + end + end + -- per aggancio del carrello Y + if sYV == 'Y' then + dTPos = max( dTPosA, dYPosA + MinJoin + EMC.TCING - EMC.LB) + dVPos = dVPosA + ( dTPos - dTPosA) + if dVPos > dMaxV then + dYPos = dYPosA - ( dVPos - dMaxV) + if dYPos < dMinY - GEO.EPS_SMALL then + EmitComment( vCmd, ' Error CLAMP Y') + error( 'Error CLAMP Y') + return + elseif dYPos < dMinY + GEO.EPS_SMALL then + dYPos = dMinY + end + dVPos = dMaxV + dTPos = dTPosA + ( dVPos - dVPosA) + else + -- ++++++++++++++++++++++++++++++++ + --dVPos = dMaxV + --dVPos = dVPos! + --dTPos = dTPosA + ( dVPos - dVPosA) + --dTpos = dTPos!! + dYPos = dYPosA + end + end + return dYPos, dVPos, dTPos +end + +--------------------------------------------------------------------- +local function PosXs2Enl (dYa, dVa, dTa, dExtraC, dCorsaTra, dCorsaYd, dCorsaVd, sYV) + -- svolge la fase di allontanamento dei carrelli per il recupero di 'ExtraV'/'ExtraY' + -- richiesto alle posizioni [--.xs2] delle funzioni SpecAdjustCarr.. + if sYV == 'V' then -- caso di ExtraV (ed eventuale ulteriore allontanamento di Y) + local dCorsaYTrA = dCorsaTra + local dExtraVn = dExtraC - dCorsaYTrA + -- eseguo allontanamento di Y e (V+T) + if dExtraVn / 2 <= dCorsaYd then + if dExtraVn / 2 <= dCorsaVd then + dYa = dYa + dExtraVn / 2 + dVa = dVa - dExtraVn / 2 + dTa = dTa - dExtraVn / 2 + else + dVa = dVa - dCorsaVd + dTa = dTa - dCorsaVd + dYa = dYa + min( dExtraVn - dCorsaVd, dCorsaYd) + end + else + dYa = dYa + dCorsaYd + dVa = dVa - min( dExtraVn - dCorsaYd, dCorsaVd) + dTa = dTa - min( dExtraVn - dCorsaYd, dCorsaVd) + end + end + + if sYV == 'Y' then -- caso di ExtraY (ed eventuale ulteriore allontanamento di V) + local dCorsaVTrA = dCorsaTra + local dExtraYn = -dExtraC - dCorsaVTrA + -- eseguo allontanamento di (Y+T) e V + if dExtraYn / 2 <= dCorsaVd then + if dExtraYn / 2 <= dCorsaYd then + dVa = dVa - dExtraYn / 2 + dYa = dYa + dExtraYn / 2 + dTa = dTa + dExtraYn / 2 + else + dYa = dYa + dCorsaYd + dTa = dTa + dCorsaYd + dVa = dVa - min( dExtraYn - dCorsaYd, dCorsaVd) + end + else + dVa = dVa - dCorsaVd + dYa = dYa + min( dExtraYn - dCorsaVd, dCorsaYd) + dTa = dTa + min( dExtraYn - dCorsaVd, dCorsaYd) + end + end + return dYa, dVa, dTa +end + +--------------------------------------------------------------------- +-- *** [A1] da carrello Y a Y : Y -> Y *** +--------------------------------------------------------------------- +function +SpecAdjustCarrA1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + EgtOutLog( ' *[A1] = Y -> Y', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y -> Y'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + -- recupero le posizioni correnti dei carrelli + local dYPosA = dTPosI + dYDeltaI + local dVPosA = ParkV + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVPosA - dTPosA + local dNewYDelta -- = dYDeltaF + local dCorsaYfc = MaxY - dYPosA + local dCorsaYd = min( dCorsaYfc, EMC.LB - dYDeltaI - MinJoin) + + -- tolleranza + local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y') + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol/2 + else + dNewYDelta = dYDeltaA + end + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta), 1) + -- flag per risalita resta a Zmax + local bZmaxOk = false + + -- **[A1Ys]** |pos. di Y cambia in modo significativo| + if bYDeltaS then + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- definisco 'ExtraY' con (Y+T) e V accentrati q.b. per la presa con V + local dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'V') + local dNewY = dTPos + dNewYDelta + local dExtraY = dNewY - MyMinY + -- effettuo spostamenti di (Y+T) e V per predisporre all'aggancio di T con V + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dVDeltaA = dVPosA - dTPosA + + -- **[A1Ys-x]** posizione di |Y non raggiungibile| (oltre MyMinY) + if dExtraY < 0 then + -- **[A1Ys-xs]** posizione di Y non raggiungibile, |con ExtraY 'significativo'| + if -dExtraY > dYDeltaTol /2 then + --EmitComment( vCmd, '[A1Ys-xs]') + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V + local dCorsaYfc = MaxY - dYPos + local dCorsaVfc = dVPos - MinV + local dDistFrN = (dVPos-dTPos) - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + local dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + local dCorsaVTr = dCorsaVd + (MaxV - dVPos) + local dCorsaYr = dCorsaYTd + -- **[A1Ys-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraY > CorsaVr + CorsaYr| + if -dExtraY > ( dCorsaVTr + dCorsaYr) and bYDeltaS then + EmitComment( vCmd, '[A1Ys-xsw]' .. 'CASO NON GESTITO') + return + end + + local dCorsaVTrA = MaxV - dVPos -- !! att.ne: non dVPosA !! + -- **[A1Ys-xs1]** se posso recuperare ExtraY semplicem' accentrando Y e (V+T) + -- (dalle posizione impostate sopra per l'aggancio di V) + if dCorsaVTrA >= -dExtraY then + EmitComment( vCmd, '[A1Ys-xs1]') + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** Y e (V+T) + dYPosA = MyMinY -- (pos. finale) + dVPosA = dVPosA + (-dExtraY) + dTPosA = dTPosA + (-dExtraY) + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dYDeltaA = dYPosA - dTPosA + + else -- **[A1Ys-xs2]** + -- ci sarebbe un doppio movimento di Y ? => caso impossibile ? + EmitComment( vCmd, '[A1Ys-xs2]') + -- **1:** posiziono (ulteriormente!) (Y+T) e V + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dVDeltaA = dVPosA - dTPosA + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2: accentro** Y e (V+T) + dYPosA = MyMinY -- (pos. finale) + dVPosA = MaxV + dTPosA = dVPosA - dVDeltaA + --dVDeltaA = dVPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [A1Ys-xs1/-xs2] + + -- **[A1Ys-xn]** |dExtraY ancora < 0 ma non 'significativo')| + else --if -dExtraY < DeltaToll/2 + EmitComment( vCmd, '[A1Ys-xn]') + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** accentro Y + dExtraY = 0 + dYPosA = MyMinY -- (pos. finale) + table.insert( vCmd, { 1, 'Y', dYPosA}) + -- dYDeltaA = dYPosA - dTPosA + end --[A1Ys-xs/xn] + + -- **[A1Ys-r]** |posizione di Y raggiungibile| (ExtraY >=0) + -- (si esclude la possibilità di extra corsa oltre maxY) + else + EmitComment( vCmd, '[A1Ys-r]') + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** posiziono Y alla posizione richiesta + dYPosA = dNewY + table.insert( vCmd, { 1, 'Y', dYPosA}) + end -- [A1Ys] + + -- calcolo il nuovo parametro di aggancio + dYDeltaA = dYPosA - dTPosA + -- chiudo Y e apro V + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V in parcheggio + table.insert( vCmd, { 1, 'V', ParkV}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, dYDeltaA, 0}) + + -- reset contatore + EMC.CNT = nil + + else -- **[A1Yns]** |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'| + EmitComment( vCmd, '[A1Yns]') + end --[A1Ys/ns] + + EgtOutLog(' YDeltaA =' .. EgtNumToString( dYDeltaA), 1) + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrA1 + +--------------------------------------------------------------------- +-- *** [A2] da entrambi a carrello Y : Y+V -> Y *** +--------------------------------------------------------------------- +function SpecAdjustCarrA2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + EgtOutLog( ' *[A2] = Y+V -> Y ', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y+V -> Y'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + local dCorsaY = MaxY - MyMinY + local dCorsaV = MaxV - MinV + -- recupero le posizioni correnti dei carrelli + local dYPosA = dTPosI + dYDeltaI + local dVPosA = dTPosI + dVDeltaI + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVDeltaI + local dNewYDelta -- = dYDeltaF + -- tolleranze + local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y') + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol/2 + else + dNewYDelta = dYDeltaA + end + -- definisco 'ExtraY' + local dNewY = dTPosA + dNewYDelta + local dExtraY = dNewY - MyMinY -- < 0 = nuova pos. di Y 'non raggiungibile' (= oltre MyMinY) + -- definisco 'ExtraY significativo' + local bYxs = -dExtraY > dYDeltaTol/2 + + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI) .. + ' VDeltaI=' .. EgtNumToString( dVDeltaI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta), 1) + -- flag per risalita resta a Zmax + local bZmaxOk = false + -- risalita testa a Zmax (da effettuare comunque, per il parcheggio di V) + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bYDeltaS then + if bYxs then + -- calcolo le **corse disponibili** dei carrelli **a partire dalle posizioni attuali** (=iniziali) + -- per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxV - dVPosA) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaYr + dCorsaVTr + end + end + + -- **[A2Ys-xsw]** posizione NewY non raggiungibile (oltre MyMinY), con ||dEXtraY | > CorsaYr + CorsaVTr| + while bXsw do + EmitComment( vCmd, '[A2Ys-xsw]') + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- chiudo eventualmente il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** allontano q.p. (Y+T) e V + dYPosA = dYPosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dVPosA = dVPosA - dCorsaVd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:** accentro Y e (V+T) + dYPosA = MyMinY + dVPosA = dVPosA + dCorsaVTr + dTPosA = dTPosA + dCorsaVTr + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + -- valuto Delta attuali + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- aggiorno l'extra corsa residua per Y + dExtraY = dExtraY + dCorsaYr + dCorsaVTr + bYxs = -dExtraY > dYDeltaTol/2 + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end -- [A2Ys-xw] + + -- **[A2Ys]** se lo |spostamento| richiesto (ev' residuo) per |Y| è |'significativo'| + if bYDeltaS then + -- **[A2Ys-x]** se la |posizione per Y non è 'raggiungibile'| + if dExtraY < 0 then + -- **[A2Ys-xs]** se |ExtraY 'significativo'| + if bYxs then + local dCorsaVTrA = MaxV - dVPosA + -- **[A2Ys-xs1]** se posso recuperare ExtraY solo accentrando (V+T) e Y + if dCorsaVTrA >= -dExtraY then + EmitComment( vCmd, '[A2Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** accentro (V+T) q.b. e Y + dVPosA = dVPosA + (-dExtraY) + dTPosA = dTPosA + (-dExtraY) + dYPosA = MyMinY -- (pos. finale) + --dYDeltaA = dYPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + else -- **[A2Ys-xs2]** + EmitComment( vCmd, '[A2Ys-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** allontano (Y+T) e V + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dVDeltaA = dVPosA - dTPosA + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:** accentro Y e (V+T) q.b. per recupero di dExtraY + dYPosA = MyMinY + dVPosA = MaxV + dTPosA = dVPosA - dVDeltaA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end --[A2Ys-xs1/-xs2] + + -- [A2Ys-xn] |ExtraY ancora <= 0, ma 'non significativo'| + else --if dExtraY <= 0 then + EmitComment( vCmd, '[A2Ys-xn]') + dExtraY = 0 + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- 1: accentro Y + dYPosA = MyMinY -- (pos. finale) + table.insert( vCmd, { 1, 'Y', dYPosA}) + end -- [A2Ys-xs/xn] + + --[A2Ys-r] dExtrav > 0 ( |pos. Y'raggiungibile|) + else + EmitComment( vCmd, '[A2Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- posizione Y + dYPosA = dTPosA + dNewYDelta -- (pos. finale) + table.insert( vCmd, { 1, 'Y', dYPosA}) + end -- [A2Ys-x/r] + + else -- [A2Yns] |spostamento Y| (ev' residuo) |non significativo| + EmitComment( vCmd, '[A2Yns]') + end -- [A2Ys/ns] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dYPosA - dTPosA + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V in parcheggio + table.insert( vCmd, { 1, 'V', ParkV}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, 0}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrA2 + +--------------------------------------------------------------------- +-- *** [A3] da carrello V a Y : V -> Y *** +--------------------------------------------------------------------- +function SpecAdjustCarrA3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + EgtOutLog( ' *[A3] = V -> Y', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'V -> Y'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + -- recupero le posizioni correnti + local dYPosA = ParkY + local dTPosA = dTPosI + local dVPosA = dTPosI + dVDeltaI + local dYDeltaA = dYPosA - dTPosA + local dVDeltaA = dVDeltaI + local dNewYDelta -- = dVDeltaF + -- tolleranza + local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y') + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol/2 + else + dNewYDelta = dYDeltaA + end + -- + EgtOutLog(' VDeltaI=' .. EgtNumToString( dVDeltaA) .. ' YDeltaI(Park)='.. EgtNumToString( dYDeltaA).. + ' TPosI=' .. EgtNumToString( dTPosI) , 1) + EgtOutLog(' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta) , 1) + local bZmaxOk = false + -- risalita testa a Zmax (da effettuare comunque, dato lo scambio di carrelli) + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dYPos, dVPos, dTPos + local dNewY, dExtraY, bYxs + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bYDeltaS then + -- definisco 'ExtraY' con Y e (V+T) accentrati q.b. per la presa con Y + dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'Y') + dNewY = dTPos + dNewYDelta + dExtraY = dNewY - MyMinY --( <0 <=> pos. 'non raggiungibile') + bYxs = -dExtraY > dYDeltaTol/2 + if bYxs then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPos + dCorsaVfc = dVPos - MinV + --local dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dDistFrN = (dVPos-dTPos) - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxV - dVPos) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end + -- inizializzo + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + end + + -- **[A3Ys-xsw]** posizione finale dNewY non raggiungibile, con |dEXtraY > CorsaVr + CorsaYr| + while bXsw do + EmitComment( vCmd, '[A3Ys-xsw]') + -- |1:| posiziono (V+T) e Y come calcolato sopra + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo ev' il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |2:| allontano (Y+T) e V quanto possibile + dYPosA = dYPosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dVPosA = dVPosA - dCorsaVd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |3:| accentro (V+T) e Y + dVPosA = dVPosA + dCorsaVTr + dTPosA = dTPosA + dCorsaVTr + dYPosA = MyMinY + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- aggiorno ExtraY + dExtraY = dExtraY + dCorsaYr + dCorsaVTr + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end --[A3Ys-xw] + + -- **[A3Ys]** |spostamento| richiesto (ev' residuo) |di Y| |'significativo'| + if bYDeltaS then + EmitComment( vCmd, '[A3Ys]') + -- **[A3Ys-x]** posizione di |Y non raggiungibile| + if dExtraY < 0 then + + -- **[A3Ys-xs]** |pos. NewY non raggiungibile, con ExtraY 'significativo'| + -- ( -dExtraY <= (CorsaYr+CorsaVr) da ciclo precedente ) + if bYxs then + local dCorsaVTrA = MaxV - dVPosA + -- **[A3Ys-xs1]** se posso recuperare ExtraY semplicem' accentrando Y e (V+T) + -- ulteriormente rispetto a YPos e Vpos definiti c.s. + if dCorsaVTrA >= -dExtraY then + EmitComment( vCmd, '[A3Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** Y e (V+T) + dYPosA = MyMinY -- (pos. finale) + dVPosA = dVPosA + dExtraY + dTPosA = dTPosA + dExtraY + dYDeltaA = dYPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[A3Ys-xs2]** + EmitComment( vCmd, '[A3Ys-xs2]') + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** ev' Y e (V+T) alle posizioni impostate + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dYDeltaA = dYPosA - dTPosA + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: allontano** (Y+T) e V + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dVDeltaA = dVPosA - dTPosA + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **3: accentro** Y e (V+T) + dYPosA = MyMinY -- (pos. finale) + dVPosA = MaxV + dTPosA = dVPosA - dVDeltaA + --dYDeltaA = dYPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [A3Ys-xs1/-xs2] + + -- **[A3Ys-xn]** |dExtraY ancora < 0 ma non 'significativo')| + else --if -dExtraY < DeltaToll/2 + EmitComment( vCmd, '[A3Ys-xn]') + -- ev' chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** accentro Y e porto (V+T) alla posizione impostata + dExtraY = 0 + dYPosA = MyMinY -- (pos. finale) + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end --[A3Ys-xs/xn] + + -- **[A3Ys-r]** |posizione di Y raggiungibile (ExtraY >=0)| + else + EmitComment( vCmd, '[A3Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- posizione Y in posizione finale ed ev' (V+T) come impostato sopra + dYPosA = dTPosA + dNewYDelta + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [A3Ys] + + else -- **[A3Yns]** |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'| + EmitComment( vCmd, '[A3Yns]') + end --[A3Ys/ns] + + -- calcolo il nuovo parametro di aggancio + dYDeltaA = dYPosA - dTPosA + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V in parcheggio + table.insert( vCmd, { 1, 'V', ParkV}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, dYDeltaA, 0}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrA3 + +--------------------------------------------------------------------- +local function AdjustPositionsForB( dNewYDelta, dNewVDelta, TCING, HCING, HOVM, bFixedDelta) + local REF_DIST = 1400 + local dYDelta = 0 + local dVDelta = 0 + -- incremento se possibile la distanza tra le due posizioni + if not bFixedDelta and ( dNewYDelta - dNewVDelta) < REF_DIST then + local dEffAddDist = ( REF_DIST - ( dNewYDelta - dNewVDelta)) / 2 + dYDelta = max( min( dEffAddDist, EMC.LB - dNewYDelta - MinJoin - TCING), 0) + dVDelta = max( min( dEffAddDist, dNewVDelta - MinJoin - HOVM - HCING), 0) + end + return dYDelta, dVDelta +end + +--------------------------------------------------------------------- +-- *** [B1] da carrello Y a entrambi : Y -> Y+V *** +--------------------------------------------------------------------- +function SpecAdjustCarrB1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[B1] = Y -> Y+V', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y -> Y+V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + local dCorsaY = MaxY - MyMinY + local dCorsaV = MaxV - MinV + -- recupero le posizioni correnti + local dYPosA = dTPosI + dYDeltaI + local dVPosA = ParkV + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVPosA - dTPosA + local dNewYDelta + local dNewVDelta + -- incremento la distanza tra le due posizioni ( se abilitato e possibile) + local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta) + -- tolleranze + local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y', bFixedDelta) + local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + -- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 2 + else + dNewYDelta = dYDeltaA + end + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + + EgtOutLog(' YDeltaI=' .. EgtNumToString( dYDeltaA) .. ' VDeltaI(Park)='.. EgtNumToString( dVDeltaA) .. + ' TPosI='.. EgtNumToString( dTPosI), 1) + EgtOutLog(' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1) + EgtOutLog(' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + + -- risalita testa a Zmax + local bZmaxOk = false + + -- calcoli preliminari in caso di spostamento richiesto per V significativo + local dYPos, dVpos, dTPos + local dNewV, dExtraV, bVxs + local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw + if bVDeltaS then + -- definisco 'ExtraV' con (Y+T) e V accentrati q.b. per la presa di V + dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'V') + dNewV = dTPos + dNewVDelta + dExtraV = dNewV - MaxV -- se > 0 pos. V non direttamente 'raggiungibile' + bVxs = dExtraV > dVDeltaTol/2 -- ExtraV 'significativo' + if bVxs then + -- calcolo le **corse disponibili** dei carrelli a partire da Y e V c.s.| + -- per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxY - dYPos + dCorsaVfc = dVPos - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto le **corse di 'recupero'** dai due carrelli possibili riaccentrando (Y+T) e V + dCorsaYTr = dCorsaYd + (dYPos - MyMinY) + dCorsaVr = dCorsaVTd + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaVr + dCorsaYTr + end + -- inizializzo + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + end + + -- **[B1Vs-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraV > CorsaVr + CorsaYr| + while bXsw do + EmitComment( vCmd, '[B1Vs-xsw]') + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- |1:| imposto (Y+T) e V come calcolato sopra + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |2:| allontano Y e (V+T) quanto possibile + dYPosA = dYPosA + dCorsaYd + dVPosA = dVPosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |3:| accentro (Y+T) e V + dYPosA = dYPosA - dCorsaYTr + dTPosA = dTPosA - dCorsaYTr + dVPosA = MaxV + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno l'extra corsa residuo per V + dExtraV = dExtraV - dCorsaYTr - dCorsaVr + + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- aggiorno i prossimi recuperi disponibili + dCorsaYTr = dCorsaYd + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaVr + dCorsaYTr + end --[B1Vs-xw] + + -- **[B1Vs]** se lo |spostamento| finale richiesto (ev' residuo) di |V| è |'significativo'| + if bVDeltaS then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- **[B1Vs-x]** posizione di |V non raggiungibile| + if dExtraV > 0 then + -- **[B1Vs-xs]** |ExtraV 'signfificativo'| + -- (ExtraV <= (CorsaYr+CorsaVr) da ciclo precedente ) + if bVxs then + local dCorsaYTrA = dYPosA - MyMinY + local dCorsaVra = MaxV - dVPosA + -- **[B1Vs-xs1]** se posso recuperare ExtraV semplicem' accentrando V e (Y+T) + -- ulteriormente rispetto a YPos e Vpos definiti c.s. + if dCorsaYTrA >= dExtraV then + EmitComment( vCmd, '[B1Vs-xs1]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** (Y+T) e V + dYPosA = dYPosA - dExtraV + dTPosA = dTPosA - dExtraV + dVPosA = MaxV -- (pos. finale) + dVDeltaA = dVPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[B1Vs-xs2]** + EmitComment( vCmd, '[B1Vs-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** ev' (Y+T) e V alle posizioni impostate + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dVDeltaA = dVPosA - dTPosA + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2: allontano** (V+T) e Y + -- tenendo conto di dover 'recuperare' ExtraV.... + local dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') + local dYDispl1 = dYPos1 - dYPosA + local dVDispl1 = dVPos1 - dVPosA + --local dTDispl1 = dTPos1 - dTPosA + local dYDeltaDiff = dNewYDelta - (dYPos1 - dTPos1) + -- ...e anche di posizionare possibilmente Y alla posizione finale + if dYDeltaDiff > 0 then + dCorsaYfc = MaxY - dYPos1 + dCorsaVfc = dVPos1 - MinV + dDistBkN = EMC.LB - (dYPos1-dTPos1) - MinJoin - EMC.TCING -- DistBack1 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dYDeltaDiff, 0, dCorsaYd, dCorsaVTd, 'V') + else + dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 + end + + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **3: accentro** (Y+T) e V + dYPosA = dYPosA - dYDispl1 - dCorsaYTrA -- POS. FINALE + dTPosA = dTPosA - dYDispl1 - dCorsaYTrA + dVPosA = dVPosA - dVDispl1 + dCorsaVra -- POS. FINALE + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B1Vs-xs1/-xs2] + + -- **[B1Vs-xn]** |dExtraV ancora > 0 ma non 'significativo')| + else --if dExtraV < DeltaToll/2 + EmitComment( vCmd, '[B1Vs-xn]') + -- ev' chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: accentro (Y+T) alla posizione impostate e V al max + dExtraV = 0 + dVPosA = MaxV -- (pos. finale) + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B1s-xs/xn] + + -- **[B1Vs-r]** |dExtraV < 0 (pos. V raggiungibile)| + else + EmitComment( vCmd, '[B1Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- posiziono ev' (Y+T) come impostato sopra e V in posizione finale + dVPosA = dTPosA + dNewVDelta + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B1Vs] + + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + + else -- **[B1Vns]** |spostamento| finale richiesto (ev' residuo) di |V non 'significativo'| + EmitComment( vCmd, '[B1Vns]') + if SpecTestOnlyRemarkInCmds( vCmd) then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- emetto posizione di V + table.insert( vCmd, { 1, 'V', dVPosA}) + end + end -- [B1-s/ns] + + -- aggiorno la verifica di movimento 'significativo' per Y + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- **[B1Ys]** Se vi è uno |spostamento residuo di Y significativo'| + if bYDeltaS then + EmitComment( vCmd, '[B1Ys]') + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewY = dTPosA + dNewYDelta + local dExtraY = dNewY - MyMinY + -- **[B1Ys-r]** se pos. NewY è raggiungibile direttamente + if dExtraY >= 0 then --dNewY > MyMinY then + EmitComment( vCmd, '[B1Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y + dYPosA = dTPosA + dNewYDelta + table.insert( vCmd, { 1, 'Y', dYPosA}) + + -- **[B1Ys-xn]** se pos. NewY non è raggiungibile direttamente, ma ExtraY non è 'significativo' + elseif -dExtraY <= dYDeltaTol / 2 then + EmitComment( vCmd, '[B1Ys-xn]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- accentro Y + dYPosA = MyMinY + table.insert( vCmd, { 1, 'Y', dYPosA}) + -- [B1sY-nr.xs] ma ExtraY 'significativo' + + else -- **[B1Ys-xs]** + EmitComment( vCmd, '[B1Ys-xs]') + EgtOutLog( ' CLAMP : caso [B1Ys-xs] non gestito') + error( ' CLAMP : caso [B1Ys-xs] non gestito') + + end --[B1Ys-r/-nr] + else -- [B1Yns] spostamento residuo di Y non significativo + EmitComment( vCmd, '[B1Yns]') + end -- [B1Ys/ns] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- se non emessi movimenti, imposto posizione V + if not bZmaxOk then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + table.insert( vCmd, { 1, 'V', dVPosA}) + end + -- imposto stato carrelli, per eventuale uso pressori (sempre eseguita risalita Z) + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, dVDeltaA}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end -- SpecAdjustCarrB1 + +--------------------------------------------------------------------- +-- *** [B2] da entrambi a entrambi i carrelli : Y+V -> Y+V *** +--------------------------------------------------------------------- +function SpecAdjustCarrB2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[B2] = Y+V -> Y+V', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y+V -> Y+V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + -- recupero le posizioni correnti + local dYPosA = dTPosI + dYDeltaI + local dVPosA = dTPosI + dVDeltaI + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVDeltaI + local dNewYDelta + local dNewVDelta + -- incremento la distanza tra le due posizioni ( se abilitato e possibile) + local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta) + -- tolleranze + local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y', bFixedDelta) + local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + -- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 2 + else + dNewYDelta = dYDeltaA + end + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + -- definisco 'ExtraY' e ExtraV' + local dNewY = dTPosA + dNewYDelta + local dNewV = dTPosA + dNewVDelta + local dExtraY = dNewY - MyMinY -- < 0 => nuova pos. di Y 'non raggiungibile' + local dExtraV = dNewV - MaxV -- > 0 => nuova pos. di V 'non raggiungibile' + local bYxs = -dExtraY > dYDeltaTol/2 + local bVxs = dExtraV > dVDeltaTol/2 + + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' VDeltaI=' .. EgtNumToString( dVDeltaI) .. + ' TPosI='.. EgtNumToString( dTPosI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1) + EgtOutLog( ' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + -- flag risalita a Zmax + local bZmaxOk = false + + -- **[B2V]** |accentramento di V| + if dVDeltaF > dVDeltaI then + EmitComment( vCmd, '[B2V]') + + -- calcoli preliminari in caso di spostamento richiesto per V significativo + local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw + if bVDeltaS then + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + if bVxs then + -- calcolo le corse disponibili dei carrelli **dalle posizioni iniziali** + -- per allontanare Y e (V+T) + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- calcolo le corse di 'recupero' accentrando (Y+T) e V dopo l'allontanamento + dCorsaYTr = dCorsaYd + (dYPosA - MyMinY) + dCorsaVr = dCorsaVTd -- ((MaxV-dNewV) non fa parte del recupero in quanto già disponibile!) + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr + end + end + + -- **[B2V-xsw]** posizione NewV non raggiungibile, con |dEXtraV > CorsaVr + CorsaYTr| + -- e spostamento richiesto di V significativo; + while bXsw do + EmitComment( vCmd, '[B2V-xsw]') + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1**: allontano Y e V(+T) quanto possibile + dYPosA = dYPosA + dCorsaYd + dVPosA = dVPosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2:** accentro (Y+T) e V + dYPosA = dYPosA - dCorsaYTr -- = MyMinY + dTPosA = dTPosA - dCorsaYTr + dVPosA = MaxV + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno ExtraV residuo + dExtraV = dExtraV - dCorsaYTr - dCorsaVr + -- **aggiorno i recuperi disponibili** riallontanando Y e (V+T) e riaccentrando (Y+T) e V + dCorsaYfc = dCorsaY -- MaxY - dNewY + dCorsaVfc = dCorsaV -- dNewV - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + dCorsaYTr = dCorsaYd + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr + end -- [B2V-xsw] + + + --[B2Vs] |accentramento| (ev' residuo) |di V 'significativo'| + if bVDeltaS then + --[B2Vs-x] accentramento di V 'significativo' |con pos. NewV 'non raggiungibile'|(= oltre MaxV) + if dExtraV > 0 then + -- (ExtraV <= (CorsaYTr+CorsaVr) da ciclo precedente) + --[B2Vs-xs] accentramento di V con |ExtraV 'significativo'| + if bVxs then + local dCorsaYTrA = dYPosA - MyMinY + local dCorsaVra = MaxV - dVPosA + -- **[B2Vs-xs1]** se posso recuperare ExtraV solo accentrando V e (Y+T) + if dCorsaYTrA >= dExtraV then + EmitComment( vCmd, '[B2Vs-xs1]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro (Y+T) q.b. e V + dYPosA = dYPosA - dExtraV + dTPosA = dTPosA - dExtraV + dVPosA = MaxV -- (pos. finale) + dExtraV = 0 + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[B2Vs-xs2]** + EmitComment( vCmd, '[B2Vs-xs2]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: allontano** (V+T) e Y + -- tenendo conto di dover 'recuperare' ExtraV... + local dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') + local dYDispl1 = dYPos1 - dYPosA + local dVDispl1 = dVPos1 - dVPosA + --local dTDispl1 = dTPos1 - dTPosA + local dYDeltaDiff = dNewYDelta - (dYPos1 - dTPos1) + -- ...e anche possibilmente di posizionare Y alla posizione finale + if dYDeltaDiff > 0 then + dCorsaYfc = MaxY - dYPos1 + dCorsaVfc = dVPos1 - MinV + dDistBkN = EMC.LB - (dYPos1-dTPos1) - MinJoin - EMC.TCING -- DistBack1 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + --dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dYDeltaDiff, 0, dCorsaYd-dYDispl1, dCorsaVTd+dVDispl1, 'V') + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dYDeltaDiff, 0, dCorsaYd, dCorsaVTd, 'V') + else + dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 + end + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: accentro** (Y+T) e V + dYPosA = dYPosA - dYDispl1 - dCorsaYTrA -- POS. FINALE + dTPosA = dTPosA - dYDispl1 - dCorsaYTrA + dVPosA = dVPosA - dVDispl1 + dCorsaVra -- POS. FINALE + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B2Vs-xs1/xs2] + + -- **[B2Vs-xn]** |dExtraV non 'significativo'| + else + EmitComment( vCmd, '[B2Vs-xn]') + dExtraV = 0 + -- ev' chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: posiziono V assumendo maxV come pos. finale + dVPosA = MaxV -- (pos finale) + table.insert( vCmd, { 1, 'V', dVPosA}) + end -- [B2Vs-xs/xn] + + -- **[B2Vs-r]** accentramento di |V| 'significativo' con pos.|'raggiungibile'| (= non oltre MaxV) + else + EmitComment( vCmd, '[B2Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: posiziono V -- (pos finale) + dVPosA = dTPosA + dNewVDelta + dExtraV = 0 + table.insert( vCmd, { 1, 'V', dVPosA}) + end --[B2Vs] + + -- **[B2Vns]** accentramento di V non 'significativo'| + else + EmitComment( vCmd, '[B2Vns]') + dExtraV = 0 + end --[B2Vs/ns] + end --[B2V] ( accentramento di V) + + -- --------------------------------------------------------------------------- + -- **[B2Y]** |accentramento di Y| + if dYDeltaF < dYDeltaI then + EmitComment( vCmd, '[B2Y]') + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr + if bYDeltaS then + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + if bYxs then + -- calcolo le **corse disponibili** dei carrelli dalle posizioni iniziali + -- per allontanare (Y+T) e V + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxV - dVPosA) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end + end + + -- **[B2Ys-xsw]** |-dEXtraY > dCorsaYr + dCorsaVTr| + while bXsw do + EmitComment( vCmd, '[B2Y-xsw]') + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |1:| allontano (Y+T) e V quanto possibile + dYPosA = dYPosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dVPosA = dVPosA - dCorsaVd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + + -- |2:| accentro Y e (V+T) + dYPosA = MyMinY -- = dYPosA - dCorsaYr + dVPosA = dVPosA + dCorsaVTr -- = MaxV + dTPosA = dTPosA + dCorsaVTr + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto Delta 'attuali' + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno ExtraY residuo + dExtraY = dExtraY + dCorsaYr + dCorsaVTr + -- aggiorno i recuperi disponibili riallontanando (Y+T) V e riaccentrando succ' Y e (V+T) + dCorsaYfc = dCorsaY -- MaxY - dNewY + dCorsaVfc = dCorsaV -- dNewV - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end -- [B2Ys-xsw] + + -- **[B2Ys]** |accentramento di Y 'significativo'| + if bYDeltaS then + -- **[B2Ys-x]** accentramento di Y 'significativo' |con pos. NewY 'non raggiungibile'|(= oltre MyMinY) + if dExtraY < 0 then + -- (-ExtraY <= (dCorsaYr + dCorsaVTr ) a ciclo precedente + -- **[B2Ys-xs]** accentramento di Y con |'ExtraY 'significativo'| + if bYxs then + local dCorsaVTrA = MaxV - dVPosA + local dCorsaYra = dYPosA - MyMinY + -- **[B2Ys-xs1]** se posso recuperare ExtraY solo accentrando Y e (V+T) + if dCorsaVTrA >= -dExtraY then + EmitComment( vCmd, '[B2Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- accentro Y e (V+T) q.b. + dYPosA = MyMinY -- (pos. finale) + dVPosA = dVPosA - dExtraY -- = +(-dEXtraY) + dTPosA = dTPosA - dExtraY -- = +(-dEXtraY) + dExtraY = 0 + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[B2Ys-xs2]** + EmitComment( vCmd, '[B2Ys-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: allontano** (Y+T) e V + -- tenendo conto di dover 'recuperare' ExtraY... + dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') + local dYDispl1 = dYPos1 - dYPosA + local dVDispl1 = dVPos1 - dVPosA + local dVDeltaDiff = dNewVDelta - (dVPos1 - dTPos1) + -- ...e anche possibilmente di posizionare V alla posizione finale + if dVDeltaDiff < 0 then + dCorsaYfc = MaxY - dYPos1 + dCorsaVfc = dVPos1 - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront1 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dVDeltaDiff, 0, dCorsaYTd, dCorsaVd, 'Y') + else + dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 + end + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + --dVDeltaA = dVPosA - dTPosA + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |2:| accentro Y e (V+T) + dYPosA = dYPosA - dYDispl1 - dCorsaYra -- POS. FINALE + dVPosA = dVPosA - dVDispl1 + dCorsaVTrA -- POS. FINALE + dTPosA = dTPosA - dVDispl1 + dCorsaVTrA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B2Ys-xs1/xs2] + + -- **[B2Ys-xn]** |dExtraY non 'significativo'| + else + EmitComment( vCmd, '[B2Ys-xn]') + dExtraY = 0 + -- ev' chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- 1: posiziono Y assumendo MyMinY come pos. finale + dYPosA = MyMinY -- (pos finale) + table.insert( vCmd, { 1, 'Y', dYPosA}) + end -- [B2Ys-xs/xn] + + --[B2Ys-r] accentramento di |Y| 'significativo' con pos.|'raggiungibile'| (non oltre MyMinY) + else + EmitComment( vCmd, '[B2Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |1:| posiziono Y -- (pos finale) + dYPosA = dTPosA + dNewYDelta + dExtraV = 0 + table.insert( vCmd, { 1, 'Y', dYPosA}) + end --[B2Ys] + + -- [B2Yns] accentramento di V non 'significativo'| + else + EmitComment( vCmd, '[B2Yns]') + dExtraV = 0 + end --[B2Ys/ns] + end --[B2Y] ( accentramento di V) + + -- ricalcolo gli 'spostamenti significativi' + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + + -- ------------------------------------------------------------------------------------------ + -- **[B2C]** |Spostamenti| di Y e/o V (ev' |residui| da cicli precedenti) + -- ++ possono essere solo allontanamenti ? +++++++++++++++++++++ + EmitComment( vCmd, '[B2C]') + -- **[B2Cs]** se c'è uno |spostamento (ev' residuo) significativo| + if bYDeltaS or bVDeltaS then + -- **[B2CYs]** se lo |spostamento (ev' residuo) di Y è 'significativo'| + if bYDeltaS then + EmitComment( vCmd, '[B2CYs]') + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewY = dTPosA + dNewYDelta + local dExtraY = dNewY - MyMinY + + -- **[B2CYs-r]** se posizione di |Y raggiungibile| + if dExtraY >= 0 and dNewY <= MaxY then + EmitComment( vCmd, '[B2CYs-r]') + -- chiudo eventualmente V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y + dYPosA = dNewY + table.insert( vCmd, { 1, 'Y', dYPosA}) + -- **[B2CYs-nr]** + else + EmitComment( vCmd, '[B2CYs-nr]') + EgtOutLog( ' CLAMP : posizione Y non raggiungibile' .. '- caso [B2Ys-nr] non gestito') + error( 'CLAMP : posizione Y non raggiungibile') + end + end -- [B2CYs] + + -- **[B2CVs]** se lo |spostamento (ev' residuo) di V è 'significativo'| + if bVDeltaS then + EmitComment( vCmd, '[B2CVs]') + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewV = dTPosA + dNewVDelta + local dExtraV = dNewV - MaxV + + -- **[B2CVs-r]** se posizione NewV raggiungibile + if dExtraV <= 0 and dNewV >= MinV then + EmitComment( vCmd, '[B2CVs-r]') + -- chiudo eventualmente Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V + dVPosA = dNewV + table.insert( vCmd, { 1, 'V', dVPosA}) + -- **[B2CVs-nr]** + else -- se ExtraV > 0 anche se non significativo + EmitComment( vCmd, '[B2CVs-nr]') + EgtOutLog( ' CLAMP : posizione V non raggiungibile' .. '- caso [B2cVs-nr] non gestito') + error( 'CLAMP : posizione V non raggiungibile') + end + end --[B2CsV] + + -- **[B2Cn]** |nessuno spostamento (ev' residuo significativo)| + else + EmitComment( vCmd, '[B2Cn]') + end -- [B2C] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- imposto stato carrelli, per eventuale uso pressori + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, dVDeltaA}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrB2 + +--------------------------------------------------------------------------------------------------------- +-- *** [B3] da carrello V a entrambi i carrelli : V -> Y+V *** +--------------------------------------------------------------------------------------------------------- +function SpecAdjustCarrB3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[B3] = V -> Y+V', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'V -> Y+V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + local dCorsaY = MaxY - MyMinY + local dCorsaV = MaxV - MinV + -- recupero le posizioni correnti + local dVPosA = dTPosI + dVDeltaI + local dYPosA = ParkY + local dTPosA = dTPosI + local dVDeltaA = dVDeltaI + local dYDeltaA = dYPosA - dTPosA + local dNewYDelta + local dNewVDelta + -- incremento la distanza tra le due posizioni ( se abilitato e possibile) + local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta) + -- tolleranze + local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y', bFixedDelta) + local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + -- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 2 + else + dNewYDelta = dYDeltaA + end + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + + EgtOutLog( ' YDeltaI(Park)='.. EgtNumToString( dYDeltaA)..' VDeltaI=' .. EgtNumToString( dVDeltaA) .. + ' TPosI='.. EgtNumToString( dTPosI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1) + EgtOutLog( ' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + -- risalita testa a Zmax + local bZmaxOk = false + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dYPos, dVPos, dTPos + local dNewY, dExtraY, bYxs + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bYDeltaS then + -- definisco 'ExtraY' con (V+T) e Y accentrati q.b. per la presa di Y + dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'Y') + dNewY = dTPos + dNewYDelta + dExtraY = dNewY - MyMinY -- se < 0 pos. Y non direttamente 'raggiungibile' + bYxs = -dExtraY > dYDeltaTol/2 -- ExtraY 'significativo' + if bYxs then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPos + dCorsaVfc = dVPos - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxV - dVPos) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end + -- inizializzo + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + end + + -- **[B3Ys-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraY > CorsaVr + CorsaYr| + while bXsw do + EmitComment( vCmd, '[B3Ys-xsw]') + + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- |1:| posiziono (V+T) e Y come calcolato sopra + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |2:| allontano (Y+T) e V quanto possibile + dYPosA = dYPosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dVPosA = dVPosA - dCorsaVd + table.insert( vCmd, { 3, 'Y', dTPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |3:| accentro (V+T) e Y + dVPosA = dVPosA + dCorsaVTr + dTPosA = dTPosA + dCorsaVTr + dYPosA = MyMinY + table.insert( vCmd, { 3, 'Y', dTPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno ExtraY + dExtraY = dExtraY + dCorsaYr + dCorsaVTr + + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end --[B3Ys-xsw] + + -- **[B3Ys]** |spostamento| finale richiesto (ev' residuo) di |Y| |'significativo'| + if bYDeltaS then + EmitComment( vCmd, '[B3Ys]') + + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- **[B3Ys-x]** posizione di |Y non raggiungibile| + -- ( -dExtraY <= (CorsaYr+CorsaVr) da ciclo precedente ) + if dExtraY < 0 then + --EmitComment( vCmd, '[B3Ys-x]') + + -- **[B3Ys-xs]** |ExtraY 'significativo'| + if bYxs then + --EmitComment( vCmd, '[B3Ys-xs]') + + local dCorsaVTrA = MaxV - dVPosA + local dCorsaYra = dYPosA - MyMinY + -- **[B3Ys-xs1]** se posso recuperare ExtraY semplicem' accentrando Y e (V+T) + -- ulteriormente rispetto a YPos e Vpos definiti c.s. + if dCorsaVTrA >= -dExtraY then + EmitComment( vCmd, '[B3Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** Y e (V+T) + dYPosA = MyMinY -- (pos. finale) + dVPosA = dVPosA - dExtraY + dTPosA = dTPosA - dExtraY + dYDeltaA = dYPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[B3Ys-xs2]** + EmitComment( vCmd, '[B3Ys-xs2]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** ev' Y e (V+T) alle posizioni impostate + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dYDeltaA = dYPosA - dTPosA + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: allontano** (Y+T) e V + -- tenendo conto di dover 'recuperare' ExtraY... + dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') + local dYDispl1 = dYPos1 - dYPosA + local dVDispl1 = dVPos1 - dVPosA + local dVDeltaDiff = dNewVDelta - (dVPos1 - dTPos1) + -- ...e anche di posizionare possibilmente V alla posizione finale + if dVDeltaDiff < 0 then + CorsaYfc = MaxY - dYPos1 + dCorsaVfc = dVPos1 - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront1 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dVDeltaDiff, 0, dCorsaYTd, dCorsaVd, 'Y') + else + dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 + end + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **3: accentro** Y e (V+T) + dYPosA = dYPosA - dYDispl1 - dCorsaYra -- POS. FINALE + dVPosA = dVPosA - dVDispl1 + dCorsaVTrA -- POS. FINALE + dTPosA = dTPosA - dVDispl1 + dCorsaVTrA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B3Ys-xs1/-xs2] + + -- **[B3Ys-xn]** |dExtraY ancora < 0 ma non 'significativo')| + else --if -dExtraY < DeltaToll/2 + EmitComment( vCmd, '[B3Ys-xn]') + -- ev' chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- 1: accentro Y e porto (V+T) alla posizione impostata + dExtraY = 0 + dYPosA = MyMinY -- (pos. finale) + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end --[B3Ys-xs/xn] + + -- **[B3Ys-r]** |dExtraY > 0 (pos. Y raggiungibile)| + else + EmitComment( vCmd, '[B3Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- posizione ev' (V+T) come impostato sopra e Y in posizione finale + dYPosA = dTPosA + dNewYDelta + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B3Ys] + -- + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + + else -- [B3Yns] |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'| + EmitComment( vCmd, '[B3Yns]') + end --[B3Ys/ns] + + -- aggiorno la verifica di movimento 'significativo' per V + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- **[B3Vs]** Se vi è uno |spostamento residuo di V significativo'| + if bVDeltaS then + EmitComment( vCmd, '[B3Vs]') + + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewV = dTPosA + dNewVDelta + local dExtraV = dNewV - MaxV + + -- **[B3Vs-x]** se pos. |NewV non è raggiungibile direttamente| (oltre MaxV) + if dExtraV > 0 then --dNewV <= MaxV then + -- **[B3Vs-xs]** |ExtraV 'significativo'| + if dExtraV > dVDeltaTol /2 then + EmitComment( vCmd, '[B3Vs-xs]') + EgtOutLog( ' CLAMP : caso [B3Vs-xs] non gestito') + error( ' CLAMP : caso [B3Vs-xs] non gestito') + + -- **[B3Vs-xn]** |ExtraV non 'significativo'| + else + EmitComment( vCmd, '[B3Vs-xn]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- accentro V q.p. + dVPosA = MaxV + table.insert( vCmd, { 1, 'V', dVPosA}) + end -- [B3Vs-xs/xn] + + else -- **[B3Vs-r]** pos. |NewV raggiungibile direttamente| (non oltre MaxV) + EmitComment( vCmd, '[B3Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V + dVPosA = dNewV + table.insert( vCmd, { 1, 'V', dVPosA}) + end --[B3Vs-x/-r] + + else -- [B3Vns] spostamento residuo di V non significativo + EmitComment( vCmd, '[B3Vns]') + end -- [B3Vs/ns] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- se non emessi movimenti, imposto posizione Y + if not bZmaxOk then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + table.insert( vCmd, { 1, 'Y', dYPosA}) + end + -- imposto stato carrelli, per eventuale uso pressori (sempre effettuato movimento) + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, dVDeltaA}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end -- SpecAdjustCarrB3 + +--------------------------------------------------------------------- +-- *** [C1] da carrello Y a V : Y -> V *** +--------------------------------------------------------------------- +function SpecAdjustCarrC1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[C1] = Y -> V ', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y -> V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + -- recupero le posizioni correnti + --local dCorsaY = MaxY - MyMinY + --local dCorsaV = MaxV - MinV + local dYPosA = dTPosI + dYDeltaI + local dVPosA = ParkV + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVPosA - dTPosA + local dNewVDelta -- = dVDeltaF + -- tolleranza + local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol/2 + else + dNewVDelta = dVDeltaA + end + EgtOutLog(' YDeltaI=' .. EgtNumToString( dYDeltaA) .. ' VDeltaI(Park)='.. EgtNumToString( dVDeltaA).. + ' TPosI=' .. EgtNumToString( dTPosI) , 1) + EgtOutLog(' VDeltaF=' .. EgtNumToString( dVDeltaF) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta) , 1) + + -- risalita testa a Zmax (da effettuare comunque, dato lo scambio di carrelli) + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per V significativo + local dYPos, dVPos, dTPos + local dNewV, dExtraV, bVxs + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bVDeltaS then + -- definisco 'ExtraV' con (Y+T) e V accentrati q.b. per la presa di V + dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'V') + dNewV = dTPos + dNewVDelta + dExtraV = dNewV - MaxV + bVxs = dExtraV > dVDeltaTol/2 -- ExtraV 'significativo' + if bVxs then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxY - dYPos + dCorsaVfc = dVPos - MinV + --local dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dDistBkN = EMC.LB - (dYPos-dTPos) - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando (Y+T) e V + dCorsaYTr = dCorsaYd + (dYPos -MyMinY) + dCorsaVr = dCorsaVTd + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaVr + dCorsaYTr + end + -- inizializzo + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + end + + -- **[C1Vs-xsw]** posizione finale di V non raggiungibile, con |dEXtraV > CorsaVr + CorsaYr| + -- con spostamento richiesto significativo e ExtraV significativo + while bXsw do + EmitComment( vCmd, '[C1Vs-xsw]') + -- **1:** posiziono (Y+T) e V come calcolato sopra + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:** allontano Y e (V+T) quanto possibile + dYPosA = dYPosA + dCorsaYd + dVPosA = dVPosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **3:** accentro (Y+T) e V + dYPosA = dYPosA - dCorsaYTr -- = MyMinY + dTPosA = dTPosA - dCorsaYTr + dVPosA = MaxV + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- **aggiorno ExtraV** + dExtraV = dExtraV - dCorsaYTr - dCorsaVr + -- **aggiorno la valutazione di ulteriori corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- aggiorno i prossimi recuperi disponibili + dCorsaYTr = dCorsaYd + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaVr + dCorsaYTr + end --[C1Vs-xw] + + -- **[C1Vs]** |spostamento| richiesto (ev' residuo) |di V| |'significativo'| + if bVDeltaS then + -- **[C1Vs-x]** posizione di |V non raggiungibile| + if dExtraV > 0 then + -- (dExtraV <= (CorsaYr+CorsaVr) da ciclo precedente) + -- **[C1Vs-xs]** posizione di V non raggiungibile, |con ExtraV 'significativo'| + if bVxs then + local dCorsaYTrA = dYPosA - MyMinY + -- **[C1Vs-xs1]** se posso recuperare dExtraV solo accentrando V e (Y+T) + if dCorsaYTrA >= dExtraV then + EmitComment( vCmd, '[C1Vs-xs1]') + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro (Y+T) q.b. e V + dYPosA = dYPosA - dExtraV + dTPosA = dTPosA - dExtraV + dVPosA = MaxV -- (pos. finale) + dVDeltaA = dVPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + -- **[C1Vs-xs2]** dCorsaYTrA < dExtraV + else + EmitComment( vCmd, '[C1Vs-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** ev' (Y+T) e V alle posizioni impostate + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + dVDeltaA = dVPosA - dTPosA + -- chiudo (ev') il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:allontano** (V+T) q.b./q.p. e Y per preparare il recupero di ExtraV + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dYDeltaA = dYPosA - dTPosA + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **3: accentro**(Y+T) e V (pos. finale) + dYPosA = MyMinY + dTPosA = dYPosA - dYDeltaA + dVPosA = MaxV + dVDeltaA = dVPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + end -- [C1Vs-xs1/xs2] + + -- **[C1Vs-xn]** |ExtraV ancora > 0 , ma non 'significativo'| (<= DeltaTol/2) + else + EmitComment( vCmd, '[C1Vs-xn]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: porto ev' (Y+T) alla posizione impostata sopra e accentro V + dExtraV = 0 + dVPosA = MaxV -- pos. finale + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + -- chiudo V (?) + table.insert( vCmd, { 12, 1}) + end -- [C1Vs-xs/xn] + + -- **[C1Vs-r]** posizione di V 'raggiungibile' (ExtraV <= 0) + else + EmitComment( vCmd, '[C1Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- posizione ev' (Y+T) come impostato sopra e V in posizione finale + dVPosA = dTPosA + dNewVDelta + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [C1V-s] + + -- **[C1Vns]** |spostamento| richIesto per V |non 'significativo'| + else + EmitComment( vCmd, '[C1Vns]') + end + + -- calcolo i nuovi parametri di aggancio + dVDeltaA = dVPosA - dTPosA + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y in parcheggio + table.insert( vCmd, { 1, 'Y', ParkY}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, 0, dVDeltaA}) + + EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrC1 + +--------------------------------------------------------------------- +-- *** [C2] da entrambi i carrelli a V : Y+V -> V *** +--------------------------------------------------------------------- +function SpecAdjustCarrC2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[C2] = Y+V -> V', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y+V -> V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + local dCorsaY = MaxY - MyMinY + local dCorsaV = MaxV - MinV + -- recupero le posizioni correnti dei carrelli + local dYPosA = dTPosI + dYDeltaI + local dVPosA = dTPosI + dVDeltaI + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVDeltaI + local dNewVDelta -- = dVDeltaF + -- tolleranze + local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + -- definisco spostamento 'significativo' in base alle tolleranze + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto ev' il delta finale + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol/2 + else + dNewVDelta = dVDeltaA + end + -- definisco 'ExtraV' + local dNewV = dTPosI + dNewVDelta + local dExtraV = dNewV - MaxV -- > 0 se nuova pos. di V 'non raggiungibile' (= oltre MaxV) + local bVxs = dExtraV > dVDeltaTol/2 -- 'ExtraV significativo' + + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' VDeltaI=' .. EgtNumToString( dVDeltaI) .. + ' VDeltaF=' .. EgtNumToString( dVDeltaF) ,1) + EgtOutLog( ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + + -- risalita testa a Zmax (da effettuare comunque, per il parcheggio di Y) + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per YV significativo + local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw + if bVDeltaS then + if bVxs then + -- calcolo le corse disponibili dei carrelli dalle posizioni attuali (=iniziali) + -- per allontanare Y e (V+T) q.p. + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando (Y+T) e V + dCorsaYTr = dCorsaYd + (dYPosA - MyMinY) + dCorsaVr = dCorsaVTd + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr + end + end + + -- **[C2Vs-xsw]** posizione finale di V non raggiungibile, |con dEXtraV > CorsaYTr + CorsaVr| + while bXsw do + EmitComment( vCmd, '[C2Vs-xsw]') + + -- chiudo eventualmente il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |1:| allontano Y e (V+T) quanto possibile + dYPosA = dYPosA + dCorsaYd + dVPosA = dVPosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |3:| accentro (Y+T) e V + dYPosA = dYPosA - dCorsaYTr + dTPosA = dTPosA - dCorsaYTr + dVPosA = MaxV + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- **aggiorno ExtraV** + dExtraV = dExtraV - dCorsaYTr - dCorsaVr + -- **aggiorno la valutazione di ulteriori corse disponibili** + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- aggiorno i prossimi recuperi disponibili + dCorsaYTr = dCorsaYd + (dYPosA - MyMinY) + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr + end -- [C2V-xsw] + + -- **[C2Vs]** se lo |spostamento richiesto per V è significativo| + if bVDeltaS then + -- **[C2Vs-x]** posizione di |V non raggiungibile| (oltre MaxV) + if dExtraV > 0 then + -- **[C2Vs-xs]** |ExtraV 'significativo'| + if bVxs then + local dCorsaYTrA = dYPosA - MyMinY + -- **[C2Vs-xs1]** se posso recuperare ExtraV semplicem' accentrando V e (Y+T) + if dCorsaYTrA >= dExtraV then + EmitComment( vCmd, '[C2Vs-xs1]') + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** (Y+T) e V + dYPosA = dYPosA - dExtraV + dTPosA = dTPosA - dExtraV + dVPosA = MaxV -- (pos. finale) + dVDeltaA = dVPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[C2Vs-xs2]** + EmitComment( vCmd, '[C2Vs-xs2]') + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: allontano** (V+T) e Y + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dYDeltaA = dYPosA - dTPosA + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: accentro** (Y+T) e V + dYPosA = MyMinY + dTPosA = dYPosA - dYDeltaA + dVPosA = MaxV -- (pos. finale) + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [C2Vs-xs1/-xs2] + + -- **[C2Vs-xn]** |dExtraV ancora > 0 ma non 'significativo')| + else --if dExtraV < DeltaToll/2 + EmitComment( vCmd, '[B1Vs-xn]') + -- ev' chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro V + dExtraV = 0 + dVPosA = MaxV -- (pos. finale) + table.insert( vCmd, { 1, 'V', dVPosA}) + end -- [C2s-xs/xn] + + -- **[C2Vs-r]** |dExtraV < 0 (pos. V raggiungibile)| + else + EmitComment( vCmd, '[C2Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- porto V in posizione finale + dVPosA = dTPosA + dNewVDelta + table.insert( vCmd, { 1, 'V', dVPosA}) + end --[C2Vs] + + -- **[C2Vns]** = |spostamento di V non significativo| + else + EmitComment( vCmd, '[C2Vns]') + end --[C2Vs/n] + + -- calcolo il nuovo parametro di aggancio + dVDeltaA = dVPosA - dTPosA + -- chiudo eventualmente il carrello V e apro Y + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y in parcheggio + table.insert( vCmd, { 1, 'Y', ParkY}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, 0, dVDeltaA}) + + EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrC2 + +--------------------------------------------------------------------- +-- *** [C3] da carrello V a V : V -> V *** +--------------------------------------------------------------------- +function SpecAdjustCarrC3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos) + EgtOutLog( ' *[C3] = V -> V', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'V -> V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + -- recupero le posizioni correnti dei carrelli + local dVPosA = dTPosI + dVDeltaI + local dYPosA = ParkY + local dTPosA = dTPosI + local dVDeltaA = dVDeltaI + local dYDeltaA = dYPosA - dTPosA + local dNewVDelta + -- tolleranza + local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + local bVDeltaS = (( dVDeltaF > dVDeltaA + dVDeltaTol and not bFixedPos) or dVDeltaF < dVDeltaA - DELTA_SIC) + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + EgtOutLog( ' VDeltaI=' .. EgtNumToString( dVDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI), 1) + EgtOutLog( ' VDeltaF=' .. EgtNumToString( dVDeltaF) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + -- flag per risalita testa a Zmax + local bZmaxOk = false + + -- **[C3Vs]** |pos. di V cambia in modo significativo| + if bVDeltaS then + EmitComment( vCmd, '[C3Vs]') + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- definisco 'ExtraV' con (V+T) e Y accentrati q.b. per la presa con Y + local dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'Y') + local dNewV = dTPos + dNewVDelta + local dExtraV = dNewV - MaxV + -- effettuo spostamenti per predisporre all'aggancio di T con Y + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dYDeltaA = dYPosA - dTPosA + + -- **[C3Vs-x]** posizione di |V non raggiungibile| (oltre MaxV) + if dExtraV > 0 then + -- **[C3Vs-xs]** posizione di V non raggiungibile, |con ExtraV 'significativo'| + if dExtraV > dVDeltaTol /2 then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (V+T) e Y + local dCorsaYfc = MaxY - dYPos + local dCorsaVfc = dVPos - MinV + local dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + local dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando (Y+T) e V + local dCorsaYTr = dCorsaYd + (dYPos - MyMinY) + local dCorsaVr = dCorsaVTd + + -- **[C3Vs-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraV > CorsaVr + CorsaYr| + if dExtraV > ( dCorsaYTr + dCorsaVr) and bVDeltaS then + EmitComment( vCmd, '[C3Vs-xsw]' .. 'CASO NON GESTITO') + return + end + + local dCorsaYTrA = dYPos - MyMinY -- !! att.ne: non dYPosA !! + -- **[C3Vs-xs1]** se posso recuperare ExtraV semplicem' accentrando (Y+T) e V + -- (dalle posizione impostate sopra per l'aggancio di Y) + if dCorsaYTrA >= dExtraV then + EmitComment( vCmd, '[C3Vs-xs1]') + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** (Y+T) e V + dYPosA = dYPosA - dExtraV + dTPosA = dTPosA - dExtraV + dVPosA = MaxV -- (pos. finale) + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dVDeltaA = dVPosA - dTPosA + + else -- **[C3Vs-xs2]** + -- ci sarebbe un doppio movimento di V ? => caso impossibile ? + EmitComment( vCmd, '[C3Vs-xs2]') + -- **1:** posiziono (ulteriormente!) Y e (V+T) + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dYDeltaA = dYPosA - dTPosA + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: accentro** (Y+T) e V + dYPosA = MyMinY + dVPosA = MaxV -- (pos. finale) + dTPosA = dYPosA - dYDeltaA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [C3Vs-xs1/-xs2] + + -- **[C3Vs-xn]** |dExtraV > 0 ma 'non significativo')| + else --if dExtraV < DeltaToll/2 + EmitComment( vCmd, '[C3Vs-xn]') + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro V + dExtraV = 0 + dVPosA = MaxV -- (pos. finale) + table.insert( vCmd, { 1, 'V', dVPosA}) + end --[C3Vs-xs/xn] + + -- **[C3Vs-r]** |posizione di Y raggiungibile| (ExtraY >=0) + -- (si esclude la possibilità di extra corsa oltre maxY) + else + EmitComment( vCmd, '[C3Vs-r]') + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2:** posiziono V alla posizione richiesta + dVPosA = dNewV + table.insert( vCmd, { 1, 'V', dVPosA}) + end -- [C3Vs] + + -- calcolo il nuovo parametro di aggancio + dVDeltaA = dVPosA - dTPosA + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y in parcheggio + table.insert( vCmd, { 1, 'Y', ParkY}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, 0, dVDeltaA}) + + -- reset contatore + EMC.CNT = nil + + else -- **[C3Vns]** |spostamento| finale richiesto (ev' residuo) di |V non 'significativo'| + EmitComment( vCmd, '[C3Vns]') + end --[C3Vs/ns] + + EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrC3 + +--------------------------------------------------------------------- +function SpecOutputCNT() + if EMC.CNT == 1 then + EgtSetInfo( EMC.PATHID, 'CNT', 1) + else + EgtRemoveInfo( EMC.PATHID, 'CNT') + end +end + +--------------------------------------------------------------------- +function SpecOutputCmds( vCmd, bEnd) + + local sRoot = EgtIf( not bEnd, 'AS', 'AE') + + -- Registro il numero di comandi + if #vCmd > 0 then + EgtSetInfo( EMC.PATHID, sRoot..'#', #vCmd) + else + EgtRemoveInfo( EMC.PATHID, sRoot..'#') + end + -- Registro i comandi + for i = 1, #vCmd do + local Cmd = vCmd[i] + local sKey = sRoot..tostring( i) + -- commento + if Cmd[1] == 0 then + local sInfo = '0,'..Cmd[2] + if Cmd[3] then sInfo = sInfo..','..Cmd[3] end + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 1 asse + elseif Cmd[1] == 1 then + local sInfo = '1,'..Cmd[2]..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 2 assi + elseif Cmd[1] == 2 then + local sInfo = '2,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 3 assi + elseif Cmd[1] == 3 then + local sInfo = '3,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3)..','.. + Cmd[6]..','..EgtNumToString( Cmd[7],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- apertura/chiusura morsa Y + elseif Cmd[1] == 11 then + local sInfo = '11,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] == 0 then EMC.YDELTA = nil end + -- apertura/chiusura morsa V + elseif Cmd[1] == 12 then + local sInfo = '12,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] == 0 then EMC.VDELTA = nil end + -- impostazione nuovo stato dei carrelli + elseif Cmd[1] == 21 then + local sInfo = '21,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = nil + elseif Cmd[3] > 0 then + EMC.YDELTA = nil + EMC.VDELTA = Cmd[3] + end + -- aggancio grezzo a carrello + elseif Cmd[1] == 31 then + local sInfo = '31,'..EgtNumToString( Cmd[2],0)..','..Cmd[3] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + end + end + + -- Salvo i nuovi delta dei carrelli + if EMC.YDELTA then + EgtSetInfo( EMC.PATHID, 'YDELTA', EMC.YDELTA) + else + EgtRemoveInfo( EMC.PATHID, 'YDELTA') + end + if EMC.VDELTA then + EgtSetInfo( EMC.PATHID, 'VDELTA', EMC.VDELTA) + else + EgtRemoveInfo( EMC.PATHID, 'VDELTA') + end + +end + +--------------------------------------------------------------------- +function SpecSetCarrPosFromCmds( vCmd) + -- recupero nuova posizione carrelli + for i = 1, #vCmd do + local Cmd = vCmd[i] + if Cmd[1] == 21 then + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = nil + elseif Cmd[3] > 0 then + EMC.YDELTA = nil + EMC.VDELTA = Cmd[3] + end + end + end +end + +--------------------------------------------------------------------- +function SpecTestOnlyRemarkInCmds( vCmd) + if not vCmd then return true end + -- verifico se nella lista dei comandi ci sono solo commenti + for i = 1, #vCmd do + if vCmd[i][1] ~= 0 then + return false + end + end + return true +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.nge new file mode 100644 index 0000000..a5ec044 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Essetre-FAST.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Machinings/Machinings.data b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Machinings/Machinings.data new file mode 100644 index 0000000..f270914 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Machinings/Machinings.data differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Machinings/Machinings.data.bak b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Machinings/Machinings.data.bak new file mode 100644 index 0000000..293fd76 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Machinings/Machinings.data.bak differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Scripts/ExitMach.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Scripts/ExitMach.lua new file mode 100644 index 0000000..18f86ad --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Scripts/ExitMach.lua @@ -0,0 +1,36 @@ +-- 2018/11/21 17:30:00 +-- Machining Exit for Essetre-FAST machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Uscita da Lavorazioni *** + +-- Nascondo il pezzo così marcato e le geometrie aggiunte, visualizzo il Box +local function ProcessPart( PartId) + -- visualizzo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.ON) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice (già chiusi tutti i gruppi di lavoro) +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +EgtZoom( SCE_ZM.ALL, false) + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Scripts/InitMach.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Scripts/InitMach.lua new file mode 100644 index 0000000..6ac761b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Scripts/InitMach.lua @@ -0,0 +1,44 @@ +-- 2018/11/21 16:30:00 +-- Machining Init for Essetre-FAST machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Ingresso in Lavorazioni *** + +-- Rendo visibile il pezzo e le geometrie aggiunte, nascondo il Box +local function ProcessPart( PartId) + -- nascondo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.OFF) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +-- Processo i pezzi già nei gruppi di lavoro (quando appena lanciata Process) +local GhostId = EgtGetFirstGhostPart() +while GhostId do + local PartId = EgtGetInfo( GhostId, GDB_SI.SOURCE, 'i') + if PartId then + ProcessPart( PartId) + end + GhostId = EgtGetNextGhostPart( GhostId) +end + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Scripts/SetUp.lua b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Scripts/SetUp.lua new file mode 100644 index 0000000..a068a55 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Scripts/SetUp.lua @@ -0,0 +1,206 @@ +-- Gestione attrezzaggio per Essetre-FAST - 2020/07/15 + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Tavola di passaggio valori +local STU = {} +STU.TUUID = "" +STU.TCPOS = "" +STU.HEAD = "" +STU.GROUP = "" +STU.POS = "" +STU.EXIT = 0 +STU.INDEX = 0 +STU.HEAD1 = "" +STU.HEAD2 = "" +STU.ISVALID = false +STU.ERR = 0 +_G.STU = STU + +local INVALIDPOS = "" +local POS = "Pos" + +-- Geom Set +local GS = {} + +-- Configurazione posizioni +local PositionTable={{Pos = "Pos1", TcPos = "T1", Head = "H1", Group = "G1"}, + {Pos = "Pos2", TcPos = "T2", Head = "H1", Group = "G1"}, + {Pos = "Pos3", TcPos = "T3", Head = "H1", Group = "G1"}, + {Pos = "Pos4", TcPos = "T4", Head = "H1", Group = "G1"}, + {Pos = "Pos5", TcPos = "T5", Head = "H1", Group = "G1"}, + {Pos = "Pos6", TcPos = "T6", Head = "H1", Group = "G1"}, + {Pos = "Pos7", TcPos = "T7", Head = "H1", Group = "G1"}, + {Pos = "Pos8", TcPos = "T8", Head = "H1", Group = "G1"}, + {Pos = "Pos9", TcPos = "T9", Head = "H1", Group = "G1"}, + {Pos = "Pos10", TcPos = "T10", Head = "H1", Group = "G1"}, + {Pos = "Pos11", TcPos = "T11", Head = "H1", Group = "G1"}, + {Pos = "Pos12", TcPos = "T42", Head = "H2", Group = "G1"}, + {Pos = "Pos13", TcPos = "T101", Head = "H3", Group = "G1"}} +if EgtGetTcPosId( 'T111') then + table.insert( PositionTable, {Pos = "Pos14", TcPos = "T111", Head = "H1", Group = "G1"}) +end +if EgtGetHeadId( 'H5') then + table.insert( PositionTable, {Pos = "Pos14", TcPos = "T91", Head = "H5", Group = "G1"}) +end + +local UsePositionHead = true + +local function IsInGeomSet( ToolHead, PosHead) + for GsIndex = 1, #GS do + local bToolHead = false + local bPosHead = false + for HIndex = 1, #GS[GsIndex] do + if GS[GsIndex][HIndex] == ToolHead then + bToolHead = true + elseif GS[GsIndex][HIndex] == PosHead then + bPosHead = true + end + if bToolHead and bPosHead then + return true + end + end + if bToolHead and bPosHead then + return true + end + end + return false +end + +function STU.IsCompatibleHeads() + STU.ISVALID = false + if IsInGeomSet(STU.HEAD1, STU.HEAD2) then + STU.ISVALID = true + else + STU.ISVALID = false + end +end + +function STU.GetValidHeadExitForPos() + -- se TUUID non valido restituisco errore + local ToolName = EgtTdbGetToolFromUUID( STU.TUUID) + if ToolName == nill then + STU.ERR = 1 + return + end + EgtTdbSetCurrTool( ToolName) + local CurrToolHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + STU.EXIT = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + -- recupero testa predefinita per la posizione corrente + local CurrPosHead + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + CurrPosHead = PositionTable[i].Head + break + end + end + -- verifico se la testa è quella della posizione predefinita + if CurrPosHead == CurrToolHead then + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + -- verifico se la testa è compatibile con quella della posizione predefinita + elseif IsInGeomSet( CurrToolHead, CurrPosHead) then + if UsePositionHead then + STU.HEAD = CurrPosHead + STU.ERR = 0 + return + else + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + end + -- la testa non è compatibile con quella della posizione predefinita + else + STU.HEAD = INVALIDPOS + STU.ERR = 0 + return + end +end + +function STU.IsValidTcPosFromHead() + STU.ISVALID = false + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + if PositionTable[i].Head == STU.HEAD then + STU.ISVALID = true + STU.ERR = 0 + return + elseif IsInGeomSet(PositionTable[i].Head, STU.HEAD) then + STU.ISVALID = true + STU.ERR = 0 + return + end + STU.ISVALID = false + STU.ERR = 0 + return + end + end +end + +function STU.GetTcPosHeadGroupFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.HEAD = PositionTable[i].Head + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.HEAD = INVALIDPOS + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetPosFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.POS = PositionTable[i].Pos + STU.ERR = 0 + return + end + end + STU.POS = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetGroupFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetHeadFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.HEAD = PositionTable[i].Head + STU.ERR = 0 + return + end + end + STU.HEAD = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetTcPosFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.ERR = 1 +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/SetUp/SetupImage.PNG b/ProgramData/EgtCAM5/Machines/Essetre-FAST/SetUp/SetupImage.PNG new file mode 100644 index 0000000..a8d5b53 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/SetUp/SetupImage.PNG differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/SetUp/Standard.stu b/ProgramData/EgtCAM5/Machines/Essetre-FAST/SetUp/Standard.stu new file mode 100644 index 0000000..50526ae --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FAST/SetUp/Standard.stu @@ -0,0 +1,15 @@ +; Commento per evitare BOM con UTF-8 +[General] +Pos1=T1;H1;1/D077C810-A58B-41DE-A3F5-D2187EBB1B67/Fresa100x60 +Pos2=T2;H1;1/0A54F32E-C48D-45DB-8502-953CA94FD7A0/Fresa25x130 +Pos3=T3;H1;1/877C9B3A-9078-42B6-808D-5ED5CF5C505B/Fresa20x50 +Pos4=T4;H1;1/E7F6A2BB-1F66-48B9-9561-496231C33403/FresaDT60x130 +Pos5=T5;H1;1/5BC80CC4-B497-4509-981C-C7593EC1279F/FresaDT35x130 +Pos6=T6;H1;1/FE2C49A5-18B9-49CD-85DB-18D1FE14ECF9/Fresa 60x80 +Pos7=T7;H1;1/0150315A-41DF-4916-AC88-338C1EF375EF/Penna +Pos8=T8;H1;1/B5B974EF-D18A-45DE-9842-05B91639BE91/PuntaD14 +Pos9=T9;H1;1/0147ED47-EB5D-44D6-9CE2-5282B484B5BD/Smusso45x40 +Pos10=T10;H1;1/5506FABC-CDB0-4E91-B39D-47115FE19F50/PuntaD18_Short +Pos11=T11;H1;1/0C3199C0-5E96-4512-A06B-EECE879330BF/Fresa10x50 +Pos12=T42;H2;1/6CB00A83-DDCD-49E6-A301-E1A0482615CA/Lama620 +Pos13=T101;H3;1/A6CFDA65-DABB-441E-990A-776B5C24C2E4/ChainSaw diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/AngTransm.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/AngTransm.nge new file mode 100644 index 0000000..d2541c4 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/AngTransm.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/BH.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/BH.nge new file mode 100644 index 0000000..fcf3868 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/BH.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/ChainSaw.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/ChainSaw.nge new file mode 100644 index 0000000..d29af27 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/ChainSaw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/MillNoTip.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/MillNoTip.nge new file mode 100644 index 0000000..414ea8e Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/MillNoTip.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Saw.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Saw.nge new file mode 100644 index 0000000..1689dc8 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Saw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Standard.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Standard.nge new file mode 100644 index 0000000..23ee6c6 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Standard.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Standard_78.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Standard_78.nge new file mode 100644 index 0000000..bb1e695 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Standard_78.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Standard_LC.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Standard_LC.nge new file mode 100644 index 0000000..7d2b4c3 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/Standard_LC.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/TcSaw.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/TcSaw.nge new file mode 100644 index 0000000..e8de2ef Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/THolders/TcSaw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge new file mode 100644 index 0000000..cb9e396 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/03E09A0D-8D12-4ADC-B640-10D1A8ED1852.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/03E09A0D-8D12-4ADC-B640-10D1A8ED1852.nge new file mode 100644 index 0000000..176fdc9 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/03E09A0D-8D12-4ADC-B640-10D1A8ED1852.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge new file mode 100644 index 0000000..b1ddce6 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/0C3199C0-5E96-4512-A06B-EECE879330BF.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/0C3199C0-5E96-4512-A06B-EECE879330BF.nge new file mode 100644 index 0000000..75551e2 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/0C3199C0-5E96-4512-A06B-EECE879330BF.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/12CCCF7E-6E46-4253-8463-A5063A77D8F6.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/12CCCF7E-6E46-4253-8463-A5063A77D8F6.nge new file mode 100644 index 0000000..bf0c624 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/12CCCF7E-6E46-4253-8463-A5063A77D8F6.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/24CB106E-76E2-4663-A911-FC8AE44132E1.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/24CB106E-76E2-4663-A911-FC8AE44132E1.nge new file mode 100644 index 0000000..dde62d9 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/24CB106E-76E2-4663-A911-FC8AE44132E1.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/2AB21EFD-2502-4975-A801-BAE26CE7B49A.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/2AB21EFD-2502-4975-A801-BAE26CE7B49A.nge new file mode 100644 index 0000000..c8087f7 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/2AB21EFD-2502-4975-A801-BAE26CE7B49A.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/3B1EFA29-E112-4090-8F4F-4EC5DA598D69.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/3B1EFA29-E112-4090-8F4F-4EC5DA598D69.nge new file mode 100644 index 0000000..b291619 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/3B1EFA29-E112-4090-8F4F-4EC5DA598D69.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/463BE81B-336D-40BE-991C-24765BC28846.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/463BE81B-336D-40BE-991C-24765BC28846.nge new file mode 100644 index 0000000..cd716d5 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/463BE81B-336D-40BE-991C-24765BC28846.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/5506FABC-CDB0-4E91-B39D-47115FE19F50.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/5506FABC-CDB0-4E91-B39D-47115FE19F50.nge new file mode 100644 index 0000000..6503e92 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/5506FABC-CDB0-4E91-B39D-47115FE19F50.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/57898FF3-0FCA-4185-B40F-2318E501260A.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/57898FF3-0FCA-4185-B40F-2318E501260A.nge new file mode 100644 index 0000000..e06630e Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/57898FF3-0FCA-4185-B40F-2318E501260A.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/5BC80CC4-B497-4509-981C-C7593EC1279F.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/5BC80CC4-B497-4509-981C-C7593EC1279F.nge new file mode 100644 index 0000000..9f168e4 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/5BC80CC4-B497-4509-981C-C7593EC1279F.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge new file mode 100644 index 0000000..198ee01 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/6DBB8C3F-4744-4AF9-B213-9D40A7E19390.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/6DBB8C3F-4744-4AF9-B213-9D40A7E19390.nge new file mode 100644 index 0000000..52f0430 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/6DBB8C3F-4744-4AF9-B213-9D40A7E19390.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/8071E2FC-B181-45E9-9EF1-DA7906A95EF2.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/8071E2FC-B181-45E9-9EF1-DA7906A95EF2.nge new file mode 100644 index 0000000..a8ad59a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/8071E2FC-B181-45E9-9EF1-DA7906A95EF2.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/82505C4D-26F2-4197-824F-25129D782E2D.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/82505C4D-26F2-4197-824F-25129D782E2D.nge new file mode 100644 index 0000000..1cf162b Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/82505C4D-26F2-4197-824F-25129D782E2D.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge new file mode 100644 index 0000000..681e8d7 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/973C769D-9B8B-40CB-92DE-5E9CC11E66D7.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/973C769D-9B8B-40CB-92DE-5E9CC11E66D7.nge new file mode 100644 index 0000000..a217c4a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/973C769D-9B8B-40CB-92DE-5E9CC11E66D7.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/9758E25E-CF88-4237-8509-49DF755A5E1E.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/9758E25E-CF88-4237-8509-49DF755A5E1E.nge new file mode 100644 index 0000000..c1f91ce Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/9758E25E-CF88-4237-8509-49DF755A5E1E.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/98CDAEAB-754D-4351-B427-CB8596B2EBF1.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/98CDAEAB-754D-4351-B427-CB8596B2EBF1.nge new file mode 100644 index 0000000..5a54265 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/98CDAEAB-754D-4351-B427-CB8596B2EBF1.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge new file mode 100644 index 0000000..7b4f653 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/B2E59B83-E04A-4B77-BBCE-A7BE2CCAB603.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/B2E59B83-E04A-4B77-BBCE-A7BE2CCAB603.nge new file mode 100644 index 0000000..e4ff467 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/B2E59B83-E04A-4B77-BBCE-A7BE2CCAB603.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/B449357F-293E-4EDC-8EE4-127A9863F116.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/B449357F-293E-4EDC-8EE4-127A9863F116.nge new file mode 100644 index 0000000..abcc480 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/B449357F-293E-4EDC-8EE4-127A9863F116.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/B5B974EF-D18A-45DE-9842-05B91639BE91.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/B5B974EF-D18A-45DE-9842-05B91639BE91.nge new file mode 100644 index 0000000..18ee8e5 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/B5B974EF-D18A-45DE-9842-05B91639BE91.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/C514F0FA-DE3B-4C4A-B411-576CAADF9F6A.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/C514F0FA-DE3B-4C4A-B411-576CAADF9F6A.nge new file mode 100644 index 0000000..07458e9 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/C514F0FA-DE3B-4C4A-B411-576CAADF9F6A.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge new file mode 100644 index 0000000..3b0c484 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/E464F880-F88F-4552-BBE5-B98D5830A89A.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/E464F880-F88F-4552-BBE5-B98D5830A89A.nge new file mode 100644 index 0000000..1f096ed Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/E464F880-F88F-4552-BBE5-B98D5830A89A.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/E4F6E66C-4CF2-4CE3-87AF-78305CEDE59A.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/E4F6E66C-4CF2-4CE3-87AF-78305CEDE59A.nge new file mode 100644 index 0000000..01df802 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/E4F6E66C-4CF2-4CE3-87AF-78305CEDE59A.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge new file mode 100644 index 0000000..37abae9 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/EADA5FF9-7189-4ADC-AAF7-B84614C19EEF.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/EADA5FF9-7189-4ADC-AAF7-B84614C19EEF.nge new file mode 100644 index 0000000..b2a84a0 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/EADA5FF9-7189-4ADC-AAF7-B84614C19EEF.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/FE2C49A5-18B9-49CD-85DB-18D1FE14ECF9.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/FE2C49A5-18B9-49CD-85DB-18D1FE14ECF9.nge new file mode 100644 index 0000000..eed21ce Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/FE2C49A5-18B9-49CD-85DB-18D1FE14ECF9.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/Tools.data b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/Tools.data new file mode 100644 index 0000000..f2abcb9 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/Tools.data differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/Tools.data.bak b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/Tools.data.bak new file mode 100644 index 0000000..59e7668 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/Tools.data.bak differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/penna.nge b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/penna.nge new file mode 100644 index 0000000..f7eb46e Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FAST/Tools/penna.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/BeamData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/BeamData.lua new file mode 100644 index 0000000..46ab697 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/BeamData.lua @@ -0,0 +1,110 @@ +-- BeamData.lua by Egaltech s.r.l. 2021/07/13 +-- Raccolta dati generali per Travi + +EgtOutLog( ' FAST-BeamData started', 1) + +-- Tabella per definizione modulo +local BeamData = { + RIGHT_LOAD = true, -- flag carico da destra + GO_FAST = 0, -- flag abilitazione modalità veloce (0=no, 1=carrelli, 2=anche cambio utensili) + ROT90 = false, -- flag abilitazione rotazione 90 gradi + MIN_WIDTH = 40, -- larghezza minima del grezzo + MIN_HEIGHT = 40, -- altezza minima del grezzo + MAX_WIDTH = 240, -- larghezza massima del grezzo + MAX_HEIGHT = 625, -- altezza massima del grezzo + MAX_WIDTH2 = 305, -- seconda larghezza massima del grezzo + MAX_HEIGHT2 = 550, -- altezza massima per seconda larghezza massima del grezzo + LEN_SHORT_PART = 1200, -- lunghezza massima pezzo corto + LEN_VERY_SHORT_PART = 400, -- lunghezza massima pezzo molto corto (molto probabile lo scarico a caduta) + MAX_RAW = 20000, -- massima lunghezza grezzo (deve essere minore di LenTable - RAW_OFFSET) + STD_RAW = 14000, -- lunghezza standard della barra di grezzo + OVM_HEAD = 10, -- sovramateriale testa + OVM_MID = 5.4, -- sovramateriale intermedio (spessore lama) + MINRAW_S = 750, -- minimo grezzo in coda scaricabile per sezioni piccole + MINRAW_L = 1070, -- minimo grezzo in coda scaricabile per sezioni grandi + MAX_LEN_SCRAP = 270, -- massima lunghezza scarto di coda + MAX_LEN_SCRAP_START = 270, -- massima lunghezza scarto di testa + MAX_DIM_HTCUT = 200, -- larghezza massima taglio di testa o coda + MAX_DIM_HTCUT_HBEAM = 121, -- larghezza massima taglio di testa o coda con trave alta + MIN_DIM_HBEAM = 360, -- altezza minima di trave alta + MAX_DIM_DICE = 155, -- dimensione trasversale massima cubetto + MAX_LEN_DICE = 400, -- lunghezza massima cubetto + COLL_SIC = 5, -- distanza di sicurezza per collisioni + CUT_SIC = 20, -- distanza di sicurezza per tagli + CUT_EXTRA = 5, -- affondamento extra standard per tagli di lama e fresature + CUT_EXTRA_MIN = 1, -- affondamento extra ridotto per tagli di lama e fresature + NZ_MINA = -0.6, -- componente limite in Z normale di una faccia (-36.8deg) + NZ_MINB = -0.4, -- componente limite in Z normale di un insieme di facce (-23deg) + DRILL_TOL = 0.2, -- tolleranza tra diametro foro e diametro punta + DRILL_VZ_MIN = -0.51, -- componente limite in Z del versore di un foro + DRILL_VX_MAX = 0.867, -- componente limite in X del versore di un foro sulle facce laterali + DRILL_OVERLAP = 5, -- sovrapposizione tra due mezze forature + MILL_OVERLAP = 5, -- sovrapposizione tra due mezze fresature + MAX_DIST_HTFEA = 50.0, -- massima distanza di feature da testa o coda per essere considerata tale + MAX_LEN_HTFEA = 2000.0, -- massima lunghezza di feature di testa o coda + LONGCUT_ENDLEN = 600, -- lunghezza lavoro estremi iniziale e finale + LONGCUT_MAXLEN = 1200, -- lunghezza massima sezione di taglio longitudinale + MAX_LEN_RIDGELAP_FROM_BOTTOM = 141, -- massima lunghezza ridgelap lavorabile da sotto + MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM = 96, -- massima lunghezza ridgelap lavorabile da sotto con trave alta + DIM_TO_CENTER_STRIP = 0, -- larghezza minima trave per inseriemento codolo nel centro del trave; 0 = automatico + DIM_STRIP = -1, -- dimensione codolo sostegno parti lasciate su contorno libero o archi (-1 = da Q...) + DIM_STRIP_SMALL = 3, -- dimensione codolo piccolo (quando le parti sostenute sono sicuramente sulla parte sopra del pezzo) + RAWCOL = { 255, 160, 32, 30}, -- colore del grezzo + RAW_OFFSET = 2000, -- spostamento grezzo rimanente dopo split + VICE_MINH = 110, -- altezza minima della morsa + OFFSET_DRILL_TENON = 0, -- offset fori su tenoni verso base degli stessi (0=non fare) + USER_HOLE_DIAM = 0, -- diametro foro per L20 + MAX_TOOL_LEN_FOR_HOR_MACH = 311, -- massima lunghezza utensile per poter fare forature (fresature) oltre i 10 gradi dalla verticale + DRILL_VZ_MIN_LONG_TOOL = 0.984, -- componente limite per lavorazioni con punta lunga + MAX_TOOL_LEN_BACK_HOR_MACH = 250, -- massima lunghezza utensile per poter eseguire lavorazioni (forature/svuotature) da dietro (faccia 4) + MAX_HEIGHT_ROT_B_ABOVE = 500 -- massima altezza della trave che permette di ruotare l'asse B sopra la stessa senza collisioni +} + + + +local function GetMaxLenRidgeLapFromBottom( dHRaw) + if dHRaw < BeamData.MIN_DIM_HBEAM then + return BeamData.MAX_LEN_RIDGELAP_FROM_BOTTOM + 0.01 + else + return BeamData.MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM + 0.01 + end +end +BeamData.GetMaxLenRidgeLapFromBottom = GetMaxLenRidgeLapFromBottom + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Beam', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-Fastrl.data" +local sData = EgtGetSourceDir().."\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Trave then + BeamData.MIN_WIDTH = Machine.Trave.XMIN or BeamData.MIN_WIDTH + BeamData.MIN_HEIGHT = Machine.Trave.ZMIN or BeamData.MIN_HEIGHT + BeamData.MAX_WIDTH = Machine.Trave.XMAX or BeamData.MAX_WIDTH + BeamData.MAX_HEIGHT = Machine.Trave.ZMAX or BeamData.MAX_HEIGHT + end + if Machine.User then + BeamData.OFFSET_DRILL_TENON = Machine.User.L040_OFFSET_P1 or BeamData.OFFSET_DRILL_TENON + if Machine.User.OPTIMIZATIONS_ENABLE_SLICES_F5 == 1 then + BeamData.MAX_LEN_SCRAP = Machine.User.OPTIMIZATIONS_LENGTH_SLICES or BeamData.MAX_LEN_SCRAP + else + BeamData.MAX_LEN_SCRAP = 100000 + end + if Machine.User.OPTIMIZATIONS_ENABLE_SLICES_F6 == 1 then + BeamData.MAX_LEN_SCRAP_START = Machine.User.OPTIMIZATIONS_LENGTH_SLICES or BeamData.MAX_LEN_SCRAP_START + else + BeamData.MAX_LEN_SCRAP_START = 100000 + end + BeamData.USER_HOLE_DIAM = Machine.User.L020_DIAM_HOLE or BeamData.USER_HOLE_DIAM + end + end +end + +--------------------------------------------------------------------- +return BeamData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/BeamTableTemplate.ini b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/BeamTableTemplate.ini new file mode 100644 index 0000000..ccb02c1 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/BeamTableTemplate.ini @@ -0,0 +1,9 @@ +-- %TABLE_NAME%.lua by Egaltech s.r.l. %DATE_TIME% +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local %TABLE_NAME% = { +} + +--------------------------------------------------------------------- +return %TABLE_NAME% diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/CutData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/CutData.lua new file mode 100644 index 0000000..68b6fa5 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/CutData.lua @@ -0,0 +1,12 @@ +-- CutData.lua by Egaltech s.r.l. 29/07/2019 17:05:59 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local CutData = { + { On = true, Name = 'MiSideInvSaw600', Type = 'HeadSide'}, + { On = true, Name = 'MiSideSaw600', Type = 'TailSide'}, + { On = true, Name = 'SplitSideSaw600', Type = 'SplitSide'} +} + +--------------------------------------------------------------------- +return CutData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/DrillData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/DrillData.lua new file mode 100644 index 0000000..9595679 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/DrillData.lua @@ -0,0 +1,21 @@ +-- DrillData.lua by Egaltech s.r.l. 03/02/2021 16:00:52 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local DrillData = { + { On = true, Name = 'DrillD05_4', Type = 'Drill'}, + { On = true, Name = 'DrillD08', Type = 'Drill'}, + { On = true, Name = 'DrillD08_Long', Type = 'Drill'}, + { On = true, Name = 'DrillD10', Type = 'Drill'}, + { On = true, Name = 'DrillD12', Type = 'Drill'}, + { On = true, Name = 'DrillD14', Type = 'Drill'}, + { On = true, Name = 'DrillD16', Type = 'Drill'}, + { On = true, Name = 'DrillD18', Type = 'Drill'}, + { On = true, Name = 'DrillD20', Type = 'Drill'}, + { On = true, Name = 'DrillD25', Type = 'Drill'}, + { On = true, Name = 'DrillPockD20', Type = 'Pocket'}, + { On = true, Name = 'DrillPockD25', Type = 'Pocket'} +} + +--------------------------------------------------------------------- +return DrillData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/MachData.ini b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/MachData.ini new file mode 100644 index 0000000..4cf4179 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/MachData.ini @@ -0,0 +1,39 @@ +; PIndex = Type, PName, Default, Description +; Type : d=double, l=length, s=string + +[1] +Name=Offsets +1=l,YCARICO,-1459.7,YCARICO +2=l,YSCARICO,12700,YSCARICO +3=l,OFFSETRIB,-200.3,OFFSETRIB +4=l,PARKYY,23480,PARKYY +5=l,PARKVV,-31180,PARKVV +6=l,PIVOTFRESA,-116.6,PIVOTFRESA +7=l,PIVOTLAMA,2342.65,PIVOTLAMA +8=l,OFFSETX,-898.199,OFFSETX +9=l,OFFSETZ,-1021.75,OFFSETZ +10=l,MIN_X,-13260,MIN_X +11=l,MAX_X,30,MAX_X +12=l,MIN_Y,310,MIN_Y +13=l,MAX_Y,3735,MAX_Y +14=l,MIN_Z,-1350,MIN_Z +15=l,MAX_Z,0,MAX_Z +16=d,MIN_B,-180,MIN_B +17=d,MAX_B,360,MAX_B +18=d,MIN_C,-360,MIN_C +19=d,MAX_C,360,MAX_C +20=l,MIN_V,-3735,MIN_V +21=l,MAX_V,-110,MAX_V +22=d,TIPO_CN,1,TIPO_CN +23=d,OFFSETCLAMA,0,OFFSETCLAMA +24=d,OFFSETBLAMA,0,OFFSETBLAMA +25=d,RIBCAR,0,RIBCAR +26=d,SECSUP,1,SECSUP +27=d,NOULOAD,0,NOULOAD + +[2] +Name=Trave +1=l,XMIN,29,XMIN +2=l,XMAX,305,XMAX +3=l,ZMIN,20,ZMIN +4=l,ZMAX,625,ZMAX diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/MachiningTypes.ini b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/MachiningTypes.ini new file mode 100644 index 0000000..1b4b06e --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/MachiningTypes.ini @@ -0,0 +1,37 @@ +[Cut] +1=HeadSide +2=TailSide +3=SplitSide + +[Drill] +1=Drill +2=Pocket + +[Milling] +1=Prof +2=FreeContour +3=Tenon +4=DtTenon +5=DtMortise +6=BirdsMouth +7=Chamfer +8=Mark +9=Text +10=Decor01 +11=Long2Cut +12=Long2CutDown +13=LongSmallCut +14=BHSideMill +15=CleanCorner +16=ProfTCone +17=Long2CutSide +18=SmallToolContour +19=AntiSplintMillCut + +[Pocketing] +1=Pocket +2=OpenPocket +3=Mortise + +[Sawing] +1=Sawing diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/MillingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/MillingData.lua new file mode 100644 index 0000000..459d7f6 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/MillingData.lua @@ -0,0 +1,31 @@ +-- MillingData.lua by Egaltech s.r.l. 28/06/2021 19:55:21 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local MillingData = { + { On = true, Name = 'Profiling25x130', Type = 'Prof'}, + { On = true, Name = 'FreeCont25x130', Type = 'FreeContour'}, + { On = true, Name = 'Mill_Tenon100x60', Type = 'Tenon'}, + { On = true, Name = 'Mill_Tenon100x150', Type = 'Tenon'}, + { On = true, Name = 'Mill_DtTen60x130', Type = 'DtTenon'}, + { On = true, Name = 'Mill_DtMrt60x130', Type = 'DtMortise'}, + { On = false, Name = 'Mill_DtMrt40x120r', Type = 'DtMortise'}, + { On = true, Name = 'Mill_DtMrt35x130', Type = 'DtMortise'}, + { On = true, Name = 'Milling100x60', Type = 'BirdsMouth'}, + { On = false, Name = 'Chamfer25x130', Type = 'Chamfer'}, + { On = true, Name = 'Milling100x60', Type = 'Chamfer'}, + { On = true, Name = 'Text45x40', Type = 'Mark'}, + { On = true, Name = 'TextPenna', Type = 'Text'}, + { On = true, Name = 'Text45x40', Type = 'Decor01'}, + { On = true, Name = 'Mill_L2C100x60', Type = 'Long2Cut'}, + { On = true, Name = 'Mill_L2CD25x130', Type = 'Long2CutDown'}, + { On = true, Name = 'Mill_L2CD25x130', Type = 'Long2CutSide'}, + { On = true, Name = 'Milling25x130', Type = 'LongSmallCut'}, + { On = true, Name = 'MillOnSideBH', Type = 'BHSideMill'}, + { On = true, Name = 'Milling10x50', Type = 'SmallToolContour'}, + { On = true, Name = 'Clean35x40', Type = 'CleanCorner'}, + { On = true, Name = 'Mill_DTCone125x160', Type = 'ProfTCone'} +} + +--------------------------------------------------------------------- +return MillingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/PocketingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/PocketingData.lua new file mode 100644 index 0000000..1f47b29 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/PocketingData.lua @@ -0,0 +1,19 @@ +-- PocketingData.lua by Egaltech s.r.l. 29/06/2021 11:32:35 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local PocketingData = { + { On = true, Name = 'Svuot100x60', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot100x150', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot60x80', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot35x70', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot25x130', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot20x50', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot35x70', Type = 'Pocket'}, + { On = true, Name = 'Svuot25x130', Type = 'Pocket'}, + { On = true, Name = 'Svuot20x50', Type = 'Pocket'}, + { On = true, Name = 'Mortiser38.89x130', Type = 'Mortise'} +} + +--------------------------------------------------------------------- +return PocketingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/SawingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/SawingData.lua new file mode 100644 index 0000000..8232c0b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/SawingData.lua @@ -0,0 +1,10 @@ +-- SawingData.lua by Egaltech s.r.l. 29/07/2019 17:06:08 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local SawingData = { + { On = true, Name = 'TaglioCatena', Type = 'Sawing'} +} + +--------------------------------------------------------------------- +return SawingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/Ts3Data.lua b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/Ts3Data.lua new file mode 100644 index 0000000..d03c166 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Beam/Ts3Data.lua @@ -0,0 +1,78 @@ +-- C:\TechnoEssetre7\EgtData\Essetre-FAST.data + +local Offsets = { + YCARICO=-1437.65, + YSCARICO=1700, + OFFSETRIB=200, + PARKYY=480, + PARKVV=-480, + PIVOTFRESA=-176.73, + PIVOTLAMA=242.36, + OFFSETX=903.15, + OFFSETZ=-1015.6, + MIN_X=0, + MAX_X=1350, + MIN_Y=110, + MAX_Y=3735, + MIN_Z=-1350, + MAX_Z=0, + MIN_B=-180, + MAX_B=360, + MIN_C=-360, + MAX_C=360, + MIN_V=-3735, + MAX_V=-110, + TIPO_CN=1, + OFFSETCLAMA=-0.03, + OFFSETBLAMA=0, + RIBCAR=0, + SECSUP=0, + NOULOAD=0, + Zzz=1 +} + +local Trave = { + XMIN=30, + XMAX=300, + ZMIN=30, + ZMAX=625, + Zzz=1 +} + +local User = { + NESTING_MATERIAL=1, + NESTING_TYPEEXTERNALOP=1, + NESTING_FROM_BTL=0, + SAFETY_DISTANCE_ZSAVE=23, + OPTIMIZATIONS_ENABLE_SLICES_F5=1, + OPTIMIZATIONS_ENABLE_SLICES_F6=1, + OPTIMIZATIONS_LENGTH_SLICES=100, + L056_ACTIVE_AS=1, + L055_ADD_P13=0, + L055_ACTIVE_AS=1, + L050_ADDDEPTH=3, + L060_PEN_F2=2, + L060_PEN_F1=2, + L138_TOLLERANZA=0, + L037_TOOL_WIDTH=0, + L032_LENGTH_MIN_DIV=500, + T055_ACTIVE_AS=1, + L040_ADD_P11=0, + L040_ADD_P11_PASS=0, + L040_OFFSET_P1=0, + L040_TYPEDRILLING=1, + L012_LIM=0, + L012_LENGTH_MIN_DIV=950, + L010_LIM=3, + L010_LENGTH_MIN_DIV=1000, + L020_DIAM_HOLE=8, + L030_AUM_DIM=0, + L030_LENGTH_MIN_DIV=500, + T010_ALTCATENA=610, + T010_OFFSETPIANOCATENA=33, + L036_LENGTH_MIN_DIV=900, + Zzz=1 +} + +local Machine = { Offsets=Offsets, Trave=Trave, User=User} +return Machine diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.NUM.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.NUM.mlpe new file mode 100644 index 0000000..c56c04a --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.NUM.mlpe @@ -0,0 +1,1224 @@ +-- Processore macchina Essetre-FASTrl by EgalTech s.r.l. 2021/07/08 +-- Con controllo numerico NUM + +-- Variabili di modulo +local MLE_INFO = 'Essetre-FASTrl.NUM.mlpe ver.'..PP_VER..' by EgalTech s.r.l.' +local TEST_USE = false + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.FMAXPINZE = 154000 -- feed massima pinze +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) + -- Se modalità test, rinomino il programma come XPI + if TEST_USE then + local sNewPath = EgtChangePathExtension( EMT.FILE, '.xpi') + EgtEraseFile( sNewPath) + EgtRenameFile( EMT.FILE, sNewPath) + end +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Intestazioni + EmtOutput( "%40.0") + if EMT.INFO then + EmtOutput( '('..EMT.INFO..')') + else + EmtOutput( '(Program Start)') + end + EmtOutput( '('.. MLE_INFO..')\n') + -- Se modalità test, aggiungo linee per muovere tappeto e alzare la testa (in automatico viene fatto dal main residente) + if TEST_USE then + EmtOutput( 'M28') + EmtOutput( 'N1 G101Z-100 L0=0') + EmtOutput( 'N1 G101ET1001') + EmtOutput( 'N1 G101ET2001\n') + end + -- Cerco primo utensile su testa 1 + EMT.TOOL_1, EMT.TLEN_1 = FindFirstToolOnHead( 'H1') +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Arresto mandrino + EmtOutput( 'M05') + -- Emissione scarico + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' or EMT.AUXTYPE == 'R' then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + elseif EMT.AUXTYPE == 'U' then + EmtOutput( 'G111ET1002') + EmtOutput( 'G111ET2002') + -- emissione conclusione pezzo precedente + if EMT.PRODID then + local sEnd= 'G113 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( EMT.CUTID)..' ED2' + EmtOutput( sEnd) + end + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + -- Se modalità test, termino il programma + if TEST_USE then + EmtOutput( 'M02') + end +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensile (esclusa lama e sega a catena) + if EMT.HEAD == 'H1' then + -- output info + local sPos = EgtIf( #EMT.TCPOS == 2, EMT.TCPOS:gsub( 'T', 'N30'), EMT.TCPOS:gsub( 'T', 'N3')) + local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( EMT.TTOTLEN, 1)..' G76H9998.2'..sPos..sPos + EmtOutput( sOut) + -- cerco posizione di attrezzaggio del primo utensile di lavorazione + if EMT.TOOL == EMT.TOOL_1 and EMT.TLEN_1 < 215.5 then + EMT.TCPOS_1 = EMT.TCPOS + end + -- emissione dati sega a catena + elseif EMT.HEAD == 'H3' then + local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( ChSawLen, 1)..' G76H9998.2N401N404' + EmtOutput( sOut) + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + --EmtOutput( '(Disposition '..EMT.DISPIND..' = '..EMT.DISPID..')') + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') + EMT.YPOS = EgtGetInfo( EMT.DISPID, 'YPOS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- emissione dati di macchina + local sOut = 'G114'..'EA'..EmtLenToString(LoadT,-2)..'EB'..EmtLenToString(MinY,-2)..'EC'..EmtLenToString(MaxY,-2).. + 'ED'..EmtLenToString(MinV,-2)..'EE'..EmtLenToString(MaxV,-2)..'EF'..EmtLenToString(MillOffs,-2).. + 'EG'..EmtLenToString(SawOffs,-2)..'EI'..EmtLenToString(ParkY,-2)..'EL'..EmtLenToString(ParkV,-2).. + 'EM'..EmtLenToString(TurnerOffs,-2) + EmtOutput( '\n' .. sOut .. '\n') + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + end +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- reset recupero sovramateriale in X non più presente + EMT.X_OFF = nil + -- dati del grezzo + local LBarra = EMT.LB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- calcolo dati pinze + local MinAccPinze = 0.3 + local MaxAccPinze = 4 + local KgMtCubo= 550 -- densità legno in Kg / metro cubo + local Massa = ( HTrave * STrave * LBarra * KgMtCubo ) / 1000000000 + local FMaxPinze = EMT.FMAXPINZE + local ForzaAtrito = 700 / 2 -- Serve per regolare P32 (700 valore reale pistone) + local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAtrito) / 1000) + if ( TempoAcc < MinAccPinze) then TempoAcc = MinAccPinze end + if ( TempoAcc > MaxAccPinze) then TempoAcc = MaxAccPinze end + local AccPinze = FMaxPinze / ( 60 * TempoAcc) + local RidFeed = 100 / Massa * 100 + if ( RidFeed > 100) then RidFeed = 100 end + if IdTrave >= 0 then + local sOut = '( SN='..IdTrave..' LBarra='..EmtLenToString(LBarra,3)..' L='..EmtLenToString(LTrave,3).. + ' H='..EmtLenToString(HTrave,3)..' S='..EmtLenToString(STrave,3)..' Acc='..EmtLenToString(TempoAcc,1).. + ' RidFeed='..EmtLenToString(RidFeed,3)..' FeedMax='..EmtLenToString(FMaxPinze / 100 * RidFeed,3)..' )' + MyOutputNoNum( sOut) + sOut = 'E30049='..EmtLenToString(AccPinze,0)..' E30050=8555 E30051='..EmtLenToString(AccPinze,0).. + ' E30052=8555'..' E30054='..EmtLenToString(AccPinze,0)..' E30039='..EmtLenToString(RidFeed*1000,0).. + ' E30040='..EmtLenToString(RidFeed*1000,0)..' E30017=E80017'..' E30018=E80018'..' E10012=1' + MyOutputNoNum( sOut) + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or EgtGetCurrMachGroup() or GDB_ID.NULL + EMT.PRODID = EgtGetInfo( BtlInfoId, 'PRODID', 'i') or 0 + EMT.PATTID = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 0 + EMT.CUTID = EgtGetInfo( EMT.IDT, 'CUTID', 'i') or 0 + local sStart = 'G113 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( EMT.CUTID)..' ED1' + -- da emettere solo se aggiorna PLC + --EmtOutput( sStart) + else + MyOutputNoNum( '(REMAIN UNLOAD)') + EMT.PRODID = nil + EMT.PATTID = nil + EMT.CUTID = nil + end + -- se carico barra + if EMT.LOAD then + -- verifico se sezione già caricata + local sOut = 'IF E30033<'..EmtLenToString(HTrave*1000,0)..' OR E30036<'..EmtLenToString(STrave*1000,0)..' THEN' + EmtOutput( sOut) + sOut = 'M119' + EmtOutput( sOut) + sOut = 'M149' + EmtOutput( sOut) + sOut = 'ENDI' + EmtOutput( sOut) + -- assegnazione dati trave e barra + sOut = 'E30033='..EmtLenToString(HTrave*1000,0)..' E30036='..EmtLenToString(STrave*1000,0).. + ' E30069='..EmtLenToString(LBarra*1000,0) + EmtOutput( sOut) + -- preselezione prima fresa (della testa 1) + sOut = 'IF E30001=0 THEN' + EmtOutput( sOut) + sOut = 'M6' .. ( EMT.TCPOS_1 or 'T1') + -- va scritto 2 volte + EmtOutput( sOut) + EmtOutput( sOut) + sOut = 'ENDI' + EmtOutput( sOut) + -- ora abilito numerazione linee + EMT.NUM = true + EMT.LINENBR = 0 + -- altrimenti recupero rimanenza + else + EmtOutput( 'G112 EC1'..' Y'..EmtLenToString( LoadT, 3).. ' EY'..EmtLenToString( EMT.YPOS, 3)..' EV'..EmtLenToString( ParkV, 3) ..' EF'..GetFmaxClamp()) + -- aggiorno dati aggancio carrelli alla trave + EMT.YDELTA = EMT.YPOS - LoadT + EMT.VDELTA = nil + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- verifico se sono diverse + if nRot ~= nPrevRot then + if nRot > nPrevRot then nRot = nRot - 4 end + local nDeltaRot = nRot - nPrevRot + -- se rotazione automatica richiesta e possibile + if AutomaticRotation and EMT.LB >= AutoRotMinLen then + local sOut = 'M180 L0=' .. tostring( -nDeltaRot) + EmtOutput( sOut) + else + local sOut + if nDeltaRot == -1 then + sOut = 'M151' + elseif nDeltaRot == -2 then + sOut = 'M152' + elseif nDeltaRot == -3 then + sOut = 'M153' + end + EmtOutput( sOut) + EmtOutput( 'M86') + EmtOutput( 'G4F.5') + end + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + MyOutputNoNum( '(PART UNLOAD)') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'G111ET1002') + EmtOutput( 'G111ET2002') + -- emissione conclusione pezzo precedente + if EMT.PRODID then + local sEnd= 'G113 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( EMT.CUTID)..' ED2' + EmtOutput( sEnd) + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + end + + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- se primo grezzo, reset lunghezza barra + if EMT.RAWIND == 1 then EMT.LB = 0 end + -- aggiungo la lunghezza del grezzo (solo se movimento in corner) + if EMT.RAWTYPE == 1 then + local b3Raw = EgtGetBBoxGlob( EgtGetFirstNameInGroup( EMT.RAWID, 'RawSolid'), GDB_BB.STANDARD) + local LBarra = b3Raw:getDimX() + EMT.LB = EMT.LB + LBarra + end + -- se primo grezzo, calcolo dati del pezzo + if EMT.RAWIND == 1 then + local PartId = EgtGetFirstPartInRawPart( EMT.RAWID) + if PartId then + EMT.IDT = PartId + EMT.IT = EgtGetInfo( PartId, 'PDN', 'i') or 0 + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box'), GDB_BB.STANDARD) + EMT.LT = b3Part:getDimX() + EMT.HT = b3Part:getDimY() + EMT.ST = b3Part:getDimZ() + EMT.HOVM = EgtGetInfo( EMT.RAWID, 'HOVM', 'd') or 0 + else + EMT.IDT = GDB_ID.NULL + EMT.IT = -1 + EMT.LT = 0 + EMT.HT = 0 + EMT.ST = 0 + EMT.HOVM = 0 + end + end + end +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOOLSEL = EMT.TCPOS..' M06' + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + --EMT.MCHNAME = EgtGetMachiningParam(MCH_MP.NAME) + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam(MCH_MP.TYPE) + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + -- la speed della lama va moltiplicata per 6 + if EMT.EXIT == 2 then + EMT.S = EMT.S * 6 + end + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + --EmtOutput( ';Mach End') + -- Emissione split + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + MyOutputNoNum( '(PART SPLIT)') + elseif EMT.AUXTYPE == 'U' then + MyOutputNoNum( '(PART UNLOAD)') + elseif EMT.AUXTYPE == 'P' then + MyOutputNoNum( '(PART ROTATION)') + end + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + elseif EMT.AUXTYPE == 'U' then + EmtOutput( 'G111ET1002') + EmtOutput( 'G111ET2002') + -- emissione conclusione pezzo precedente + if EMT.PRODID then + local sEnd= 'G113 EA'..tostring( EMT.PRODID)..' EB'..tostring( EMT.PATTID)..' EC'..tostring( EMT.CUTID)..' ED2' + EmtOutput( sEnd) + end + elseif EMT.AUXTYPE == 'P' then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStart() + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + + -- se richiesto, preparo il carico barra + if EMT.LOAD then + PrepareLoad( EMT.AUX) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( EMT.AUX) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnPathEndAux() + --EgtOutLog( 'OnPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'P' + end + end + end + -- preparo a seconda del tipo + if EMT.AUXTYPE == 'R' then + -- per lo scarico della rimanenza + PrepareResidue( EMT.AUX) + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnRapid() + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + if not EMT.LOAD then + if not EMT.ZMAX and #EMT.AUXSTR > 0 then + EmitZmax() + end + EmtOutput( '( *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** )') + end + -- primo posizionamento + EmtResetPrev() + local bZmax = ( #EMT.AUXSTR > 0 or EMT.TOOL ~= EMT.PREVTOOL or EMT.L3 > -1) + local sEE = EgtIf( bZmax, ' EE3', ' EE4') + local sEL = 'EL' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TLEN, ChSawLen), 3) + local sER = 'ER' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TDIAM / 2, EMT.TLEN), 3) + local sOut = 'G101' .. EmtGetAxis( 'L2') .. EmtGetAxis( 'L3') .. + EmtGetAxis( 'R2') .. EmtGetAxis( 'R1') .. sEE .. sEL .. sER + if EMT.HEAD == 'H1' then + sOut = sOut..'E'..EMT.TCPOS + elseif EMT.HEAD == 'H2' then + sOut = sOut..'ET42' + elseif EMT.HEAD == 'H3' then + if abs( EMT.R3 - 0) < 0.1 then + sOut = sOut..'E'..'T101' + elseif abs( EMT.R3 - 270) < 0.1 then + sOut = sOut..'E'..'T102' + elseif abs( EMT.R3 - 180) < 0.1 then + sOut = sOut..'E'..'T103' + elseif abs( EMT.R3 - 90) < 0.1 then + sOut = sOut..'E'..'T104' + else + EmtSetLastError( 1210, 'Chain saw orientation not allowed') + end + else + error( "Unknown Head") + end + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H2', 1, 6) + sOut = sOut..'ES'..EgtNumToString( Speed, 0)..' L0=0' + EmtOutput( sOut) + sOut = 'G101ET1001' + EmtOutput( sOut) + -- se prima lavorazione + if EMT.LOAD then + sOut = 'G79 E80060<>0 N9 E10015=0' + EmtOutput( sOut) + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + EMT.AUXSTR = {} + sOut = 'G111ET1001' + EmtOutput( sOut) + sOut = 'G79N9' + EmtOutput( sOut) + sOut = 'E80060=1' + EmtOutput( sOut) + sOut = 'G111ET2001' + EmtOutput( sOut) + EmtOutput( '( *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** )') + sOut = 'G101ET2001' + EmtOutput( sOut) + local sY = EmtLenToString( EMT.L1 + EMT.YDELTA) + local sV = EmtLenToString( ParkV) + sOut = 'G112EA1EB2'..EmtGetAxis('L1')..'EY'..sY..'EV'..sV..'EF'..GetFmaxClamp() + EmtOutput( sOut) + EMT.LOAD = false + -- altrimenti lavorazione successiva + else + -- eventuale G111 + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if not EMT.POSTROT then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + else + EmtOutput( 'G111ET1001') + EmtOutput( 'G111ET2001') + end + end + EMT.AUXSTR = {} + local sY, sA + if EMT.YDELTA then + sY = EmtLenToString( EMT.L1 + EMT.YDELTA - ( EMT.X_OFF or 0)) + sA = '1' + else + sY = EmtLenToString( EgtIf( EMT.YPOS, EMT.YPOS, ParkY)) + sA = '2' + end + local sV, sB + if EMT.VDELTA then + sV = EmtLenToString( EMT.L1 + EMT.VDELTA - ( EMT.X_OFF or 0)) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + sOut = 'G112EA'..sA..'EB'..sB..EmtGetAxis('L1')..'EY'..sY..'EV'..sV..'EF'..GetFmaxClamp() + EmtOutput( sOut) + sOut = 'G101ET2001' + EmtOutput( sOut) + EMT.POSTROT = false + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se standard + elseif EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EmtOutput( 'G102'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3')..EMT.IPLGLSTR) + else + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + end + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmitZmax() + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- altrimenti errore + else + error( "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EmtOutput( 'G102'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3')..EMT.IPLGLSTR) + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- aggiungo feed + local sFeed = EmtGetFeed() + -- emetto linea + EmtOutput( "G1"..sAxes..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + -- non modale su archi + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString(EMT.RR,3) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- emetto arco + EmtOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd, bSkipPress) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + elseif sCmd == '1' then + return '2' + -- chiuso con pressore attivato + elseif sCmd == '2' then + return EgtIf( bSkipPress, '2', '0') + end +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = 'EB112' + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sYTaking = 'Y'..EmtLenToString( Cmd[3] + TurnerOffs) + local sBeamRot = '0+0' + if StartRotation and EMT.LB >= AutoRotMinLen then + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= 0 then + if TEST_USE then + sBeamRot = '0+' .. tostring( -nRot) + else + sBeamRot = '@(LOAD90)+' .. tostring( -nRot) + end + end + end + local sOut = 'G111'..sYTaking..'EA75EB112EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1E80057='..sBeamRot..' E80058=0' + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + local sYLoad = 'Y'..EmtLenToString( LoadT) + local sOut = 'G111'..sYLoad..'EA76'..EMT.SB..'EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1' + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = EgtIf( EMT.YDELTA, 'EA112', 'EA111') + EMT.SB = EgtIf( EMT.YDELTA, 'EB112', 'EB111') + EMT.SC = EgtIf( EMT.VDELTA, 'EC142', 'EC141') + EMT.SD = EgtIf( EMT.VDELTA, 'ED142', 'ED141') + EMT.SE = EgtIf( EMT.YDELTA, 'EE1', 'EE2') + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut = 'G111'..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.YPOS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', Cmd[6] .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'EB11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = 'EA11' .. CalcCharStatus( Cmd[2]) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE1', 'EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'ED14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = 'EC14' .. CalcCharStatus( Cmd[2]) + EMT.SD = 'ED14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE2', 'EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.YDELTA, 'EA112', 'EA111') + EMT.SB = EgtIf( EMT.YDELTA, 'EB112', 'EB111') + EMT.SC = EgtIf( EMT.VDELTA, 'EC142', 'EC141') + EMT.SD = EgtIf( EMT.VDELTA, 'ED142', 'ED141') + EMT.SE = EgtIf( EMT.YDELTA, 'EE1', 'EE2') + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + if not EMT.UNL then + sOut = 'G111'..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + else + sOut = 'G111'..Cmd[2]..Cmd[3]..'EC141ED83EE0EF'..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', Cmd[6] .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'EB11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = 'EA11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE1', 'EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'ED14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = 'EC14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = 'ED14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE2', 'EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sOut = 'G111'..Cmd[2]..Cmd[3]..'EA110EB110EC142ED142EE2EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.YPOS = tonumber( Cmd[3]) + end + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sEE = EgtIf( EMT.PHASE == EgtGetPhaseCount(), '0', '1') + local sOut = 'G111'..Cmd[2]..Cmd[3]..'EC141ED83EE'..sEE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[4] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sEAB = EgtIf( EMT.PHASE == EgtGetPhaseCount(), '111', '112') + local sOut = 'G111'..Cmd[4]..Cmd[5]..'EA'..sEAB..'EB'..sEAB..'EC142ED141EE2EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + -- non interessa + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.YDELTA, 'EA112', 'EA111') + EMT.SB = EgtIf( EMT.YDELTA, 'EB112', 'EB111') + EMT.SC = EgtIf( EMT.VDELTA, 'EC142', 'EC141') + EMT.SD = EgtIf( EMT.VDELTA, 'ED142', 'ED141') + EMT.SE = EgtIf( EMT.YDELTA, 'EE1', 'EE2') + end + -- se è pre-rotazione + if Cmd[2] == 'Pre-Rotation' then + EMT.PREROT = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + if not EMT.PREROT then + sOut = 'G111'..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + else + sOut = 'G111'..Cmd[2]..Cmd[3]..'EA86EB87EC141EE0EF'..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', Cmd[6] .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'EB11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = 'EA11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE1', 'EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'ED14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = 'EC14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = 'ED14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE2', 'EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = 'EB112' + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + local sYTaking = 'Y'..EmtLenToString( Cmd[3] - EMT.HOVM) + local sOut = 'G111'..sYTaking..'EA75EB112EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1 E80058=0' + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + local sYLoad = 'Y'..EmtLenToString( LoadT) + local sOut = 'G111'..sYLoad..'EA76'..EMT.SB..'EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1' + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + if EMT.REFLOC then + local vtE + if EMT.HEAD ~= 'H3' then + local Len = EMT.TLEN + EgtIf( EMT.HEAD == 'H1', MillOffs, abs( SawOffs)) + local LenRef = MillOffs + vtE = Vector3d( EMT.EXTR) * Len - Z_AX() * LenRef + else + local Len = ChSawLen + MillOffs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + vtE = Vector3d( vtAux) * Len - Z_AX() * LenRef + end + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - DeltaTabY - vtE:getY() + EMT.L3 = EMT.L3 - DeltaTabZ - vtE:getZ() + end + + if EMT.X_OFF then EMT.L1 = EMT.L1 + EMT.X_OFF end + + EmtAdjustLinearAxes() + + if not EMT.REFLOC then + EMT.L2 = - EMT.L2 + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function MyOutputNoNum( sOut) + local bNum = EMT.NUM + EMT.NUM = false + EmtOutput( sOut) + EMT.NUM = bNum +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + LoadT + if EMT.X_OFF then xS = xS + EMT.X_OFF end + local ptS = Point3d( xS, 0, 0) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H3' then + vtE = Vector3d( EMT.EXTR) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --EmtOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local _, dAngV, dAngO = SphericalFromVector( vtE) + local dAngO2 = EmtGetAngO2( EMT.IPLGLFR:getVersZ(), EMT.IPLGLFR:getVersX(), dAngV, dAngO) + dAngO = dAngO + 90 + while dAngO >= 360 do + dAngO = dAngO - 360 + end + EMT.IPLGLSTR = ' EX0 EY'..EmtLenToString( xS)..' EZ0'.. + ' EA0'..' EB'..EgtNumToString(dAngV)..' EC'..EgtNumToString(dAngO)..' ED'..EgtNumToString(dAngO2) + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function EmitZmax() + local sOut = 'G101 Z' .. EgtGetAxisHomePos('Z') .. ' L0=0' + EmtOutput( sOut) + sOut = 'G101ET1001' + EmtOutput( sOut) + sOut = 'G101ET2001' + EmtOutput( sOut) +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE, 0) +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.TPA.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.TPA.mlpe new file mode 100644 index 0000000..ef98680 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.TPA.mlpe @@ -0,0 +1,1622 @@ +-- Processore macchina Essetre-FASTrl by EgalTech s.r.l. 2021/07/08 +-- Con controllo numerico TPA + +-- Variabili di modulo +local MLE_INFO = 'Essetre-FASTrl.TPA.mlpe ver.'..PP_VER..' by EgalTech s.r.l.' +local TEST_USE = false + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.DECNUM = 5 -- numero di decimali dopo la virgola + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.FMAXPINZE = 154000 -- feed massima pinze +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Intestazioni + if EMT.INFO then + ParkLine( '('..EMT.INFO..')') + else + ParkLine( '(Program Start)') + end + ParkLine( '('.. MLE_INFO..')') + -- Se modalità test, aggiungo linee per muovere tappeto e alzare la testa (in automatico viene fatto dal main residente) + if TEST_USE then + ParkLine( 'M199') + end + -- Cerco primo utensile su testa 1 + EMT.TOOL_1, EMT.TLEN_1 = FindFirstToolOnHead( 'H1') + -- Dichiaro inizio + EMT.FIRST = true + EMT.TLAST = nil + -- Inizializzazioni varie + ParkLine( 'M6 T000000') + ParkLine( 'G49') + -- Inizio lista utensili + ParkLine( 'M993 (Tool List Start)') +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Arresto mandrino + EmtOutput( 'M05') + -- Emissione scarico + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + elseif EMT.AUXTYPE == 'R' then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + elseif EMT.AUXTYPE == 'U' then + local sP1x = EgtIf( EMT.CHY_ON, '0', '2') + EmtOutput( 'M111 P1=2'..sP1x) + EmtOutput( EgtIf( EMT.U_STD, ';', '')..'M111 P1=3'..sP1x) + -- emissione conclusione pezzo precedente (se non si è in test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + EmtOutput( sEnd) + end + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.RELOAD = nil + EMT.RELOAD2 = nil + -- Termino il programma + EmtOutput( 'M02') +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensile (esclusa sega a catena) + if EMT.HEAD ~= 'H3' then + local sOut = 'M992 P1=' .. EMT.TCPOS:gsub( 'T', '') .. ' P2=' .. EmtLenToString( EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( EMT.TTOTLEN, 3) + ParkLine( sOut) + -- cerco posizione di attrezzaggio del primo utensile di lavorazione + if EMT.HEAD == 'H1' then + if EMT.TOOL == EMT.TOOL_1 and EMT.TLEN_1 < 215.5 then + EMT.TCPOS_1 = EMT.TCPOS + end + end + -- emissione dati sega a catena + else + local sData = ' P2=' .. EmtLenToString( ChSawLen, 3) .. ' P3=' .. EmtLenToString( EMT.TLEN, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( ChSawLen, 3) + ParkLine( 'M992 P1=101' .. sData) + ParkLine( 'M992 P1=102' .. sData) + ParkLine( 'M992 P1=103' .. sData) + ParkLine( 'M992 P1=104' .. sData) + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + --EmtOutput( '(Disposition '..EMT.DISPIND..' = '..EMT.DISPID..')') + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') + EMT.YPOS = EgtGetInfo( EMT.DISPID, 'YPOS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- terminazione lista utensili + ParkLine( 'G990 (Tool List End)') + -- abilito numerazione linee + EMT.NUM = false + EMT.LINENBR = 0 + ParkLine( 'M28') + -- emissione dati di macchina + local sOut = 'M114'..' P1='..EmtLenToString( LoadT, 2)..' P2='..EmtLenToString( MinY, 2)..' P3='..EmtLenToString( MaxY, 2).. + ' P4='..EmtLenToString( MinV, 2)..' P5='..EmtLenToString( MaxV, 2)..' P6='..EmtLenToString( MillOffs, 2).. + ' P7='..EmtLenToString( SawOffs, 2)..' P8='..EmtLenToString( ParkY, 2)..' P9='..EmtLenToString( ParkV, 2).. + ' P10='..EmtLenToString( TurnerOffs, 2)..' P11='..EmtLenToString( -DeltaTabY, 2)..' P12='..EmtLenToString( DeltaTabZ - MillOffs, 2) + ParkLine( sOut) + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + if IsEnd2Phase( EMT.PHASE - 1) then + EMT.RELOAD = true + EMT.RELOAD2 = false + elseif IsStartPhase( EMT.PHASE) then + EMT.YDELTA = EMT.YPOS - LoadT + EMT.VDELTA = nil + end + end +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- reset recupero sovramateriale in X non più presente + EMT.X_OFF = nil + -- gruppo con info da BTL (se mancano prova dal gruppo di lavoro corrente) + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or EgtGetCurrMachGroup() or GDB_ID.NULL + -- dati del grezzo + local LBarra = EMT.LB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- calcolo dati pinze + local MinAccPinze = 0.3 + local MaxAccPinze = 4 + local KgMtCubo= 550 -- densità legno in Kg / metro cubo + local Massa = ( HTrave * STrave * LBarra * KgMtCubo ) / 1000000000 + local FMaxPinze = EMT.FMAXPINZE + local ForzaAtrito = 700 / 2 -- Serve per regolare P32 (700 valore reale pistone) + local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAtrito) / 1000) + if ( TempoAcc < MinAccPinze) then TempoAcc = MinAccPinze end + if ( TempoAcc > MaxAccPinze) then TempoAcc = MaxAccPinze end + local AccPinze = FMaxPinze / ( 60 * TempoAcc) + local RidFeed = 100 / Massa * 100 + if ( RidFeed > 100) then RidFeed = 100 end + if IdTrave >= 0 then + local sPrt = '( *** Part '.. EgtNumToString( IdTrave, 0) ..' ***)' + local sOut = '( SN=' .. IdTrave .. ' LBarra=' .. EmtLenToString( LBarra, 3) .. ' L='..EmtLenToString( LTrave, 3) .. + ' H=' .. EmtLenToString( HTrave, 3) .. ' S=' .. EmtLenToString( STrave, 3) .. ' )' + EMT.PRODID = EgtGetInfo( BtlInfoId, 'PRODID', 'i') or 0 + EMT.PATTID = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 0 + EMT.CUTID = EgtGetInfo( EMT.IDT, 'CUTID', 'i') or 0 + local sStart = 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=1' + if EMT.LOAD then + ParkLine( sPrt) + ParkLine( sOut) + if not TEST_USE then ParkLine( sStart) end + else + EmtOutput( sPrt) + EmtOutput( sOut) + if not TEST_USE then EmtOutput( sStart) end + end + else + EmtOutput( '(REMAIN UNLOAD)') + EMT.PRODID = nil + EMT.PATTID = nil + EMT.CUTID = nil + end + -- se carico barra + if EMT.LOAD or EMT.RELOAD then + local nLoad90 = EgtGetInfo( BtlInfoId, 'LOAD90', 'i') or 0 + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( HTrave, 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( nLoad90) .. ' P6=' .. EmtLenToString( LTrave, 2) + if EMT.LOAD then + ParkLine( sOut) + SetStartValue( 1, LBarra) + SetStartValue( 2, HTrave) + SetStartValue( 3, STrave) + SetStartValue( 6, HOverM) + else + EmtOutput( sOut) + end + -- altrimenti recupero rimanenza + else + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( HTrave, 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( 0) .. ' P6=' .. EmtLenToString( EgtIf( IdTrave >= 0, LTrave, LBarra), 2) + EmtOutput( sOut) + EmtOutput( 'M112'..' P1='..EmtLenToString( LoadT, 3).. ' P5=1 P6='..EmtLenToString( EMT.YPOS, 3)..' P7='..EmtLenToString( ParkV, 3) ..' P9='..GetFmaxClamp()) + -- aggiorno dati aggancio carrelli alla trave + EMT.YDELTA = EMT.YPOS - LoadT + EMT.VDELTA = nil + end + -- eventuale preparazione per rotazione immediata + if IsStartPhase( EMT.PHASE) and EMT.AUXSTR then + -- emissione movimento carrelli per rotazione + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmtOutput( '( ** Rotation ** )') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se rotazioni diverse, emetto il comando e aggiorno lo stato + if VerifyEmitRotation() then + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- se altrimenti disposizione intermedia speciale con eventuale rotazione + elseif IsMid2Phase( EMT.PHASE) then + -- emissione movimento carrelli + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmtOutput( '( ** Rotation ** )') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + -- se rotazioni diverse, emetto il comando e aggiorno lo stato + if VerifyEmitRotation() then + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + EmtOutput( '( ** Unload ** )') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'M111 P1=22') + -- se dopo c'è scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE + 1) then + EmtOutput( 'M111 P1=32') + else + EmtOutput( EgtIf( EMT.U_STD, ';', '')..'M111 P1=32') + end + -- emissione conclusione pezzo precedente (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + EmtOutput( sEnd) + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + end + + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- se primo grezzo, reset lunghezza barra + if EMT.RAWIND == 1 then EMT.LB = 0 end + -- aggiungo la lunghezza del grezzo (solo se movimento in corner) + if EMT.RAWTYPE == 1 then + local b3Raw = EgtGetBBoxGlob( EgtGetFirstNameInGroup( EMT.RAWID, 'RawSolid'), GDB_BB.STANDARD) + local LBarra = b3Raw:getDimX() + EMT.LB = EMT.LB + LBarra + end + -- se primo grezzo, calcolo dati del pezzo + if EMT.RAWIND == 1 then + local PartId = EgtGetFirstPartInRawPart( EMT.RAWID) + if PartId then + EMT.IDT = PartId + EMT.IT = EgtGetInfo( PartId, 'PDN', 'i') or 0 + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box'), GDB_BB.STANDARD) + EMT.LT = b3Part:getDimX() + EMT.HT = b3Part:getDimY() + EMT.ST = b3Part:getDimZ() + EMT.HOVM = EgtGetInfo( EMT.RAWID, 'HOVM', 'd') or 0 + else + EMT.IDT = GDB_ID.NULL + EMT.IT = -1 + EMT.LT = 0 + EMT.HT = EMT.HT or 0 + EMT.ST = EMT.ST or 0 + EMT.HOVM = 0 + end + end + end +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOOLSEL = EMT.TCPOS..' M06' + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + --EMT.MCHNAME = EgtGetMachiningParam( MCH_MP.NAME) + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) + -- la speed della lama va moltiplicata per 6 + if EMT.EXIT == 2 then + EMT.S = EMT.S * 6 + end +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + --EmtOutput( ';Mach End') + -- Emissione split + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmtOutput( '( ** Split ** )') + elseif EMT.AUXTYPE == 'U' then + if not EMT.ZMAX then + EmitZmax() + end + EmtOutput( '( ** Unload ** )') + elseif EMT.AUXTYPE == 'P' then + if EMT.PREROT then + EmitZmax() + EmtOutput( '( ** Rotation ** )') + elseif EMT.FALL then + if not EMT.ZMAX then + EmitZmax() + end + EmtOutput( '( ** Fall ** )') + else + EmitZmax() + EmtOutput( '( ** Split 2 ** )') + end + end + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + elseif EMT.AUXTYPE == 'U' then + local sP1x = EgtIf( EMT.CHY_ON, '0', '2') + EmtOutput( 'M111 P1=2'..sP1x) + -- se dopo cè scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE +1) then + EmtOutput( 'M111 P1=3'..sP1x) + else + EmtOutput( EgtIf( EMT.U_STD, ';', '')..'M111 P1=3'..sP1x) + end + -- emissione conclusione pezzo precedente (se non è modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + EmtOutput( sEnd) + end + elseif EMT.AUXTYPE == 'P' then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + if EMT.FALL then + EmtOutput( 'M155') + -- emissione conclusione pezzo (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + EmtOutput( sEnd) + end + elseif not EMT.PREROT then + EmtOutput( 'M77') + end + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.U_STD = nil + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStart() + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + EMT.MCHFIRSTFEED = true + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + if not EMT.ZMAX then + EmtOutput( 'G27') + EmtOutput( 'M6 T000000') + EmtOutput( 'M99') + end + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + + -- se richiesto, preparo il carico barra + if EMT.LOAD or EMT.RELOAD then + PrepareLoad( EMT.AUX, true) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( EMT.AUX) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnPathEndAux() + --EgtOutLog( 'OnPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif EgtGetInfo( EMT.DISPID, 'TYPE') == 'REST' then + EMT.AUXTYPE = 'R' + else + EMT.AUXTYPE = 'P' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'P' + if Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.FALL = true + end + end + elseif EMT.AUXTYPE == 'P' then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.CHY_ON = true + EMT.AUXTYPE = 'U' + end + end + end + -- preparo a seconda del tipo + if EMT.AUXTYPE == 'R' then + -- per il carico della rimanenza dopo rotazione speciale + if EMT.RELOAD and not EMT.RELOAD2 then + PrepareLoad( EMT.AUX, false) + -- per lo scarico della rimanenza + else + PrepareResidue( EMT.AUX) + end + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnRapid() + MyBackupAxes() + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + -- decido se muovere prima testa o carrelli (standard prima testa) + local bHeadFirst = true + if not ( EMT.LOAD or EMT.RELOAD) and not EMT.ZMAX then + local DeltaT = EMT.L1 - EMT.TLAST + if ( DeltaT < -GEO.EPS_SMALL and EMT.VDELTA) or ( DeltaT > GEO.EPS_SMALL and EMT.YDELTA) then bHeadFirst = false end + end + -- sistemo movimenti + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + if not ( EMT.LOAD or EMT.RELOAD) then + if not EMT.ZMAX and #EMT.AUXSTR > 0 then + EmitZmax() + end + end + if not EMT.LOAD then + local sOut = string.gsub( string.gsub( EMT.MCHNAME..'/'..EMT.TOOL, '%(', '['), '%)', ']') + EmtOutput( '( * ' .. sOut .. ' * )') + end + -- primo posizionamento + EmtResetPrev() + local bZmax = ( #EMT.AUXSTR > 0 or EMT.TOOL ~= EMT.PREVTOOL or EMT.L3 > -1) + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H2', 1, 6) + local sOut = 'M101 P1=1' .. ' P2=' .. EmtLenToString( EMT.L2, 3) .. ' P3=' .. EmtLenToString( EMT.L3, 3) .. + ' P4=' .. EgtNumToString( EMT.R2, 3) .. ' P5=' .. EgtNumToString( EMT.R1, 3) .. + ' P6=' .. AdjustTcPos( false) .. ' P7=' .. EgtNumToString( Speed, 0) .. + ' P8=0' .. ' P9=0' .. ' P10=' .. EgtIf( bZmax, '3', '4') + if EMT.ST > BeamHeightForFixRot then + sOut = sOut .. ' P12=1' + end + if EMT.LOAD then + ParkLine( sOut) + else + EmtOutput( sOut) + end + sOut = 'M101 P1=2' + if EMT.LOAD then + ParkLine( sOut) + else + if bHeadFirst then EmtOutput( sOut) end + end + -- se prima lavorazione + if EMT.LOAD then + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + local bOnlyCharY = true + for i = 1, #EMT.AUXSTR do + ParkLine( EMT.AUXSTR[i]) + if string.find( EMT.AUXSTR[i], 'P1=10', 1, true) then bOnlyCharY = false end + end + EMT.AUXSTR = {} + sOut = EgtIf( bOnlyCharY, 'M111 P1=21', 'M111 P1=20') + ParkLine( sOut) + sOut = EgtIf( bOnlyCharY, 'M111 P1=31', 'M111 P1=30') + ParkLine( sOut) + sOut = string.gsub( string.gsub( EMT.MCHNAME..'/'..EMT.TOOL, '%(', '['), '%)', ']') + ParkLine( '( * ' .. sOut ..' * )') + sOut = 'M101 P1=3' + ParkLine( sOut) + local sY, sA + if EMT.YDELTA then + sY = EmtLenToString( EMT.L1 + EMT.YDELTA) + sA = '1' + else + sY = EmtLenToString( ParkY) + sA = '2' + end + local sV, sB + if EMT.VDELTA then + sV = EmtLenToString( EMT.L1 + EMT.VDELTA) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + sOut = 'M112 P1='..EmtLenToString( EMT.L1, 3)..' P3='..sA..' P4='..sB..' P5=0 P6='..sY..' P7='..sV..' P9='..GetFmaxClamp() + ParkLine( sOut) + EMT.LOAD = false + -- emissione prime linee speciali e linee parcheggiate + EmitStartValues() + EmtOutput( ';LISTA = ' .. tostring( EMT.PRODID)) + EmitParkedLines() + -- altrimenti lavorazione successiva + else + -- eventuale G111 + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if not ( EMT.POSTROT or EMT.RELOAD) then + EmtOutput( 'M111 P1=20') + EmtOutput( 'M111 P1=30') + else + EmtOutput( 'M111 P1=21') + EmtOutput( 'M111 P1=31') + end + end + EMT.AUXSTR = {} + local sY, sA + if EMT.YDELTA then + sY = EmtLenToString( EMT.L1 + EMT.YDELTA - ( EMT.X_OFF or 0)) + sA = '1' + else + sY = EmtLenToString( EgtIf( EMT.YPOS, EMT.YPOS, ParkY)) + sA = '2' + end + local sV, sB + if EMT.VDELTA then + sV = EmtLenToString( EMT.L1 + EMT.VDELTA - ( EMT.X_OFF or 0)) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + -- se taglio di coda senza residuo da scaricare, emetto M175 per accelerare il carico della barra successiva + if EMT.MCHUSERNOTES and EMT.MCHUSERNOTES:find( 'Cut') then + EmtOutput( 'M175') + end + if bHeadFirst then + sOut = 'M101 P1=3' + EmtOutput( sOut) + end + sOut = 'M112 P1=' .. EmtLenToString( EMT.L1, 3) ..' P3='..sA..' P4='..sB..' P6='..sY..' P7='..sV..' P9=' .. GetFmaxClamp() + EmtOutput( sOut) + if not bHeadFirst then + sOut = 'M101 P1=2' + EmtOutput( sOut) + sOut = 'M101 P1=3' + EmtOutput( sOut) + end + EMT.POSTROT = false + EMT.RELOAD = false + EMT.RELOAD2 = nil + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se alto in Z (non serve l'avvicinamento finale) + if EMT.FLAG == 2 then + -- aggiorno valori come precedenti + EMT.TLAST = EMT.L1b + EmtUpdatePrev() + return + -- altrimenti ripristino i valori originali degli assi + else + MyRestoreAxes() + end + end + -- se standard + if EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EmtOutput( 'M102 P1=' .. GetFaceCode()) + EmtOutput( 'M98') + sOut = 'M6 T1' .. EgtIf( EMT.HEAD == 'H1' or EMT.HEAD == 'H3', '01', '02') .. AdjustTcPos( true) + EmtOutput( sOut) + EmtOutput( 'G24' .. EMT.IPLGLSTR) + -- forzo successiva emissione assi rotanti + EMT.R1p = nil + EMT.R2p = nil + else + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + end + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmitZmax( true) + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- se altrimenti rotazione a Z max + elseif EMT.FLAG == 5 then + -- viene gestito all'inizio della lavorazione successiva + -- altrimenti errore + else + error( "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EMT.TLAST = EMT.L1b + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + MyBackupAxes() + EMT.TLAST = EMT.L1 + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente (se presente devo annullare l'offset in X per sovramateriale di testa) + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + if EMT.X_OFF then EMT.L1 = EMT.L1 - EMT.X_OFF end + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EmtOutput( 'M102 P1=' .. GetFaceCode()) + EmtOutput( 'M98') + local sPos = EMT.TCPOS:gsub( 'T', '') + if #sPos == 1 then + sPos = '00' .. sPos + elseif #sPos == 2 then + sPos = '0' .. sPos + elseif sPos == '101' and abs( EMT.R3 - 90) < 0.1 then + sPos = '104' + end + sOut = 'M6 T1' .. EgtIf( EMT.HEAD == 'H1' or EMT.HEAD == 'H3', '01', '02') .. sPos + EmtOutput( sOut) + EmtOutput( 'G24' .. EMT.IPLGLSTR) + -- emissione movimento + EMT.R1p = nil + EMT.R2p = nil + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + EmtOutput( 'M97') + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- aggiungo feed + local sFeed = EmtGetFeed() + -- emetto linea + EmtOutput( "G1"..sAxes..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + MyBackupAxes() + EMT.TLAST = EMT.L1 + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + EmtOutput( 'M97') + end + + -- non modale su archi + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString( EMT.RR, EMT.DECNUM) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- emetto arco + EmtOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd, bSkipPress) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + elseif sCmd == '1' then + return '2' + -- chiuso con pressore attivato + elseif sCmd == '2' then + return EgtIf( bSkipPress, '2', '0') + end +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd, bStart) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = ' P4=111' + EMT.SB = ' P5=112' + EMT.SC = ' P6=141' + EMT.SD = ' P7=141' + EMT.SE = ' P8=0' + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + if bStart then + EMT.RELOAD = false + else + EMT.RELOAD2 = true + end + for i = 1, #EMT.AUXSTR do + EMT.AUXSTR[i] = string.gsub( EMT.AUXSTR[i], 'P1=11', 'P1=10') + end + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..sPar2..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.YPOS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sYTaking = ' P2='..EmtLenToString( Cmd[3] + TurnerOffs) + local sOut = 'M111 P1=11' .. sYTaking .. ' P4=75 P5=110 P8=0 P9=' .. GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + SetStartValue( 4, Cmd[3] + TurnerOffs) + SetStartValue( 5, 110) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sPar6 = EgtIf( Cmd[6] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', sPar6 .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2]) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2]) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + if not FindM111P4EQ76( EMT.AUXSTR) then + local sYLoad = ' P2=' .. EmtLenToString( LoadT) + local sOut = 'M111 P1=11' .. sYLoad .. ' P4=76 P5=110 P8=0 P9=' .. GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = EgtIf( EMT.YDELTA, ' P4=112', ' P4=111') + EMT.SB = EgtIf( EMT.YDELTA, ' P5=112', ' P5=111') + EMT.SC = EgtIf( EMT.VDELTA, ' P6=142', ' P6=141') + EMT.SD = EgtIf( EMT.VDELTA, ' P7=142', ' P7=141') + EMT.SE = EgtIf( EMT.YDELTA, ' P8=1', ' P8=2') + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..sPar2..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.YPOS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sPar6 = EgtIf( Cmd[6] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', sPar6 .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2]) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2]) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd) + + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.YDELTA, ' P4=112', ' P4=111') + EMT.SB = EgtIf( EMT.YDELTA, ' P5=112', ' P5=111') + EMT.SC = EgtIf( EMT.VDELTA, ' P6=142', ' P6=141') + EMT.SD = EgtIf( EMT.VDELTA, ' P7=142', ' P7=141') + EMT.SE = EgtIf( EMT.YDELTA, ' P8=1', ' P8=2') + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + if not EMT.UNL then + sOut = 'M111 P1=10'..sPar2..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + else + sOut = 'M111 P1=10'..sPar2..Cmd[3]..' P6=141 P7=84 P8=0 P9='..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sPar2 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + local sPar4 = EgtIf( Cmd[4] == 'Y', ' P2=', ' P3=') + local sPar6 = EgtIf( Cmd[6] == 'Y', ' P2=', ' P3=') + local sOut = 'M111 P1=10'..(EgtIf( Cmd[2] ~= 'T', sPar2 .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', sPar4 .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', sPar6 .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sOut = 'M111 P1=10'..' P2='..Cmd[3]..' P4=112 P5=112 P6=142 P7=142 P8=2 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.YPOS = tonumber( Cmd[3]) + end + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd) + + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sP1 = EgtIf( EMT.CHY_ON, '10', '12') + local sP7 = '84' + if not EMT.U_STD then + sP7 = EgtIf( EMT.U_MAN ~= 1, '85', '114') + EMT.U_MAN = EgtIf( EMT.U_MAN == 1, nil, 1) + end + local sP8 = EgtIf( EMT.PHASE == EgtGetPhaseCount() or IsEnd2Phase( EMT.PHASE), '0', '1') + local sOut = 'M111 P1='..sP1..' P3='..Cmd[3]..' P6=141 P7='..sP7..' P8='..sP8..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[4] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sP1 = EgtIf( EMT.CHY_ON, '10', '12') + local sP45 = EgtIf( EMT.PHASE == EgtGetPhaseCount() or IsEnd2Phase( EMT.PHASE), '111', '112') + local sOut = 'M111 P1='..sP1..' P3='..Cmd[5]..' P4=' .. sP45 .. ' P5=' .. sP45 .. ' P6=142 P7=141 P8=2 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.U_STD = true + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. EgtIf( Cmd[2] == '0', ' 0', ' 1') + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. EgtIf( Cmd[2] == '0', ' 0', ' 1') + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + -- non interessa + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.YDELTA, ' P4=112', ' P4=111') + EMT.SB = EgtIf( EMT.YDELTA, ' P5=112', ' P5=111') + EMT.SC = EgtIf( EMT.VDELTA, ' P6=142', ' P6=141') + EMT.SD = EgtIf( EMT.VDELTA, ' P7=142', ' P7=141') + EMT.SE = EgtIf( EMT.YDELTA, ' P8=1', ' P8=2') + end + -- se è pre-rotazione + if Cmd[2] == 'Pre-Rotation' then + EMT.PREROT = true + elseif Cmd[2] == 'SplitRot' then + EMT.SPLITROT = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + local sP23 = EgtIf( Cmd[2] == 'Y', ' P2=', ' P3=') + if not EMT.PREROT then + sOut = 'M111'..' P1=10'..sP23..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + else + sOut = 'M111 P1=10'..sP23..Cmd[3]..' P4=86 P5=87 P6=141 P8=0 P9='..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sP2 = '' + local sP3 = '' + if Cmd[2] == 'Y' then + sP2 = ' P2=' .. Cmd[3] + elseif Cmd[4] == 'Y' then + sP2 = ' P2=' .. Cmd[5] + end + if Cmd[2] == 'V' then + sP3 = ' P3=' .. Cmd[3] + elseif Cmd[4] == 'V' then + sP3 = ' P3=' .. Cmd[5] + end + local sOut = 'M111 P1=10'..sP2..sP3..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sP2 = '' + local sP3 = '' + if Cmd[2] == 'Y' then + sP2 = ' P2=' .. Cmd[3] + elseif Cmd[4] == 'Y' then + sP2 = ' P2=' .. Cmd[5] + elseif Cmd[6] == 'Y' then + sP2 = ' P2=' .. Cmd[7] + end + if Cmd[2] == 'V' then + sP3 = ' P3=' .. Cmd[3] + elseif Cmd[4] == 'V' then + sP3 = ' P3=' .. Cmd[5] + elseif Cmd[6] == 'V' then + sP3 = ' P3=' .. Cmd[7] + end + local sOut = 'M111 P1=10'..sP2..sP3..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..' P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P5=11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + if EMT.SPLITROT then + EMT.SA = EgtIf( Cmd[2] ~= '0', ' P4=11' .. CalcCharStatus( Cmd[2], true), ' P4=86') + EMT.SB = EgtIf( Cmd[2] ~= '0', ' P5=11' .. CalcCharStatus( Cmd[2], true), ' P5=87') + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + else + EMT.SA = ' P4=11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=1', ' P8=2') + end + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = ' P7=14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = ' P6=14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = ' P7=14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', ' P8=2', ' P8=1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = ' P5=112' + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + EMT.POSTROT = false + for i = 1, #EMT.AUXSTR do + EMT.AUXSTR[i] = string.gsub( EMT.AUXSTR[i], 'P1=11', 'P1=10') + end + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + -- su NUM si pone E80058=0, con TPA non sembra necessaria una equivalente impostazione + local sYTaking = ' P2='..EmtLenToString( Cmd[3] - EMT.HOVM) + local sOut = 'M111 P1=11'..sYTaking..' P4=75 P5=112 P8=0 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = ' P5=11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + local sYLoad = ' P2='..EmtLenToString( LoadT) + local sOut = 'M111 P1=11'..sYLoad..' P4=76'..EMT.SB..' P8=0 P9='..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function MyBackupAxes() + EMT.L1b = EMT.L1 + EMT.L2b = EMT.L2 + EMT.L3b = EMT.L3 + EMT.R1b = EMT.R1 + EMT.R2b = EMT.R2 + EMT.R3b = EMT.R3 + EMT.R4b = EMT.R4 + EMT.RRb = EMT.RR + EMT.C1b = EMT.C1 + EMT.C2b = EMT.C2 + EMT.C3b = EMT.C3 +end + +--------------------------------------------------------------------- +function MyRestoreAxes() + EMT.L1 = EMT.L1b + EMT.L2 = EMT.L2b + EMT.L3 = EMT.L3b + EMT.R1 = EMT.R1b + EMT.R2 = EMT.R2b + EMT.R3 = EMT.R3b + EMT.R4 = EMT.R4b + EMT.RR = EMT.RRb + EMT.C1 = EMT.C1b + EMT.C2 = EMT.C2b + EMT.C3 = EMT.C3b +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + if EMT.REFLOC then + local vtE + if EMT.HEAD ~= 'H3' then + local Len = EMT.TLEN + EgtIf( EMT.HEAD == 'H1', MillOffs, abs( SawOffs)) + local LenRef = MillOffs + vtE = Vector3d( EMT.EXTR) * Len - Z_AX() * LenRef + else + local Len = ChSawLen + MillOffs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + vtE = Vector3d( vtAux) * Len - Z_AX() * LenRef + end + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - DeltaTabY - vtE:getY() + EMT.L3 = EMT.L3 - DeltaTabZ - vtE:getZ() + end + + if EMT.X_OFF then EMT.L1 = EMT.L1 + EMT.X_OFF end + + EmtAdjustLinearAxes() + + if not EMT.REFLOC then + EMT.L2 = -EMT.L2 + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function AdjustTcPos( bLen3) + local sPos = EMT.TCPOS:gsub( 'T', '') + if bLen3 then + if #sPos == 1 then + sPos = '00' .. sPos + elseif #sPos == 2 then + sPos = '0' .. sPos + end + end + if sPos == '101' then + if abs( EMT.R3 - 0) < 0.1 then + sPos = '101' + elseif abs( EMT.R3 - 270) < 0.1 then + sPos = '102' + elseif abs( EMT.R3 - 180) < 0.1 then + sPos = '103' + elseif abs( EMT.R3 - 90) < 0.1 then + sPos = '104' + else + EmtSetLastError( 1210, 'Chain saw orientation not allowed') + end + end + return sPos +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + LoadT + if EMT.X_OFF then xS = xS + EMT.X_OFF end + local ptS = Point3d( xS, 0, 0) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H3' then + vtE = Vector3d( EMT.EXTR) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --EmtOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local vtX = EMT.IPLGLFR:getVersX() + local vtY = EMT.IPLGLFR:getVersY() + local vtZ = EMT.IPLGLFR:getVersZ() + EMT.IPLGLSTR = ' X0 Y' .. EmtLenToString( xS, EMT.DECNUM) .. ' Z0' .. + ' A' .. EgtNumToString( - vtX:getY(), 6) .. ' B' .. EgtNumToString( vtX:getX(), 6) .. ' C' .. EgtNumToString( vtX:getZ(), 6) .. + ' I' .. EgtNumToString( - vtY:getY(), 6) .. ' J' .. EgtNumToString( vtY:getX(), 6) .. ' K' .. EgtNumToString( vtY:getZ(), 6) .. + ' P' .. EgtNumToString( - vtZ:getY(), 6) .. ' Q' .. EgtNumToString( vtZ:getX(), 6) .. ' R' .. EgtNumToString( vtZ:getZ(), 6) + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function VerifyEmitRotation() + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- se sono uguali non devo fare alcunchè + if nRot == nPrevRot then + return false + end + -- rotazione automatica o manuale (sempre con il medesimo comando) + local nDeltaRot = nRot - nPrevRot + local sOut = 'M180 P1=' .. tostring( nDeltaRot) + EmtOutput( sOut) + return true +end + +--------------------------------------------------------------------- +function GetFaceCode() + if EMT.YDELTA and EMT.VDELTA then + return '3' + elseif EMT.YDELTA then + return '6' + else + return '5' + end +end + +--------------------------------------------------------------------- +function EmitZmax( bReset) + if bReset then + EmtOutput( 'G27') + EmtOutput( 'M6 T000000') + EmtOutput( 'M99') + end + EmtOutput( 'M116') +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE / 1000, 0) +end + +--------------------------------------------------------------------- +function FindM111P4EQ76( vStr) + for i = 1, #vStr do + if vStr[i]:find( 'M111', 1, true) and vStr[i]:find( 'P4=76', 1, true) then + return true + end + end + return false +end + +--------------------------------------------------------------------- +local ParkedLines = {} + +--------------------------------------------------------------------- +function ParkLine( sLine) + table.insert( ParkedLines, sLine) +end + +--------------------------------------------------------------------- +function EmitParkedLines() + for i = 1, #ParkedLines do + EmtOutput( ParkedLines[i]) + end + ParkedLines = {} +end + +--------------------------------------------------------------------- +local StartValues = {} + +--------------------------------------------------------------------- +function SetStartValue( nI, dVal) + StartValues[nI] = dVal +end + +--------------------------------------------------------------------- +function EmitStartValues() + local sLine = '' + for i = 1, 10 do + sLine = sLine .. string.format( ';V%02d=', i) .. EgtNumToString( StartValues[i] or 0, 3) + end + EmtOutput( sLine) +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.ini b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.ini new file mode 100644 index 0000000..70e4d56 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.ini @@ -0,0 +1,58 @@ +; Commento per evitare BOM con UTF-8 +[General] +Material=Beam + +[Tools] +Drillbit=1 +Sawblade=1 +Mill=1 +Mortise=1 +Chisel=0 +DrillMaker=MakeWoodDrill.lua +SawbladeMaker=MakeSawblade.lua +MillMaker=MakeWoodCylMill.lua +MortiseMaker=MakeMortise.lua +ChiselMaker=MakeChisel.lua +Active=1 + +[ToolHolder] +H1.1=Standard.nge +H1.1:MILL_NOTIP=MillNoTip.nge +H2.1=Saw.nge +H3.1=ChainSaw.nge + +[Machinings] +Drilling=1 +Sawing=1 +Milling=1 +Pocketing=1 +Mortising=1 +Chiseling=0 +SawRoughing=0 +SawFinishing=0 + +[Machining] +InitScript=InitMach.lua +ExitScript=ExitMach.lua + +[Disposition] +;InitScript=InitDisp.lua + +[Heads] +; 5 axis head +H1=6608 +; 5 axis saw +H2=6615 +; Chainsaw +H3=6616 + +[SetUp] +Default=Standard + +[Estimations] +Enable=1 +WinPlace=0,458,111,669,906 + +[VMill] +Enable=1 +Save=0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.mlde b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.mlde new file mode 100644 index 0000000..814dab1 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.mlde @@ -0,0 +1,471 @@ +-- Descrizione macchina Essetre-FAST by EgalTech s.r.l. 2021/07/13 + +require( 'EmtGenerator') +EgtEnableDebug( false) + +PP_VER = '2.3g2' + +-- Parametri macchina +NumericalControl = 'TPA' -- NUM o TPA +MinX = -1350 +MaxX = 0 +MinZ = -1350 +MaxZ = 0 +MinB = -180 +MaxB = 360 +MinC = -360 +MaxC = 360 +MinY = 110.0 +MaxY = 3760.0 +ParkY = 480.0 +MinV = -3760.0 +MaxV = -110.0 +ParkV = -480.0 +LoadT = 1454.2 +UnloadT = -1700 +MaxOpen = 305 +MillOffs = 177.35 +SawOffs = -242.68 +SawBOffs = 0 +SawCOffs = 0 +ChSawLen = 90.0 +TurnerOffs = 200.0 +DeltaTabY = -898.0 +DeltaTabZ = -1017.8 + MillOffs -- per TPA : -1013.3 + MillOffs -- per NUM : -838.4 +DimTabY = 400 +DimTabX = 24000 +LenToPress = 900 +StartRotation = true +AutomaticRotation = true +AutoRotMinLen = 2600 +DefTcPos = 'T2' +SecondSupport = false +MaxUnloadLen = 0 +BeamHeightForFixRot = 9999 -- per abilitare assegnare 500 +CoeffVM = 0.5 + +-- Aggiornamento con dati da BeamData.lua +local sBeamData = EgtGetSourceDir().."\\Beam\\BeamData.lua" +if EgtExistsFile( sBeamData) then + local BD = dofile( sBeamData) + if BD then + BeamHeightForFixRot = BD.MAX_HEIGHT_ROT_B_ABOVE or BeamHeightForFixRot + end +end + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Beam', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-Fastrl.data" +local sData = EgtGetSourceDir().."\\Beam\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Offsets then + NumericalControl = EgtIf( Machine.Offsets.TIPO_CN == 0, 'NUM', 'TPA') + if Machine.Offsets.MIN_X then MaxX = -Machine.Offsets.MIN_X end + if Machine.Offsets.MAX_X then MinX = -Machine.Offsets.MAX_X end + MinZ = Machine.Offsets.MIN_Z or MinZ + MaxZ = Machine.Offsets.MAX_Z or MaxZ + MinB = Machine.Offsets.MIN_B or MinB + MaxB = Machine.Offsets.MAX_B or MaxB + MinC = Machine.Offsets.MIN_C or MinC + MaxC = Machine.Offsets.MAX_C or MaxC + MinY = Machine.Offsets.MIN_Y or Machine.Offsets.MINY or MinY + MaxY = Machine.Offsets.MAX_Y or Machine.Offsets.MAXY or MaxY + ParkY = Machine.Offsets.PARKYY or ParkY + MinV = Machine.Offsets.MIN_V or Machine.Offsets.MINV or MinV + MaxV = Machine.Offsets.MAX_V or Machine.Offsets.MAXV or MaxV + ParkV = Machine.Offsets.PARKVV or ParkV + if Machine.Offsets.YCARICO then LoadT = - Machine.Offsets.YCARICO end + if Machine.Offsets.YSCARICO then UnloadT = - Machine.Offsets.YSCARICO end + if Machine.Offsets.PIVOTFRESA then MillOffs = - Machine.Offsets.PIVOTFRESA end + if Machine.Offsets.PIVOTLAMA then SawOffs = - Machine.Offsets.PIVOTLAMA end + if Machine.Offsets.OFFSETBLAMA then SawBOffs= Machine.Offsets.OFFSETBLAMA end + if Machine.Offsets.OFFSETCLAMA then SawCOffs= Machine.Offsets.OFFSETCLAMA end + TurnerOffs = Machine.Offsets.OFFSETRIB or TurnerOffs + if Machine.Offsets.OFFSETX then DeltaTabY = -Machine.Offsets.OFFSETX end + if Machine.Offsets.OFFSETZ then DeltaTabZ = Machine.Offsets.OFFSETZ + MillOffs end + if Machine.Offsets.SECSUP then SecondSupport = ( Machine.Offsets.SECSUP == 1) end + if Machine.Offsets.NOULOAD then MaxUnloadLen = Machine.Offsets.NOULOAD end + end + end +end + + +EmtGeneral { + File='Essetre-FASTrl.nge', + Offset = Vector3d( 0, -1150.16, -1500.0), + AxisMaxAdjust = 30, + AxisMaxRotAdj = 0.5, + ExitMaxAdjust = 30, + ExitMaxRotAdj = 0.5, + AngDeltaMinForHome = 165, + Special = 'Essetre-FASTrl.mlse', + Processor = 'Essetre-FASTrl.mlpe'} +local BaseId = EmtBase { + Name = 'Base', + Geo='BASE/GEO', + Aux={'BASE/SOLID', 'BASE/TC', 'BASE/SIGN'}} +local XId = EmtAxis { + Name = 'X', + Parent = 'Base', + Invert = true, + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( -639.5, 372.66, 945.7), + Stroke = {MinX, MaxX}, + Home = 0, + Geo = 'X_AXIS/GEO', + Aux = 'X_AXIS/SOLID'} +EmtAxis { + Name = 'Z', + Parent = 'X', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d( -19.25, -113.54, 790.0), + Stroke = {MinZ, MaxZ}, + Home = 0, + Geo = 'Z_AXIS/GEO', + Aux = {'Z_AXIS/SOLID', 'Z_AXIS/COLLISION'}} +EmtAxis { + Name = 'C', + Parent = 'Z', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = {MinC, MaxC}, + Home = 0, + Geo = 'C_AXIS/GEO', + Aux = {'C_AXIS/SOLID', 'C_AXIS/COLLISION'}} +EmtAxis { + Name = 'B', + Parent = 'C', + Type = MCH_AT.ROTARY, + Dir = X_AX(), + Pos = Point3d( 0, 0, MillOffs), + Stroke = {MinB, MaxB}, + Home = 0, + Geo = 'B_AXIS/GEO', + Aux = {'B_AXIS/SOLID', 'B_AXIS/COLLISION'}} +-- Frese +local H1Id = EmtHead { + Name = 'H1', + Parent = 'B', + HSet = 'H1', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, 0), + TDir = Z_AX(), + ADir = X_AX(), + Rot1W = 2, + OthColl = {'H2', 'B/SOLID', 'C/SOLID'}, + Geo = 'H1_HEAD/GEO'} +EgtSetInfo( H1Id, 'ZMAXONROT', '1,60') +if BeamHeightForFixRot < 1000 then + EgtSetInfo( H1Id, 'ROTATZMAX', '1') +end +-- Lama +local H2Id = EmtHead { + Name = 'H2', + Parent = 'B', + HSet = 'H2', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, (MillOffs-SawOffs)), + TDir = Vector3d( 0, -sin( SawBOffs), -cos( SawBOffs)), + ADir = X_AX(), + Rot1W = 0.2, + OthColl = {'H1', 'H3', 'B/SOLID', 'C/SOLID'}, + Geo = 'H2_HEAD/GEO'} +EgtSetInfo( H2Id, 'ZMAXONROT', '1,5') +if BeamHeightForFixRot < 1000 then + EgtSetInfo( H2Id, 'ROTATZMAX', '1') +end +-- Sega a catena +EmtAxis { + Name = 'A', + Parent = 'B', + Token = '**', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = { 0, 270}, + Home = 0, + Geo = 'A_AXIS/GEO'} +local H3Id = EmtHead { + Name = 'H3', + Parent = 'A', + HSet = 'H1', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, -ChSawLen), + TDir = X_AX(), + ADir = Z_AX(), + Rot1W = 0.2, + SolCh = MCH_SCC.ADIR_NEAR, + OthColl = {'H2', 'B/SOLID', 'C/SOLID'}, + Geo = 'H3_HEAD/GEO'} +EgtSetInfo( H3Id, 'ZMAXONROT', '1,5') +if BeamHeightForFixRot < 1000 then + EgtSetInfo( H3Id, 'ROTATZMAX', '1') +end +-- Dummy +EmtHead { + Name = 'H4', + Parent = 'B', + HSet = 'H4', + Type = MCH_HT.STD, + Pos = Point3d( 0, 0, 0), + TDir = Z_AX(), + ADir = X_AX(), + Rot1W = 0.2, + Geo = 'H4_HEAD/GEO'} +-- Morse +local YId = EmtAxis { + Name = 'Y', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d( -953.0, 111.75, 1450.0), + Stroke = { MinY, MaxY}, + Home = ParkY, + Geo = 'Y_AXIS/GEO', + Aux = {'Y_AXIS/SOLID', 'Y_AXIS/COLLISION'}} +local PYId = EmtAxis { + Name = 'PY', + Parent = 'Y', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( -904.0, -276.5, 1449.0), + Stroke = { 0, MaxOpen}, + Home = MaxOpen, + Geo = 'PY_AXIS/GEO', + Aux = {'PY_AXIS/SOLID', 'PY_AXIS/COLLISION'}} +local VId = EmtAxis { + Name = 'V', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d( 953.0, 111.75, 1450.0), + Stroke = { MinV, MaxV}, + Home = ParkV, + Geo = 'V_AXIS/GEO', + Aux = {'V_AXIS/SOLID', 'V_AXIS/COLLISION'}} +local PVId = EmtAxis { + Name = 'PV', + Parent = 'V', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d( 904.0, -276.5, 1449.0), + Stroke = { 0, MaxOpen}, + Home = MaxOpen, + Geo = 'PV_AXIS/GEO', + Aux = {'PV_AXIS/SOLID', 'PV_AXIS/COLLISION'}} +EmtAxis { + Name = 'T', + Parent = 'Base', + --Token = '**', + Type = MCH_AT.LINEAR, + Dir = - X_AX(), + Pos = Point3d( 0, 613.16, -830.037), + Stroke = { -30000, 30000}, + Home = LoadT, + Geo = 'T_AXIS/GEO'} +EmtTable { + Name = 'Tab', + Parent = 'T', + Type = MCH_TT.FLAT, + Ref1 = Point3d( - DimTabX, DeltaTabY, DeltaTabZ), + Geo = 'TABLE/GEO', + Aux = 'TABLE/SOLID'} +-- ToolChanger +EmtTcPos { + Name = 'T1', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, 172.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T1'} +EmtTcPos { + Name = 'T2', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, 67.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T2'} +EmtTcPos { + Name = 'T3', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, -37.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T3'} +EmtTcPos { + Name = 'T4', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, -142.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T4'} +EmtTcPos { + Name = 'T5', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, -247.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T5'} +EmtTcPos { + Name = 'T6', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, -352.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T6'} +EmtTcPos { + Name = 'T7', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, -457.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T7'} +EmtTcPos { + Name = 'T8', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, -562.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T8'} +EmtTcPos { + Name = 'T9', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, -667.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T9'} +EmtTcPos { + Name = 'T10', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, -772.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T10'} +EmtTcPos { + Name = 'T11', + Parent = 'Base', + Pos = Point3d( -523.8, -88.0, -877.5), + TDir = X_AX(), + ADir = Y_AX(), + Geo = 'BASE/T11'} +EmtTcPos { + Name = 'T101', + Parent = 'Base', + Pos = Point3d( 510.4, -113.2, -160.8), + TDir = -X_AX(), + ADir = Z_AX(), + Geo = 'BASE/T101'} +if SecondSupport then + EmtTcPos { + Name = 'T111', + Parent = 'Base', + Pos = Point3d( 510.4, -113.2, -329.8), + TDir = Z_AX(), + ADir = -X_AX(), + Geo = 'BASE/T111'} +end + +-- Aggiusto posizioni geometriche +local vtMove = Vector3d( 0, ( DeltaTabY + 913.16), ( DeltaTabZ + 830.037)) +local vtMoveX = Vector3d( 0, 0, ( DeltaTabZ + 830.037)) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SIGN'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( YId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( YId, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PYId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PYId, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( VId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( VId, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PVId, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PVId, 'COLLISION'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( XId, 'SOLID'), vtMoveX, GDB_RT.GLOB) + +-- Assegno identificativi alle spie delle morse +PYLightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PYId, 'SOLID') or GDB_ID.NULL, 'Light') +PVLightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( PVId, 'SOLID') or GDB_ID.NULL, 'Light') + +--------------------------------------------------------------------- +-- Funzioni richiamate per modificare i dati macchina in casi particolari +--function OnSetTable() +--end + +--------------------------------------------------------------------- +function OnSetHead() + -- se testa lama + if EMC.HEAD == 'H2' then + EmtModifyAxisDirection( 'B', Vector3d( cos( SawCOffs), -sin( SawCOffs), 0)) + -- altrimenti + else + EmtModifyAxisDirection( 'B', X_AX()) + end +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello Y +function SetPYLight( bClosed) + if not PYLightId then return end + EgtSetColor( PYLightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PYLightId, 'On', '1') + else + EgtRemoveInfo( PYLightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello Y +function GetPYLight() + if not PYLightId then return false end + return ( EgtGetInfo( PYLightId, 'On') == '1') +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello V +function SetPVLight( bClosed) + if not PVLightId then return end + EgtSetColor( PVLightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PVLightId, 'On', '1') + else + EgtRemoveInfo( PVLightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello V +function GetPVLight() + if not PVLightId then return false end + return ( EgtGetInfo( PVLightId, 'On') == '1') +end + +--------------------------------------------------------------------- +-- Funzione per resettare tutte le attivazioni della macchina +function OnResetMachine() + EmtUnlinkAllRawPartsFromGroups() + EmtUnlinkAllFixturesFromGroups() + SetPYLight( false) + SetPVLight( false) + -- nascondo Vmill + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nVmId = EgtGetFirstNameInGroup( nRawId, 'VMill') + local nId = EgtGetFirstInGroup( nRawId) + while nId do + EgtSetStatus( nId, EgtIf( nId ~= nVmId, GDB_ST.ON, GDB_ST.OFF)) + nId = EgtGetNext( nId) + end + nRawId = EgtGetNextRawPart( nRawId) + end + EgtSetStatus( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') or GDB_ID.NULL, GDB_ST.OFF) +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.mlpe new file mode 100644 index 0000000..af5fe9b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.mlpe @@ -0,0 +1,1396 @@ +-- Processore macchina Essetre-FAST by EgalTech s.r.l. 2021/07/13 +-- Funzioni generiche indipendenti dal controllo +-- 2020/09/22 DS ver 2.2i4 Distanza di sicurezza per collisioni da 2 a 4mm (inoltre allontanata flangia lama e aggiunto cilindro asse Z) +-- 2020/09/26 DS ver 2.2i5 Gestione cambio presa sega a catena tra due lavorazioni successive. +-- 2020/10/06 DS ver 2.2j1 Punta lunga da togliere basata su sua lunhezza totale e non più su T111. +-- 2021/01/08 DS ver 2.3a1 Gestione utensile di default da posizione e non da nome. +-- 2021/01/24 DS ver 2.3a2 Correzione deposito sega a catena con ripresa della stessa per angola A diverso. +-- 2021/01/31 DS ver 2.3a3 Altre correzioni per sega a catena. +-- 2021/06/28 DS ver 2.3f5 Correzioni per scarico punte lunghe con pezzi alti. +-- 2021/07/12 DS ver 2.3g2 Correzioni per verifica collisioni durante scarico utensili. + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +local sBaseDir = EgtGetSourceDir() +if NumericalControl == 'NUM' then + dofile( sBaseDir .. 'Essetre-FASTrl.NUM.mlpe') +elseif NumericalControl == 'TPA' then + dofile( sBaseDir .. 'Essetre-FASTrl.TPA.mlpe') +else + error( 'Numerical Control error : unkwnown type') +end + +--------------------------------------------------------------------- +-- *** SIMULATION *** +--------------------------------------------------------------------- +local COLL_SAFE_DIST = 3 +local LONG_TOOL_MINLEN = 221 + +--------------------------------------------------------------------- +function OnSimulStart() + -- Carico gli utensili sulle barre portautensili + local vTcPos = EgtGetAllTcPosNames() + if vTcPos then + for i = 1, #vTcPos do + local vTools = EgtGetToolsInCurrSetupPos( vTcPos[i]) + if vTools and vTools[1] then + EgtLoadTool( vTcPos[i], 1, vTools[1]) + ShowToolInTcPos( vTcPos[i], true) + end + end + end + -- Se reset o home, esco + if EMT.SIM1ST then return end + -- Creo o svuoto gruppo per copia finale degli oggetti virtual milling + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + if nVmGrpId then + EgtSetStatus( nVmGrpId, GDB_ST.ON) + EgtEmptyGroup( nVmGrpId) + else + nVmGrpId = EgtGroup( GDB_ID.ROOT) + EgtSetName( nVmGrpId, 'VMill') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + -- Preparo lista oggetti da verificare per collisioni + EMT.COLLOBJ = {} + AddToCollisionCheck( 'Z', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'B', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C', 'COLLISION', EMT.COLLOBJ) + AddToolToCollisionCheck( 'H2', 1, EMT.COLLOBJ) + DumpCollisionCheck( EMT.COLLOBJ, 'Collision Objects :', 4) + -- Preparo lista solidi macchina con cui possono collidere gli oggetti sopra riportati (in aggiunta a VMill) + EMT.MCODET = {} + EMT.MCODET[1] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'VOL1') + EMT.MCODET[2] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Y'), 'COLLISION'), 'VOL2') + EMT.MCODET[3] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PY'), 'COLLISION'), 'VOL') + EMT.MCODET[4] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'V'), 'COLLISION'), 'VOL1') + EMT.MCODET[5] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'V'), 'COLLISION'), 'VOL2') + EMT.MCODET[6] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'PV'), 'COLLISION'), 'VOL') + -- Preparo lista collisioni vuota + EMT.COLLIDE = {} +end + +--------------------------------------------------------------------- +--function OnSimulEnd() +--end + +--------------------------------------------------------------------- +function OnSimulDispositionStarting() + EmtUnlinkAllRawPartsFromGroups() + if EMT.PHASE > 1 then + if IsStartOrRestPhase( EMT.PHASE) then + EgtSetAxisPos( 'T', LoadT) + end + end +end + +--------------------------------------------------------------------- +function OnSimulDispositionStart() + EMT.OPEISDISP = true + + -- Se prima disposizione + if EMT.PHASE == 1 then + -- Determino dimensioni del grezzo + local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL + local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + EMT.LB = 0 + EMT.SB = 0 + EMT.HB = 0 + if b3Sol then + EMT.LB = b3Sol:getDimX() + EMT.SB = b3Sol:getDimY() + EMT.HB = b3Sol:getDimZ() + end + -- Carico primo utensile sulla testa 1 + local sTool, nTlen = FindFirstToolOnHead( 'H1') + if sTool and nTlen < 215.5 then + EMT.TOOL_1 = sTool + else + EMT.TOOL_1 = GetDefaultToolName() + end + EgtLoadTool( 'H1', 1, EMT.TOOL_1) + EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1) + ShowToolInTcPos( EMT.TCPOS_1, false) + EMT.LOAD = true + -- Se vero inizio e abilitato creo gli Zmap + EMT.VMILL = {} + if not EMT.SIM1ST and EgtGetInfo( EgtGetCurrMachGroup(), 'Vm', 'b') then + local nLastOrd = GetPhaseOrd( EgtGetPhaseCount()) + local nPartRawId = EgtGetFirstRawPart() + while nPartRawId do + -- se è lo scarto finale tagliato a pezzi, esco + local nRawOrd = EgtGetInfo( nPartRawId, 'ORD', 'i') + if nRawOrd == nLastOrd + 1 then break end + -- elimino eventuale vecchio Zmap + EgtErase( EgtGetFirstNameInGroup( nPartRawId, 'VMill') or GDB_ID.NULL) + -- recupero il solido + local nSolId = EgtGetFirstNameInGroup( nPartRawId, 'RawSolid') + local b3Raw = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + -- aggiungo eventuale scrap successivo + if nRawOrd == nLastOrd then + local nScrapId = EgtGetNextRawPart( nPartRawId) + if nScrapId then + local nScrapSolId = EgtGetFirstNameInGroup( nScrapId, 'RawSolid') + local b3ScrapRaw = EgtGetBBoxGlob( nScrapSolId, GDB_BB.STANDARD) + if b3ScrapRaw then + b3Raw:Add( b3ScrapRaw) + end + end + end + -- determino la risoluzione dello Zmap + local dArea = b3Raw:getDimX() * b3Raw:getDimY() + b3Raw:getDimX() * b3Raw:getDimZ() + b3Raw:getDimY() * b3Raw:getDimZ() + local dTol = 4.71 + if dArea < CoeffVM * 0.15e6 then + dTol = 0.71 + elseif dArea < CoeffVM * 0.3e6 then + dTol = 1.01 + elseif dArea < CoeffVM * 0.6e6 then + dTol = 1.51 + elseif dArea < CoeffVM * 1.2e6 then + dTol = 1.97 + elseif dArea < CoeffVM * 2.4e6 then + dTol = 2.81 + elseif dArea < CoeffVM * 4.8e6 then + dTol = 3.77 + end + -- creo lo Zmap + local VMillId = EgtVolZmapBox( nPartRawId, b3Raw:getMin(), b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol, true, GDB_RT.GLOB) + if VMillId then + EgtSetName( VMillId, 'VMill') + EgtSetLevel( VMillId, GDB_LV.TEMP) + EgtSetColor( VMillId, EgtGetColor( nSolId), false) + -- nascondo le altre geometrie + local nId = EgtGetFirstInGroup( nPartRawId) + while nId do + if nId ~= VMillId then + EgtSetStatus( nId, GDB_ST.OFF) + end + nId = EgtGetNext( nId) + end + table.insert( EMT.VMILL, VMillId) + end + nPartRawId = EgtGetNextRawPart( nPartRawId) + end + -- imposto eventuale utensile corrente + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + end + -- fasi successive + else + EMT.LOAD = false + end + + -- Nascondo tutte le lavorazioni + local nMchId = EgtGetFirstOperation() + while nMchId do + if EgtGetOperationType( nMchId) ~= MCH_OY.DISP then + EgtSetOperationStatus( nMchId, false) + end + nMchId = EgtGetNextOperation( nMchId) + end + + -- Se fase inizio o rimanenza, aggancio grezzi della fase alla tavola + if IsStartOrRestPhase( EMT.PHASE) then + -- se fase inizio, segnalo giacitura del grezzo + if IsStartPhase( EMT.PHASE) then + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= 0 then + EgtOutText( tostring( -90 * nRot) .. '° rotated bar') + else + EgtOutText( 'Not rotated bar') + end + end + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + local nScrapOrd = GetPhaseOrd( EgtGetPhaseCount()) + 1 + local b3Raw = BBox3d() + local nPartRawId, nScrapRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + b3Raw = EgtGetRawPartBBox( nRawId) + nPartRawId = nRawId + elseif nRawOrd == nOrd + 1 and nRawOrd == nScrapOrd then + local b3Tmp = EgtGetRawPartBBox( nRawId) or BBox3d() + b3Raw:Add( b3Tmp) + nScrapRawId = nRawId + end + end + nRawId = nNextRawId + end + -- gestione eventuale scarto affettato successivo + if EMT.VMILL and #EMT.VMILL > 0 then + EMT.SCRAP = nScrapRawId + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + else + EMT.SCRAP = nil + end + -- recupero CutId del pezzo in lavorazione + EMT.CUTID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + EMT.YSPEC = nil + -- se vero inizio, assegno solidi per verifica collisione + if not EMT.SIM1ST then + EMT.CODET = {} + for i = 1, #( EMT.MCODET or {}) do + EMT.CODET[i] = EMT.MCODET[i] + end + for i = 1, #( EMT.VMILL or {}) do + table.insert( EMT.CODET, EMT.VMILL[i]) + end + end + -- se altrimenti fase intermedia, aggancio grezzi della fase alla tavola + elseif IsMidPhase( EMT.PHASE) then + -- se cambiata giacitura, lo segnalo + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= nPrevRot then + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- eseguo aggancio + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + end + nRawId = nNextRawId + end + -- se Vmill, nascondo eventuale scrap + if EMT.VMILL then + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + end + -- se altrimenti fasi intermedia o finale speciali, aggancio primo grezzo alla tavola e gli altri in posizione pre-carico + elseif IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se cambiata giacitura, lo segnalo + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= nPrevRot then + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + -- ricerco vettore movimento per i successivi + local vtMove = Vector3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then + vtMove = Vector3d( - LoadT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then + EmtLinkRawPartToGroup( nRawId, 'Tab') + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EgtSetStatus( nRawId, GDB_ST.OFF) + end + end + nRawId = nNextRawId + end + -- altrimenti fase finale, aggancio primo grezzo alla tavola e gli altri in posizione carico al carro Y + else + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + -- ricerco vettore movimento per i successivi + local vtMove = Vector3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then + vtMove = Vector3d( - LoadT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then + EmtLinkRawPartToGroup( nRawId, 'Tab') + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EmtLinkRawPartToGroup( nRawId, 'Y') + end + end + nRawId = nNextRawId + end + end + -- Indicazione angolo rotazione pezzo + EMT.ROT = EgtGetInfo( EMT.DISPID, 'ROT', 'i') or 0 + local SignId = EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'SIGN') + EgtSetStatus( EgtGetFirstNameInGroup( SignId, '0'), EgtIf( EMT.ROT == 0, GDB_ST.ON, GDB_ST.OFF)) + EgtSetStatus( EgtGetFirstNameInGroup( SignId, '90'), EgtIf( EMT.ROT == -1, GDB_ST.ON, GDB_ST.OFF)) + EgtSetStatus( EgtGetFirstNameInGroup( SignId, '180'), EgtIf( EMT.ROT == -2, GDB_ST.ON, GDB_ST.OFF)) +end + +--------------------------------------------------------------------- +function OnSimulDispositionEnd() + if EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + end + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnSimulToolSelect( dPosA) + -- se utensile non definito, è disposizione ed esco + if EMT.TOOL == '' then return end + -- recupero dati utensile + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + -- se non è chiamato da altro script (non c'è parametro) + if not dPosA then + -- se attivo Vmill + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + -- se attivo Collision Check + EMT.SAFEDIST = COLL_SAFE_DIST + if EMT.COLLOBJ then + for i, Coll in ipairs( EMT.COLLOBJ) do + EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3) + end + if EMT.HEAD ~= 'H2' then + AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1001) + AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, 1002) + else + AddToolToCollisionObj( nil, 'H1', 1, 1001) + AddToolHolderToCollisionObj( nil, 'H1', 1, 1002) + end + end + -- dichiaro assi ausiliari da visualizzare + EMT.AuxAxes = 2 + EMT.A1n = 'Y' + EMT.A2n = 'V' + end + -- carico utensile se non lama su sua testa o dummy + if EMT.HEAD ~= 'H2' and EMT.HEAD ~= 'H4' then + -- se sega a catena, imposto subito angolo scelto per asse virtuale A + if EMT.HEAD == 'H3' then + if not dPosA then + -- recupero la lavorazione successiva + local NextMchId + if EMT.MCHID then + NextMchId = EgtGetNextActiveOperation( EMT.MCHID) + else + NextMchId = EgtGetFirstActiveOperation() + end + while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do + NextMchId = EgtGetNextActiveOperation( NextMchId) + end + EgtSetCurrMachining( NextMchId) + -- recupero il valore dell'asse virtuale bloccato A + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + dPosA = tonumber( sVal:sub( 3)) + end + -- imposto il valore di A + EgtSetAxisPos( 'A', dPosA) + if abs( dPosA) < 0.1 then + EgtSetAxisPos( 'C', 180) + end + EgtSetAxisPos( 'B', 0) + end + -- breve pausa + EgtPause( 100) + EgtOutText( '') + EMT.TOOL_1 = EMT.TOOL + EMT.TCPOS_1 = EMT.TCPOS + -- lo nascondo sul portautensili + ShowToolInTcPos( EMT.TCPOS, false) + end +end + +--------------------------------------------------------------------- +function OnSimulToolDeselect() + -- se sega a catena o punta lunga, devo cambiare + if EMT.HEAD == 'H3' or ( EMT.HEAD == 'H1' and EMT.TOTLEN > LONG_TOOL_MINLEN) then + EgtOutText( 'Tool change in progress...') + local RapSimStep = 4 * EMT.SIMSTEP + local RapSimRotStep = RapSimStep / 10 + local CollSimRotStep = min( RapSimRotStep, 5) + -- movimento scarico sega a catena + if EMT.HEAD == 'H3' then + local dPosA = EgtGetAxisPos( 'A') + if abs( dPosA) < 0.1 then + SimulMoveAxes( 'B', 0, CollSimRotStep, 'C', 180, CollSimRotStep) + else + SimulMoveAxes( 'B', 0, CollSimRotStep, 'C', 90, CollSimRotStep) + end + SimulMoveAxis( 'X', 0, RapSimStep) + -- movimento scarico punta lunga + else + local dPosB = EgtGetAxisPos( 'B') + local dNewB = EgtIf( dPosB < 0, -90, 90) + SimulMoveAxes( 'B', dPosB, CollSimRotStep, 'C', 180, CollSimRotStep) + SimulMoveAxis( 'X', 0, RapSimStep) + SimulMoveAxis( 'B', 0, CollSimRotStep) + end + -- breve pausa + EgtPause( 100) + -- nascondo utensile su testa e lo visualizzo su TcPos + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF) + ShowToolInTcPos( EMT.TCPOS_1, true) + -- movimento per carico utensile + if EMT.NEXTHEAD ~= 'H3' then + SimulMoveAxes( 'B', 90, RapSimRotStep, 'C', 90, RapSimRotStep) + else + SimulMoveAxes( 'B', 0, RapSimRotStep, 'C', 90, RapSimRotStep) + end + -- se segue lama, carico utensile di default + if EMT.NEXTHEAD == 'H2' then + local sDefTool = GetDefaultToolName() + EgtLoadTool( 'H1', 1, sDefTool) + EMT.TOOL_1 = sDefTool + EMT.TCPOS_1 = GetToolTcPos( EMT.TOOL_1) + -- lo nascondo sul portautensili + ShowToolInTcPos( EMT.TCPOS_1, false) + end + EgtOutText( '') + -- deposito utensile se non lama su sua testa o dummy + elseif EMT.NEXTHEAD ~= 'H2' and EMT.NEXTHEAD ~= 'H4' then + if EMT.NEXTTOOL ~= EMT.TOOL_1 then + EgtOutText( 'Tool change in progress...') + local RapSimStep = 4 * EMT.SIMSTEP + local RapSimRotStep = RapSimStep / 10 + local CollSimRotStep = min( RapSimRotStep, 10) + -- simulo movimento + SimulMoveAxes( 'B', 90, CollSimRotStep, 'C', 90, CollSimRotStep) + SimulMoveAxis( 'X', 0, RapSimStep) + -- breve pausa + EgtPause( 100) + ShowToolInTcPos( EMT.TCPOS_1, true) + -- se segue sega a catena + if EMT.NEXTHEAD == 'H3' then + -- se non lama, nascondo l'utensile corrente + if EMT.HEAD ~= 'H2' then + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.OFF) + end + -- eseguo movimento opportuno + SimulMoveAxes( 'B', 0, CollSimRotStep, 'C', 90, CollSimRotStep) + end + else + EMT.TOOL_1 = nil + EMT.TCPOS_1 = nil + end + end +end + +--------------------------------------------------------------------- +function OnSimulMachiningStart() + -- se lavorazione attuale e precedente con sega a catena con angolo A diverso, devo scaricare e ricaricare + if EMT.HEAD == 'H3' and EMT.HEAD == EMT.PREVHEAD then + local dPrevA = EgtGetAxisPos( 'A') + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + local dPosA = tonumber( sVal:sub( 3)) + if abs( dPosA - dPrevA) > 1 then + OnSimulToolDeselect() + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON) + OnSimulToolSelect( dPosA) + end + end + -- recupero alcuni dati della lavorazione + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + EMT.VMRS = ( EMT.MCHTYPE ~= MCH_MY.DRILLING and not ( sNotes and sNotes:find( 'VMRS=0;', 1, true))) + -- recupero TASKID della feature lavorata + local vId = EgtGetMachiningGeometry() + if vId and #vId > 0 and #vId[1] > 0 then + EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ; + else + EMT.TASKID = 0 + end + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true +end + +--------------------------------------------------------------------- +function OnSimulMachiningEnd() + if EMT.LOAD then + EMT.LOAD = false + elseif EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + end + EMT.PREVHEAD = EMT.HEAD +end + +--------------------------------------------------------------------- +--function OnSimulPathStart() +--end + +--------------------------------------------------------------------- +function OnSimulPathEnd() + -- se attivo VMILL, lavorazione ed è richiesto di eliminare gli sfridi + if EMT.VMILL and #EMT.VMILL > 0 and not EMT.OPEISDISP and EMT.VMRS then + EgtOutLog( 'OnSimulPathEnd', 5) + local vMillId = EMT.VMILL[1] + local nPart = EgtVolZmapPartCount( vMillId) + if nPart > 1 then + -- ricerca del pezzo con massimo volume + local nPartMax = 0 + local dVolMax = 0 + for i = 1, nPart do + local dVol = EgtVolZmapPartVolume( vMillId, i - 1) + if dVol > dVolMax then + dVolMax = dVol + nPartMax = i + end + end + -- eliminazione di tutti i pezzi piccoli + for i = nPart, 1, -1 do + if i ~= nPartMax then + local b3Vmill = EgtVolZmapGetPartBBoxGlob( vMillId, i - 1, GDB_BB.STANDARD) + if b3Vmill:getDimX() < 1200 then + EgtRemoveVolZmapPart( vMillId, i - 1) + end + end + end + -- aggiorno visualizzazione + EgtDraw() + end + end +end + +--------------------------------------------------------------------- +function OnSimulPathStartAux() + --EgtOutLog( 'OnSimulPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + EgtOutLog( 'OnSimulPathStartAux', 5) + -- eseguo il comando + ExecAuxCmd( EMT.AUX) +end + +--------------------------------------------------------------------- +function OnSimulPathEndAux() + --EgtOutLog( 'OnSimulPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + EgtOutLog( 'OnSimulPathEndAux', 5) + -- eseguo il comando + ExecAuxCmd( EMT.AUX) +end + +--------------------------------------------------------------------- +function OnSimulMoveStart() + -- Recupero la posizione corrente dei carrelli + local Yp = EgtGetAxisPos( 'Y') + local Vp = EgtGetAxisPos( 'V') + -- Imposto movimento carrelli insieme con la tavola : + -- entrambe le pinze + if EMT.YDELTA and EMT.VDELTA then + EMT.AuxAxes = 2 + EMT.A1n = 'Y' + EMT.A1 = EMT.L1 + EMT.YDELTA + EMT.A2n = 'V' + EMT.A2 = EMT.L1 + EMT.VDELTA + -- solo pinza Y + elseif EMT.YDELTA then + EMT.AuxAxes = 2 + EMT.A1n = 'Y' + EMT.A1 = EMT.L1 + EMT.YDELTA + EMT.A2n = 'V' + EMT.A2 = ParkV + -- solo pinza V + elseif EMT.VDELTA then + EMT.AuxAxes = 2 + EMT.A1n = 'Y' + EMT.A1 = EgtIf( EMT.YSPEC, Yp, ParkY) + EMT.A2n = 'V' + EMT.A2 = EMT.L1 + EMT.VDELTA + end + -- Controllo scorrimento pinze chiuse Y e V + if EMT.YDELTA then + local dYDeltaP = Yp - EMT.L1p + if abs( EMT.YDELTA - dYDeltaP) > 0.1 then + EMT.ERR = 2 + local sErr = 'Y slide : ' .. EmtLenToString( dYDeltaP, 3) .. ' -> ' .. EmtLenToString( EMT.YDELTA, 3) + EmtSetLastError( 1202, sErr) + end + end + if EMT.VDELTA then + local dVDeltaP = Vp - EMT.L1p + if abs( EMT.VDELTA - dVDeltaP) > 0.1 then + EMT.ERR = 2 + local sErr = 'V slide : ' .. EgtNumToString( dVDeltaP, 3) .. ' -> ' .. EgtNumToString( EMT.VDELTA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Controllo corse assi Y e V + VerifyYStroke( EMT.A1) + VerifyVStroke( EMT.A2) + -- se inizio lavorazione + if EMT.MCHFIRST then + EgtOutText( '') + EMT.MCHFIRST = false + -- con pezzi alti aggiorno gli assi rotanti prima di muovermi sopra il pezzo + if not EMT.LOAD and EMT.MOVE == 0 and EMT.HB > BeamHeightForFixRot then + local RapSimStep = 4 * EMT.SIMSTEP + SimulMoveAxes( 'C', EMT.R1, RapSimStep/10, 'B', EMT.R2, RapSimStep/10) + end + end +end + +--------------------------------------------------------------------- +--function OnSimulMoveEnd() +--end + +--------------------------------------------------------------------- +function OnSimulCollision() + -- se prima collisione della lavorazione, la segnalo + if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then + local Class = '' + if EMT.SIMCOBIND == 1001 then + Class = 'T_H1' + elseif EMT.SIMCOBIND == 1002 then + Class = 'TH_H1' + else + Class = EMT.COLLOBJ[EMT.SIMCOBIND].Cl + end + table.insert( EMT.COLLIDE, { Mc = EMT.MCHNAME, Cl = Class, Vm = EMT.SIMVMID}) + EMT.LAST_MCHNAME_COLLIDE = EMT.MCHNAME + EMT.ERR = 1 + local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Class='..Class..'; VMill='..EMT.SIMVMID + EmtSetLastError( 1221, sErr, true) + EgtOutLog( 'Collision : ' .. sErr, 1) + end +end + +--------------------------------------------------------------------- +function ExecAuxCmd( sCmd) + local RapSimStep = 4 * EMT.SIMSTEP + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + if Cmd[2] == 'Unloading' then + EMT.UNLOADING = true + elseif Cmd[2] == 'Fall' then + EMT.FALL = true + end + EgtOutText( EgtIf( Cmd[3], Cmd[3], Cmd[2])) + elseif Cmd[1] == '1' then + if not SimulMoveAxis( Cmd[2], tonumber( Cmd[3]), RapSimStep) then + if VerifyYVStroke( Cmd[2], tonumber( Cmd[3])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + end + elseif Cmd[1] == '2' then + -- Verifico movimento carrello con trave agganciata + VerifyOneChariotSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5]) + -- Eseguo il movimento + local _, bOk, bOk2 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), RapSimStep, + Cmd[4], tonumber( Cmd[5]), RapSimStep) + if not ( bOk and bOk2) then + local nI = EgtIf( not bOk, 2, 4) + if VerifyYVStroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + end + elseif Cmd[1] == '3' then + -- Verifico movimento carrelli con trave agganciata + VerifyTwoChariotsSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5], Cmd[6], Cmd[7]) + -- Eseguo il movimento + local _, bOk, bOk2, bOk3 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), RapSimStep, + Cmd[4], tonumber( Cmd[5]), RapSimStep, + Cmd[6], tonumber( Cmd[7]), RapSimStep) + if not ( bOk and bOk2 and bOk3) then + local nI = EgtIf( not bOk, 2, EgtIf( not bOk2, 4, 6)) + if VerifyYVStroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + end + elseif Cmd[1] == '11' then + local dPY = MaxOpen + if Cmd[2] ~= '0' then + dPY = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB) + end + SimulMoveAxis( 'PY', dPY, RapSimStep) + SetPYLight( Cmd[2] ~= '0') + elseif Cmd[1] == '12' then + local dPV = MaxOpen + if Cmd[2] ~= '0' then + dPV = EgtIf( EMT.ROT == -1, EMT.HB, EMT.SB) + end + SimulMoveAxis( 'PV', dPV, RapSimStep) + SetPVLight( Cmd[2] ~= '0') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0.01 and nVDelta > 0.01 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nVDelta + elseif nYDelta > 0.01 then + EMT.YDELTA = nYDelta + EMT.VDELTA = nil + elseif nVDelta > 0.01 then + EMT.YDELTA = nil + EMT.VDELTA = nVDelta + end + elseif Cmd[1] == '31' then + local nRawId = tonumber( Cmd[2]) + EmtUnlinkRawPartFromGroup( nRawId) + EmtLinkRawPartToGroup( nRawId, Cmd[3]) + EMT.YSPEC = true + end +end + +--------------------------------------------------------------------- +function ExecUnloading() + if EMT.VMILL and #EMT.VMILL > 0 then + local vMillId = EMT.VMILL[1] + -- gruppo dei Vmill + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + -- li sposto per lasciare spazio al nuovo pezzo + local nId = EgtGetFirstInGroup( nVmGrpId) + while nId do + EgtMove( nId, Vector3d( 0, ( EMT.SB + 50.0), 0), GDB_RT.GLOB) + nId = EgtGetNext( nId) + end + -- creo un nuovo layer e vi inserisco il nuovo pezzo + local nLayId = EgtGroup( nVmGrpId, EgtGetGlobFrame( vMillId)) + EgtRelocate( vMillId, nLayId) + local vtMove = Vector3d( 0, 450, 0) + if EMT.FALL then vtMove = Vector3d( -500, 0, 750) end + EgtMove( nLayId, vtMove, GDB_RT.GLOB) + EgtSetLevel( vMillId, GDB_LV.USER) + -- aggiungo gli spigoli + local nFirstId, nCount = EgtVolZmapGetEdges( vMillId, nLayId) + if nFirstId then + for nId = nFirstId, nFirstId + nCount - 1 do + EgtSetColor( nId, Color3d( 96, 96, 96)) + end + end + -- rilascio Vmill + table.remove( EMT.VMILL, 1) + -- aggiorno la visualizzazione + EgtDraw() + -- se finito + if EMT.PHASE == EgtGetPhaseCount() then + -- se impostato di salvare i Vmill, lo faccio + local sMachIni = EgtGetCurrMachineDir() .. '\\' .. EgtGetCurrMachineName() .. '.ini' + if EgtGetStringFromIni( 'VMill', 'Save', '', sMachIni) == '1' then + local sFile = EgtGetCurrFilePath() + if sFile then + local sDir, sName, sExt = EgtSplitPath( sFile) + if sExt and sExt:lower() == ".nge" then + sName = sName .. '_VM_' .. EgtGetMachGroupName( EgtGetCurrMachGroup()) + EgtSetLevel( nVmGrpId, GDB_LV.USER) + EgtSaveObjToFile( nVmGrpId, sDir .. sName .. '.Nge') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + end + end + end + end +end + +--------------------------------------------------------------------- +function VerifyYSlide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello Y + if sName1 == 'T' and sName2 == 'Y' and GetPYLight() then + local dYDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'Y') + local dYDeltaA = tonumber( dVal1) - tonumber( dVal2) + EgtOutLog( string.format( 'YDeltaP=%.3f YDeltaA=%.3f', dYDeltaP, dYDeltaA), 5) + if abs( dYDeltaA - dYDeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'Y slide : ' .. EmtLenToString( dYDeltaP, 3) .. ' -> ' .. EmtLenToString( dYDeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Tutto bene + return true +end + +--------------------------------------------------------------------- +function VerifyVSlide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello V + if sName1 == 'T' and sName2 == 'V' and GetPVLight() then + local dVDeltaP = EgtGetAxisPos( 'T') - EgtGetAxisPos( 'V') + local dVDeltaA = tonumber( dVal1) - tonumber( dVal2) + EgtOutLog( string.format( 'VDeltaP=%.3f VDeltaA=%.3f', dVDeltaP, dVDeltaA), 5) + if abs( dVDeltaA - dVDeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'V slide : ' .. EmtLenToString( dVDeltaP, 3) .. ' -> ' .. EmtLenToString( dVDeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + return true +end + +--------------------------------------------------------------------- +function VerifyOneChariotSlide( sName1, dVal1, sName2, dVal2) + -- Metto in prima posizione la trave + if sName2 == 'T' then + sName1, sName2 = sName2, sName1 + dVal1, dVal2 = dVal2, dVal1 + end + -- Eseguo verifica + if sName2 == 'Y' then + return VerifyYSlide( sName1, dVal1, sName2, dVal2) + elseif sName2 == 'V' then + return VerifyVSlide( sName1, dVal1, sName2, dVal2) + end + return true +end + +--------------------------------------------------------------------- +function VerifyTwoChariotsSlide( sName1, dVal1, sName2, dVal2, sName3, dVal3) + -- Metto in prima posizione la trave + if sName2 == 'T' then + sName1, sName2 = sName2, sName1 + dVal1, dVal2 = dVal2, dVal1 + elseif sName3 == 'T' then + sName1, sName3 = sName3, sName1 + dVal1, dVal3 = dVal3, dVal1 + end + -- Eseguo verifica + if sName2 == 'Y' then + return VerifyYSlide( sName1, dVal1, sName2, dVal2) and VerifyVSlide( sName1, dVal1, sName3, dVal3) + elseif sName2 == 'V' then + return VerifyVSlide( sName1, dVal1, sName2, dVal2) and VerifyYSlide( sName1, dVal1, sName3, dVal3) + end + return true +end + +--------------------------------------------------------------------- +function VerifyYStroke( dY) + if dY < MinY then + EmtSetOutstrokeInfo( 'Y', 'Y', true, dY - MinY, ' (L1-)') + EMT.ERR = 1 + local sErr = 'Y axis outstroke ' .. EgtNumToString( dY - MinY, 3) + EgtOutLog( sErr) + return false + elseif dY > MaxY then + EmtSetOutstrokeInfo( 'Y', 'Y', true, dY - MaxY, ' (L1+)') + EMT.ERR = 1 + local sErr = 'Y axis outstroke ' .. EgtNumToString( dY - MaxY, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyVStroke( dV) + if dV > MaxV then + EmtSetOutstrokeInfo( 'V', 'V', true, dV - MaxV, ' (L1+)') + EMT.ERR = 1 + local sErr = 'V axis outstroke ' .. EgtNumToString( dV - MaxV, 3) + EgtOutLog( sErr) + return false + elseif dV < MinV then + EmtSetOutstrokeInfo( 'V', 'V', true, dV - MinV, ' (L1-)') + EMT.ERR = 1 + local sErr = 'V axis outstroke ' .. EgtNumToString( dV - MinV, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyYVStroke( sName, dVal) + if sName == 'Y' then + return VerifyYStroke( dVal) + elseif sName == 'V' then + return VerifyVStroke( dVal) + else + return nil + end +end + +--------------------------------------------------------------------- +function ShowToolInTcPos( sTcPos, bShow) + -- recupero il gruppo dell'utensile + local TcExitId = EgtGetFirstNameInGroup( EgtGetTcPosId( sTcPos or '') or GDB_ID.NULL, 'T1') + if not TcExitId then return end + -- imposto lo stato di visualizzazione + EgtSetStatus( TcExitId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF)) +end + +--------------------------------------------------------------------- +function GetToolTcPos( sTool) + -- salvo stato iniziale + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- recupero la posizione di cambio utensile dell'utensile indicato + local sTcPos + if EgtTdbSetCurrTool( sTool) then + sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + end + -- ripristino stato iniziale + if CurrTool then + EgtTdbSetCurrTool( CurrTool) + else + EgtTdbSetCurrTool( '') + end + -- restituisco risultato + return sTcPos +end + + +--------------------------------------------------------------------- +-- *** ESTIMATION T&L *** +--------------------------------------------------------------------- +local RAPID_X_FEED = 75000 -- mm/min +local RAPID_Y_FEED = 100000 -- mm/min +local RAPID_Z_FEED = 50000 -- mm/min +local RAPID_C_FEED = 15000 -- deg/min +local RAPID_B_FEED = 15000 -- deg/min +local RAPID_MIN_T = 0.1 -- s +local LOAD_T = 2 -- s +local CHAR_ONE_MOVE_T = 1 -- s +local ROTATION_T = 40 -- s +local SPLIT_T = 6 -- s +local UNLOAD_T = 4 -- s +local FALL_T = 2 -- s + +--------------------------------------------------------------------- +function OnEstimStart() + EMT.INCHES = not EgtUiUnitsAreMM() -- unità di misura mm/inches +end + +--------------------------------------------------------------------- +function OnEstimEnd() +end + +--------------------------------------------------------------------- +function OnEstimProgramStart() + -- imposto inizio movimenti da Home + EMT.L1 = EgtGetAxisHomePos( 'T') + EMT.L2 = EgtGetAxisHomePos( 'X') + EMT.L3 = EgtGetAxisHomePos( 'Z') + EMT.R1 = EgtGetAxisHomePos( 'C') + EMT.R2 = EgtGetAxisHomePos( 'B') + -- aggiorno valori come precedenti + EmtUpdatePrev() + -- totalizzatori tempi e lunghezze + EMT.TOTCUTLEN = 0 + EMT.TOTCUTTIME = 0 + EMT.TOTEXTLEN = 0 + EMT.TOTEXTTIME = 0 + -- variabile per lunghezza taglio utensili + EMT.TOOLCUTLEN = {} + -- intestazioni + EmtTleStart( EMT.INFO) +end + +--------------------------------------------------------------------- +function OnEstimProgramEnd() + -- stampa dei totali delle lavorazioni + EmtTleAddTotal( EmtSecToHMS( EMT.TOTCUTTIME + EMT.TOTEXTTIME), EmtLenToMF( EMT.TOTCUTLEN)) + -- stampa dei totali degli utensili + for i = 1, #EMT.TOOLCUTLEN do + local TCL = EMT.TOOLCUTLEN[i] + EmtTleAddTool( TCL.Name, EmtLenToMF( TCL.Len)) + end + -- completo il file + local _, _, sExt = EgtSplitPath( EMT.FILE) + EmtTleEnd( sExt:sub( 2)) + -- salvo i dati principali nel progetto + EgtSetInfo( EgtGetCurrMachGroup(), 'Ttot', EgtNumToString( EMT.TOTCUTTIME + EMT.TOTEXTTIME, 0)) + EgtSetInfo( EgtGetCurrMachGroup(), 'Ltot', EgtNumToString( EMT.TOTCUTLEN, 0)) +end + +--------------------------------------------------------------------- +function OnEstimDispositionStart() + -- inizio disposizione + EMT.OPEISDISP = true + -- sulla prima fase dichiaro carico barra + if EMT.PHASE == 1 then + EMT.LOAD = true + else + EMT.LOAD = false + end +end + +--------------------------------------------------------------------- +function OnEstimDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + ; + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) then + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- verifico se sono diverse + if nRot ~= nPrevRot then + -- imposto stato post-rotazione + EMT.POSTROT = true + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + ; + end + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end + -- termine disposizione + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnEstimToolSelect() + -- reset indice utensile in tabella lunghezze + EMT.TCLIND = 0 + -- verifico che l'utensile sia definito + if #EMT.TOOL == 0 then return end + -- cerco l'utensile nella tabella + for i = 1, #EMT.TOOLCUTLEN do + if EMT.TOOLCUTLEN[i].Name == EMT.TOOL then + EMT.TCLIND = i + break + end + end + -- se non trovato, lo aggiungo + if EMT.TCLIND == 0 then + table.insert( EMT.TOOLCUTLEN, { Name = EMT.TOOL, Len = 0}) + EMT.TCLIND = #EMT.TOOLCUTLEN + end +end + +--------------------------------------------------------------------- +function OnEstimToolDeselect() +end + +--------------------------------------------------------------------- +function OnEstimMachiningStart() + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EgtOutLog( 'Mach : ' .. EMT.MCHNAME, 5) + -- reset contatori di lavorazione + EMT.MCHCUTLEN = 0 + EMT.MCHCUTTIME = 0 + EMT.MCHEXTLEN = 0 + EMT.MCHEXTTIME = 0 +end + +--------------------------------------------------------------------- +function OnEstimMachiningEnd() + -- nel caso di foratura devo dimezzare la lunghezza di taglio perchè comprende anche l'uscita + if EMT.MCHTYPE == MCH_MY.DRILLING then + EMT.MCHCUTLEN = EMT.MCHCUTLEN / 2 + end + local sName = EgtGetName( EMT.MCHID) + EmtTleAddMachining( sName, EmtSecToHMS( EMT.MCHCUTTIME + EMT.MCHEXTTIME), EmtLenToMF( EMT.MCHCUTLEN), EMT.TOOL) + -- aggiorno totali e utensili + EMT.TOTCUTLEN = EMT.TOTCUTLEN + EMT.MCHCUTLEN + EMT.TOTCUTTIME = EMT.TOTCUTTIME + EMT.MCHCUTTIME + EMT.TOTEXTLEN = EMT.TOTEXTLEN + EMT.MCHEXTLEN + EMT.TOTEXTTIME = EMT.TOTEXTTIME + EMT.MCHEXTTIME + EMT.TOOLCUTLEN[EMT.TCLIND].Len = EMT.TOOLCUTLEN[EMT.TCLIND].Len + EMT.MCHCUTLEN + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end +end + +--------------------------------------------------------------------- +function OnEstimPathStart() + EMT.AUXTYPE = nil + EMT.MCHMOVEFIRST = true +end + +--------------------------------------------------------------------- +function OnEstimPathEnd() + EMT.AUXTYPE = nil +end + +--------------------------------------------------------------------- +function OnEstimPathStartAux() + -- se richiesto, preparo il carico barra + if EMT.LOAD then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Loading', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.LOAD = false + end + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = ROTATION_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Rotation', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.POSTROT = false + end + -- altrimenti, spostamento carrelli + else + if EMT.AUXTOT > 2 and EMT.AUXIND == EMT.AUXTOT then + local dTime = ( EMT.AUXTOT - 2) * CHAR_ONE_MOVE_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Charriots move', EmtSecToHMS( dTime), ' - ', ' - ') + end + end +end + +--------------------------------------------------------------------- +function OnEstimPathEndAux() + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.AUXTYPE = 'F' + else + EMT.AUXTYPE = 'P' + end + end + end + -- per lo scarico della rimanenza + if EMT.AUXTYPE == 'R' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Remnant unloading' + EMT.TLE_TIME = dTime + end + -- per lo split + elseif EMT.AUXTYPE == 'S' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = SPLIT_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Splitting' + EMT.TLE_TIME = dTime + end + -- per lo scarico + elseif EMT.AUXTYPE == 'U' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Unloading' + EMT.TLE_TIME = dTime + end + -- per lo scarico a caduta + elseif EMT.AUXTYPE == 'F' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = FALL_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Fall' + EMT.TLE_TIME = dTime + end + -- per la pre-rotazione + elseif EMT.AUXTYPE == 'P' then + ; -- calcolato come parte della rotazione + end +end + +--------------------------------------------------------------------- +function OnEstimRapid() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + local dR1 = 0 + if EMT.R1 and EMT.R1p then dR1 = EMT.R1 - EMT.R1p end + local dR2 = 0 + if EMT.R2 and EMT.R2p then dR2 = EMT.R2 - EMT.R2p end + -- se primo posizionamento della lavorazione il movimento di L1 è già conteggiato in quello dei carrelli + if EMT.MCHMOVEFIRST then + EMT.MCHMOVEFIRST = false + dL1 = 0 + end + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHEXTLEN = EMT.MCHEXTLEN + dLen + -- calcolo tempo + local dTime = RAPID_MIN_T + local dT1 = abs( dL1) / RAPID_X_FEED * 60 + if dT1 > dTime then dTime = dT1 end + local dT2 = abs( dL2) / RAPID_Y_FEED * 60 + if dT2 > dTime then dTime = dT2 end + local dT3 = abs( dL3) / RAPID_Z_FEED * 60 + if dT3 > dTime then dTime = dT3 end + local dT4 = abs( dR1) / RAPID_C_FEED * 60 + if dT4 > dTime then dTime = dT4 end + local dT5 = abs( dR2) / RAPID_B_FEED * 60 + if dT5 > dTime then dTime = dT5 end + EMT.MCHEXTTIME = EMT.MCHEXTTIME + dTime + EgtOutLog( string.format( ' G0 Len=%.0f Rot=%.0f° Time=%.2f', dLen, abs( dR1) + abs( dR2), dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimLinear() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G1 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimArc() + -- dati movimento + local dLxy = EMT.RR * abs( EMT.AC) * pi / 180 + local dLz = abs( ( Point3d( EMT.L1, EMT.L2, EMT.L3) - Point3d( EMT.L1p, EMT.L2p, EMT.L3p)) * Vector3d( EMT.EXTR)) + -- calcolo lunghezza + local dLen = sqrt( dLxy * dLxy + dLz * dLz) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G2 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +-- *** GENERAL *** +--------------------------------------------------------------------- +function FindFirstToolOnHead( sH1) + -- salvo stato iniziale + local CurrMachId = EgtGetCurrMachining() + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- cerco lavorazione con utensile su testa indicata + local sTool, nTlen + local OpId = EgtGetFirstActiveOperation() + while OpId do + local nType = EgtGetOperationType( OpId) + if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then + if EgtSetCurrMachining( OpId) then + local sTest = EgtGetMachiningParam( MCH_MP.TOOL) + if EgtTdbSetCurrTool( sTest) then + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if sHead and ( sHead == sH1) then + sTool = sTest + nTlen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + break + end + end + end + end + OpId = EgtGetNextActiveOperation( OpId) + end + -- ripristino stato iniziale + if CurrMachId then + EgtSetCurrMachining( CurrMachId) + else + EgtResetCurrMachining() + end + if CurrTool then + EgtTdbSetCurrTool( CurrTool) + else + EgtTdbSetCurrTool( '') + end + -- restituisco risultato + return sTool, nTlen +end + +--------------------------------------------------------------------- +function GetDefaultToolName() + local vTools = EgtGetToolsInCurrSetupPos( DefTcPos) + if vTools and vTools[1] and #vTools[1] > 0 then + return vTools[1] + else + local sErr = 'Missing tool in Default Position ' .. DefTcPos + EgtOutLog( 'Error : ' .. sErr) + if EMT.VER and EMT.VER >= '2.3a2' and EMT.SIM1ST then + EgtOutBox( sErr, 'ERROR', 'ERROR') + end + return '' + end +end + +--------------------------------------------------------------------- +function IsStartPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START') +end + +--------------------------------------------------------------------- +function IsRestPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'REST') +end + +--------------------------------------------------------------------- +function IsStartOrRestPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START' or sVal == 'REST') +end + +--------------------------------------------------------------------- +function IsMidPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'MID') +end + +--------------------------------------------------------------------- +function IsMid2Phase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'MID2') +end + +--------------------------------------------------------------------- +function IsEnd2Phase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'END2') +end + +--------------------------------------------------------------------- +function GetPhaseType( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '') +end + +--------------------------------------------------------------------- +function GetPhaseOrd( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ORD', 'i') or 0) +end + +--------------------------------------------------------------------- +function GetPhaseRot( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) +end + +--------------------------------------------------------------------- +-- *** END GENERAL *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.mlse b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.mlse new file mode 100644 index 0000000..4384e5f --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.mlse @@ -0,0 +1,3821 @@ +-- Special Operations macchina Essetre-FAST by EgalTech s.r.l. 2021/07/09 +-- 2020/05/15 DS ver.2.2e1 Correzione a SpecAdjustCarrC3 per bFixedDelta. +-- 2020/05/16 DS ver 2.2e2 Aggiunta gestione rotazione 90deg. +-- 2020/05/21 DS ver 2.2e3 Aggiunto a SpecAdjustCarrC3 parametro bFixedPos (per lavorazioni Split e Cut precedute da Pre). +-- 2020/05/26 DS ver 2.2e4 Nuova gestione dei pezzi a caduta. +-- 2020/05/27 DS ver 2.2e5 Corretto blocco pinza V su presplit e precut. +-- 2020/05/28 DS ver 2.2e7 Correzione per mancanza EMC.HOVM allo scarico. +-- 2020/06/18 DS ver 2.2f3 Aumento ingombro fresatura opposta a cerrello per evitare extracorsa. +-- 2020/07/02 DS ver 2.2g1 Correzione quota di presa al carico per casi senza tagli in testa e lavorazioni solo in coda. +-- 2020/09/03 DS ver 2.2i1 Correzione in Load dopo rotazione deve tener conto dell'ingombro delle lavorazioni in coda. +-- 2020/09/09 DS ver 2.2i2 Nel calcolo pinzaggi ora si tiene conto anche della larghezza della sezione della barra. +-- 2020/09/25 DS ver 2.2i5 Migliorato calcolo ingombro lama con testa opposta al carrello. +-- 2020/09/29 DS ver 2.2i6 Migliorato calcolo ingombro fresa su tagli longitudinali di fianco. +-- 2020/10/13 DS ver 2.2j2 Aggiunta gestione sezione molto piccola (Very Small) per presa minima. Corretta gestione ingombri con fori a 30 deg. +-- 2020/12/09 DS ver 2.2l1 Migliorato calcolo ingombro con lama verticale inclinata di +/-45deg rispetto a X. +-- 2021/01/24 DS ver 2.3a2 Migliorato controllo assi rotanti definiti con sega a catena per SpecialCalcMachiningEncumbrance. +-- 2021/02/02 DS ver 2.3b1 Migliorato calcolo ingombro tagli di lama quasi verticale angolata. +-- 2021/02/17 DS ver 2.3b2 Corretta B3Ys-xs1 per accentrare V e T bisogna sottrarre dExtraY che è negativo e non sommare. +-- 2021/04/02 DS ver 2.3d1 Corretto calcolo ingombro con lama per non andare in extracorsa con le pinze quando lavorazione vicino a Y0. +-- 2021/06/01 DS ver 2.3f1 Aggiunta segnalazione pezzo scaricato a caduta. +-- 2021/06/25 DS ver 2.3f5 Corretta segnalazione tipo di scarico del pezzo. + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +-- Carico i dati globali +local sBaseDir = EgtGetSourceDir() +local BD = dofile( sBaseDir .. 'Beam\\BeamData.lua') + +EgtOutLog ( '** Essetre-FAST '..PP_VER..' **', 1) + +----------------------- Costanti ------------------------------------ +local DELTA_TOL_S = 210 +local DELTA_TOL_L = 410 +local DELTA_TOL_FIXED = 50 +local DeltaTol = DELTA_TOL_S +local DELTA_SIC = 1 +local AGG_LOAD = 50 +local AGG_B_SPLIT = 0 +local MIN_JOIN_VV = 75 +local MIN_JOIN_SS = 100 +local MIN_JOIN_LS = 300 +local MIN_JOIN_SL = 100 +local MIN_JOIN_LL = 400 +local MinJoin = MIN_JOIN_SS +local MinOther = abs( MinY) + abs( MaxV) + MinJoin + +----------------------- Variabili ----------------------------------- +local Test = false + +--------------------------------------------------------------------- +local function PrepareClGroup( nParentId) + + local nClId = EgtGetFirstNameInGroup( nParentId, 'CL') + -- se non c'è, lo aggiunge + if not nClId then + nClId = EgtGroup( EMC.DISPID) + if not nClId then + return nil + end + EgtSetName( nClId, 'CL') + -- altrimenti lo svuoto + else + EgtEmptyGroup( nClId) + end + + return nClId +end + +--------------------------------------------------------------------- +local function IsStartOrRestPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'START' or sVal == 'REST') +end + +--------------------------------------------------------------------- +local function IsMidPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'MID') +end + +--------------------------------------------------------------------- +local function IsEndPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'END') +end + +--------------------------------------------------------------------- +local function IsMid2Phase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'MID2') +end + +--------------------------------------------------------------------- +local function IsEnd2Phase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'END2') +end + +--------------------------------------------------------------------- +local function GetNextStartOrRestPhase( nPhase) + local nNextPhase = nPhase + 1 + while nNextPhase <= EgtGetPhaseCount() do + if IsStartOrRestPhase( nNextPhase) then + break ; + end + nNextPhase = nNextPhase + 1 + end + return nNextPhase +end + +--------------------------------------------------------------------- +local function GetPhaseRot( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) +end + +--------------------------------------------------------------------- +local function IsLastOperationBeforeRotation( nOperId) + -- se ultima fase o ultima fase del pezzo, ritorno risultato negativo + if EMC.PHASE == EgtGetPhaseCount() or IsEndPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) then + return false + end + -- recupero la successiva operazione attiva + local nNextOperId = EgtGetNextActiveOperation( nOperId) + -- se non esiste o non è una disposizione, ritorno risultato negativo + if not nNextOperId or EgtGetOperationType( nNextOperId) ~= MCH_OY.DISP then + return false + end + -- recupero le rotazioni della fase corrente e della prossima fase + local nRot = GetPhaseRot( EMC.PHASE) + local nNextRot = GetPhaseRot( EMC.PHASE + 1) + -- ritorno se sono diverse + return ( nRot ~= nNextRot) +end + +--------------------------------------------------------------------- +local function IsFirstMachiningAfterRotation( nMchId) + -- se prima fase o prima fase del pezzo, ritorno risultato negativo + if EMC.PHASE == 1 or IsStartOrRestPhase( EMC.PHASE) then + return false + end + -- recupero la precedente operazione attiva + local nPrevOperId = EgtGetPrevActiveOperation( nMchId) + -- se non esiste o non è una disposizione, ritorno risultato negativo + if not nPrevOperId or EgtGetOperationType( nPrevOperId) ~= MCH_OY.DISP then + return false + end + -- recupero le rotazioni della fase corrente e della fase precedente + local nRot = GetPhaseRot( EMC.PHASE) + local nPrevRot = GetPhaseRot( EMC.PHASE - 1) + -- ritorno se sono diverse + return ( nRot ~= nPrevRot) +end + +--------------------------------------------------------------------- +local function UpdateMinJoinDeltaTol() + local L_SMALL = 800 + local H_V = 100 + local H_S = 200 + local H_L = 400 + local W_V = 100 + local W_S = 150 + local W_L = 250 + if EMC.SB <= W_V and EMC.HB <= H_V then + MinJoin = MIN_JOIN_VV + DeltaTol = DELTA_TOL_S + elseif EMC.LB <= L_SMALL then + MinJoin = MIN_JOIN_SS + DeltaTol = DELTA_TOL_S + else + local dMinJoinS + local dMinJoinL + if EMC.SB <= W_S then + dMinJoinS = MIN_JOIN_SS + dMinJoinL = MIN_JOIN_LS + elseif EMC.SB <= W_L then + local Coeff = ( EMC.SB - W_S) / ( W_L - W_S) + dMinJoinS = ( 1 - Coeff) * MIN_JOIN_SS + Coeff * MIN_JOIN_SL + dMinJoinL = ( 1 - Coeff) * MIN_JOIN_LS + Coeff * MIN_JOIN_LL + else + dMinJoinS = MIN_JOIN_SL + dMinJoinL = MIN_JOIN_LL + end + if EMC.HB <= H_S then + MinJoin = dMinJoinS + DeltaTol = DELTA_TOL_S + elseif EMC.HB <= H_L then + local Coeff = ( EMC.HB - H_S) / ( H_L - H_S) + MinJoin = ( 1 - Coeff) * dMinJoinS + Coeff * dMinJoinL + DeltaTol = ( 1 - Coeff) * DELTA_TOL_S + Coeff * DELTA_TOL_L + else + MinJoin = dMinJoinL + DeltaTol = DELTA_TOL_L + end + end + MinOther = abs( MinY) + abs( MaxV) + MinJoin +end + +--------------------------------------------------------------------- +local function GetCUTID() + -- recupero CUTID del pezzo in lavoro + local nOrd = GetPhaseOrd( EMC.PHASE) + local nPartRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + nPartRawId = nRawId + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + local CutID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + return CutID +end + +--------------------------------------------------------------------- +local function EnsureZmax( bZmaxOk, vCmd) + if not bZmaxOk then table.insert( vCmd, { 1, 'Z', EgtGetAxisHomePos( 'Z')}) end + return true +end + +--------------------------------------------------------------------- +local function EmitComment( vCmd, sOut) + EgtOutLog( ' ' .. sOut, 1) + if Test then + table.insert( vCmd, { 0, sOut}) + end +end + +--------------------------------------------------------------------- +function OnSpecialApplyDisposition() + + EgtOutLog( ' *** Fase : ' .. EgtNumToString( EMC.PHASE, 0) .. ' ***', 1) + + -- Inizializzo codice di errore + EMC.ERR = 0 + + -- Campi obbligatori ma non usati + EMC.HEAD = "H4" + EMC.EXIT = 1 + EMC.TCPOS = "" + EMC.SHIFTS = 0 + EMC.SBH = false + + -- Se disposizione da saltare non devo fare alcunché + if EgtExistsInfo( EMC.DISPID, 'SKIP') then return end + + -- Assegno flag di pezzo separato dal resto del grezzo + local bSplit = IsEndPhase( EMC.PHASE) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) + + -- Recupero il tipo dell'operazione successiva + local nNextOpeType = EgtGetOperationType( EgtGetNextActiveOperation( EMC.DISPID) or GDB_ID.NULL) + + -- Se ci sono lavorazioni successive non devo fare alcunché + if nNextOpeType ~= MCH_OY.NONE and nNextOpeType ~= MCH_OY.DISP then return end + + -- Imposto gruppo e path di movimento + local nClId = PrepareClGroup( EMC.DISPID) + if not nClId then + EMC.ERR = 3 + return + end + local nPathId = EgtGroup( nClId) + if not nPathId then + EMC.ERR = 6 + return + end + EgtSetName( nPathId, 'Empty') + EMC.PATHID = nPathId + EMC.SHIFTS = -1 + + -- Se l'operazione successiva è una disposizione con rotazione, devo preparare il pezzo alla rotazione + if IsLastOperationBeforeRotation( EMC.DISPID) then + -- aggiornamento posizioni + if IsStartPhase( EMC.PHASE) then + -- carico le posizioni + local dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd') + local dPosY = EgtGetInfo( EMC.DISPID, 'YPOS', 'd') + EMC.TPOS = dPosT + EMC.YDELTA = dPosY - dPosT + EMC.VDELTA = nil + EMC.CNT = 1 + else + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + end + -- Determinazione delle dimensioni del grezzo in lavoro + local b3Raw = BBox3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + b3Raw = EgtGetRawPartBBox( nRawId) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + -- Assegno sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 + EMC.HCING = 0 + EMC.TCING = EgtGetInfo( nRawId, 'TCING', 'd') or 0 + -- Eseguo preparazione alla rotazione + local vCmd = SpecCalcPreRot() + SpecOutputCmds( vCmd, true) + return + end + + -- Se l'operazione successiva è ancora una disposizione, devo scaricare il pezzo + if nNextOpeType == MCH_OY.DISP and bSplit and not IsEnd2Phase( EMC.PHASE) then + -- aggiornamento posizioni + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + -- Determinazione delle dimensioni del grezzo in lavoro + local b3Raw = BBox3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) and not EgtVerifyRawPartPhase( nRawId, EMC.PHASE + 1) then + b3Raw = EgtGetRawPartBBox( nRawId) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + EMC.HOVM = EgtGetInfo( nRawId or GDB_ID.NULL, 'HOVM', 'd') or 0 + -- Eseguo scarico + local vCmd = SpecCalcUnload() + SpecOutputCmds( vCmd, true) + return + end + + -- Verifico ci sia un solo grezzo nella fase corrente + local nRawCount = 0 + local nCurrRawId = GDB_ID.NULL + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + nRawCount = nRawCount + 1 + nCurrRawId = nRawId + end + nRawId = EgtGetNextRawPart( nRawId) + end + + -- Determinazione delle sue dimensioni + local b3Raw = EgtGetRawPartBBox( nCurrRawId) + if b3Raw:isEmpty() then + EMC.ERR = 11 + return + end + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + EMC.SB = b3Raw:getDimY() + EMC.HB = b3Raw:getDimZ() + EMC.ZMIN = b3Raw:getMin():getZ() + + -- Aggiorno limiti di presa e tolleranza + UpdateMinJoinDeltaTol() + + -- Assegno sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = 0 + EMC.HCING = 0 + EMC.TCING = 0 + + -- Devo scaricare il grezzo rimasto (deve essere unico) + -- Posizione trave + local dPosT + + -- Se fase 1 o dopo rotazione eseguo carico con carrello Y + local vCmd = {} + if EMC.PHASE == 1 or IsEnd2Phase( EMC.PHASE) then + dPosT = LoadT + if IsEnd2Phase( EMC.PHASE) then dPosT = dPosT + TurnerOffs end + vCmd = SpecCalcLoad( dPosT, 0, min( EMC.LB - MinOther - AGG_LOAD, MaxY - dPosT)) + -- se altrimenti fase successiva alla prima di tipo inizio o rimanenza + elseif IsStartOrRestPhase( EMC.PHASE) then + -- recupero posizione trave e quota di aggancio carrello + dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd') + local dPosY = EgtGetInfo( EMC.DISPID, 'YPOS', 'd') + -- se carrello agganciato + if dPosY then + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dPosY - dPosT, 0}) + -- recupero CNT + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + if EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP and EgtExistsInfo( nPrevOpeId, 'SKIP') then + nPrevOpeId = EgtGetPrevActiveOperation( nPrevOpeId) + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + -- altrimenti è grezzo scaricato al carico e devo ricaricarlo + else + vCmd = SpecCalcLoad( dPosT, 0, min( EMC.LB - MinOther - AGG_LOAD, MaxY - dPosT)) + end + -- altrimenti fase successiva pari + else + local dPosV = EgtGetInfo( EMC.DISPID, 'VPOS', 'd') + EMC.VDELTA = dPosV + end + -- Se fase inizio o rimanenza, eseguo scambio per avere solo pinza V + local vCmd2 = {} + if IsStartOrRestPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) then + EMC.TPOS = dPosT + SpecSetCarrPosFromCmds( vCmd) + local dDistFront = EgtIf( EMC.LB < abs( MinV - UnloadT), MinJoin, EMC.LB - abs( MinV - UnloadT) + MinJoin + DeltaTol) + vCmd2 = SpecCalcCarriages( dDistFront, 0) + if vCmd and #vCmd > 1 and vCmd2 and #vCmd2 > 1 then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + end + -- eseguo scarico + SpecSetCarrPosFromCmds( vCmd2) + local vCmd3 = SpecCalcUnload() + -- unisco ed emetto i comandi + vCmd = EgtJoinTables( vCmd, vCmd2) + vCmd = EgtJoinTables( vCmd, vCmd3) + SpecOutputCmds( vCmd, true) +end + +--------------------------------------------------------------------- +function OnPostApplyMachining() + + EgtOutLog( ' Lavorazione : ' .. EgtGetName( EMC.MCHID), 1) + + -- Inizializzo codice di errore + EMC.ERR = 0 + + -- Recupero la posizione della trave e dei carrelli al termine della precedente operazione + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID) + -- se precedente operazione non esiste, errore + if not nPrevOpeId then + EMC.ERR = 1 + return + -- se precedente operazione è disposizione + elseif EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP then + if EMC.PHASE == 1 or IsFirstMachiningAfterRotation( EMC.MCHID) then + -- posizioni home + EMC.TPOS = nil + EMC.YDELTA = nil + EMC.VDELTA = nil + EMC.HCING_IGNORE = true + elseif IsStartOrRestPhase( EMC.PHASE) then + -- carico le posizioni + local dPosT = EgtGetInfo( nPrevOpeId, 'TPOS', 'd') + local dPosY = EgtGetInfo( nPrevOpeId, 'YPOS', 'd') + -- se carrello agganciato + if dPosY then + EMC.TPOS = dPosT + EMC.YDELTA = dPosY - dPosT + EMC.VDELTA = nil + -- altrimenti è grezzo scaricato al carico e devo ricaricarlo + else + EMC.TPOS = nil + EMC.YDELTA = nil + EMC.VDELTA = nil + end + EMC.HCING_IGNORE = true + else + -- aggiornamento posizioni (da lavorazione precedente a disposizione) + local nPrev2OpeId = EgtGetPrevActiveOperation( nPrevOpeId) + if not nPrev2OpeId then + EMC.ERR = 1 + return + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrev2OpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + end + EMC.CNT = nil + -- altrimenti precedente operazione è lavorazione + else + -- aggiornamento posizioni + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.YDELTA = EgtGetInfo( nLastPathId, 'YDELTA', 'd') + EMC.VDELTA = EgtGetInfo( nLastPathId, 'VDELTA', 'd') + EMC.CNT = EgtGetInfo( nLastPathId, 'CNT', 'i') + end + + -- Verifico se ultima lavorazione della fase + local nNextOpeId = EgtGetNextActiveOperation( EMC.MCHID) + local bMchLast = ( not nNextOpeId or EgtGetOperationPhase( nNextOpeId) ~= EMC.PHASE) + + -- Verifico se ultima lavorazione prima di una rotazione + local bPreRotMch = IsLastOperationBeforeRotation( EMC.MCHID) + + -- Verifico flag di separazione e fase di scarico + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + local bPreSplit = ( sNotes:find( 'Presplit') ~= nil) + local bSplitting = ( sNotes:find( 'Split') ~= nil) + local bPreCut = ( sNotes:find( 'Precut') ~= nil) + local bCutting = ( sNotes:find( 'Cut') ~= nil) + local bUnload = IsEndPhase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) + if bPreSplit or bPreCut then + EgtSetInfo( EMC.MCHID, 'IS_PRE', '1') + else + EgtRemoveInfo( EMC.MCHID, 'IS_PRE') + end + + -- Agisco sui diversi percorsi della lavorazione + local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EMC.MCHID, 'CL') or GDB_ID.NULL) + while nPathId do + -- assegno id percorso da elaborare + EMC.PATHID = nPathId + -- recupero id del successivo + nPathId = EgtGetNext( nPathId) + -- verifico se ultimo percorso di ultima lavorazione della fase + local bLast = ( bMchLast and ( not nPathId)) + -- se ultimo, elimino ritorno in home + if bLast then EgtRemoveOperationHome( EMC.MCHID) end + -- salvo lo stato di trave e carrelli + local OriTPos = EMC.TPOS + local OriYDelta = EMC.YDELTA + local OriVDelta = EMC.VDELTA + local OriCnt = EMC.CNT + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) + -- se separazione, verifico il risultato + if bSplitting then + -- recupero CUTID del pezzo in lavoro + local CutID = GetCUTID() + -- in caso di errore mancato pinzaggio uscita riprovo dopo aver disabilitato le lavorazioni finali + if EMC.ERR == 18 then + -- segnalazione warning + EMC.ERR = -101 + EMC.MSG = 'Warning : skipped final processes (WRN=101,CUTID='..tostring( CutID)..')' + -- ripristino lo stato originale di trave e carrelli + EMC.TPOS = OriTPos + EMC.YDELTA = OriYDelta + EMC.VDELTA = OriVDelta + EMC.CNT = OriCnt + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) + -- pinzaggio ancora impossibile, pezzo a caduta + if EMC.ERR == 18 then + -- segnalazione warning + EMC.ERR = -102 + EMC.MSG = 'Warning : skipped final processes and unload by fall (WRN=102,CUTID='..tostring( CutID)..')' + end + -- scarico standard + elseif EMC.ERR == 0 then + -- segnalazione warning + EMC.ERR = -100 + EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' + end + -- se taglio del residuo finale, scarico standard + elseif bCutting then + -- recupero CUTID del pezzo in lavoro + local CutID = GetCUTID() + -- se non ci sono errori, segnalazione warning + if EMC.ERR == 0 then + EMC.ERR = -100 + EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' + end + end + if EMC.ERR > 0 then return end + -- determino la posizione finale della trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + end + +end + +--------------------------------------------------------------------- +function SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bUnload, bPreRotMch) + + -- Assegno flag di pezzo separato dal resto del grezzo + local bSplit = IsEndPhase( EMC.PHASE) or IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE) + + -- Assegno flag di pezzo in separazione + local bFixedDelta = ( bPreSplit or bSplitting or bPreCut or bCutting) + + -- Se separazione o taglio del grezzo finale, verifico se precedente era una preparazione + local bFixedPos = false + if bPreSplit or bSplitting or bPreCut or bCutting then + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID) + bFixedPos = EgtExistsInfo( nPrevOpeId or GDB_ID.NULL, 'IS_PRE') + end + + -- Determinazione delle dimensioni totali dei grezzi e del grezzo in lavoro + local b3Tot = BBox3d() + local b3Raw = BBox3d() + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + local nCurrRawId = GDB_ID.NULL + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + local b3Tmp = EgtGetRawPartBBox( nRawId) + b3Tot:Add( b3Tmp) + if EgtGetPartInRawPartCount( nRawId) > 0 and not EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + b3Raw = b3Tmp + nCurrRawId = nRawId + end + end + nRawId = EgtGetNextRawPart( nRawId) + end + if b3Tot:isEmpty() then + EMC.ERR = 11 + return + end + EMC.LB = EgtIf( bSplit, b3Raw:getDimX(), b3Tot:getDimX()) + 10 * GEO.EPS_SMALL + EMC.SB = b3Tot:getDimY() + EMC.HB = b3Tot:getDimZ() + EMC.LR = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + EMC.YMIN = b3Raw:getMin():getY() + EMC.ZMIN = b3Raw:getMin():getZ() + + -- Aggiorno limiti di presa e tolleranza + UpdateMinJoinDeltaTol() + + -- Recupero sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = EgtGetInfo( nCurrRawId, 'HOVM', 'd') or 0 + EMC.HCING = EgtGetInfo( nCurrRawId, 'HCING', 'd') or 0 + EMC.TCING = EgtGetInfo( nCurrRawId, 'TCING', 'd') or 0 + + -- Calcolo dell'ingombro della lavorazione + local dDistFront, dDistBack = SpecialCalcMachiningEncumbrance( EMC.MCHID, bPreCut) + if not dDistFront or not dDistBack then return end + if bPreSplit or bSplitting then + local dDistF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + local dNextHOVM = EgtGetInfo( EgtGetNextRawPart( nCurrRawId) or GDB_ID.NULL, 'HOVM', 'd') or 0 + dDistBack = dDistBack - AGG_B_SPLIT - max( dNextHOVM - 300, 0) + elseif bPreCut or bCutting then + local dDistF = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + dDistBack = 0.0 + end + + -- Verifico lunghezza pezzo + if not bSplit and not VerifyPartLength() then + return + end + + -- Se inizio o appena dopo rotazione, eseguo il carico + if not EMC.TPOS then + local dPosT = LoadT + if IsFirstMachiningAfterRotation( EMC.MCHID) then dPosT = dPosT + TurnerOffs end + local vCmd = SpecCalcLoad( dPosT, dDistFront, max( dDistBack, MinJoin)) + local vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos) + if vCmd2 and #vCmd2 > 1 then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + EgtJoinTables( vCmd, vCmd2) + SpecOutputCmds( vCmd) + + -- Se altrimenti carri entrambi diponibili, eseguo calcoli per carrelli + elseif not IsEndPhase( EMC.PHASE) then + local vCmd = SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos) + -- Se non ci sono spostamenti, confermo i parametri di aggancio + if SpecTestOnlyRemarkInCmds( vCmd) then + table.insert( vCmd, { 21, EgtIf( EMC.YDELTA, EMC.YDELTA, 0), EgtIf( EMC.VDELTA, EMC.VDELTA, 0)}) + end + SpecOutputCmds( vCmd) + + -- Altrimenti, non muovo i carrelli rispetto alla trave + else + local vCmd = {} + SpecOutputCmds( vCmd) + end + EMC.HCING_IGNORE = nil + + -- Se taglio di separazione + local vCmd = {} + if bSplitting then + -- rimuovo eventuale vecchia info di Skip + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) or GDB_ID.NULL + EgtRemoveInfo( NextDispId, 'SKIP') + -- verifico se separazione con caduta + if not EMC.VDELTA then + EgtOutLog( ' Warning SPLITTING -> separazione con caduta pezzo') + if IsEndPhase( EMC.PHASE + 1) then + EgtSetInfo( NextDispId, 'SKIP', '1') + local NextOpeId = EgtGetNextOperation( NextDispId) + while NextOpeId and EgtGetOperationPhase( NextOpeId) == EMC.PHASE + 1 do + EgtSetOperationMode( NextOpeId, false) + NextOpeId = EgtGetNextOperation( NextOpeId) + end + end + EMC.ERR = 18 + -- verifico che la barra sia agganciata ad entrambi i carrelli + elseif not EMC.YDELTA or not EMC.VDELTA then + EMC.ERR = 19 + EMC.MSG = ' Error SPLIT : Y or V not clamped' + return false + end + -- eseguo la separazione ( standard o di pezzo ruotato) + if not IsMid2Phase( EMC.PHASE + 1) then + vCmd = SpecCalcSplit( b3Raw:getDimX()) + else + vCmd = SpecCalcSplitRot( b3Raw:getDimX()) + end + end + -- Se taglio finale di grezzo a perdere + if bCutting then + -- salvo distanza carrello V da inizio grezzo rimasto nella disposizione della prossima fase + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if NextDispId then + EgtSetInfo( NextDispId, 'VPOS', EMC.VDELTA) + end + end + + -- Se previsto scarico, lo eseguo + if bUnload then + EMC.LB = b3Raw:getDimX() + 10 * GEO.EPS_SMALL + local vCmdTmp = SpecCalcUnload() + vCmd = EgtJoinTables( vCmd, vCmdTmp) + end + + -- Se ritorno al carico per rotazione + if bPreRotMch then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + -- eseguo movimento prima di rotazione + local vCmdTmp = SpecCalcPreRot() + vCmd = EgtJoinTables( vCmd, vCmdTmp) + end + + -- Emetto eventuali comandi di separazione e/o scarico + if #vCmd > 0 then + SpecOutputCmds( vCmd, true) + end + +end --SpecApplyPath( bLast) + +--------------------------------------------------------------------- +function SpecialCalcMachiningEncumbrance( nMchId, bPreCut) + -- gruppi della lavorazione + local nClId = EgtGetFirstNameInGroup( nMchId, 'CL') + local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) + if not nPathId then + EMC.ERR = 12 + return + end + -- recupero ptMin ptMax della lavorazione + local ptMin = EgtGetInfo( nClId, 'MMIN', 'p') + local ptMax = EgtGetInfo( nClId, 'MMAX', 'p') + if not ptMin or not ptMax then + EMC.ERR = 13 + return + end + -- se pre-taglio, aggiorno ptMax con quello del taglio finale + if bPreCut then + local ptFinMax = GetFinalCutPmax( nMchId) + if ptFinMax then + ptMax = ptFinMax + end + end + -- Recupero del vettore estrusione (coincide con il vettore utensile) + local vtTool = EgtGetInfo( nPathId, 'EXTR', 'v') + if not vtTool then + EMC.ERR = 14 + return + end + -- Recupero testa + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + -- Calcolo del vettore ausiliario + local vAxes = EmtGetAxesPos( EgtGetFirstInGroup( nPathId)) + if not vAxes or #vAxes < 5 or ( sHead == 'H3' and #vAxes < 6) then + EMC.ERR = 15 + return + end + local vtAux = EgtGetCalcAuxDirFromAngles( vAxes[4], vAxes[5], vAxes[6]) + if not vtAux then + EMC.ERR = 16 + return + end + -- Recupero dei dati dell'utensile + local nToolType = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + local bSaw = ( nToolType == MCH_TY.SAW_FLAT) + local bChain = ( nToolType == MCH_TY.MORTISE_STD) + local dTLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + -- Se sega a catena, devo correggere il versore Aux per farlo coincidere con la direzione del braccio C + if bChain then + if abs( vAxes[6] or 0) < 1 then + vtAux = vtTool + else + vtAux = vtTool ^ vtAux + end + end + -- Calcolo limiti derivanti dalla lavorazione + local dDistFront, dDistBack = SpecCalcEncumbrance( vtTool, vtAux, ptMin, ptMax, bSaw, bChain, dTLen, dTDiam) + return dDistFront, dDistBack +end + +--------------------------------------------------------------------- +function SpecialCalcPhaseEncumbrance( nPhase) + -- Deve essere la fase finale di lavorazione di un pezzo (già staccato dal resto della trave) + local dDistFront = EMC.LB + local dDistBack = EMC.LB + -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine + local nOrigMchId = EgtGetCurrMachining() + local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + local sOrigHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local nOrigExit = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + -- Ciclo sulle lavorazioni + local nMchId = EgtGetNextActiveOperation( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL) + while nMchId and EgtGetOperationPhase( nMchId) == nPhase do + -- imposto lavorazione e utensile correnti + EgtSetCurrMachining( nMchId) + local sTool = EgtGetMachiningParam( MCH_MP.TOOL) + if not EgtTdbSetCurrTool( sTool) then + local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID) + sTool = EgtTdbGetToolFromUUID( sTuuid) + EgtTdbSetCurrTool( sTool) + end + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local nExit = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + if sTool and sHead and nExit then EgtSetCalcTool( sTool, sHead, nExit) end + -- calcolo ingombri + local dDistF, dDistB = SpecialCalcMachiningEncumbrance( nMchId) + if dDistF and dDistB then + dDistFront = min( dDistFront, dDistF) + dDistBack = min( dDistBack, dDistB) + end + nMchId = EgtGetNextActiveOperation( nMchId) + end + -- Ripristino lavorazione e utensile correnti + if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end + if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end + if sOrigTool and sOrigHead and nOrigExit then EgtSetCalcTool( sOrigTool, sOrigHead, nOrigExit) end + -- Restituisco gli ingombri trovati + return dDistFront, dDistBack +end + +--------------------------------------------------------------------- +function GetFinalCutPmax( nMchId) + local nFinalCutId + local nId = EgtGetNextActiveOperation( nMchId) + while nId and EgtGetOperationPhase( nId) == EMC.PHASE do + nFinalCutId = nId + nId = EgtGetNextActiveOperation( nId) + end + if not nFinalCutId then return end + local nCLId = EgtGetFirstNameInGroup( nFinalCutId, 'CL') + if not nCLId then return end + return EgtGetInfo( nCLId, 'MMAX', 'p') +end + +--------------------------------------------------------------------- +function SpecCalcEncumbrance( vtTool, vtArm, ptMin, ptMax, bSaw, bChain, dTLen, dTDiam) + -- Quota in Z dal punto di inclinazione dei carrelli + local dCompZ = sqrt( 1 - vtTool:getZ() * vtTool:getZ()) + local dZup = ptMin:getZ() - 0.5 * dCompZ * dTDiam - ( EMC.ZMIN + 130) + -- Ingombro a sinistra + local dDistBack = EMC.LB + ptMin:getX() + LoadT + local dHeadBack = 350 + if bSaw then + if vtTool:getX() > 0 and abs( vtTool:getY()) < 0.088 and abs( vtTool:getZ()) < 0.088 then + dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.35 then + dHeadBack = EgtIf( vtArm:getX() < 0, 540, 350) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.71 then + if vtArm:getX() < 0 then + dHeadBack = 450 + else + dHeadBack = EgtIf( vtTool:getX() > 0, 50, 90) + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + elseif ( vtTool:getX() > 0.7 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + 0.9 * EMC.HB) then + if vtTool:getZ() > 0 then + dHeadBack = max( 50, 90 - 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + else + dHeadBack = max( 50, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + end + if ptMax:getZ() < EMC.ZMIN + BD.VICE_MINH then + dHeadBack = dHeadBack + BD.VICE_MINH + end + elseif ( vtTool:getX() > 0.2 and abs( vtTool:getZ()) < 0.5) then + dHeadBack = max( 90, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + elseif abs( vtTool:getZ()) < 0.93 then + if vtTool:getX() > 0 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + BD.VICE_MINH then + dHeadBack = 180 + elseif vtTool:getX() > -0.05 then + dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif vtTool:getX() > -0.3 then + dHeadBack = 250 + elseif vtTool:getX() > -0.707 then + dHeadBack = 350 + elseif vtTool:getX() > -0.8667 then + dHeadBack = 450 + else + dHeadBack = 650 + end + else + dHeadBack = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + else + if ( vtTool:getX() > -0.1 and vtArm:getX() > -0.1) or + ( abs( vtTool:getX()) < 0.1 and abs( vtTool:getZ()) < 0.1) then + dHeadBack = EgtIf( EMC.CNT == 1, 180, 130) + elseif ( vtTool:getX() > -0.1 and vtArm:getX() > -0.95) then + dHeadBack = 180 + elseif ( vtTool:getX() < -0.8) then + dHeadBack = 675 + elseif ( vtTool:getX() < -0.75) then + dHeadBack = 650 + elseif ( vtTool:getX() < -0.5) then + dHeadBack = 450 + end + if vtTool:getX() < -0.25 then + dHeadBack = dHeadBack + max( dTLen - 130, 0) * abs( vtTool:getX()) + elseif vtTool:getX() < 0 then + dHeadBack = dHeadBack + ( dTLen + 180) * abs( vtTool:getX()) + end + if vtTool:getX() > 0.866 then + dHeadBack = 50 + elseif vtTool:getX() >= 0 and dZup > 0 then + dHeadBack = max( EgtIf( EMC.CNT == 1, 180, 130), dHeadBack - dZup) + end + if abs( vtTool:getX()) < 0.5 and abs( vtTool:getZ()) > 0.259 and dZup < 0 then + if vtArm:getX() < -0.259 then + dHeadBack = 510 + else + dHeadBack = 260 + end + end + -- pre fresature longitudinali con utensile di fianco + if abs( vtTool:getX()) < 0.1 and vtTool:getZ() < 0.707 and vtArm:getX() < -0.5 then + dHeadBack = 500 + end + -- per sega a catena di fianco + if bChain and vtTool:getX() < 0.5 and vtTool:getZ() < 0.5 and vtArm:getX() < -0.5 then + dHeadBack = max( dHeadBack, 510) + end + -- per interferenza con triangolo di rinforzo sulla pinza Y + if vtTool:getZ() < 0.25 and vtTool:getX() < 0.10 and vtTool:getY() < 0 and vtArm:getX() < -0.707 then + dHeadBack = dHeadBack + 90 + end + end + -- Ingombro a destra + local dDistFront = - ptMax:getX() - LoadT + local dHeadFront = 350 + if bSaw then + if vtTool:getX() < 0 and abs( vtTool:getY()) < 0.088 and abs( vtTool:getZ()) < 0.088 then + dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.35 then + dHeadFront = EgtIf( vtArm:getX() > 0, 540, 350) + elseif abs( vtTool:getZ()) < 0.26 and abs( vtTool:getX()) < 0.71 then + if vtArm:getX() > 0 then + dHeadFront = 450 + else + dHeadFront = EgtIf( vtTool:getX() < 0, 50, 90) + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + elseif ( vtTool:getX() < - 0.7 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + 0.9 * EMC.HB) then + if vtTool:getZ() > 0 then + dHeadFront = max( 50, 90 - 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + else + dHeadFront = max( 50, 40 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX())) + end + if ptMax:getZ() < EMC.ZMIN + BD.VICE_MINH then + dHeadFront = dHeadFront + BD.VICE_MINH + end + elseif ( vtTool:getX() < -0.2 and abs( vtTool:getZ()) < 0.5) then + dHeadFront = max( 90, 40 + 0.5 * dTDiam * sqrt( vtTool:getY() * vtTool:getY() + vtTool:getZ() * vtTool:getZ())) + elseif abs( vtTool:getZ()) < 0.93 then + if vtTool:getX() < 0 and abs( vtTool:getY()) < 0.2 and ptMax:getZ() > EMC.ZMIN + BD.VICE_MINH then + dHeadFront = 180 + elseif vtTool:getX() < 0.05 then + dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + elseif vtTool:getX() < 0.3 then + dHeadFront = 250 + elseif vtTool:getX() < 0.707 then + dHeadFront = 350 + elseif vtTool:getX() < 0.8667 then + dHeadFront = 450 + else + dHeadFront = 650 + end + else + dHeadFront = 50 + 0.5 * dTDiam * sqrt( 1 - vtTool:getX() * vtTool:getX()) + end + else + if ( vtTool:getX() < -0.5 and vtArm:getX() < 0.1) then + dHeadFront = max( 50, dTDiam / 2 * abs( vtTool:getZ()) + 20) + elseif ( vtTool:getX() < 0.1 and vtArm:getX() < 0.1) or + ( abs( vtTool:getX()) < 0.1 and abs( vtTool:getZ()) < 0.1) then + dHeadFront = 130 + elseif ( vtTool:getX() < 0.1 and vtArm:getX() < 0.95) then + dHeadFront = 180 + elseif ( vtTool:getX() > 0.8) then + dHeadFront = 675 + elseif ( vtTool:getX() > 0.75) then + dHeadFront = 650 + elseif ( vtTool:getX() > 0.5) then + dHeadFront = 450 + end + if vtTool:getX() > 0.25 then + dHeadFront = dHeadFront + max( dTLen - 130, 0) * vtTool:getX() + elseif vtTool:getX() > 0 then + dHeadFront = dHeadFront + ( dTLen + 180) * vtTool:getX() + end + if vtTool:getX() < -0.866 then + dHeadFront = 50 + elseif vtTool:getX() <= 0 and dZup > 0 then + dHeadFront = max( 130, dHeadFront - dZup) + end + if abs( vtTool:getX()) < 0.5 and abs( vtTool:getZ()) > 0.259 and dZup < 0 then + if vtArm:getX() > 0.259 then + dHeadFront = 510 + else + dHeadFront = 260 + end + end + -- pre fresature longitudinali con utensile di fianco + if abs( vtTool:getX()) < 0.1 and vtTool:getZ() < 0.707 and vtArm:getX() > 0.5 then + dHeadFront = 500 + end + -- per sega a catena di fianco + if bChain and vtTool:getX() > -0.5 and vtTool:getZ() < 0.5 and vtArm:getX() > 0.5 then + dHeadFront = max( dHeadFront, 510) + end + -- per interferenza con triangolo di rinforzo sulla pinza V + if vtTool:getZ() < 0.25 and vtTool:getX() > -0.10 and vtTool:getY() < 0 and vtArm:getX() > 0.707 then + dHeadFront = dHeadFront + 90 + end + end + -- Stampe debug + EgtOutLog( ' Tdir=' .. tostring( vtTool) .. ' Adir=' .. tostring( vtArm) .. ' Zup=' .. EgtNumToString( dZup), 3) + EgtOutLog( ' DistFront=' .. EgtNumToString( dDistFront) .. ' DistBack=' .. EgtNumToString( dDistBack) .. + ' HeadFront=' .. EgtNumToString( dHeadFront) .. ' HeadBack=' .. EgtNumToString( dHeadBack), 3) + -- Restituisco ingombri effettivi + return ( dDistFront - dHeadFront), ( dDistBack - dHeadBack) +end + +--------------------------------------------------------------------- +function VerifyPartLength() + + -- Verifico lunghezza pezzo + if EMC.LB < MinJoin + MinOther + AGG_LOAD + EMC.HCING + EMC.HOVM then + EgtOutLog( ' Error CLAMP -> pezzo troppo corto') + EMC.ERR = 17 + return false + end + + return true +end + +--------------------------------------------------------------------- +function SpecCalcLoad( dPosT, dDistFront, dDistBack) + --[L] + local dMinDistBack= max( dDistBack, MinJoin + EgtIf( IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE), EMC.TCING, 0)) + local dNewYDelta = max( EMC.LB - dMinDistBack, MinOther + AGG_LOAD + EMC.HCING + EMC.HOVM) + local dNewVDelta = nil + local dNewY = dPosT + TurnerOffs + dNewYDelta + local vCmd = {} + EgtOutLog( ' *[L]', 1) + -- [L-1] + if dNewY - MaxY > 0 then + dNewYDelta = min( EMC.LB - MinJoin + AGG_LOAD, MaxY - dPosT - TurnerOffs) + EgtOutLog( ' *[L1]', 1) + end --[L-2] + if EMC.LB - dNewYDelta < MinJoin then + dNewYDelta = min( EMC.LB - MinJoin + AGG_LOAD, MaxY - dPosT - TurnerOffs) + EgtOutLog( ' *[L2]', 1) + end + -- Commento + table.insert( vCmd, { 0, 'Loading'}) + -- risalita testa a Zmax + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- Apro entrambe le morse + table.insert( vCmd, { 11, 0}) + table.insert( vCmd, { 12, 0}) + -- Sposto il carrello Y per il carico + table.insert( vCmd, { 2, 'Y', dPosT + dNewYDelta, 'V', ParkV}) + -- Chiudo morsa Y + table.insert( vCmd, { 11, EgtIf( EMC.LB - dNewYDelta < LenToPress, 1, 2)}) + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dNewYDelta, 0}) + -- Inizializzo contatore globale + EMC.CNT = 1 + SpecOutputCNT() + -- Assegno stato corrente + EMC.TPOS = dPosT + EMC.YDELTA = dNewYDelta + EMC.VDELTA = nil + -- Restituisco i comandi + return vCmd +end -- SpecAdjustLoad [L] + +--------------------------------------------------------------------- +function SpecCalcCarriages( dDistFront, dDistBack, bFixedDelta, bFixedPos) + + local MinFrontJoin = MinJoin + EMC.HCING + EMC.HOVM + local MinBackJoin = MinJoin + EgtIf( IsMid2Phase( EMC.PHASE) or IsEnd2Phase( EMC.PHASE), EMC.TCING, 0) + local MyMinOther = MinOther + EgtIf( EMC.CNT == 1, AGG_LOAD, 0) + + local dDistFrontEff = min( dDistFront, EMC.LB - MyMinOther - EMC.TCING) + if bFixedDelta and IsMid2Phase( EMC.PHASE + 1) then + dDistFrontEff = min( dDistFrontEff, EMC.LR - MinOther - EMC.TCING) + end + local dDistBackEff = min( dDistBack, EMC.LB - MyMinOther - EMC.HCING - EMC.HOVM) + + EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBackEff, 1) .. '/' .. EgtNumToString( MinBackJoin, 1) .. + ' Front=' .. EgtNumToString( dDistFrontEff, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1) .. + ' Fixed : Delta=' .. EgtIf( bFixedDelta, 'T', 'F') .. ' Pos=' .. EgtIf( bFixedPos, 'T', 'F'), 3) + + -- [A] se posso mettere solo carrello Y + if dDistFrontEff < MinFrontJoin and dDistBackEff > MinBackJoin - GEO.EPS_SMALL then + + local dPosT = EMC.TPOS + local dYDelta = EMC.YDELTA + local dVDelta = EMC.VDELTA + + local dNewPosT = nil + local dNewYDelta = EMC.LB - dDistBackEff + local dNewVDelta = nil + + return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos) + + -- [B] se altrimenti posso mettere entrambi i carrelli Y e V + elseif dDistBackEff > MinBackJoin - GEO.EPS_SMALL and + dDistFrontEff > MinFrontJoin - GEO.EPS_SMALL then + + local dPosT = EMC.TPOS + local dYDelta = EMC.YDELTA + local dVDelta = EMC.VDELTA + + local dNewPosT = nil + local dNewYDelta = EMC.LB - dDistBackEff + local dNewVDelta = dDistFrontEff + + return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos) + + -- [C] se altrimenti posso mettere solo carrello V + elseif dDistBackEff < MinBackJoin and dDistFrontEff > MinFrontJoin - GEO.EPS_SMALL then + + local dPosT = EMC.TPOS + local dYDelta = EMC.YDELTA + local dVDelta = EMC.VDELTA + + local dNewPosT = nil + local dNewYDelta = nil + local dNewVDelta = dDistFrontEff + + return SpecAdjustCarriages( dPosT, dYDelta, dVDelta, dNewPosT, dNewYDelta, dNewVDelta, bFixedDelta, bFixedPos) + + -- altrimenti errore + else + if EgtGetDebugLevel() < 3 then + EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBackEff, 1) .. '/' .. EgtNumToString( MinBackJoin, 1) .. + ' Front=' .. EgtNumToString( dDistFrontEff, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1)) + end + EgtOutLog( ' Error CLAMP impossible') + EMC.ERR = 18 + return {} + end + +end + +--------------------------------------------------------------------- +function SpecCalcSplit( dLenRaw) + local vCmd = {} + EgtOutLog( ' *[S]', 1) + table.insert( vCmd, { 0, EgtIf( EMC.VDELTA, 'Split', 'Fall')}) + -- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari) + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + table.insert( vCmd, { 31, nRawId, 'Y'}) + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- riporto il carrello Y al carico con il resto della trave + local dLDelta = EMC.YDELTA - dLenRaw + table.insert( vCmd, { 1, 'Y', LoadT + dLDelta}) + table.insert( vCmd, { 21, 0, EMC.VDELTA or 0}) + -- imposto subito Y non più attaccato al trave in lavoro + EMC.YDELTA = nil + -- salvo posizione carrello Y in disposizione del pezzo dopo split + local PostDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if PostDispId then + EgtSetInfo( PostDispId, 'YPOS', LoadT + dLDelta) + end + -- salvo posizione grezzo rimasto e posizione carrello Y nella disposizione iniziale del pezzo succ (prossima fase dispari) + local NextDispId = EgtGetPhaseDisposition( nNextOddPhase) + if NextDispId then + EgtSetInfo( NextDispId, 'TPOS', LoadT) + EgtSetInfo( NextDispId, 'YPOS', LoadT + dLDelta) + end + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcSplitRot( dLenRaw) + local vCmd = {} + EgtOutLog( ' *[SR]', 1) + table.insert( vCmd, { 0, 'SplitRot'}) + -- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari) + local vRaw = {} + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + table.insert( vRaw, nRawId) + end + nRawId = EgtGetNextRawPart( nRawId) + end + for _, nId in ipairs( vRaw) do + table.insert( vCmd, { 31, nId, 'Y'}) + end + -- riporto il carrello Y al carico con il resto della trave + local dLDelta = EMC.YDELTA - dLenRaw + table.insert( vCmd, { 1, 'Y', LoadT + TurnerOffs + dLDelta}) + table.insert( vCmd, { 21, 0, EMC.VDELTA}) + -- imposto subito Y non più attaccato alla trave in lavoro + EMC.YDELTA = nil + -- apro il carrello Y + table.insert( vCmd, { 11, 0}) + -- sgancio i grezzi dal carrello Y + for _, nId in ipairs( vRaw) do + table.insert( vCmd, { 31, nId, ''}) + end + -- lo porto in parcheggio + table.insert( vCmd, { 1, 'Y', ParkY}) + -- salvo posizione grezzo rimasto nella disposizione iniziale del pezzo succ (prossima fase dispari) + local NextDispId = EgtGetPhaseDisposition( nNextOddPhase) + if NextDispId then + EgtSetInfo( NextDispId, 'TPOS', LoadT) + end + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcUnload() + local vCmdPre = {} + EgtOutLog( ' *[U]', 1) + -- Se pinza Y chiusa , devo effettuare uno scambio + if EMC.YDELTA then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + -- imposto quote aggancio per avere solo pinza V + local dDistFront = EMC.LB - MinOther - EMC.TCING - 10 * GEO.EPS_SMALL + local dDistBack = 0 + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack) + if EMC.ERR ~= 0 then + return {} + end + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' *[U1]', 1) + end + local vCmd = {} + -- Tipo di scarico + local bStdUl = ( MaxUnloadLen < 1 or EMC.LB - EMC.HOVM < MaxUnloadLen + 1) + -- Commento + table.insert( vCmd, { 0, 'Unloading', EgtIf( bStdUl, 'Unloading', 'Manual Unloading')}) + -- risalita testa a Zmax + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- Se pinza Y chiusa, la apro + if EMC.YDELTA then + table.insert( vCmd, { 11, 0}) + end + -- Se non supero la lunghezza massima di scarico, sposto il pezzo in posizione di scarico + if bStdUl then + local dFinT = UnloadT - EMC.LB + local dFinV = dFinT + EMC.VDELTA + table.insert( vCmd, { 2, 'T', dFinT, 'V', dFinV}) + else + table.insert( vCmd, { 1, 'V', MaxV}) + end + -- apro la morsa + table.insert( vCmd, { 12, 0}) + -- riporto il carrello in home + table.insert( vCmd, { 1, 'V', ParkV}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcPreRot() + local vCmdPre = {} + EgtOutLog( ' *[PR]', 1) + -- Se pinza V chiusa , devo effettuare uno scambio + if EMC.VDELTA then + -- imposto quote aggancio per avere solo pinza Y + local dDistFront = 0 + local dDistBack = EMC.LB - MinOther - EMC.HOVM + 10 * GEO.EPS_SMALL + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack) + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' *[PR1]', 1) + end + -- porto il pezzo alla zona di rotazione con il carro Y + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Pre-Rotation'}) + -- risalita testa a Zmax + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- Se pinza V chiusa, la apro + if EMC.VDELTA then + table.insert( vCmd, { 12, 0}) + end + -- riporto la trave al carico + local RotT = LoadT + TurnerOffs + table.insert( vCmd, { 2, 'Y', RotT + EMC.YDELTA, 'T', RotT}) + -- apro la morsa + table.insert( vCmd, { 11, 0}) + -- riporto il carrello in home + table.insert( vCmd, { 1, 'Y', ParkY}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecAdjustCarriages( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos) + + -- [A] richiesto solo carrello Y + if dYDeltaF and ( not dVDeltaF) then + -- [A1] rimango sul carrello Y + if dYDeltaI and ( not dVDeltaI) then + return SpecAdjustCarrA1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + -- [A2] torno da entrambi + elseif dYDeltaI and dVDeltaI then + return SpecAdjustCarrA2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + -- [A3] torno da carrello V + elseif dVDeltaI and (not dYDeltaI) then + return SpecAdjustCarrA3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + else + EgtOutLog( ' Error CLAMP NULL-> Y impossibile') + error( 'Error CLAMP NULL-> Y impossibile') + end + + -- (B) richiesti entrambi i carrelli + elseif dYDeltaF and dVDeltaF then + -- [B1] passo da carrello Y a entrambi + if dYDeltaI and ( not dVDeltaI) then + return SpecAdjustCarrB1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [B2] continuo con entrambi i carrelli + elseif dYDeltaI and dVDeltaI then + return SpecAdjustCarrB2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [B3] passo da carrello V a entrambi + elseif dVDeltaI and (not dYDeltaI) then + return SpecAdjustCarrB3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + else + EgtOutLog( ' Error CLAMP NULL-> Y+V impossibile') + error( 'Error CLAMP NULL-> Y+V impossibile') + end + + -- [C] richiesto solo carrello V + elseif ( not dYDeltaF) and dVDeltaF then + -- [C1] provengo da solo carrello Y + if dYDeltaI and ( not dVDeltaI) then + return SpecAdjustCarrC1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [C2] provengo da carrelli Y e V + elseif dYDeltaI and dVDeltaI then + return SpecAdjustCarrC2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + -- [C3] rimango sul carrello V + elseif ( not dYDeltaI) and dVDeltaI then + return SpecAdjustCarrC3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos) + else + EgtOutLog( ' Error CLAMP NULL-> V impossibile') + error( 'Error CLAMP NULL-> V impossibile') + end + + end + +end + +--------------------------------------------------------------------- +local function CalcCharStatus( sType, dDelta) + -- se per carrello Y + if sType == 'Y' then + return EgtIf( EMC.LB - dDelta < LenToPress, 1, 2) + -- altrimenti per carrello V + else + return EgtIf( dDelta < LenToPress, 1, 2) + end +end + +--------------------------------------------------------------------- +local function GetDeltaTol( dLenPresa, TCING, HCING, HOVM, Carr, bFixedDelta) + local dDeltaTolEff = DELTA_SIC + if Carr == 'Y' then + local dLenPreEff = dLenPresa - TCING + if dLenPreEff < MinJoin + DeltaTol then + dDeltaTolEff = max( DELTA_SIC, dLenPreEff - MinJoin + 10 * GEO.EPS_SMALL) + else + if BD.GO_FAST and BD.GO_FAST ~= 0 then + if bFixedDelta == false then + dDeltaTolEff = min( EMC.LB + 700, dLenPreEff, 3200) + else + dDeltaTolEff = 900 + end + else + dDeltaTolEff = DeltaTol + end + end + elseif Carr == 'V' then + local dLenPreEff = dLenPresa - HCING - HOVM + if dLenPreEff < MinJoin + DeltaTol then + dDeltaTolEff = max( DELTA_SIC, dLenPreEff - MinJoin + 10 * GEO.EPS_SMALL) + else + dDeltaTolEff = DeltaTol + end + end + return EgtIf( bFixedDelta, min( dDeltaTolEff, DELTA_TOL_FIXED), dDeltaTolEff) +end + +--------------------------------------------------------------------- +local function GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistN, sSide) + local dRecTotn = min( dDistN, dCorsaYfc+ dCorsaVfc) -- recupero possibile al netto di dCorsa..TrA) + local dCorsaYd, dCorsaYTd, dCorsaVd, dCorsaVTd + if sSide == 'Fr' then + if dRecTotn / 2 <= dCorsaYfc then + if dRecTotn / 2 <= dCorsaVfc then + dCorsaYTd = dRecTotn / 2 + dCorsaVd = dRecTotn / 2 + else + dCorsaVd = dCorsaVfc + dCorsaYTd = min( dCorsaYfc, dRecTotn - dCorsaVd) + end + else + dCorsaYTd = dCorsaYfc + dCorsaVd = min( dCorsaVfc, dRecTotn - dCorsaYTd) + end + dCorsaY = dCorsaYTd + dCorsaV = dCorsaVd + else + if dRecTotn / 2 <= dCorsaVfc then + if dRecTotn / 2 <= dCorsaYfc then + dCorsaVTd = dRecTotn / 2 + dCorsaYd = dRecTotn / 2 + else + dCorsaYd = dCorsaYfc + dCorsaVTd = min( dCorsaVfc, dRecTotn - dCorsaYd) + end + else + dCorsaVTd = dCorsaVfc + dCorsaYd = min( dCorsaYfc, dRecTotn - dCorsaVTd) + end + dCorsaY = dCorsaYd + dCorsaV = dCorsaVTd + end + return dCorsaY, dCorsaV +end + +--------------------------------------------------------------------- +local function PosxExtraYV( dYPosA, dVPosA, dTPosA, dMinY, dMaxV, sYV) + -- svolge la predisposizione iniziale di trave e carrelli in caso di situazione iniziale con un solo carrello chiuso + -- con un solo carrello chiuso per l'aggancio del carrello aperto + local dYPos, dVPos, dTPos + -- per aggancio del carrello V + if sYV == 'V' then + dTPos = min( dTPosA, dVPosA - MinJoin - EgtIf( EMC.HCING_IGNORE, 0, EMC.HCING) - EMC.HOVM) + dYPos = dYPosA + ( dTPos - dTPosA) + if dYPos < dMinY then + dVPos = dVPosA + ( dMinY - dYPos) + if dVPos > dMaxV + GEO.EPS_SMALL then + EmitComment( vCmd, ' Error CLAMP V') + error( 'Error CLAMP V') + return + elseif dVPos > dMaxV - GEO.EPS_SMALL then + dVPos = dMaxV + end + dYPos = dMinY + dTPos = dTPosA + ( dYPos - dYPosA) + else + --dYPos = dMinY + --dYPos = dYPos! + --dTPos = dTPosA + ( dYPos - dYPosA) + --dTPos = dTPos! + dVPos = dVPosA + end + end + -- per aggancio del carrello Y + if sYV == 'Y' then + dTPos = max( dTPosA, dYPosA + MinJoin + EMC.TCING - EMC.LB) + dVPos = dVPosA + ( dTPos - dTPosA) + if dVPos > dMaxV then + dYPos = dYPosA - ( dVPos - dMaxV) + if dYPos < dMinY - GEO.EPS_SMALL then + EmitComment( vCmd, ' Error CLAMP Y') + error( 'Error CLAMP Y') + return + elseif dYPos < dMinY + GEO.EPS_SMALL then + dYPos = dMinY + end + dVPos = dMaxV + dTPos = dTPosA + ( dVPos - dVPosA) + else + -- ++++++++++++++++++++++++++++++++ + --dVPos = dMaxV + --dVPos = dVPos! + --dTPos = dTPosA + ( dVPos - dVPosA) + --dTpos = dTPos!! + dYPos = dYPosA + end + end + return dYPos, dVPos, dTPos +end + +--------------------------------------------------------------------- +local function PosXs2Enl (dYa, dVa, dTa, dExtraC, dCorsaTra, dCorsaYd, dCorsaVd, sYV) + -- svolge la fase di allontanamento dei carrelli per il recupero di 'ExtraV'/'ExtraY' + -- richiesto alle posizioni [--.xs2] delle funzioni SpecAdjustCarr.. + if sYV == 'V' then -- caso di ExtraV (ed eventuale ulteriore allontanamento di Y) + local dCorsaYTrA = dCorsaTra + local dExtraVn = dExtraC - dCorsaYTrA + -- eseguo allontanamento di Y e (V+T) + if dExtraVn / 2 <= dCorsaYd then + if dExtraVn / 2 <= dCorsaVd then + dYa = dYa + dExtraVn / 2 + dVa = dVa - dExtraVn / 2 + dTa = dTa - dExtraVn / 2 + else + dVa = dVa - dCorsaVd + dTa = dTa - dCorsaVd + dYa = dYa + min( dExtraVn - dCorsaVd, dCorsaYd) + end + else + dYa = dYa + dCorsaYd + dVa = dVa - min( dExtraVn - dCorsaYd, dCorsaVd) + dTa = dTa - min( dExtraVn - dCorsaYd, dCorsaVd) + end + end + + if sYV == 'Y' then -- caso di ExtraY (ed eventuale ulteriore allontanamento di V) + local dCorsaVTrA = dCorsaTra + local dExtraYn = -dExtraC - dCorsaVTrA + -- eseguo allontanamento di (Y+T) e V + if dExtraYn / 2 <= dCorsaVd then + if dExtraYn / 2 <= dCorsaYd then + dVa = dVa - dExtraYn / 2 + dYa = dYa + dExtraYn / 2 + dTa = dTa + dExtraYn / 2 + else + dYa = dYa + dCorsaYd + dTa = dTa + dCorsaYd + dVa = dVa - min( dExtraYn - dCorsaYd, dCorsaVd) + end + else + dVa = dVa - dCorsaVd + dYa = dYa + min( dExtraYn - dCorsaVd, dCorsaYd) + dTa = dTa + min( dExtraYn - dCorsaVd, dCorsaYd) + end + end + return dYa, dVa, dTa +end + +--------------------------------------------------------------------- +-- *** [A1] da carrello Y a Y : Y -> Y *** +--------------------------------------------------------------------- +function +SpecAdjustCarrA1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + EgtOutLog( ' *[A1] = Y -> Y', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y -> Y'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + -- recupero le posizioni correnti dei carrelli + local dYPosA = dTPosI + dYDeltaI + local dVPosA = ParkV + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVPosA - dTPosA + local dNewYDelta -- = dYDeltaF + local dCorsaYfc = MaxY - dYPosA + local dCorsaYd = min( dCorsaYfc, EMC.LB - dYDeltaI - MinJoin) + + -- tolleranza + local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y') + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol/2 + else + dNewYDelta = dYDeltaA + end + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta), 1) + -- flag per risalita resta a Zmax + local bZmaxOk = false + + -- **[A1Ys]** |pos. di Y cambia in modo significativo| + if bYDeltaS then + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- definisco 'ExtraY' con (Y+T) e V accentrati q.b. per la presa con V + local dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'V') + local dNewY = dTPos + dNewYDelta + local dExtraY = dNewY - MyMinY + -- effettuo spostamenti di (Y+T) e V per predisporre all'aggancio di T con V + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dVDeltaA = dVPosA - dTPosA + + -- **[A1Ys-x]** posizione di |Y non raggiungibile| (oltre MyMinY) + if dExtraY < 0 then + -- **[A1Ys-xs]** posizione di Y non raggiungibile, |con ExtraY 'significativo'| + if -dExtraY > dYDeltaTol /2 then + --EmitComment( vCmd, '[A1Ys-xs]') + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V + local dCorsaYfc = MaxY - dYPos + local dCorsaVfc = dVPos - MinV + local dDistFrN = (dVPos-dTPos) - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + local dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + local dCorsaVTr = dCorsaVd + (MaxV - dVPos) + local dCorsaYr = dCorsaYTd + -- **[A1Ys-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraY > CorsaVr + CorsaYr| + if -dExtraY > ( dCorsaVTr + dCorsaYr) and bYDeltaS then + EmitComment( vCmd, '[A1Ys-xsw]' .. 'CASO NON GESTITO') + return + end + + local dCorsaVTrA = MaxV - dVPos -- !! att.ne: non dVPosA !! + -- **[A1Ys-xs1]** se posso recuperare ExtraY semplicem' accentrando Y e (V+T) + -- (dalle posizione impostate sopra per l'aggancio di V) + if dCorsaVTrA >= -dExtraY then + EmitComment( vCmd, '[A1Ys-xs1]') + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** Y e (V+T) + dYPosA = MyMinY -- (pos. finale) + dVPosA = dVPosA + (-dExtraY) + dTPosA = dTPosA + (-dExtraY) + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dYDeltaA = dYPosA - dTPosA + + else -- **[A1Ys-xs2]** + -- ci sarebbe un doppio movimento di Y ? => caso impossibile ? + EmitComment( vCmd, '[A1Ys-xs2]') + -- **1:** posiziono (ulteriormente!) (Y+T) e V + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dVDeltaA = dVPosA - dTPosA + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2: accentro** Y e (V+T) + dYPosA = MyMinY -- (pos. finale) + dVPosA = MaxV + dTPosA = dVPosA - dVDeltaA + --dVDeltaA = dVPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [A1Ys-xs1/-xs2] + + -- **[A1Ys-xn]** |dExtraY ancora < 0 ma non 'significativo')| + else --if -dExtraY < DeltaToll/2 + EmitComment( vCmd, '[A1Ys-xn]') + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** accentro Y + dExtraY = 0 + dYPosA = MyMinY -- (pos. finale) + table.insert( vCmd, { 1, 'Y', dYPosA}) + -- dYDeltaA = dYPosA - dTPosA + end --[A1Ys-xs/xn] + + -- **[A1Ys-r]** |posizione di Y raggiungibile| (ExtraY >=0) + -- (si esclude la possibilità di extra corsa oltre maxY) + else + EmitComment( vCmd, '[A1Ys-r]') + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** posiziono Y alla posizione richiesta + dYPosA = dNewY + table.insert( vCmd, { 1, 'Y', dYPosA}) + end -- [A1Ys] + + -- calcolo il nuovo parametro di aggancio + dYDeltaA = dYPosA - dTPosA + -- chiudo Y e apro V + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V in parcheggio + table.insert( vCmd, { 1, 'V', ParkV}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, dYDeltaA, 0}) + + -- reset contatore + EMC.CNT = nil + + else -- **[A1Yns]** |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'| + EmitComment( vCmd, '[A1Yns]') + end --[A1Ys/ns] + + EgtOutLog(' YDeltaA =' .. EgtNumToString( dYDeltaA), 1) + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrA1 + +--------------------------------------------------------------------- +-- *** [A2] da entrambi a carrello Y : Y+V -> Y *** +--------------------------------------------------------------------- +function SpecAdjustCarrA2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + EgtOutLog( ' *[A2] = Y+V -> Y ', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y+V -> Y'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + local dCorsaY = MaxY - MyMinY + local dCorsaV = MaxV - MinV + -- recupero le posizioni correnti dei carrelli + local dYPosA = dTPosI + dYDeltaI + local dVPosA = dTPosI + dVDeltaI + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVDeltaI + local dNewYDelta -- = dYDeltaF + -- tolleranze + local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y') + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol/2 + else + dNewYDelta = dYDeltaA + end + -- definisco 'ExtraY' + local dNewY = dTPosA + dNewYDelta + local dExtraY = dNewY - MyMinY -- < 0 = nuova pos. di Y 'non raggiungibile' (= oltre MyMinY) + -- definisco 'ExtraY significativo' + local bYxs = -dExtraY > dYDeltaTol/2 + + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI) .. + ' VDeltaI=' .. EgtNumToString( dVDeltaI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta), 1) + -- flag per risalita resta a Zmax + local bZmaxOk = false + -- risalita testa a Zmax (da effettuare comunque, per il parcheggio di V) + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bYDeltaS then + if bYxs then + -- calcolo le **corse disponibili** dei carrelli **a partire dalle posizioni attuali** (=iniziali) + -- per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxV - dVPosA) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaYr + dCorsaVTr + end + end + + -- **[A2Ys-xsw]** posizione NewY non raggiungibile (oltre MyMinY), con ||dEXtraY | > CorsaYr + CorsaVTr| + while bXsw do + EmitComment( vCmd, '[A2Ys-xsw]') + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- chiudo eventualmente il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** allontano q.p. (Y+T) e V + dYPosA = dYPosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dVPosA = dVPosA - dCorsaVd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:** accentro Y e (V+T) + dYPosA = MyMinY + dVPosA = dVPosA + dCorsaVTr + dTPosA = dTPosA + dCorsaVTr + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + -- valuto Delta attuali + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- aggiorno l'extra corsa residua per Y + dExtraY = dExtraY + dCorsaYr + dCorsaVTr + bYxs = -dExtraY > dYDeltaTol/2 + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end -- [A2Ys-xw] + + -- **[A2Ys]** se lo |spostamento| richiesto (ev' residuo) per |Y| è |'significativo'| + if bYDeltaS then + -- **[A2Ys-x]** se la |posizione per Y non è 'raggiungibile'| + if dExtraY < 0 then + -- **[A2Ys-xs]** se |ExtraY 'significativo'| + if bYxs then + local dCorsaVTrA = MaxV - dVPosA + -- **[A2Ys-xs1]** se posso recuperare ExtraY solo accentrando (V+T) e Y + if dCorsaVTrA >= -dExtraY then + EmitComment( vCmd, '[A2Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** accentro (V+T) q.b. e Y + dVPosA = dVPosA + (-dExtraY) + dTPosA = dTPosA + (-dExtraY) + dYPosA = MyMinY -- (pos. finale) + --dYDeltaA = dYPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + else -- **[A2Ys-xs2]** + EmitComment( vCmd, '[A2Ys-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** allontano (Y+T) e V + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dVDeltaA = dVPosA - dTPosA + -- chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:** accentro Y e (V+T) q.b. per recupero di dExtraY + dYPosA = MyMinY + dVPosA = MaxV + dTPosA = dVPosA - dVDeltaA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end --[A2Ys-xs1/-xs2] + + -- [A2Ys-xn] |ExtraY ancora <= 0, ma 'non significativo'| + else --if dExtraY <= 0 then + EmitComment( vCmd, '[A2Ys-xn]') + dExtraY = 0 + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- 1: accentro Y + dYPosA = MyMinY -- (pos. finale) + table.insert( vCmd, { 1, 'Y', dYPosA}) + end -- [A2Ys-xs/xn] + + --[A2Ys-r] dExtrav > 0 ( |pos. Y'raggiungibile|) + else + EmitComment( vCmd, '[A2Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- posizione Y + dYPosA = dTPosA + dNewYDelta -- (pos. finale) + table.insert( vCmd, { 1, 'Y', dYPosA}) + end -- [A2Ys-x/r] + + else -- [A2Yns] |spostamento Y| (ev' residuo) |non significativo| + EmitComment( vCmd, '[A2Yns]') + end -- [A2Ys/ns] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dYPosA - dTPosA + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V in parcheggio + table.insert( vCmd, { 1, 'V', ParkV}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, 0}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrA2 + +--------------------------------------------------------------------- +-- *** [A3] da carrello V a Y : V -> Y *** +--------------------------------------------------------------------- +function SpecAdjustCarrA3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF) + EgtOutLog( ' *[A3] = V -> Y', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'V -> Y'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + -- recupero le posizioni correnti + local dYPosA = ParkY + local dTPosA = dTPosI + local dVPosA = dTPosI + dVDeltaI + local dYDeltaA = dYPosA - dTPosA + local dVDeltaA = dVDeltaI + local dNewYDelta -- = dVDeltaF + -- tolleranza + local dYDeltaTol = GetDeltaTol( EMC.LB - dYDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y') + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol/2 + else + dNewYDelta = dYDeltaA + end + -- + EgtOutLog(' VDeltaI=' .. EgtNumToString( dVDeltaA) .. ' YDeltaI(Park)='.. EgtNumToString( dYDeltaA).. + ' TPosI=' .. EgtNumToString( dTPosI) , 1) + EgtOutLog(' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' NewYDelta=' .. EgtNumToString( dNewYDelta) , 1) + local bZmaxOk = false + -- risalita testa a Zmax (da effettuare comunque, dato lo scambio di carrelli) + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dYPos, dVPos, dTPos + local dNewY, dExtraY, bYxs + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bYDeltaS then + -- definisco 'ExtraY' con Y e (V+T) accentrati q.b. per la presa con Y + dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'Y') + dNewY = dTPos + dNewYDelta + dExtraY = dNewY - MyMinY --( <0 <=> pos. 'non raggiungibile') + bYxs = -dExtraY > dYDeltaTol/2 + if bYxs then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPos + dCorsaVfc = dVPos - MinV + --local dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dDistFrN = (dVPos-dTPos) - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxV - dVPos) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end + -- inizializzo + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + end + + -- **[A3Ys-xsw]** posizione finale dNewY non raggiungibile, con |dEXtraY > CorsaVr + CorsaYr| + while bXsw do + EmitComment( vCmd, '[A3Ys-xsw]') + -- |1:| posiziono (V+T) e Y come calcolato sopra + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo ev' il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |2:| allontano (Y+T) e V quanto possibile + dYPosA = dYPosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dVPosA = dVPosA - dCorsaVd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |3:| accentro (V+T) e Y + dVPosA = dVPosA + dCorsaVTr + dTPosA = dTPosA + dCorsaVTr + dYPosA = MyMinY + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- aggiorno ExtraY + dExtraY = dExtraY + dCorsaYr + dCorsaVTr + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end --[A3Ys-xw] + + -- **[A3Ys]** |spostamento| richiesto (ev' residuo) |di Y| |'significativo'| + if bYDeltaS then + EmitComment( vCmd, '[A3Ys]') + -- **[A3Ys-x]** posizione di |Y non raggiungibile| + if dExtraY < 0 then + + -- **[A3Ys-xs]** |pos. NewY non raggiungibile, con ExtraY 'significativo'| + -- ( -dExtraY <= (CorsaYr+CorsaVr) da ciclo precedente ) + if bYxs then + local dCorsaVTrA = MaxV - dVPosA + -- **[A3Ys-xs1]** se posso recuperare ExtraY semplicem' accentrando Y e (V+T) + -- ulteriormente rispetto a YPos e Vpos definiti c.s. + if dCorsaVTrA >= -dExtraY then + EmitComment( vCmd, '[A3Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** Y e (V+T) + dYPosA = MyMinY -- (pos. finale) + dVPosA = dVPosA + dExtraY + dTPosA = dTPosA + dExtraY + dYDeltaA = dYPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[A3Ys-xs2]** + EmitComment( vCmd, '[A3Ys-xs2]') + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** ev' Y e (V+T) alle posizioni impostate + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dYDeltaA = dYPosA - dTPosA + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: allontano** (Y+T) e V + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dVDeltaA = dVPosA - dTPosA + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **3: accentro** Y e (V+T) + dYPosA = MyMinY -- (pos. finale) + dVPosA = MaxV + dTPosA = dVPosA - dVDeltaA + --dYDeltaA = dYPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [A3Ys-xs1/-xs2] + + -- **[A3Ys-xn]** |dExtraY ancora < 0 ma non 'significativo')| + else --if -dExtraY < DeltaToll/2 + EmitComment( vCmd, '[A3Ys-xn]') + -- ev' chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1:** accentro Y e porto (V+T) alla posizione impostata + dExtraY = 0 + dYPosA = MyMinY -- (pos. finale) + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end --[A3Ys-xs/xn] + + -- **[A3Ys-r]** |posizione di Y raggiungibile (ExtraY >=0)| + else + EmitComment( vCmd, '[A3Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- posizione Y in posizione finale ed ev' (V+T) come impostato sopra + dYPosA = dTPosA + dNewYDelta + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [A3Ys] + + else -- **[A3Yns]** |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'| + EmitComment( vCmd, '[A3Yns]') + end --[A3Ys/ns] + + -- calcolo il nuovo parametro di aggancio + dYDeltaA = dYPosA - dTPosA + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V in parcheggio + table.insert( vCmd, { 1, 'V', ParkV}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, dYDeltaA, 0}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrA3 + +--------------------------------------------------------------------- +local function AdjustPositionsForB( dNewYDelta, dNewVDelta, TCING, HCING, HOVM, bFixedDelta) + local REF_DIST = 1400 + local dYDelta = 0 + local dVDelta = 0 + -- incremento se possibile la distanza tra le due posizioni + if not bFixedDelta and ( dNewYDelta - dNewVDelta) < REF_DIST then + local dEffAddDist = ( REF_DIST - ( dNewYDelta - dNewVDelta)) / 2 + dYDelta = max( min( dEffAddDist, EMC.LB - dNewYDelta - MinJoin - TCING), 0) + dVDelta = max( min( dEffAddDist, dNewVDelta - MinJoin - HOVM - HCING), 0) + end + return dYDelta, dVDelta +end + +--------------------------------------------------------------------- +-- *** [B1] da carrello Y a entrambi : Y -> Y+V *** +--------------------------------------------------------------------- +function SpecAdjustCarrB1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[B1] = Y -> Y+V', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y -> Y+V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + local dCorsaY = MaxY - MyMinY + local dCorsaV = MaxV - MinV + -- recupero le posizioni correnti + local dYPosA = dTPosI + dYDeltaI + local dVPosA = ParkV + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVPosA - dTPosA + local dNewYDelta + local dNewVDelta + -- incremento la distanza tra le due posizioni ( se abilitato e possibile) + local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta) + -- tolleranze + local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y', bFixedDelta) + local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + -- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 2 + else + dNewYDelta = dYDeltaA + end + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + + EgtOutLog(' YDeltaI=' .. EgtNumToString( dYDeltaA) .. ' VDeltaI(Park)='.. EgtNumToString( dVDeltaA) .. + ' TPosI='.. EgtNumToString( dTPosI), 1) + EgtOutLog(' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1) + EgtOutLog(' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + + -- risalita testa a Zmax + local bZmaxOk = false + + -- calcoli preliminari in caso di spostamento richiesto per V significativo + local dYPos, dVpos, dTPos + local dNewV, dExtraV, bVxs + local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw + if bVDeltaS then + -- definisco 'ExtraV' con (Y+T) e V accentrati q.b. per la presa di V + dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'V') + dNewV = dTPos + dNewVDelta + dExtraV = dNewV - MaxV -- se > 0 pos. V non direttamente 'raggiungibile' + bVxs = dExtraV > dVDeltaTol/2 -- ExtraV 'significativo' + if bVxs then + -- calcolo le **corse disponibili** dei carrelli a partire da Y e V c.s.| + -- per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxY - dYPos + dCorsaVfc = dVPos - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto le **corse di 'recupero'** dai due carrelli possibili riaccentrando (Y+T) e V + dCorsaYTr = dCorsaYd + (dYPos - MyMinY) + dCorsaVr = dCorsaVTd + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaVr + dCorsaYTr + end + -- inizializzo + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + end + + -- **[B1Vs-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraV > CorsaVr + CorsaYr| + while bXsw do + EmitComment( vCmd, '[B1Vs-xsw]') + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- |1:| imposto (Y+T) e V come calcolato sopra + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |2:| allontano Y e (V+T) quanto possibile + dYPosA = dYPosA + dCorsaYd + dVPosA = dVPosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |3:| accentro (Y+T) e V + dYPosA = dYPosA - dCorsaYTr + dTPosA = dTPosA - dCorsaYTr + dVPosA = MaxV + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno l'extra corsa residuo per V + dExtraV = dExtraV - dCorsaYTr - dCorsaVr + + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- aggiorno i prossimi recuperi disponibili + dCorsaYTr = dCorsaYd + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaVr + dCorsaYTr + end --[B1Vs-xw] + + -- **[B1Vs]** se lo |spostamento| finale richiesto (ev' residuo) di |V| è |'significativo'| + if bVDeltaS then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- **[B1Vs-x]** posizione di |V non raggiungibile| + if dExtraV > 0 then + -- **[B1Vs-xs]** |ExtraV 'signfificativo'| + -- (ExtraV <= (CorsaYr+CorsaVr) da ciclo precedente ) + if bVxs then + local dCorsaYTrA = dYPosA - MyMinY + local dCorsaVra = MaxV - dVPosA + -- **[B1Vs-xs1]** se posso recuperare ExtraV semplicem' accentrando V e (Y+T) + -- ulteriormente rispetto a YPos e Vpos definiti c.s. + if dCorsaYTrA >= dExtraV then + EmitComment( vCmd, '[B1Vs-xs1]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** (Y+T) e V + dYPosA = dYPosA - dExtraV + dTPosA = dTPosA - dExtraV + dVPosA = MaxV -- (pos. finale) + dVDeltaA = dVPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[B1Vs-xs2]** + EmitComment( vCmd, '[B1Vs-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** ev' (Y+T) e V alle posizioni impostate + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dVDeltaA = dVPosA - dTPosA + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2: allontano** (V+T) e Y + -- tenendo conto di dover 'recuperare' ExtraV.... + local dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') + local dYDispl1 = dYPos1 - dYPosA + local dVDispl1 = dVPos1 - dVPosA + --local dTDispl1 = dTPos1 - dTPosA + local dYDeltaDiff = dNewYDelta - (dYPos1 - dTPos1) + -- ...e anche di posizionare possibilmente Y alla posizione finale + if dYDeltaDiff > 0 then + dCorsaYfc = MaxY - dYPos1 + dCorsaVfc = dVPos1 - MinV + dDistBkN = EMC.LB - (dYPos1-dTPos1) - MinJoin - EMC.TCING -- DistBack1 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dYDeltaDiff, 0, dCorsaYd, dCorsaVTd, 'V') + else + dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 + end + + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **3: accentro** (Y+T) e V + dYPosA = dYPosA - dYDispl1 - dCorsaYTrA -- POS. FINALE + dTPosA = dTPosA - dYDispl1 - dCorsaYTrA + dVPosA = dVPosA - dVDispl1 + dCorsaVra -- POS. FINALE + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B1Vs-xs1/-xs2] + + -- **[B1Vs-xn]** |dExtraV ancora > 0 ma non 'significativo')| + else --if dExtraV < DeltaToll/2 + EmitComment( vCmd, '[B1Vs-xn]') + -- ev' chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: accentro (Y+T) alla posizione impostate e V al max + dExtraV = 0 + dVPosA = MaxV -- (pos. finale) + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B1s-xs/xn] + + -- **[B1Vs-r]** |dExtraV < 0 (pos. V raggiungibile)| + else + EmitComment( vCmd, '[B1Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- posiziono ev' (Y+T) come impostato sopra e V in posizione finale + dVPosA = dTPosA + dNewVDelta + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B1Vs] + + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + + else -- **[B1Vns]** |spostamento| finale richiesto (ev' residuo) di |V non 'significativo'| + EmitComment( vCmd, '[B1Vns]') + if SpecTestOnlyRemarkInCmds( vCmd) then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- emetto posizione di V + table.insert( vCmd, { 1, 'V', dVPosA}) + end + end -- [B1-s/ns] + + -- aggiorno la verifica di movimento 'significativo' per Y + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + -- **[B1Ys]** Se vi è uno |spostamento residuo di Y significativo'| + if bYDeltaS then + EmitComment( vCmd, '[B1Ys]') + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewY = dTPosA + dNewYDelta + local dExtraY = dNewY - MyMinY + -- **[B1Ys-r]** se pos. NewY è raggiungibile direttamente + if dExtraY >= 0 then --dNewY > MyMinY then + EmitComment( vCmd, '[B1Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y + dYPosA = dTPosA + dNewYDelta + table.insert( vCmd, { 1, 'Y', dYPosA}) + + -- **[B1Ys-xn]** se pos. NewY non è raggiungibile direttamente, ma ExtraY non è 'significativo' + elseif -dExtraY <= dYDeltaTol / 2 then + EmitComment( vCmd, '[B1Ys-xn]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- accentro Y + dYPosA = MyMinY + table.insert( vCmd, { 1, 'Y', dYPosA}) + -- [B1sY-nr.xs] ma ExtraY 'significativo' + + else -- **[B1Ys-xs]** + EmitComment( vCmd, '[B1Ys-xs]') + EgtOutLog( ' CLAMP : caso [B1Ys-xs] non gestito') + error( ' CLAMP : caso [B1Ys-xs] non gestito') + + end --[B1Ys-r/-nr] + else -- [B1Yns] spostamento residuo di Y non significativo + EmitComment( vCmd, '[B1Yns]') + end -- [B1Ys/ns] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- se non emessi movimenti, imposto posizione V + if not bZmaxOk then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + table.insert( vCmd, { 1, 'V', dVPosA}) + end + -- imposto stato carrelli, per eventuale uso pressori (sempre eseguita risalita Z) + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, dVDeltaA}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end -- SpecAdjustCarrB1 + +--------------------------------------------------------------------- +-- *** [B2] da entrambi a entrambi i carrelli : Y+V -> Y+V *** +--------------------------------------------------------------------- +function SpecAdjustCarrB2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[B2] = Y+V -> Y+V', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y+V -> Y+V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + -- recupero le posizioni correnti + local dYPosA = dTPosI + dYDeltaI + local dVPosA = dTPosI + dVDeltaI + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVDeltaI + local dNewYDelta + local dNewVDelta + -- incremento la distanza tra le due posizioni ( se abilitato e possibile) + local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta) + -- tolleranze + local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y', bFixedDelta) + local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + -- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 2 + else + dNewYDelta = dYDeltaA + end + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + -- definisco 'ExtraY' e ExtraV' + local dNewY = dTPosA + dNewYDelta + local dNewV = dTPosA + dNewVDelta + local dExtraY = dNewY - MyMinY -- < 0 => nuova pos. di Y 'non raggiungibile' + local dExtraV = dNewV - MaxV -- > 0 => nuova pos. di V 'non raggiungibile' + local bYxs = -dExtraY > dYDeltaTol/2 + local bVxs = dExtraV > dVDeltaTol/2 + + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' VDeltaI=' .. EgtNumToString( dVDeltaI) .. + ' TPosI='.. EgtNumToString( dTPosI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1) + EgtOutLog( ' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + -- flag risalita a Zmax + local bZmaxOk = false + + -- **[B2V]** |accentramento di V| + if dVDeltaF > dVDeltaI then + EmitComment( vCmd, '[B2V]') + + -- calcoli preliminari in caso di spostamento richiesto per V significativo + local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw + if bVDeltaS then + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + if bVxs then + -- calcolo le corse disponibili dei carrelli **dalle posizioni iniziali** + -- per allontanare Y e (V+T) + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- calcolo le corse di 'recupero' accentrando (Y+T) e V dopo l'allontanamento + dCorsaYTr = dCorsaYd + (dYPosA - MyMinY) + dCorsaVr = dCorsaVTd -- ((MaxV-dNewV) non fa parte del recupero in quanto già disponibile!) + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr + end + end + + -- **[B2V-xsw]** posizione NewV non raggiungibile, con |dEXtraV > CorsaVr + CorsaYTr| + -- e spostamento richiesto di V significativo; + while bXsw do + EmitComment( vCmd, '[B2V-xsw]') + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1**: allontano Y e V(+T) quanto possibile + dYPosA = dYPosA + dCorsaYd + dVPosA = dVPosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2:** accentro (Y+T) e V + dYPosA = dYPosA - dCorsaYTr -- = MyMinY + dTPosA = dTPosA - dCorsaYTr + dVPosA = MaxV + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno ExtraV residuo + dExtraV = dExtraV - dCorsaYTr - dCorsaVr + -- **aggiorno i recuperi disponibili** riallontanando Y e (V+T) e riaccentrando (Y+T) e V + dCorsaYfc = dCorsaY -- MaxY - dNewY + dCorsaVfc = dCorsaV -- dNewV - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + dCorsaYTr = dCorsaYd + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr + end -- [B2V-xsw] + + + --[B2Vs] |accentramento| (ev' residuo) |di V 'significativo'| + if bVDeltaS then + --[B2Vs-x] accentramento di V 'significativo' |con pos. NewV 'non raggiungibile'|(= oltre MaxV) + if dExtraV > 0 then + -- (ExtraV <= (CorsaYTr+CorsaVr) da ciclo precedente) + --[B2Vs-xs] accentramento di V con |ExtraV 'significativo'| + if bVxs then + local dCorsaYTrA = dYPosA - MyMinY + local dCorsaVra = MaxV - dVPosA + -- **[B2Vs-xs1]** se posso recuperare ExtraV solo accentrando V e (Y+T) + if dCorsaYTrA >= dExtraV then + EmitComment( vCmd, '[B2Vs-xs1]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro (Y+T) q.b. e V + dYPosA = dYPosA - dExtraV + dTPosA = dTPosA - dExtraV + dVPosA = MaxV -- (pos. finale) + dExtraV = 0 + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[B2Vs-xs2]** + EmitComment( vCmd, '[B2Vs-xs2]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: allontano** (V+T) e Y + -- tenendo conto di dover 'recuperare' ExtraV... + local dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') + local dYDispl1 = dYPos1 - dYPosA + local dVDispl1 = dVPos1 - dVPosA + --local dTDispl1 = dTPos1 - dTPosA + local dYDeltaDiff = dNewYDelta - (dYPos1 - dTPos1) + -- ...e anche possibilmente di posizionare Y alla posizione finale + if dYDeltaDiff > 0 then + dCorsaYfc = MaxY - dYPos1 + dCorsaVfc = dVPos1 - MinV + dDistBkN = EMC.LB - (dYPos1-dTPos1) - MinJoin - EMC.TCING -- DistBack1 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + --dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dYDeltaDiff, 0, dCorsaYd-dYDispl1, dCorsaVTd+dVDispl1, 'V') + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dYDeltaDiff, 0, dCorsaYd, dCorsaVTd, 'V') + else + dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 + end + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: accentro** (Y+T) e V + dYPosA = dYPosA - dYDispl1 - dCorsaYTrA -- POS. FINALE + dTPosA = dTPosA - dYDispl1 - dCorsaYTrA + dVPosA = dVPosA - dVDispl1 + dCorsaVra -- POS. FINALE + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B2Vs-xs1/xs2] + + -- **[B2Vs-xn]** |dExtraV non 'significativo'| + else + EmitComment( vCmd, '[B2Vs-xn]') + dExtraV = 0 + -- ev' chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: posiziono V assumendo maxV come pos. finale + dVPosA = MaxV -- (pos finale) + table.insert( vCmd, { 1, 'V', dVPosA}) + end -- [B2Vs-xs/xn] + + -- **[B2Vs-r]** accentramento di |V| 'significativo' con pos.|'raggiungibile'| (= non oltre MaxV) + else + EmitComment( vCmd, '[B2Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: posiziono V -- (pos finale) + dVPosA = dTPosA + dNewVDelta + dExtraV = 0 + table.insert( vCmd, { 1, 'V', dVPosA}) + end --[B2Vs] + + -- **[B2Vns]** accentramento di V non 'significativo'| + else + EmitComment( vCmd, '[B2Vns]') + dExtraV = 0 + end --[B2Vs/ns] + end --[B2V] ( accentramento di V) + + -- --------------------------------------------------------------------------- + -- **[B2Y]** |accentramento di Y| + if dYDeltaF < dYDeltaI then + EmitComment( vCmd, '[B2Y]') + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr + if bYDeltaS then + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + if bYxs then + -- calcolo le **corse disponibili** dei carrelli dalle posizioni iniziali + -- per allontanare (Y+T) e V + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxV - dVPosA) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end + end + + -- **[B2Ys-xsw]** |-dEXtraY > dCorsaYr + dCorsaVTr| + while bXsw do + EmitComment( vCmd, '[B2Y-xsw]') + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |1:| allontano (Y+T) e V quanto possibile + dYPosA = dYPosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dVPosA = dVPosA - dCorsaVd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + + -- |2:| accentro Y e (V+T) + dYPosA = MyMinY -- = dYPosA - dCorsaYr + dVPosA = dVPosA + dCorsaVTr -- = MaxV + dTPosA = dTPosA + dCorsaVTr + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto Delta 'attuali' + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - YDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno ExtraY residuo + dExtraY = dExtraY + dCorsaYTr + dCorsaVr + -- aggiorno i recuperi disponibili riallontanando (Y+T) V e riaccentrando succ' Y e (V+T) + dCorsaYfc = dCorsaY -- MaxY - dNewY + dCorsaVfc = dCorsaV -- dNewV - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end -- [B2Ys-xsw] + + -- **[B2Ys]** |accentramento di Y 'significativo'| + if bYDeltaS then + -- **[B2Ys-x]** accentramento di Y 'significativo' |con pos. NewY 'non raggiungibile'|(= oltre MyMinY) + if dExtraY < 0 then + -- (-ExtraY <= (dCorsaYr + dCorsaVTr ) a ciclo precedente + -- **[B2Ys-xs]** accentramento di Y con |'ExtraY 'significativo'| + if bYxs then + local dCorsaVTrA = MaxV - dVPosA + local dCorsaYra = dYPosA - MyMinY + -- **[B2Ys-xs1]** se posso recuperare ExtraY solo accentrando Y e (V+T) + if dCorsaVTrA >= -dExtraY then + EmitComment( vCmd, '[B2Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- accentro Y e (V+T) q.b. + dYPosA = MyMinY -- (pos. finale) + dVPosA = dVPosA - dExtraY -- = +(-dEXtraY) + dTPosA = dTPosA - dExtraY -- = +(-dEXtraY) + dExtraY = 0 + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[B2Ys-xs2]** + EmitComment( vCmd, '[B2Ys-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: allontano** (Y+T) e V + -- tenendo conto di dover 'recuperare' ExtraY... + dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') + local dYDispl1 = dYPos1 - dYPosA + local dVDispl1 = dVPos1 - dVPosA + local dVDeltaDiff = dNewVDelta - (dVPos1 - dTPos1) + -- ...e anche possibilmente di posizionare V alla posizione finale + if dVDeltaDiff < 0 then + dCorsaYfc = MaxY - dYPos1 + dCorsaVfc = dVPos1 - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront1 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dVDeltaDiff, 0, dCorsaYTd, dCorsaVd, 'Y') + else + dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 + end + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + --dVDeltaA = dVPosA - dTPosA + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |2:| accentro Y e (V+T) + dYPosA = dYPosA - dYDispl1 - dCorsaYra -- POS. FINALE + dVPosA = dVPosA - dVDispl1 + dCorsaVTrA -- POS. FINALE + dTPosA = dTPosA - dVDispl1 + dCorsaVTrA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B2Ys-xs1/xs2] + + -- **[B2Ys-xn]** |dExtraY non 'significativo'| + else + EmitComment( vCmd, '[B2Ys-xn]') + dExtraY = 0 + -- ev' chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- 1: posiziono Y assumendo MyMinY come pos. finale + dYPosA = MyMinY -- (pos finale) + table.insert( vCmd, { 1, 'Y', dYPosA}) + end -- [B2Ys-xs/xn] + + --[B2Ys-r] accentramento di |Y| 'significativo' con pos.|'raggiungibile'| (non oltre MyMinY) + else + EmitComment( vCmd, '[B2Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |1:| posiziono Y -- (pos finale) + dYPosA = dTPosA + dNewYDelta + dExtraV = 0 + table.insert( vCmd, { 1, 'Y', dYPosA}) + end --[B2Ys] + + -- [B2Yns] accentramento di V non 'significativo'| + else + EmitComment( vCmd, '[B2Yns]') + dExtraV = 0 + end --[B2Ys/ns] + end --[B2Y] ( accentramento di V) + + -- ricalcolo gli 'spostamenti significativi' + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + + -- ------------------------------------------------------------------------------------------ + -- **[B2C]** |Spostamenti| di Y e/o V (ev' |residui| da cicli precedenti) + -- ++ possono essere solo allontanamenti ? +++++++++++++++++++++ + EmitComment( vCmd, '[B2C]') + -- **[B2Cs]** se c'è uno |spostamento (ev' residuo) significativo| + if bYDeltaS or bVDeltaS then + -- **[B2CYs]** se lo |spostamento (ev' residuo) di Y è 'significativo'| + if bYDeltaS then + EmitComment( vCmd, '[B2CYs]') + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewY = dTPosA + dNewYDelta + local dExtraY = dNewY - MyMinY + + -- **[B2CYs-r]** se posizione di |Y raggiungibile| + if dExtraY >= 0 and dNewY <= MaxY then + EmitComment( vCmd, '[B2CYs-r]') + -- chiudo eventualmente V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y + dYPosA = dNewY + table.insert( vCmd, { 1, 'Y', dYPosA}) + -- **[B2CYs-nr]** + else + EmitComment( vCmd, '[B2CYs-nr]') + EgtOutLog( ' CLAMP : posizione Y non raggiungibile' .. '- caso [B2Ys-nr] non gestito') + error( 'CLAMP : posizione Y non raggiungibile') + end + end -- [B2CYs] + + -- **[B2CVs]** se lo |spostamento (ev' residuo) di V è 'significativo'| + if bVDeltaS then + EmitComment( vCmd, '[B2CVs]') + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewV = dTPosA + dNewVDelta + local dExtraV = dNewV - MaxV + + -- **[B2CVs-r]** se posizione NewV raggiungibile + if dExtraV <= 0 and dNewV >= MinV then + EmitComment( vCmd, '[B2CVs-r]') + -- chiudo eventualmente Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V + dVPosA = dNewV + table.insert( vCmd, { 1, 'V', dVPosA}) + -- **[B2CVs-nr]** + else -- se ExtraV > 0 anche se non significativo + EmitComment( vCmd, '[B2CVs-nr]') + EgtOutLog( ' CLAMP : posizione V non raggiungibile' .. '- caso [B2cVs-nr] non gestito') + error( 'CLAMP : posizione V non raggiungibile') + end + end --[B2CsV] + + -- **[B2Cn]** |nessuno spostamento (ev' residuo significativo)| + else + EmitComment( vCmd, '[B2Cn]') + end -- [B2C] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- imposto stato carrelli, per eventuale uso pressori + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, dVDeltaA}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrB2 + +--------------------------------------------------------------------------------------------------------- +-- *** [B3] da carrello V a entrambi i carrelli : V -> Y+V *** +--------------------------------------------------------------------------------------------------------- +function SpecAdjustCarrB3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[B3] = V -> Y+V', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'V -> Y+V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + local dCorsaY = MaxY - MyMinY + local dCorsaV = MaxV - MinV + -- recupero le posizioni correnti + local dVPosA = dTPosI + dVDeltaI + local dYPosA = ParkY + local dTPosA = dTPosI + local dVDeltaA = dVDeltaI + local dYDeltaA = dYPosA - dTPosA + local dNewYDelta + local dNewVDelta + -- incremento la distanza tra le due posizioni ( se abilitato e possibile) + local dYDeltaAgg, dVDeltaAgg = AdjustPositionsForB( dYDeltaF, dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, bFixedDelta) + -- tolleranze + local dYDeltaTol = dYDeltaAgg + GetDeltaTol( EMC.LB - dYDeltaF - dYDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'Y', bFixedDelta) + local dVDeltaTol = dVDeltaAgg + GetDeltaTol( dVDeltaF - dVDeltaAgg, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + -- definisco criteri per movimenti 'significativi' in base alle 'nuove' tolleranze + local bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bYDeltaS then + dNewYDelta = dYDeltaF + dYDeltaTol / 2 + else + dNewYDelta = dYDeltaA + end + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + + EgtOutLog( ' YDeltaI(Park)='.. EgtNumToString( dYDeltaA)..' VDeltaI=' .. EgtNumToString( dVDeltaA) .. + ' TPosI='.. EgtNumToString( dTPosI), 1) + EgtOutLog( ' YDeltaF=' .. EgtNumToString( dYDeltaF) .. ' VDeltaF=' .. EgtNumToString( dVDeltaF), 1) + EgtOutLog( ' NewYDelta=' .. EgtNumToString( dNewYDelta) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + -- risalita testa a Zmax + local bZmaxOk = false + + -- calcoli preliminari in caso di spostamento richiesto per Y significativo + local dYPos, dVPos, dTPos + local dNewY, dExtraY, bYxs + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bYDeltaS then + -- definisco 'ExtraY' con (V+T) e Y accentrati q.b. per la presa di Y + dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'Y') + dNewY = dTPos + dNewYDelta + dExtraY = dNewY - MyMinY -- se < 0 pos. Y non direttamente 'raggiungibile' + bYxs = -dExtraY > dYDeltaTol/2 -- ExtraY 'significativo' + if bYxs then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPos + dCorsaVfc = dVPos - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + (MaxV - dVPos) + dCorsaYr = dCorsaYTd + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end + -- inizializzo + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + end + + -- **[B3Ys-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraY > CorsaVr + CorsaYr| + while bXsw do + EmitComment( vCmd, '[B3Ys-xsw]') + + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- |1:| posiziono (V+T) e Y come calcolato sopra + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |2:| allontano (Y+T) e V quanto possibile + dYPosA = dYPosA + dCorsaYTd + dTPosA = dTPosA + dCorsaYTd + dVPosA = dVPosA - dCorsaVd + table.insert( vCmd, { 3, 'Y', dTPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |3:| accentro (V+T) e Y + dVPosA = dVPosA + dCorsaVTr + dTPosA = dTPosA + dCorsaVTr + dYPosA = MyMinY + table.insert( vCmd, { 3, 'Y', dTPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bYDeltaS = ( dYDeltaF < dYDeltaA - dYDeltaTol or dYDeltaF > dYDeltaA + DELTA_SIC) + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- aggiorno ExtraY + dExtraY = dExtraY + dCorsaYr + dCorsaVTr + + -- **aggiorno la valutazione delle corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. (Y+T) e V + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando Y e (V+T) + dCorsaVTr = dCorsaVd + dCorsaYr = dCorsaYTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bYDeltaS and bYxs and -dExtraY > dCorsaVTr + dCorsaYr + end --[B3Ys-xsw] + + -- **[B3Ys]** |spostamento| finale richiesto (ev' residuo) di |Y| |'significativo'| + if bYDeltaS then + EmitComment( vCmd, '[B3Ys]') + + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- **[B3Ys-x]** posizione di |Y non raggiungibile| + -- ( -dExtraY <= (CorsaYr+CorsaVr) da ciclo precedente ) + if dExtraY < 0 then + --EmitComment( vCmd, '[B3Ys-x]') + + -- **[B3Ys-xs]** |ExtraY 'significativo'| + if bYxs then + --EmitComment( vCmd, '[B3Ys-xs]') + + local dCorsaVTrA = MaxV - dVPosA + local dCorsaYra = dYPosA - MyMinY + -- **[B3Ys-xs1]** se posso recuperare ExtraY semplicem' accentrando Y e (V+T) + -- ulteriormente rispetto a YPos e Vpos definiti c.s. + if dCorsaVTrA >= -dExtraY then + EmitComment( vCmd, '[B3Ys-xs1]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** Y e (V+T) + dYPosA = MyMinY -- (pos. finale) + dVPosA = dVPosA - dExtraY + dTPosA = dTPosA - dExtraY + dYDeltaA = dYPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[B3Ys-xs2]** + EmitComment( vCmd, '[B3Ys-xs2]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: accentro** ev' Y e (V+T) alle posizioni impostate + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dYDeltaA = dYPosA - dTPosA + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: allontano** (Y+T) e V + -- tenendo conto di dover 'recuperare' ExtraY... + dYPos1, dVPos1, dTPos1 = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraY, dCorsaVTrA, dCorsaYTd, dCorsaVd, 'Y') + local dYDispl1 = dYPos1 - dYPosA + local dVDispl1 = dVPos1 - dVPosA + local dVDeltaDiff = dNewVDelta - (dVPos1 - dTPos1) + -- ...e anche di posizionare possibilmente V alla posizione finale + if dVDeltaDiff < 0 then + CorsaYfc = MaxY - dYPos1 + dCorsaVfc = dVPos1 - MinV + dDistFrN = dVDeltaA - MinJoin - EMC.HCING - EMC.HOVM -- DistFront1 'netta' + dCorsaYTd, dCorsaVd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistFrN, 'Fr') + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPos1, dVPos1, dTPos1, dVDeltaDiff, 0, dCorsaYTd, dCorsaVd, 'Y') + else + dYPosA = dYPos1; dVPosA = dVPos1; dTPosA = dTPos1 + end + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + + -- chiudo il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **3: accentro** Y e (V+T) + dYPosA = dYPosA - dYDispl1 - dCorsaYra -- POS. FINALE + dVPosA = dVPosA - dVDispl1 + dCorsaVTrA -- POS. FINALE + dTPosA = dTPosA - dVDispl1 + dCorsaVTrA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B3Ys-xs1/-xs2] + + -- **[B3Ys-xn]** |dExtraY ancora < 0 ma non 'significativo')| + else --if -dExtraY < DeltaToll/2 + EmitComment( vCmd, '[B3Ys-xn]') + -- ev' chiudo V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- 1: accentro Y e porto (V+T) alla posizione impostata + dExtraY = 0 + dYPosA = MyMinY -- (pos. finale) + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end --[B3Ys-xs/xn] + + -- **[B3Ys-r]** |dExtraY > 0 (pos. Y raggiungibile)| + else + EmitComment( vCmd, '[B3Ys-r]') + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- posizione ev' (V+T) come impostato sopra e Y in posizione finale + dYPosA = dTPosA + dNewYDelta + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [B3Ys] + -- + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + + else -- [B3Yns] |spostamento| finale richiesto (ev' residuo) di |Y non 'significativo'| + EmitComment( vCmd, '[B3Yns]') + end --[B3Ys/ns] + + -- aggiorno la verifica di movimento 'significativo' per V + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- **[B3Vs]** Se vi è uno |spostamento residuo di V significativo'| + if bVDeltaS then + EmitComment( vCmd, '[B3Vs]') + + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + local dNewV = dTPosA + dNewVDelta + local dExtraV = dNewV - MaxV + + -- **[B3Vs-x]** se pos. |NewV non è raggiungibile direttamente| (oltre MaxV) + if dExtraV > 0 then --dNewV <= MaxV then + -- **[B3Vs-xs]** |ExtraV 'significativo'| + if dExtraV > dVDeltaTol /2 then + EmitComment( vCmd, '[B3Vs-xs]') + EgtOutLog( ' CLAMP : caso [B3Vs-xs] non gestito') + error( ' CLAMP : caso [B3Vs-xs] non gestito') + + -- **[B3Vs-xn]** |ExtraV non 'significativo'| + else + EmitComment( vCmd, '[B3Vs-xn]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- accentro V q.p. + dVPosA = MaxV + table.insert( vCmd, { 1, 'V', dVPosA}) + end -- [B3Vs-xs/xn] + + else -- **[B3Vs-r]** pos. |NewV raggiungibile direttamente| (non oltre MaxV) + EmitComment( vCmd, '[B3Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- sposto il carrello V + dVPosA = dNewV + table.insert( vCmd, { 1, 'V', dVPosA}) + end --[B3Vs-x/-r] + + else -- [B3Vns] spostamento residuo di V non significativo + EmitComment( vCmd, '[B3Vns]') + end -- [B3Vs/ns] + + -- calcolo i nuovi parametri di aggancio + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- se non emessi movimenti, imposto posizione Y + if not bZmaxOk then + -- risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + table.insert( vCmd, { 1, 'Y', dYPosA}) + end + -- imposto stato carrelli, per eventuale uso pressori (sempre effettuato movimento) + table.insert( vCmd, { 11, CalcCharStatus( 'Y', dYDeltaA)}) + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dYDeltaA, dVDeltaA}) + + EgtOutLog( ' YDeltaA =' .. EgtNumToString( dYDeltaA) .. ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end -- SpecAdjustCarrB3 + +--------------------------------------------------------------------- +-- *** [C1] da carrello Y a V : Y -> V *** +--------------------------------------------------------------------- +function SpecAdjustCarrC1( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[C1] = Y -> V ', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y -> V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + -- recupero le posizioni correnti + --local dCorsaY = MaxY - MyMinY + --local dCorsaV = MaxV - MinV + local dYPosA = dTPosI + dYDeltaI + local dVPosA = ParkV + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVPosA - dTPosA + local dNewVDelta -- = dVDeltaF + -- tolleranza + local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto i delta finali in caso di spostamenti richiesti significativi, tenuto conto delle tolleranze + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol/2 + else + dNewVDelta = dVDeltaA + end + EgtOutLog(' YDeltaI=' .. EgtNumToString( dYDeltaA) .. ' VDeltaI(Park)='.. EgtNumToString( dVDeltaA).. + ' TPosI=' .. EgtNumToString( dTPosI) , 1) + EgtOutLog(' VDeltaF=' .. EgtNumToString( dVDeltaF) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta) , 1) + + -- risalita testa a Zmax (da effettuare comunque, dato lo scambio di carrelli) + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per V significativo + local dYPos, dVPos, dTPos + local dNewV, dExtraV, bVxs + local dCorsaYfc, dCorsaVfc, dDistFrN, dCorsaYTd, dCorsaVd, dCorsaVTr, dCorsaYr, bXsw + if bVDeltaS then + -- definisco 'ExtraV' con (Y+T) e V accentrati q.b. per la presa di V + dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'V') + dNewV = dTPos + dNewVDelta + dExtraV = dNewV - MaxV + bVxs = dExtraV > dVDeltaTol/2 -- ExtraV 'significativo' + if bVxs then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxY - dYPos + dCorsaVfc = dVPos - MinV + --local dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dDistBkN = EMC.LB - (dYPos-dTPos) - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando (Y+T) e V + dCorsaYTr = dCorsaYd + (dYPos -MyMinY) + dCorsaVr = dCorsaVTd + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaVr + dCorsaYTr + end + -- inizializzo + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + end + + -- **[C1Vs-xsw]** posizione finale di V non raggiungibile, con |dEXtraV > CorsaVr + CorsaYr| + -- con spostamento richiesto significativo e ExtraV significativo + while bXsw do + EmitComment( vCmd, '[C1Vs-xsw]') + -- **1:** posiziono (Y+T) e V come calcolato sopra + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:** allontano Y e (V+T) quanto possibile + dYPosA = dYPosA + dCorsaYd + dVPosA = dVPosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **3:** accentro (Y+T) e V + dYPosA = dYPosA - dCorsaYTr -- = MyMinY + dTPosA = dTPosA - dCorsaYTr + dVPosA = MaxV + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- **aggiorno ExtraV** + dExtraV = dExtraV - dCorsaYTr - dCorsaVr + -- **aggiorno la valutazione di ulteriori corse disponibili** + -- a partire da Y e V c.s. per allontanare q.p. Y e (V+T) + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- aggiorno i prossimi recuperi disponibili + dCorsaYTr = dCorsaYd + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaVr + dCorsaYTr + end --[C1Vs-xw] + + -- **[C1Vs]** |spostamento| richiesto (ev' residuo) |di V| |'significativo'| + if bVDeltaS then + -- **[C1Vs-x]** posizione di |V non raggiungibile| + if dExtraV > 0 then + -- (dExtraV <= (CorsaYr+CorsaVr) da ciclo precedente) + -- **[C1Vs-xs]** posizione di V non raggiungibile, |con ExtraV 'significativo'| + if bVxs then + local dCorsaYTrA = dYPosA - MyMinY + -- **[C1Vs-xs1]** se posso recuperare dExtraV solo accentrando V e (Y+T) + if dCorsaYTrA >= dExtraV then + EmitComment( vCmd, '[C1Vs-xs1]') + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro (Y+T) q.b. e V + dYPosA = dYPosA - dExtraV + dTPosA = dTPosA - dExtraV + dVPosA = MaxV -- (pos. finale) + dVDeltaA = dVPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + -- **[C1Vs-xs2]** dCorsaYTrA < dExtraV + else + EmitComment( vCmd, '[C1Vs-xs2]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** ev' (Y+T) e V alle posizioni impostate + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + dVDeltaA = dVPosA - dTPosA + -- chiudo (ev') il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **2:allontano** (V+T) q.b./q.p. e Y per preparare il recupero di ExtraV + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dYDeltaA = dYPosA - dTPosA + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **3: accentro**(Y+T) e V (pos. finale) + dYPosA = MyMinY + dTPosA = dYPosA - dYDeltaA + dVPosA = MaxV + dVDeltaA = dVPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + end -- [C1Vs-xs1/xs2] + + -- **[C1Vs-xn]** |ExtraV ancora > 0 , ma non 'significativo'| (<= DeltaTol/2) + else + EmitComment( vCmd, '[C1Vs-xn]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- 1: porto ev' (Y+T) alla posizione impostata sopra e accentro V + dExtraV = 0 + dVPosA = MaxV -- pos. finale + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + -- chiudo V (?) + table.insert( vCmd, { 12, 1}) + end -- [C1Vs-xs/xn] + + -- **[C1Vs-r]** posizione di V 'raggiungibile' (ExtraV <= 0) + else + EmitComment( vCmd, '[C1Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- posizione ev' (Y+T) come impostato sopra e V in posizione finale + dVPosA = dTPosA + dNewVDelta + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [C1V-s] + + -- **[C1Vns]** |spostamento| richIesto per V |non 'significativo'| + else + EmitComment( vCmd, '[C1Vns]') + end + + -- calcolo i nuovi parametri di aggancio + dVDeltaA = dVPosA - dTPosA + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y in parcheggio + table.insert( vCmd, { 1, 'Y', ParkY}) + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, 0, dVDeltaA}) + + EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrC1 + +--------------------------------------------------------------------- +-- *** [C2] da entrambi i carrelli a V : Y+V -> V *** +--------------------------------------------------------------------- +function SpecAdjustCarrC2( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta) + EgtOutLog( ' *[C2] = Y+V -> V', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Y+V -> V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + local dCorsaY = MaxY - MyMinY + local dCorsaV = MaxV - MinV + -- recupero le posizioni correnti dei carrelli + local dYPosA = dTPosI + dYDeltaI + local dVPosA = dTPosI + dVDeltaI + local dTPosA = dTPosI + local dYDeltaA = dYDeltaI + local dVDeltaA = dVDeltaI + local dNewVDelta -- = dVDeltaF + -- tolleranze + local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + -- definisco spostamento 'significativo' in base alle tolleranze + local bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- reimposto ev' il delta finale + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol/2 + else + dNewVDelta = dVDeltaA + end + -- definisco 'ExtraV' + local dNewV = dTPosI + dNewVDelta + local dExtraV = dNewV - MaxV -- > 0 se nuova pos. di V 'non raggiungibile' (= oltre MaxV) + local bVxs = dExtraV > dVDeltaTol/2 -- 'ExtraV significativo' + + EgtOutLog( ' YDeltaI=' .. EgtNumToString( dYDeltaI) .. ' VDeltaI=' .. EgtNumToString( dVDeltaI) .. + ' VDeltaF=' .. EgtNumToString( dVDeltaF) ,1) + EgtOutLog( ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + + -- risalita testa a Zmax (da effettuare comunque, per il parcheggio di Y) + local bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + + -- calcoli preliminari in caso di spostamento richiesto per YV significativo + local dCorsaYfc, dCorsaVfc, dDistBkN, dCorsaYd, dCorsaVd, dCorsaVTd, dCorsaYTr, dCorsaVr, bXsw + if bVDeltaS then + if bVxs then + -- calcolo le corse disponibili dei carrelli dalle posizioni attuali (=iniziali) + -- per allontanare Y e (V+T) q.p. + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto le corse di 'recupero' dai due carrelli possibili riaccentrando (Y+T) e V + dCorsaYTr = dCorsaYd + (dYPosA - MyMinY) + dCorsaVr = dCorsaVTd + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr + end + end + + -- **[C2Vs-xsw]** posizione finale di V non raggiungibile, |con dEXtraV > CorsaYTr + CorsaVr| + while bXsw do + EmitComment( vCmd, '[C2Vs-xsw]') + + -- chiudo eventualmente il carrello V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- |1:| allontano Y e (V+T) quanto possibile + dYPosA = dYPosA + dCorsaYd + dVPosA = dVPosA - dCorsaVTd + dTPosA = dTPosA - dCorsaVTd + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- |3:| accentro (Y+T) e V + dYPosA = dYPosA - dCorsaYTr + dTPosA = dTPosA - dCorsaYTr + dVPosA = MaxV + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + + -- valuto i Delta ottenuti + dYDeltaA = dYPosA - dTPosA + dVDeltaA = dVPosA - dTPosA + -- aggiorno la verifica di spostamento significativo + bVDeltaS = ( dVDeltaF > dVDeltaA + dVDeltaTol or dVDeltaF < dVDeltaA - DELTA_SIC) + -- **aggiorno ExtraV** + dExtraV = dExtraV - dCorsaYTr - dCorsaVr + -- **aggiorno la valutazione di ulteriori corse disponibili** + dCorsaYfc = MaxY - dYPosA + dCorsaVfc = dVPosA - MinV + dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- aggiorno i prossimi recuperi disponibili + dCorsaYTr = dCorsaYd + (dYPosA - MyMinY) + dCorsaVr = dCorsaVTd + -- aggiorno verifica per ripetizione del ciclo + bXsw = bVDeltaS and bVxs and dExtraV > dCorsaYTr + dCorsaVr + end -- [C2V-xsw] + + -- **[C2Vs]** se lo |spostamento richiesto per V è significativo| + if bVDeltaS then + -- **[C2Vs-x]** posizione di |V non raggiungibile| (oltre MaxV) + if dExtraV > 0 then + -- **[C2Vs-xs]** |ExtraV 'significativo'| + if bVxs then + local dCorsaYTrA = dYPosA - MyMinY + -- **[C2Vs-xs1]** se posso recuperare ExtraV semplicem' accentrando V e (Y+T) + if dCorsaYTrA >= dExtraV then + EmitComment( vCmd, '[C2Vs-xs1]') + + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** (Y+T) e V + dYPosA = dYPosA - dExtraV + dTPosA = dTPosA - dExtraV + dVPosA = MaxV -- (pos. finale) + dVDeltaA = dVPosA - dTPosA + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + + else -- **[C2Vs-xs2]** + EmitComment( vCmd, '[C2Vs-xs2]') + + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + -- **1: allontano** (V+T) e Y + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dYDeltaA = dYPosA - dTPosA + + -- chiudo il carrello Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: accentro** (Y+T) e V + dYPosA = MyMinY + dTPosA = dYPosA - dYDeltaA + dVPosA = MaxV -- (pos. finale) + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [C2Vs-xs1/-xs2] + + -- **[C2Vs-xn]** |dExtraV ancora > 0 ma non 'significativo')| + else --if dExtraV < DeltaToll/2 + EmitComment( vCmd, '[B1Vs-xn]') + -- ev' chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro V + dExtraV = 0 + dVPosA = MaxV -- (pos. finale) + table.insert( vCmd, { 1, 'V', dVPosA}) + end -- [C2s-xs/xn] + + -- **[C2Vs-r]** |dExtraV < 0 (pos. V raggiungibile)| + else + EmitComment( vCmd, '[C2Vs-r]') + -- chiudo ev' Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- porto V in posizione finale + dVPosA = dTPosA + dNewVDelta + table.insert( vCmd, { 1, 'V', dVPosA}) + end --[C2Vs] + + -- **[C2Vns]** = |spostamento di V non significativo| + else + EmitComment( vCmd, '[C2Vns]') + end --[C2Vs/n] + + -- calcolo il nuovo parametro di aggancio + dVDeltaA = dVPosA - dTPosA + -- chiudo eventualmente il carrello V e apro Y + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y in parcheggio + table.insert( vCmd, { 1, 'Y', ParkY}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, 0, dVDeltaA}) + + EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + -- reset contatore + EMC.CNT = nil + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrC2 + +--------------------------------------------------------------------- +-- *** [C3] da carrello V a V : V -> V *** +--------------------------------------------------------------------- +function SpecAdjustCarrC3( dTPosI, dYDeltaI, dVDeltaI, dTPosF, dYDeltaF, dVDeltaF, bFixedDelta, bFixedPos) + EgtOutLog( ' *[C3] = V -> V', 1) + -- elenco comandi + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'V -> V'}) + -- se primo scambio + local MyMinY = EgtIf( EMC.CNT == 1, MinY + AGG_LOAD, MinY) + -- recupero le posizioni correnti dei carrelli + local dVPosA = dTPosI + dVDeltaI + local dYPosA = ParkY + local dTPosA = dTPosI + local dVDeltaA = dVDeltaI + local dYDeltaA = dYPosA - dTPosA + local dNewVDelta + -- tolleranza + local dVDeltaTol = GetDeltaTol( dVDeltaF, EMC.TCING, EMC.HCING, EMC.HOVM, 'V', bFixedDelta) + local bVDeltaS = (( dVDeltaF > dVDeltaA + dVDeltaTol and not bFixedPos) or dVDeltaF < dVDeltaA - DELTA_SIC) + if bVDeltaS then + dNewVDelta = dVDeltaF - dVDeltaTol / 2 + else + dNewVDelta = dVDeltaA + end + EgtOutLog( ' VDeltaI=' .. EgtNumToString( dVDeltaI) .. ' TPosI=' .. EgtNumToString( dTPosI), 1) + EgtOutLog( ' VDeltaF=' .. EgtNumToString( dVDeltaF) .. ' NewVDelta=' .. EgtNumToString( dNewVDelta), 1) + -- flag per risalita testa a Zmax + local bZmaxOk = false + + -- **[C3Vs]** |pos. di V cambia in modo significativo| + if bVDeltaS then + EmitComment( vCmd, '[C3Vs]') + -- eventuale risalita testa a Zmax + bZmaxOk = EnsureZmax( bZmaxOk, vCmd) + -- definisco 'ExtraV' con (V+T) e Y accentrati q.b. per la presa con Y + local dYPos, dVPos, dTPos = PosxExtraYV( dYPosA, dVPosA, dTPosA, MyMinY, MaxV, 'Y') + local dNewV = dTPos + dNewVDelta + local dExtraV = dNewV - MaxV + -- effettuo spostamenti per predisporre all'aggancio di T con Y + dYPosA = dYPos + dVPosA = dVPos + dTPosA = dTPos + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dYDeltaA = dYPosA - dTPosA + + -- **[C3Vs-x]** posizione di |V non raggiungibile| (oltre MaxV) + if dExtraV > 0 then + -- **[C3Vs-xs]** posizione di V non raggiungibile, |con ExtraV 'significativo'| + if dExtraV > dVDeltaTol /2 then + -- calcolo le **corse disponibili dei carrelli a partire da Y e V c.s.** per allontanare q.p. (V+T) e Y + local dCorsaYfc = MaxY - dYPos + local dCorsaVfc = dVPos - MinV + local dDistBkN = EMC.LB - dYDeltaA - MinJoin - EMC.TCING -- DistBack 'netta' + local dCorsaYd, dCorsaVTd = GetCorseDisp( dCorsaYfc, dCorsaVfc, dDistBkN, 'Bk') + -- valuto **le corse di 'recupero'** dai due carrelli possibili riaccentrando (Y+T) e V + local dCorsaYTr = dCorsaYd + (dYPos - MyMinY) + local dCorsaVr = dCorsaVTd + + -- **[C3Vs-xsw]** posizione finale dNewV non raggiungibile, con |dEXtraV > CorsaVr + CorsaYr| + if dExtraV > ( dCorsaYTr + dCorsaVr) and bVDeltaS then + EmitComment( vCmd, '[C3Vs-xsw]' .. 'CASO NON GESTITO') + return + end + + local dCorsaYTrA = dYPos - MyMinY -- !! att.ne: non dYPosA !! + -- **[C3Vs-xs1]** se posso recuperare ExtraV semplicem' accentrando (Y+T) e V + -- (dalle posizione impostate sopra per l'aggancio di Y) + if dCorsaYTrA >= dExtraV then + EmitComment( vCmd, '[C3Vs-xs1]') + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1: accentro** (Y+T) e V + dYPosA = dYPosA - dExtraV + dTPosA = dTPosA - dExtraV + dVPosA = MaxV -- (pos. finale) + table.insert( vCmd, { 3, 'Y', dYPosA , 'T', dTPosA, 'V', dVPosA}) + dVDeltaA = dVPosA - dTPosA + + else -- **[C3Vs-xs2]** + -- ci sarebbe un doppio movimento di V ? => caso impossibile ? + EmitComment( vCmd, '[C3Vs-xs2]') + -- **1:** posiziono (ulteriormente!) Y e (V+T) + dYPosA, dVPosA, dTPosA = PosXs2Enl( dYPosA, dVPosA, dTPosA, dExtraV, dCorsaYTrA, dCorsaYd, dCorsaVTd, 'V') + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA }) + dYDeltaA = dYPosA - dTPosA + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2: accentro** (Y+T) e V + dYPosA = MyMinY + dVPosA = MaxV -- (pos. finale) + dTPosA = dYPosA - dYDeltaA + table.insert( vCmd, { 3, 'Y', dYPosA, 'T', dTPosA, 'V', dVPosA}) + end -- [C3Vs-xs1/-xs2] + + -- **[C3Vs-xn]** |dExtraV > 0 ma 'non significativo')| + else --if dExtraV < DeltaToll/2 + EmitComment( vCmd, '[C3Vs-xn]') + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **1:** accentro V + dExtraV = 0 + dVPosA = MaxV -- (pos. finale) + table.insert( vCmd, { 1, 'V', dVPosA}) + end --[C3Vs-xs/xn] + + -- **[C3Vs-r]** |posizione di Y raggiungibile| (ExtraY >=0) + -- (si esclude la possibilità di extra corsa oltre maxY) + else + EmitComment( vCmd, '[C3Vs-r]') + -- chiudo Y e apro V + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- **2:** posiziono V alla posizione richiesta + dVPosA = dNewV + table.insert( vCmd, { 1, 'V', dVPosA}) + end -- [C3Vs] + + -- calcolo il nuovo parametro di aggancio + dVDeltaA = dVPosA - dTPosA + -- chiudo ev' V e apro Y + table.insert( vCmd, { 12, CalcCharStatus( 'V', dVDeltaA)}) + table.insert( vCmd, { 11, 0}) + -- sposto il carrello Y in parcheggio + table.insert( vCmd, { 1, 'Y', ParkY}) + -- imposto il nuovo parametro di aggancio + table.insert( vCmd, { 21, 0, dVDeltaA}) + + -- reset contatore + EMC.CNT = nil + + else -- **[C3Vns]** |spostamento| finale richiesto (ev' residuo) di |V non 'significativo'| + EmitComment( vCmd, '[C3Vns]') + end --[C3Vs/ns] + + EgtOutLog( ' VDeltaA =' .. EgtNumToString( dVDeltaA), 1) + + SpecOutputCNT() + return vCmd +end --SpecAdjustCarrC3 + +--------------------------------------------------------------------- +function SpecOutputCNT() + if EMC.CNT == 1 then + EgtSetInfo( EMC.PATHID, 'CNT', 1) + else + EgtRemoveInfo( EMC.PATHID, 'CNT') + end +end + +--------------------------------------------------------------------- +function SpecOutputCmds( vCmd, bEnd) + + local sRoot = EgtIf( not bEnd, 'AS', 'AE') + + -- Registro il numero di comandi + if #vCmd > 0 then + EgtSetInfo( EMC.PATHID, sRoot..'#', #vCmd) + else + EgtRemoveInfo( EMC.PATHID, sRoot..'#') + end + -- Registro i comandi + for i = 1, #vCmd do + local Cmd = vCmd[i] + local sKey = sRoot..tostring( i) + -- commento + if Cmd[1] == 0 then + local sInfo = '0,'..Cmd[2] + if Cmd[3] then sInfo = sInfo..','..Cmd[3] end + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 1 asse + elseif Cmd[1] == 1 then + local sInfo = '1,'..Cmd[2]..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 2 assi + elseif Cmd[1] == 2 then + local sInfo = '2,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 3 assi + elseif Cmd[1] == 3 then + local sInfo = '3,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3)..','.. + Cmd[6]..','..EgtNumToString( Cmd[7],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- apertura/chiusura morsa Y + elseif Cmd[1] == 11 then + local sInfo = '11,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] == 0 then EMC.YDELTA = nil end + -- apertura/chiusura morsa V + elseif Cmd[1] == 12 then + local sInfo = '12,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] == 0 then EMC.VDELTA = nil end + -- impostazione nuovo stato dei carrelli + elseif Cmd[1] == 21 then + local sInfo = '21,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = nil + elseif Cmd[3] > 0 then + EMC.YDELTA = nil + EMC.VDELTA = Cmd[3] + end + -- aggancio grezzo a carrello + elseif Cmd[1] == 31 then + local sInfo = '31,'..EgtNumToString( Cmd[2],0)..','..Cmd[3] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + end + end + + -- Salvo i nuovi delta dei carrelli + if EMC.YDELTA then + EgtSetInfo( EMC.PATHID, 'YDELTA', EMC.YDELTA) + else + EgtRemoveInfo( EMC.PATHID, 'YDELTA') + end + if EMC.VDELTA then + EgtSetInfo( EMC.PATHID, 'VDELTA', EMC.VDELTA) + else + EgtRemoveInfo( EMC.PATHID, 'VDELTA') + end + +end + +--------------------------------------------------------------------- +function SpecSetCarrPosFromCmds( vCmd) + -- recupero nuova posizione carrelli + for i = 1, #vCmd do + local Cmd = vCmd[i] + if Cmd[1] == 21 then + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.YDELTA = Cmd[2] + EMC.VDELTA = nil + elseif Cmd[3] > 0 then + EMC.YDELTA = nil + EMC.VDELTA = Cmd[3] + end + end + end +end + +--------------------------------------------------------------------- +function SpecTestOnlyRemarkInCmds( vCmd) + if not vCmd then return true end + -- verifico se nella lista dei comandi ci sono solo commenti + for i = 1, #vCmd do + if vCmd[i][1] ~= 0 then + return false + end + end + return true +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.nge new file mode 100644 index 0000000..53ee17b Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Essetre-FASTrl.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Machinings/Machinings.data b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Machinings/Machinings.data new file mode 100644 index 0000000..fce99a8 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Machinings/Machinings.data differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Machinings/Machinings.data.bak b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Machinings/Machinings.data.bak new file mode 100644 index 0000000..9d130ba Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Machinings/Machinings.data.bak differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Scripts/ExitMach.lua b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Scripts/ExitMach.lua new file mode 100644 index 0000000..18f86ad --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Scripts/ExitMach.lua @@ -0,0 +1,36 @@ +-- 2018/11/21 17:30:00 +-- Machining Exit for Essetre-FAST machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Uscita da Lavorazioni *** + +-- Nascondo il pezzo così marcato e le geometrie aggiunte, visualizzo il Box +local function ProcessPart( PartId) + -- visualizzo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.ON) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice (già chiusi tutti i gruppi di lavoro) +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +EgtZoom( SCE_ZM.ALL, false) + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Scripts/InitMach.lua b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Scripts/InitMach.lua new file mode 100644 index 0000000..6ac761b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Scripts/InitMach.lua @@ -0,0 +1,44 @@ +-- 2018/11/21 16:30:00 +-- Machining Init for Essetre-FAST machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Ingresso in Lavorazioni *** + +-- Rendo visibile il pezzo e le geometrie aggiunte, nascondo il Box +local function ProcessPart( PartId) + -- nascondo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.OFF) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +-- Processo i pezzi già nei gruppi di lavoro (quando appena lanciata Process) +local GhostId = EgtGetFirstGhostPart() +while GhostId do + local PartId = EgtGetInfo( GhostId, GDB_SI.SOURCE, 'i') + if PartId then + ProcessPart( PartId) + end + GhostId = EgtGetNextGhostPart( GhostId) +end + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Scripts/SetUp.lua b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Scripts/SetUp.lua new file mode 100644 index 0000000..2806b6e --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Scripts/SetUp.lua @@ -0,0 +1,204 @@ +-- Gestione attrezzaggio per Essetre-FAST - 2020/04/26 + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Tavola di passaggio valori +local STU = {} +STU.TUUID = "" +STU.TCPOS = "" +STU.HEAD = "" +STU.GROUP = "" +STU.POS = "" +STU.EXIT = 0 +STU.INDEX = 0 +STU.HEAD1 = "" +STU.HEAD2 = "" +STU.ISVALID = false +STU.ERR = 0 +_G.STU = STU + +local INVALIDPOS = "" +local POS = "Pos" + +-- Geom Set +local GS = {} + +-- Configurazione posizioni +local PositionTable={{Pos = "Pos1", TcPos = "T1", Head = "H1", Group = "G1"}, + {Pos = "Pos2", TcPos = "T2", Head = "H1", Group = "G1"}, + {Pos = "Pos3", TcPos = "T3", Head = "H1", Group = "G1"}, + {Pos = "Pos4", TcPos = "T4", Head = "H1", Group = "G1"}, + {Pos = "Pos5", TcPos = "T5", Head = "H1", Group = "G1"}, + {Pos = "Pos6", TcPos = "T6", Head = "H1", Group = "G1"}, + {Pos = "Pos7", TcPos = "T7", Head = "H1", Group = "G1"}, + {Pos = "Pos8", TcPos = "T8", Head = "H1", Group = "G1"}, + {Pos = "Pos9", TcPos = "T9", Head = "H1", Group = "G1"}, + {Pos = "Pos10", TcPos = "T10", Head = "H1", Group = "G1"}, + {Pos = "Pos11", TcPos = "T11", Head = "H1", Group = "G1"}, + {Pos = "Pos12", TcPos = "T42", Head = "H2", Group = "G1"}, + {Pos = "Pos13", TcPos = "T101", Head = "H3", Group = "G1"}} + +if EgtGetTcPosId( 'T111') then + table.insert( PositionTable, {Pos = "Pos14", TcPos = "T111", Head = "H1", Group = "G1"}) +end + +local UsePositionHead = true + +local function IsInGeomSet( ToolHead, PosHead) + for GsIndex = 1, #GS do + local bToolHead = false + local bPosHead = false + for HIndex = 1, #GS[GsIndex] do + if GS[GsIndex][HIndex] == ToolHead then + bToolHead = true + elseif GS[GsIndex][HIndex] == PosHead then + bPosHead = true + end + if bToolHead and bPosHead then + return true + end + end + if bToolHead and bPosHead then + return true + end + end + return false +end + +function STU.IsCompatibleHeads() + STU.ISVALID = false + if IsInGeomSet(STU.HEAD1, STU.HEAD2) then + STU.ISVALID = true + else + STU.ISVALID = false + end +end + +function STU.GetValidHeadExitForPos() + -- se TUUID non valido restituisco errore + local ToolName = EgtTdbGetToolFromUUID( STU.TUUID) + if ToolName == nill then + STU.ERR = 1 + return + end + EgtTdbSetCurrTool( ToolName) + local CurrToolHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + STU.EXIT = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + -- recupero testa predefinita per la posizione corrente + local CurrPosHead + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + CurrPosHead = PositionTable[i].Head + break + end + end + -- verifico se la testa è quella della posizione predefinita + if CurrPosHead == CurrToolHead then + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + -- verifico se la testa è compatibile con quella della posizione predefinita + elseif IsInGeomSet( CurrToolHead, CurrPosHead) then + if UsePositionHead then + STU.HEAD = CurrPosHead + STU.ERR = 0 + return + else + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + end + -- la testa non è compatibile con quella della posizione predefinita + else + STU.HEAD = INVALIDPOS + STU.ERR = 0 + return + end +end + +function STU.IsValidTcPosFromHead() + STU.ISVALID = false + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + if PositionTable[i].Head == STU.HEAD then + STU.ISVALID = true + STU.ERR = 0 + return + elseif IsInGeomSet(PositionTable[i].Head, STU.HEAD) then + STU.ISVALID = true + STU.ERR = 0 + return + end + STU.ISVALID = false + STU.ERR = 0 + return + end + end +end + +function STU.GetTcPosHeadGroupFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.HEAD = PositionTable[i].Head + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.HEAD = INVALIDPOS + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetPosFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.POS = PositionTable[i].Pos + STU.ERR = 0 + return + end + end + STU.POS = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetGroupFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetHeadFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.HEAD = PositionTable[i].Head + STU.ERR = 0 + return + end + end + STU.HEAD = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetTcPosFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.ERR = 1 +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/SetUp/SetupImage.PNG b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/SetUp/SetupImage.PNG new file mode 100644 index 0000000..a8d5b53 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/SetUp/SetupImage.PNG differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/SetUp/Standard.stu b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/SetUp/Standard.stu new file mode 100644 index 0000000..122fba6 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/SetUp/Standard.stu @@ -0,0 +1,16 @@ +; Commento per evitare BOM con UTF-8 +[General] +Pos1=T1;H1;1/D077C810-A58B-41DE-A3F5-D2187EBB1B67/Fresa100x60 +Pos2=T2;H1;1/877C9B3A-9078-42B6-808D-5ED5CF5C505B/Fresa20x50 +Pos3=T3;H1;1/0A54F32E-C48D-45DB-8502-953CA94FD7A0/Fresa25x130 +Pos4=T4;H1;1/E7F6A2BB-1F66-48B9-9561-496231C33403/FresaDT60x130 +Pos5=T5;H1;1/5BC80CC4-B497-4509-981C-C7593EC1279F/FresaDT35x130 +Pos6=T6;H1;1/12CCCF7E-6E46-4253-8463-A5063A77D8F6/Clean35x40 +Pos7=T7;H1;1/0150315A-41DF-4916-AC88-338C1EF375EF/Penna +Pos8=T8;H1;1/B449357F-293E-4EDC-8EE4-127A9863F116/PuntaD12 +Pos9=T9;H1;1/0147ED47-EB5D-44D6-9CE2-5282B484B5BD/Smusso45x40 +Pos10=T10;H1;1/3B1EFA29-E112-4090-8F4F-4EC5DA598D69/PuntaD16 +Pos11=T11;H1;1/0C3199C0-5E96-4512-A06B-EECE879330BF/Fresa10x50 +Pos12=T42;H2;1/6CB00A83-DDCD-49E6-A301-E1A0482615CA/Lama600 +Pos13=T101;H3;1/A6CFDA65-DABB-441E-990A-776B5C24C2E4/ChainSaw +Pos14=T111;H1;1/57898FF3-0FCA-4185-B40F-2318E501260A/PuntaD18 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/ChainSaw.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/ChainSaw.nge new file mode 100644 index 0000000..d29af27 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/ChainSaw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/MillNoTip.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/MillNoTip.nge new file mode 100644 index 0000000..5b2fe8a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/MillNoTip.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Saw.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Saw.nge new file mode 100644 index 0000000..4243139 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Saw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Standard.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Standard.nge new file mode 100644 index 0000000..23ee6c6 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Standard.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Standard_78.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Standard_78.nge new file mode 100644 index 0000000..bb1e695 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Standard_78.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Standard_LC.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Standard_LC.nge new file mode 100644 index 0000000..7d2b4c3 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/THolders/Standard_LC.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge new file mode 100644 index 0000000..cb9e396 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/03E09A0D-8D12-4ADC-B640-10D1A8ED1852.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/03E09A0D-8D12-4ADC-B640-10D1A8ED1852.nge new file mode 100644 index 0000000..176fdc9 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/03E09A0D-8D12-4ADC-B640-10D1A8ED1852.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge new file mode 100644 index 0000000..f167271 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/0C3199C0-5E96-4512-A06B-EECE879330BF.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/0C3199C0-5E96-4512-A06B-EECE879330BF.nge new file mode 100644 index 0000000..75551e2 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/0C3199C0-5E96-4512-A06B-EECE879330BF.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/12CCCF7E-6E46-4253-8463-A5063A77D8F6.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/12CCCF7E-6E46-4253-8463-A5063A77D8F6.nge new file mode 100644 index 0000000..bf0c624 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/12CCCF7E-6E46-4253-8463-A5063A77D8F6.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/24CB106E-76E2-4663-A911-FC8AE44132E1.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/24CB106E-76E2-4663-A911-FC8AE44132E1.nge new file mode 100644 index 0000000..dde62d9 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/24CB106E-76E2-4663-A911-FC8AE44132E1.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/3B1EFA29-E112-4090-8F4F-4EC5DA598D69.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/3B1EFA29-E112-4090-8F4F-4EC5DA598D69.nge new file mode 100644 index 0000000..b291619 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/3B1EFA29-E112-4090-8F4F-4EC5DA598D69.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/463BE81B-336D-40BE-991C-24765BC28846.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/463BE81B-336D-40BE-991C-24765BC28846.nge new file mode 100644 index 0000000..cd716d5 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/463BE81B-336D-40BE-991C-24765BC28846.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/57898FF3-0FCA-4185-B40F-2318E501260A.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/57898FF3-0FCA-4185-B40F-2318E501260A.nge new file mode 100644 index 0000000..e06630e Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/57898FF3-0FCA-4185-B40F-2318E501260A.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/5BC80CC4-B497-4509-981C-C7593EC1279F.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/5BC80CC4-B497-4509-981C-C7593EC1279F.nge new file mode 100644 index 0000000..9f168e4 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/5BC80CC4-B497-4509-981C-C7593EC1279F.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge new file mode 100644 index 0000000..b8b145c Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/6DBB8C3F-4744-4AF9-B213-9D40A7E19390.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/6DBB8C3F-4744-4AF9-B213-9D40A7E19390.nge new file mode 100644 index 0000000..52f0430 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/6DBB8C3F-4744-4AF9-B213-9D40A7E19390.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/8071E2FC-B181-45E9-9EF1-DA7906A95EF2.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/8071E2FC-B181-45E9-9EF1-DA7906A95EF2.nge new file mode 100644 index 0000000..a8ad59a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/8071E2FC-B181-45E9-9EF1-DA7906A95EF2.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/82505C4D-26F2-4197-824F-25129D782E2D.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/82505C4D-26F2-4197-824F-25129D782E2D.nge new file mode 100644 index 0000000..1cf162b Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/82505C4D-26F2-4197-824F-25129D782E2D.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge new file mode 100644 index 0000000..97abb27 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/973C769D-9B8B-40CB-92DE-5E9CC11E66D7.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/973C769D-9B8B-40CB-92DE-5E9CC11E66D7.nge new file mode 100644 index 0000000..a217c4a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/973C769D-9B8B-40CB-92DE-5E9CC11E66D7.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/9758E25E-CF88-4237-8509-49DF755A5E1E.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/9758E25E-CF88-4237-8509-49DF755A5E1E.nge new file mode 100644 index 0000000..c1f91ce Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/9758E25E-CF88-4237-8509-49DF755A5E1E.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/98CDAEAB-754D-4351-B427-CB8596B2EBF1.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/98CDAEAB-754D-4351-B427-CB8596B2EBF1.nge new file mode 100644 index 0000000..5a54265 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/98CDAEAB-754D-4351-B427-CB8596B2EBF1.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge new file mode 100644 index 0000000..7b4f653 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/B449357F-293E-4EDC-8EE4-127A9863F116.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/B449357F-293E-4EDC-8EE4-127A9863F116.nge new file mode 100644 index 0000000..abcc480 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/B449357F-293E-4EDC-8EE4-127A9863F116.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/B5B974EF-D18A-45DE-9842-05B91639BE91.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/B5B974EF-D18A-45DE-9842-05B91639BE91.nge new file mode 100644 index 0000000..18ee8e5 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/B5B974EF-D18A-45DE-9842-05B91639BE91.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge new file mode 100644 index 0000000..6576c80 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/E464F880-F88F-4552-BBE5-B98D5830A89A.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/E464F880-F88F-4552-BBE5-B98D5830A89A.nge new file mode 100644 index 0000000..1f096ed Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/E464F880-F88F-4552-BBE5-B98D5830A89A.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/E4F6E66C-4CF2-4CE3-87AF-78305CEDE59A.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/E4F6E66C-4CF2-4CE3-87AF-78305CEDE59A.nge new file mode 100644 index 0000000..01df802 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/E4F6E66C-4CF2-4CE3-87AF-78305CEDE59A.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge new file mode 100644 index 0000000..63ec066 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/EADA5FF9-7189-4ADC-AAF7-B84614C19EEF.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/EADA5FF9-7189-4ADC-AAF7-B84614C19EEF.nge new file mode 100644 index 0000000..b2a84a0 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/EADA5FF9-7189-4ADC-AAF7-B84614C19EEF.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/FE2C49A5-18B9-49CD-85DB-18D1FE14ECF9.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/FE2C49A5-18B9-49CD-85DB-18D1FE14ECF9.nge new file mode 100644 index 0000000..d1626b5 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/FE2C49A5-18B9-49CD-85DB-18D1FE14ECF9.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/Tools.data b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/Tools.data new file mode 100644 index 0000000..40ef454 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/Tools.data differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/Tools.data.bak b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/Tools.data.bak new file mode 100644 index 0000000..a25ec87 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/Tools.data.bak differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/penna.nge b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/penna.nge new file mode 100644 index 0000000..f7eb46e Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-FASTrl/Tools/penna.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/BeamData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/BeamData.lua new file mode 100644 index 0000000..3eec4eb --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/BeamData.lua @@ -0,0 +1,140 @@ +-- BeamData.lua by Egaltech s.r.l. 2022/03/23 +-- Raccolta dati generali per Travi + +EgtOutLog( ' PF1250-BeamData started') + +-- Tabella per definizione modulo +local BeamData = { + MIN_WIDTH = 40, -- larghezza minima del grezzo + MIN_HEIGHT = 40, -- altezza minima del grezzo + MAX_WIDTH = 1250, -- larghezza massima del grezzo + MAX_HEIGHT = 400, -- altezza massima del grezzo + LEN_SHORT_PART = 1200, -- lunghezza massima pezzo piccolo + MAX_RAW = 20000, -- massima lunghezza grezzo (deve essere minore di LenTable - RAW_OFFSET) + STD_RAW = 14000, -- lunghezza standard della barra di grezzo + OVM_HEAD = 10, -- sovramateriale testa + OVM_MID = 5.4, -- sovramateriale intermedio (spessore lama) + MIN_JOIN_S = 100, -- minima presa pinza per pezzo piccolo + MIN_JOIN_L = 450, -- minima presa pinza per pezzo grande + MINRAW_S = 980, -- minimo grezzo in coda scaricabile per sezioni piccole + MINRAW_L = 1680, -- minimo grezzo in coda scaricabile per sezioni grandi + CHAR_EXTRA_DIST = 400, -- distanza aggiuntiva per minimizzare scambi di carrelli + MAX_LEN_SCRAP = 150, -- massima lunghezza scarto di coda + MAX_LEN_SCRAP_START = 150, -- massima lunghezza scarto di testa + MAX_DIM_HTCUT = 201.1, -- larghezza massima taglio di testa o coda + MAX_DIM_HTCUT_HBEAM = 201.1, -- larghezza massima taglio di testa o coda con trave alta + MIN_DIM_HBEAM = 410, -- altezza minima di trave alta + MAX_DIM_DICE = 135, -- dimensione trasversale massima cubetto + MAX_LEN_DICE = 400, -- lunghezza massima cubetto 400 + DECR_VERT_CUT = 25, -- riduzione profondità per affondamento verticale in taglio orizzontale + COLL_SIC = 5, -- distanza di sicurezza per collisioni + CUT_SIC = 30, -- distanza di sicurezza per tagli + CUT_EXTRA = 5, -- affondamento extra standard per tagli di lama e fresature + CUT_EXTRA_MIN = 1, -- affondamento extra ridotto per tagli di lama e fresature + NZ_MINA = -0.6, -- componente limite in Z normale di una faccia (-30deg) + NZ_MINB = -0.4, -- componente limite in Z normale di un insieme di facce (-23deg) + DRILL_TOL = 0.2, -- tolleranza tra diametro foro e diametro punta + DRILL_VZ_MIN = - 0.51, -- componente limite in Z del versore di un foro + DRILL_VX_MAX = 0.867, -- componente limite in X del versore di un foro sulle facce laterali + DRILL_OVERLAP = 5, -- sovrapposizione tra due mezze forature + MILL_OVERLAP = 5, -- sovrapposizione tra due mezze fresature + MAX_DIST_HTFEA = 50.0, -- massima distanza di feature da testa o coda per essere considerata tale + MAX_LEN_HTFEA = 2550.0, -- massima lunghezza di feature di testa o coda + LONGCUT_ENDLEN = 1500, -- lunghezza lavoro estremi iniziale e finale + LONGCUT_MAXLEN = 3000, -- lunghezza massima sezione di taglio longitudinale + MAX_LEN_RIDGELAP_FROM_BOTTOM = 0, -- massima lunghezza ridgelap lavorabile da sotto + MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM = 0, -- massima lunghezza ridgelap lavorabile da sotto con trave alta + DIM_TO_CENTER_STRIP = 0, -- larghezza minima trave per inserimento codolo nel centro della trave; 0 = automatico + DIM_STRIP = 3, -- dimensione codolo sostegno parti lasciate su contorno libero o archi + DIM_STRIP_SMALL = 1.5, -- dimensione codolo piccolo (quando le parti sostenute sono sicuramente sulla parte sopra del pezzo) + RAWCOL = { 255, 160, 32, 30}, -- colore del grezzo + RAW_OFFSET = 2000, -- spostamento grezzo rimanente dopo split + VICE_MINH = 110, -- altezza minima della morsa + OFFSET_DRILL_TENON = 0, -- offset fori su tenoni verso base degli stessi (0=non fare) + USER_HOLE_DIAM = 0, -- diametro foro per L20 + MAX_TOOL_LEN_FOR_HOR_MACH = 500, -- massima lunghezza ingombro per poter fare forature (fresature) oltre i 10 gradi dalla verticale + DRILL_VZ_MIN_LONG_TOOL = 0.984, -- componente limite per lavorazioni con punta lunga + MAX_TOOL_LEN_BACK_HOR_MACH = 500, -- massima lunghezza utensile per poter eseguire lavorazioni (forature/svuotature) da dietro (faccia 4) + MIN_LEN_LAMELLO = 1000, -- lunghezza minima di fessura longitudinale per lavorazione tipo lamello (SideMillAsBlade) + PRESS_ROLLER = true, -- dichiarazione presenza rulli pressori + C_SIMM = true, -- dichiarazione simmetria mensola asse C + DOWN_HEAD = true, -- dichiarazione presenza seconda testa dal basso + DH_MAX_TOP = 370, -- quota massima raggiungibile dalla testa da sotto dal sotto del pezzo + KIOTP = 2, -- coefficiente moltiplicativo per attacco/uscita lama tangente anzichè perpendicolare + MAXDIAM_POCK_CORNER = 30, -- diametro massimo utensile ammesso per tasche con angoli interni + USE_LONGCUT = false, -- per i tagli longitudinali usare solo la lavorazione di lama LongCut + ADVANCE_TAIL_CUT = true, -- per spostare prima del taglio di separazione il taglio di coda su pezzi corti con robabile caduta + ADVANCE_TAIL_OFFS = 5 -- accorciamento taglio di coda avanzato (minimo 1) +} + +local function GetMaxLenRidgeLapFromBottom( dHRaw) + if dHRaw < BeamData.MIN_DIM_HBEAM then + return BeamData.MAX_LEN_RIDGELAP_FROM_BOTTOM + 0.01 + else + return BeamData.MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM + 0.01 + end +end +BeamData.GetMaxLenRidgeLapFromBottom = GetMaxLenRidgeLapFromBottom + +local function GetBottomToolMaxTotLen( vtDir) + if not vtDir or vtDir:getZ() < -0.867 then + return 240 + elseif vtDir:getZ() < -0.707 then + return 240 + else + return 280 + end +end +BeamData.GetBottomToolMaxTotLen = GetBottomToolMaxTotLen + +local function GetSectionCoeff( dW, dH, dL) + local SEZ_L = 80000 + local SEZ_S = 20000 + local LEN_SMALL = 2000 + local dSez = dW * dH + if dSez <= SEZ_S then + return 0.0 + elseif dSez < SEZ_L then + if dL and dL < LEN_SMALL then dSez = max( 0.6 * dSez, SEZ_S) end + local dCoeff = ( dSez - SEZ_S) / ( SEZ_L - SEZ_S) + return dCoeff + else + return 1.0 + end +end + +local function GetMinJoin( dW, dH, dL) + local dCoeff = GetSectionCoeff( dW, dH, dL) + return ( 1 - dCoeff) * BeamData.MIN_JOIN_S + dCoeff * BeamData.MIN_JOIN_L +end +BeamData.GetMinJoin = GetMinJoin + +local function GetMinUnloadableRaw( dW, dH) + local dCoeff = GetSectionCoeff( dW, dH) + return BeamData.MINRAW_S + dCoeff * ( BeamData.MINRAW_L - BeamData.MINRAW_S) +end +BeamData.GetMinUnloadableRaw = GetMinUnloadableRaw + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Beam', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-PF1250.data" +local sData = EgtGetSourceDir().."\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Trave then + BeamData.MIN_WIDTH = Machine.Trave.XMIN or BeamData.MIN_WIDTH + BeamData.MIN_HEIGHT = Machine.Trave.ZMIN or BeamData.MIN_HEIGHT + BeamData.MAX_WIDTH = Machine.Trave.XMAX or BeamData.MAX_WIDTH + BeamData.MAX_HEIGHT = Machine.Trave.ZMAX or BeamData.MAX_HEIGHT + end + end +end + +--------------------------------------------------------------------- +return BeamData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/BeamTableTemplate.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/BeamTableTemplate.ini new file mode 100644 index 0000000..ccb02c1 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/BeamTableTemplate.ini @@ -0,0 +1,9 @@ +-- %TABLE_NAME%.lua by Egaltech s.r.l. %DATE_TIME% +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local %TABLE_NAME% = { +} + +--------------------------------------------------------------------- +return %TABLE_NAME% diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/CutData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/CutData.lua new file mode 100644 index 0000000..0abf46b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/CutData.lua @@ -0,0 +1,13 @@ +-- CutData.lua by Egaltech s.r.l. 25/02/2022 14:59:28 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local CutData = { + { On = true, Name = 'MiSideInvSaw550', Type = 'HeadSide'}, + { On = true, Name = 'MiSideInvSaw450_H2', Type = 'HeadSide_H2'}, + { On = true, Name = 'MiSideSaw550', Type = 'TailSide'}, + { On = true, Name = 'MiSideSaw450_H2', Type = 'TailSide_H2'} +} + +--------------------------------------------------------------------- +return CutData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/DrillData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/DrillData.lua new file mode 100644 index 0000000..1b4ed7f --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/DrillData.lua @@ -0,0 +1,24 @@ +-- DrillData.lua by Egaltech s.r.l. 15/09/2021 12:15:23 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local DrillData = { + { On = true, Name = 'DrillD12_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD12_H2', Type = 'Drill_H2'}, + { On = true, Name = 'DrillD14_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD14_H2', Type = 'Drill_H2'}, + { On = true, Name = 'DrillD16_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD18_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD20_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD20_H2', Type = 'Drill_H2'}, + { On = true, Name = 'DrillD25_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD25_H2', Type = 'Drill_H2'}, + { On = true, Name = 'DrillPock20x50_H1', Type = 'Pocket'}, + { On = true, Name = 'DrillPock25x130_H1', Type = 'Pocket'}, + { On = true, Name = 'DrillPock40x280_H1', Type = 'Pocket'}, + { On = true, Name = 'DrillPock20x50_H2', Type = 'Pocket_H2'}, + { On = true, Name = 'DrillPock25x130_H2', Type = 'Pocket_H2'} +} + +--------------------------------------------------------------------- +return DrillData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/MachData.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/MachData.ini new file mode 100644 index 0000000..558fe47 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/MachData.ini @@ -0,0 +1,81 @@ +; PIndex = Type, PName, Default, Description +; Type : d=double, l=length, s=string + +[1] +Name=Offsets +1=l,X1_NEG,-3450.0,X1_NEG +2=l,X1_POS,34,X1_POS +3=l,PARK_X1,125,PARK_X1 +4=l,Z1_NEG,1550.0,Z1_NEG +5=l,Z1_POS,0.0,Z1_POS +6=l,PARK_Z1,-535.0,PARK_Z1 +7=l,PARK_SAWZ1,-150.0,PARK_SAWZ1 +8=l,B1_NEG,-127.0,B1_NEG +9=l,B1_NEG1,-119.0,B1_NEG1 +10=l,B1_POS,127.0,B1_POS +11=l,B1_POS1,119.0,B1_POS1 +12=l,PARK_B1,-90.0,PARK_B1 +13=l,PARK_SAWB1,0.0,PARK_SAWB1 +14=l,C1_NEG,-275.0,C1_NEG +15=l,C1_POS,275.0,C1_POS +16=d,PARK_C1,-90.0,PARK_C1 +17=d,PARK_SAWC1,-90.0,PARK_SAWC1 +18=d,X2_NEG,-2760.0,X2_NEG +19=d,X2_POS,0.0,X2_POS +20=l,PARK_X2,-70.0,PARK_X2 +21=l,PIVOT_T1,170.0,PIVOT_T1 +22=d,Z2_NEG,-795.0,Z2_NEG +23=d,Z2_POS,0.0,Z2_POS +24=d,PARK_Z2,-10.0,PARK_Z2 +25=d,B2_NEG,-127.0,B2_NEG1 +26=d,B2_NEG1,-119.0,B2_NEG1 +27=d,B2_POS,127.0,B2_POS +28=d,B2_POS1,119.0,B2_POS1 +29=d,PARK_B2,-90.0,PARK_B2 +30=l,C2_NEG,-275.0,C2_NEG +31=l,C2_POS,275.0,C2_POS +32=d,PARK_C2,-90.0,PARK_C2 +33=d,MIN_Y1,317,MIN_Y1 +34=d,MAX_Y1,5772.0,MAX_Y1 +35=d,PARK_Y1,952.0,PARK_Y1 +36=d,MIN_V1,5.0,MIN_V1 +37=d,MAX_V1,635.0,MAX_V1 +38=d,PIVOT_T2,170.0,PIVOT_T2 +39=d,X1P_NEG,30.0,X1P_NEG +40=l,X1P_POS,1330.0,X1P_POS +41=l,DIST_FTZERO,2167.6,DIST_FTZERO +42=d,DELTA_CARICZERO,120.0,DELTA_CARICZERO +43=d,X2P_NEG,35.0,X2P_NEG +44=d,X2P_POS,1330.0,X2P_POS +45=d,Z2P_NEG,30.0,Z2P_NEG +46=d,Z2P_POS,350.0,Z2P_POS +47=d,X3P_NEG,35.0,X3P_NEG +48=d,X3P_POS,1330.0,X3P_POS +49=d,Z3P_NEG,30.0,Z3P_NEG +50=l,Z3P_POS,350.0,Z3P_POS +51=l,MIN_V2,-635.0,MIN_V2 +52=d,MAX_V2,-5.0,MAX_V2 +53=d,X4P_NEG,30.0,X4P_NEG +54=d,X4P_POS,1330.0,X4P_POS +55=d,MIN_Y2,-5772.0,MIN_Y2 +56=d,MAX_Y2,-321.0,MAX_Y2 +57=d,PARK_Y2,-952.0,PARK_Y2 +58=d,MIN_DELTAVY,317,MIN_DELTAVY +59=d,DIST_UNLOAD,-2400,DIST_UNLOAD +60=l,OFFSETBLAMAT1,0,OFFSETBLAMAT1 +61=l,OFFSETCLAMAT1,0,OFFSETCLAMAT1 +62=d,OFFSETBLAMAT2,0,OFFSETBLAMAT2 +63=d,OFFSETCLAMAT2,0,OFFSETCLAMAT2 +64=d,OFFSETXT1,-2466.7,OFFSETXT1 +65=d,OFFSETZT1,-1140.6,OFFSETZT1 +66=d,OFFSETXT2,-967.3,OFFSETXT2 +67=d,OFFSETZT2,-394.3,OFFSETZT2 +68=d,Zzz,1,Zzz + +[2] +Name=Trave +1=l,XMIN,30,XMIN +2=l,XMAX,1251,XMAX +3=l,ZMIN,30,ZMIN +4=l,ZMAX,300,ZMAX +68=d,Zzz,1,Zzz diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/MachiningTypes.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/MachiningTypes.ini new file mode 100644 index 0000000..463354c --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/MachiningTypes.ini @@ -0,0 +1,59 @@ +[Cut] +1=HeadSide +2=HeadSide_H2 +3=TailSide +4=TailSide_H2 +5=LongCut + +[Drill] +1=Drill +2=Drill_H2 +3=Pocket +4=Pocket_H2 + +[Milling] +1=Prof +2=Prof_H2 +3=FreeContour +4=Tenon +5=Tenon_H2 +6=DtTenon +7=DtTenon_H2 +8=DtMortise +9=DtMortise_H2 +10=BirdsMouth +11=BirdsMouth_H2 +12=Chamfer +13=Mark +14=Mark_H2 +15=Text +16=Text_H2 +17=Decor01 +18=Long2Cut +19=Long2Cut_H2 +20=Long2CutDown +21=Long2CutDown_H2 +22=LongSmallCut +23=LongSmallCut_H2 +24=BHSideMill +25=CleanCorner +26=ProfTCone +27=Long2CutSide +28=Long2CutSide_H2 +29=SmallToolContour +30=SmallToolContour_H2 +31=AntiSplintMillCut +32=AntiSplintMillCut_H2 +33=SideMillAsBlade +34=SideMillAsBlade_H2 + +[Pocketing] +1=Pocket +2=Pocket_H2 +3=OpenPocket +4=OpenPocket_H2 +5=Mortise +6=Mortise_H2 + +[Sawing] +1=Sawing diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/MillingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/MillingData.lua new file mode 100644 index 0000000..757bf81 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/MillingData.lua @@ -0,0 +1,38 @@ +-- MillingData.lua by Egaltech s.r.l. 07/03/2022 17:36:03 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local MillingData = { + { On = true, Name = 'Profiling25x130_H1', Type = 'Prof'}, + { On = true, Name = 'Profiling25x130_H2', Type = 'Prof_H2'}, + { On = true, Name = 'FreeCont25x130_H1', Type = 'FreeContour'}, + { On = true, Name = 'FreeCont25x130_H2', Type = 'FreeContour'}, + { On = true, Name = 'Mill_Tenon200x60_H1', Type = 'Tenon'}, + { On = true, Name = 'Mill_Tenon100x60_H2', Type = 'Tenon_H2'}, + { On = true, Name = 'Mill_DtTen60x130_H1', Type = 'DtTenon'}, + { On = true, Name = 'Mill_DtTen60x130_H2', Type = 'DtTenon_H2'}, + { On = true, Name = 'Mill_DtMrt60x130_H1', Type = 'DtMortise'}, + { On = true, Name = 'Mill_DtMrt60x130_H2', Type = 'DtMortise_H2'}, + { On = true, Name = 'Milling200x60_H1', Type = 'BirdsMouth'}, + { On = true, Name = 'Milling100x60_H2', Type = 'BirdsMouth_H2'}, + { On = true, Name = 'Edge25x130_H1', Type = 'Chamfer'}, + { On = true, Name = 'Edge25x130_H2', Type = 'Chamfer'}, + { On = true, Name = 'Chamf45x40_H1', Type = 'Mark'}, + { On = true, Name = 'Chamf45x40_H2', Type = 'Mark_H2'}, + { On = true, Name = 'Chamf45x40_H1', Type = 'Text'}, + { On = true, Name = 'Chamf45x40_H2', Type = 'Text_H2'}, + { On = true, Name = 'Marking_H1', Type = 'Text'}, + { On = true, Name = 'Marking_H2', Type = 'Text_H2'}, + { On = true, Name = 'Mill_L2C200x60_H1', Type = 'Long2Cut'}, + { On = true, Name = 'Mill_L2C100x60_H2', Type = 'Long2Cut_H2'}, + { On = true, Name = 'Milling25x130_H1', Type = 'LongSmallCut'}, + { On = true, Name = 'Milling25x130_H2', Type = 'LongSmallCut_H2'}, + { On = true, Name = 'Mill_L2CD25x130_H1', Type = 'Long2CutSide'}, + { On = true, Name = 'Mill_L2CD25x130_H2', Type = 'Long2CutSide_H2'}, + { On = true, Name = 'Mill_L2CD25x130_H1', Type = 'Long2CutDown'}, + { On = true, Name = 'Mill_L2CD25x130_H2', Type = 'Long2CutDown_H2'}, + { On = true, Name = 'Lamello21_H1', Type = 'SideMillAsBlade'} +} + +--------------------------------------------------------------------- +return MillingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/PocketingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/PocketingData.lua new file mode 100644 index 0000000..658e829 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/PocketingData.lua @@ -0,0 +1,21 @@ +-- PocketingData.lua by Egaltech s.r.l. 25/02/2022 14:58:55 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local PocketingData = { + { On = true, Name = 'Svuot200x60_H1', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot200x60_H2', Type = 'OpenPocket_H2'}, + { On = true, Name = 'Svuot100x60_H2', Type = 'OpenPocket_H2'}, + { On = true, Name = 'Svuot25x130_H1', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot25x130_H2', Type = 'OpenPocket_H2'}, + { On = true, Name = 'Svuot20x50_H1', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot20x50_H2', Type = 'OpenPocket_H2'}, + { On = true, Name = 'Svuot25x130_H1', Type = 'Pocket'}, + { On = true, Name = 'Svuot20x50_H1', Type = 'Pocket'}, + { On = true, Name = 'Svuot25x130_H2', Type = 'Pocket_H2'}, + { On = true, Name = 'Svuot20x50_H2', Type = 'Pocket_H2'}, + { On = true, Name = 'Svuot15x60_H2', Type = 'Pocket_H2'} +} + +--------------------------------------------------------------------- +return PocketingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/SawingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/SawingData.lua new file mode 100644 index 0000000..098bd6a --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/SawingData.lua @@ -0,0 +1,11 @@ +-- SawingData.lua by Egaltech s.r.l. 16/09/2021 14:08:42 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local SawingData = { + { On = true, Name = 'TaglioCatena', Type = 'Sawing'}, + { On = true, Name = 'TaglioCatena_corta', Type = 'Sawing'} +} + +--------------------------------------------------------------------- +return SawingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/Ts3Data.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/Ts3Data.lua new file mode 100644 index 0000000..0705ec7 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Beam/Ts3Data.lua @@ -0,0 +1,120 @@ +-- C:\TechnoEssetre7\EgtData\Essetre-PF1250.data + +local Offsets = { + X1_NEG=-3450.0, + X1_POS=0.0, + PARK_X1=250.0, + Z1_NEG=-1550.0, + Z1_POS=0.0, + PARK_Z1=-535.0, + PARK_SAWZ1=-150.0, + B1_NEG=-127.0, + B1_NEG1=-119.0, + B1_POS=127.0, + B1_POS1=119.0, + PARK_B1=-90.0, + PARK_SAWB1=0.0, + C1_NEG=-275.0, + C1_POS=275.0, + PARK_C1=-90.0, + PARK_SAWC1=-90.0, + X2_NEG=-2760.0, + X2_POS=0.0, + PARK_X2=-70.0, + PIVOT_T1=170.0, + Z2_NEG=-870.0, + Z2_POS=0.0, + PARK_Z2=-10.0, + B2_NEG=-127.0, + B2_NEG1=-119.0, + B2_POS=127.0, + B2_POS1=119.0, + PARK_B2=-90.0, + C2_NEG=-275.0, + C2_POS=275.0, + PARK_C2=-90.0, + MIN_Y1=363.0, + MAX_Y1=5754.0, + PARK_Y1=1014, + MIN_V1=10, + MAX_V1=670, + PIVOT_T2=170.0, + X1P_NEG=30.0, + X1P_POS=1330.0, + DIST_FTZERO=2262.35, + DELTA_CARICZERO=45, + X2P_NEG=35.0, + X2P_POS=1330.0, + Z2P_NEG=30.0, + Z2P_POS=420.0, + X3P_NEG=35.0, + X3P_POS=1330.0, + Z3P_NEG=30.0, + Z3P_POS=420.0, + MIN_V2=-670, + MAX_V2=-10, + X4P_NEG=30.0, + X4P_POS=1330.0, + MIN_Y2=-5763.0, + MAX_Y2=-363, + PARK_Y2=-1014, + MIN_DELTAVY=353, + DIST_UNLOAD=-2100, + OFFSETBLAMAT1=0.04, + OFFSETCLAMAT1=0.02, + OFFSETBLAMAT2=0, + OFFSETCLAMAT2=0, + OFFSETXT1=-2479.6, + OFFSETZT1=-1238.0, + OFFSETXT2=-1155.7, + OFFSETZT2=-456.2, + OFFSETZSOTTOTRAVE=990, + Zzz=1 +} + +local Trave = { + XMIN=30, + XMAX=1251, + ZMIN=30, + ZMAX=401, + Zzz=1 +} + +local User = { + NESTING_MATERIAL=1, + NESTING_TYPEEXTERNALOP=1, + NESTING_FROM_BTL=0, + SAFETY_DISTANCE_ZSAVE=30, + OPTIMIZATIONS_ENABLE_SLICES_F5=1, + OPTIMIZATIONS_ENABLE_SLICES_F6=1, + OPTIMIZATIONS_LENGTH_SLICES=100, + L056_ACTIVE_AS=1, + L055_ADD_P13=0, + L055_ACTIVE_AS=1, + L050_ADDDEPTH=3, + L060_PEN_F2=2, + L060_PEN_F1=2, + L138_TOLLERANZA=0, + L037_TOOL_WIDTH=0, + L032_LENGTH_MIN_DIV=0, + T055_ACTIVE_AS=1, + L040_ADD_P11=0, + L040_ADD_P11_PASS=3, + L040_OFFSET_P1=0, + L040_TYPEDRILLING=0, + L012_LIM=0, + L012_LENGTH_MIN_DIV=950, + L010_LIM=3, + L010_LENGTH_MIN_DIV=1000, + L020_DIAM_HOLE=12, + L030_AUM_DIM=0, + L030_LENGTH_MIN_DIV=0, + T010_ALTCATENA=361, + T010_OFFSETPIANOCATENA=20, + L036_LENGTH_MIN_DIV=900, + OPTIMIZATIONS_LENGTH_MAX_SCRAP_F5=1200, + Zzz=1 +} + +local Machine = { Offsets=Offsets, Trave=Trave, User=User} +return Machine diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.NUM.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.NUM.mlpe new file mode 100644 index 0000000..fc2116f --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.NUM.mlpe @@ -0,0 +1,1176 @@ +-- Processore macchina Essetre-PF1250 by EgalTech s.r.l. 2020/10/21 +-- Con controllo numerico NUM + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +-- Variabili di modulo +local MLE_INFO = 'Essetre-PF1250.NUM.mlpe ver.'..PP_VER..' by EgalTech s.r.l.' +local DELTA_TAKING = 200 +local TEST_USE = false + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.FMAXPINZE = 154000 -- feed massima pinze +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Intestazioni + EmtOutput( "%40.0") + if EMT.INFO then + EmtOutput( '('..EMT.INFO..')') + else + EmtOutput( '(Program Start)') + end + EmtOutput( '('.. MLE_INFO..')\n') + -- Se modalità test, aggiungo linee per muovere tappeto e alzare la testa (in automatico viene fatto dal main residente) + if TEST_USE then + EmtOutput( 'M28') + EmtOutput( 'N1 G101Z-100 L0=0') + EmtOutput( 'N1 G101ET1001') + EmtOutput( 'N1 G101ET2001\n') + end +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Arresto mandrino + EmtOutput( 'M05') + -- Emissione scarico + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' or EMT.AUXTYPE == 'R' then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + elseif EMT.AUXTYPE == 'U' then + EmtOutput( 'G111ET1002') + EmtOutput( 'G111ET2002') + -- emissione conclusione pezzo precedente + local sOut = 'G113 EA0EB1EC1' + EmtOutput( sOut) + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + -- Se modalità test, termino il programma + if TEST_USE then + EmtOutput( 'M02') + end +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensile (esclusa sega a catena) + if EMT.HEAD == 'H1' then + -- output info + local sPos = EgtIf( #EMT.TCPOS == 2, EMT.TCPOS:gsub( 'T', 'N30'), EMT.TCPOS:gsub( 'T', 'N3')) + local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( EMT.TTOTLEN, 1)..' G76H9998.2'..sPos..sPos + EmtOutput( sOut) + -- emissione dati sega a catena + elseif EMT.HEAD == 'H3' then + local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( ChSawLen, 1)..' G76H9998.2N401N404' + EmtOutput( sOut) + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + --EmtOutput( '(Disposition '..EMT.DISPIND..' = '..EMT.DISPID..')') + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') + EMT.Y1POS = EgtGetInfo( EMT.DISPID, 'Y1POS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- emissione dati di macchina + local sOut = 'G114'..'EA'..EmtLenToString(LoadT,-2)..'EB'..EmtLenToString(MinY,-2)..'EC'..EmtLenToString(MaxY,-2).. + 'ED'..EmtLenToString(MinV,-2)..'EE'..EmtLenToString(MaxV,-2)..'EF'..EmtLenToString(MillOffs,-2).. + 'EG'..EmtLenToString(SawOffs,-2)..'EI'..EmtLenToString(ParkY,-2)..'EL'..EmtLenToString(ParkV,-2).. + 'EM'..EmtLenToString(TurnerOffs,-2) + EmtOutput( '\n' .. sOut .. '\n') + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + end +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- reset recupero sovramateriale in X non più presente + EMT.X_OFF = nil + -- dati del grezzo + local LBarra = EMT.LB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- calcolo dati pinze + local MinAccPinze = 0.3 + local MaxAccPinze = 4 + local KgMtCubo= 550 -- densità legno in Kg / metro cubo + local Massa = ( HTrave * STrave * LBarra * KgMtCubo ) / 1000000000 + local FMaxPinze = EMT.FMAXPINZE + local ForzaAtrito = 700 / 2 -- Serve per regolare P32 (700 valore reale pistone) + local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAtrito) / 1000) + if ( TempoAcc < MinAccPinze) then TempoAcc = MinAccPinze end + if ( TempoAcc > MaxAccPinze) then TempoAcc = MaxAccPinze end + local AccPinze = FMaxPinze / ( 60 * TempoAcc) + local RidFeed = 100 / Massa * 100 + if ( RidFeed > 100) then RidFeed = 100 end + if IdTrave >= 0 then + local sOut = '( SN='..IdTrave..' LBarra='..EmtLenToString(LBarra,3)..' L='..EmtLenToString(LTrave,3).. + ' H='..EmtLenToString(HTrave,3)..' S='..EmtLenToString(STrave,3)..' Acc='..EmtLenToString(TempoAcc,1).. + ' RidFeed='..EmtLenToString(RidFeed,3)..' FeedMax='..EmtLenToString(FMaxPinze / 100 * RidFeed,3)..' )' + MyOutputNoNum( sOut) + sOut = 'E30049='..EmtLenToString(AccPinze,0)..' E30050=8555 E30051='..EmtLenToString(AccPinze,0).. + ' E30052=8555'..' E30054='..EmtLenToString(AccPinze,0)..' E30039='..EmtLenToString(RidFeed*1000,0).. + ' E30040='..EmtLenToString(RidFeed*1000,0)..' E30017=E80017'..' E30018=E80018'..' E10012=1' + MyOutputNoNum( sOut) + else + MyOutputNoNum( '(REMAIN UNLOAD)') + end + -- se carico barra + if EMT.LOAD then + -- verifico se sezione già caricata + local sOut = 'IF E30033<'..EmtLenToString(HTrave*1000,0)..' OR E30036<'..EmtLenToString(STrave*1000,0)..' THEN' + EmtOutput( sOut) + sOut = 'M119' + EmtOutput( sOut) + sOut = 'M149' + EmtOutput( sOut) + sOut = 'ENDI' + EmtOutput( sOut) + -- assegnazione dati trave e barra + sOut = 'E30033='..EmtLenToString(HTrave*1000,0)..' E30036='..EmtLenToString(STrave*1000,0).. + ' E30069='..EmtLenToString(LBarra*1000,0) + EmtOutput( sOut) + -- ora abilito numerazione linee + EMT.NUM = true + EMT.LINENBR = 0 + -- altrimenti recupero rimanenza + else + EmtOutput( 'G112 EC1'..' Y'..EmtLenToString( LoadT, 3).. ' EY'..EmtLenToString( EMT.Y1POS, 3)..' EV'..EmtLenToString( ParkV, 3) ..' EF'..GetFmaxClamp()) + -- aggiorno dati aggancio carrelli alla trave + EMT.Y1DELTA = EMT.Y1POS - LoadT + EMT.Y2DELTA = nil + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) then + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- verifico se sono diverse + if nRot ~= nPrevRot then + if nRot > nPrevRot then nRot = nRot - 4 end + local nDeltaRot = nRot - nPrevRot + -- se rotazione automatica richiesta e possibile + if AutomaticRotation and EMT.LB >= AutoRotMinLen then + local sOut = 'M180 L0=' .. tostring( -nDeltaRot) + EmtOutput( sOut) + else + local sOut + if nDeltaRot == -1 then + sOut = 'M151' + elseif nDeltaRot == -2 then + sOut = 'M152' + elseif nDeltaRot == -3 then + sOut = 'M153' + end + EmtOutput( sOut) + EmtOutput( 'M86') + EmtOutput( 'G4F.5') + end + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + MyOutputNoNum( '(PART UNLOAD)') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'G111ET1002') + EmtOutput( 'G111ET2002') + -- emissione conclusione pezzo precedente + local sOut = 'G113 EA0EB1EC1' + EmtOutput( sOut) + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + end + + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- se primo grezzo, reset lunghezza barra + if EMT.RAWIND == 1 then EMT.LB = 0 end + -- aggiungo la lunghezza del grezzo (solo se movimento in corner) + if EMT.RAWTYPE == 1 then + local b3Raw = EgtGetBBoxGlob( EgtGetFirstNameInGroup( EMT.RAWID, 'RawSolid'), GDB_BB.STANDARD) + local LBarra = b3Raw:getDimX() + EMT.LB = EMT.LB + LBarra + end + -- se primo grezzo, calcolo dati del pezzo + if EMT.RAWIND == 1 then + local PartId = EgtGetFirstPartInRawPart( EMT.RAWID) + if PartId then + EMT.IT = EgtGetInfo( PartId, 'PDN', 'i') or 0 + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box'), GDB_BB.STANDARD) + EMT.LT = b3Part:getDimX() + EMT.HT = b3Part:getDimY() + EMT.ST = b3Part:getDimZ() + EMT.HOVM = EgtGetInfo( EMT.RAWID, 'HOVM', 'd') or 0 + else + EMT.IT = -1 + EMT.LT = 0 + EMT.HT = 0 + EMT.ST = 0 + EMT.HOVM = 0 + end + end + end +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOOLSEL = EMT.TCPOS..' M06' + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + EMT.MCHNAME = EgtGetMachiningParam(MCH_MP.NAME) + EMT.MCHTYPE = EgtGetMachiningParam(MCH_MP.TYPE) + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + -- la speed della lama va moltiplicata per 6 + if EMT.EXIT == 2 then + EMT.S = EMT.S * 6 + end + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + --EmtOutput( ';Mach End') + -- Emissione split + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + MyOutputNoNum( '(PART SPLIT)') + elseif EMT.AUXTYPE == 'U' then + MyOutputNoNum( '(PART UNLOAD)') + elseif EMT.AUXTYPE == 'P' then + MyOutputNoNum( '(PART ROTATION)') + end + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + elseif EMT.AUXTYPE == 'U' then + EmtOutput( 'G111ET1002') + EmtOutput( 'G111ET2002') + -- emissione conclusione pezzo precedente + local sOut = 'G113 EA0EB1EC1' + EmtOutput( sOut) + elseif EMT.AUXTYPE == 'P' then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStart() + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + + -- se richiesto, preparo il carico barra + if EMT.LOAD then + PrepareLoad( EMT.AUX) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( EMT.AUX) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnPathEndAux() + --EgtOutLog( 'OnPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'P' + end + end + end + -- preparo a seconda del tipo + if EMT.AUXTYPE == 'R' then + -- per lo scarico della rimanenza + PrepareResidue( EMT.AUX) + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnRapid() + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + if not EMT.LOAD then + if not EMT.ZMAX and #EMT.AUXSTR > 0 then + EmitZmax() + end + EmtOutput( '( *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** )') + end + -- primo posizionamento + EmtResetPrev() + local bZmax = ( #EMT.AUXSTR > 0 or EMT.TOOL ~= EMT.PREVTOOL or EMT.L3 > -1) + local sEE = EgtIf( bZmax, ' EE3', ' EE4') + local sEL = 'EL' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TLEN, ChSawLen), 3) + local sER = 'ER' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TDIAM / 2, EMT.TLEN), 3) + local sOut = 'G101' .. EmtGetAxis( 'L2') .. EmtGetAxis( 'L3') .. + EmtGetAxis( 'R2') .. EmtGetAxis( 'R1') .. sEE .. sEL .. sER + if EMT.HEAD == 'H1' then + sOut = sOut..'E'..EMT.TCPOS + elseif EMT.HEAD == 'H2' then + sOut = sOut..'ET42' + elseif EMT.HEAD == 'H3' then + sOut = sOut..'E'..EMT.TCPOS + else + error( "Unknown Head") + end + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H2', 1, 6) + sOut = sOut..'ES'..EgtNumToString( Speed, 0)..' L0=0' + EmtOutput( sOut) + sOut = 'G101ET1001' + EmtOutput( sOut) + -- se prima lavorazione + if EMT.LOAD then + sOut = 'G79 E80060<>0 N9 E10015=0' + EmtOutput( sOut) + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + EMT.AUXSTR = {} + sOut = 'G111ET1001' + EmtOutput( sOut) + sOut = 'G79N9' + EmtOutput( sOut) + sOut = 'E80060=1' + EmtOutput( sOut) + sOut = 'G111ET2001' + EmtOutput( sOut) + EmtOutput( '( *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** )') + sOut = 'G101ET2001' + EmtOutput( sOut) + local sY = EmtLenToString( EMT.L1 + EMT.Y1DELTA) + local sV = EmtLenToString( ParkV) + sOut = 'G112EA1EB2'..EmtGetAxis('L1')..'EY'..sY..'EV'..sV..'EF'..GetFmaxClamp() + EmtOutput( sOut) + EMT.LOAD = false + -- altrimenti lavorazione successiva + else + -- eventuale G111 + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if not EMT.POSTROT then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + else + EmtOutput( 'G111ET1001') + EmtOutput( 'G111ET2001') + end + end + EMT.AUXSTR = {} + local sY, sA + if EMT.Y1DELTA then + sY = EmtLenToString( EMT.L1 + EMT.Y1DELTA - ( EMT.X_OFF or 0)) + sA = '1' + else + sY = EmtLenToString( EgtIf( EMT.Y1POS, EMT.Y1POS, ParkY)) + sA = '2' + end + local sV, sB + if EMT.Y2DELTA then + sV = EmtLenToString( EMT.L1 + EMT.Y2DELTA - ( EMT.X_OFF or 0)) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + sOut = 'G112EA'..sA..'EB'..sB..EmtGetAxis('L1')..'EY'..sY..'EV'..sV..'EF'..GetFmaxClamp() + EmtOutput( sOut) + sOut = 'G101ET2001' + EmtOutput( sOut) + EMT.POSTROT = false + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se standard + elseif EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EmtOutput( 'G102'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3')..EMT.IPLGLSTR) + else + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + end + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmitZmax() + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- altrimenti errore + else + error( "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmtOutput( 'G102'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3')..EMT.IPLGLSTR) + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R1')..EmtGetAxis('R2') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- aggiungo feed + local sFeed = EmtGetFeed() + -- emetto linea + EmtOutput( "G1"..sAxes..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + -- non modale su archi + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R1')..EmtGetAxis('R2') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString(EMT.RR,3) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- emetto arco + EmtOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd, bSkipPress) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + elseif sCmd == '1' then + return '2' + -- chiuso con pressore attivato + elseif sCmd == '2' then + return EgtIf( bSkipPress, '2', '0') + end +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = 'EB112' + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sYTaking = 'Y'..EmtLenToString( Cmd[3] + DELTA_TAKING) + local sBeamRot = '0+0' + if StartRotation and EMT.LB >= AutoRotMinLen then + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= 0 then + if TEST_USE then + sBeamRot = '0+' .. tostring( -nRot) + else + sBeamRot = '@(LOAD90)+' .. tostring( -nRot) + end + end + end + local sOut = 'G111'..sYTaking..'EA75EB112EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1E80057='..sBeamRot..' E80058=0' + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + local sYLoad = 'Y'..EmtLenToString( LoadT) + local sOut = 'G111'..sYLoad..'EA76'..EMT.SB..'EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1' + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = EgtIf( EMT.Y1DELTA, 'EA112', 'EA111') + EMT.SB = EgtIf( EMT.Y1DELTA, 'EB112', 'EB111') + EMT.SC = EgtIf( EMT.Y2DELTA, 'EC142', 'EC141') + EMT.SD = EgtIf( EMT.Y2DELTA, 'ED142', 'ED141') + EMT.SE = EgtIf( EMT.Y1DELTA, 'EE1', 'EE2') + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut = 'G111'..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.Y1POS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', Cmd[6] .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'EB11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = 'EA11' .. CalcCharStatus( Cmd[2]) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE1', 'EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'ED14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = 'EC14' .. CalcCharStatus( Cmd[2]) + EMT.SD = 'ED14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE2', 'EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.Y1DELTA, 'EA112', 'EA111') + EMT.SB = EgtIf( EMT.Y1DELTA, 'EB112', 'EB111') + EMT.SC = EgtIf( EMT.Y2DELTA, 'EC142', 'EC141') + EMT.SD = EgtIf( EMT.Y2DELTA, 'ED142', 'ED141') + EMT.SE = EgtIf( EMT.Y1DELTA, 'EE1', 'EE2') + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + if not EMT.UNL then + sOut = 'G111'..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + else + sOut = 'G111'..Cmd[2]..Cmd[3]..'EC141ED83EE0EF'..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', Cmd[6] .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'EB11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = 'EA11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE1', 'EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'ED14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = 'EC14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = 'ED14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE2', 'EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sOut = 'G111'..Cmd[2]..Cmd[3]..'EA110EB110EC142ED142EE2EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.Y1POS = tonumber( Cmd[3]) + end + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sEE = EgtIf( EMT.PHASE == EgtGetPhaseCount(), '0', '1') + local sOut = 'G111'..Cmd[2]..Cmd[3]..'EC141ED83EE'..sEE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[4] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sEAB = EgtIf( EMT.PHASE == EgtGetPhaseCount(), '111', '112') + local sOut = 'G111'..Cmd[4]..Cmd[5]..'EA'..sEAB..'EB'..sEAB..'EC142ED141EE2EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + -- non interessa + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.Y1DELTA, 'EA112', 'EA111') + EMT.SB = EgtIf( EMT.Y1DELTA, 'EB112', 'EB111') + EMT.SC = EgtIf( EMT.Y2DELTA, 'EC142', 'EC141') + EMT.SD = EgtIf( EMT.Y2DELTA, 'ED142', 'ED141') + EMT.SE = EgtIf( EMT.Y1DELTA, 'EE1', 'EE2') + end + -- se è pre-rotazione + if Cmd[2] == 'Pre-Rotation' then + EMT.PREROT = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + if not EMT.PREROT then + sOut = 'G111'..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + else + sOut = 'G111'..Cmd[2]..Cmd[3]..'EA86EB87EC141EE0EF'..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', Cmd[6] .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'EB11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = 'EA11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE1', 'EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'ED14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = 'EC14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = 'ED14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE2', 'EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = 'EB112' + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + local sYTaking = 'Y'..EmtLenToString( Cmd[3] - EMT.HOVM) + local sOut = 'G111'..sYTaking..'EA75EB112EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1 E80058=0' + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + local sYLoad = 'Y'..EmtLenToString( LoadT) + local sOut = 'G111'..sYLoad..'EA76'..EMT.SB..'EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1' + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + if EMT.REFLOC then + local vtE + if EMT.HEAD ~= 'H3' then + local Len = EMT.TLEN + EgtIf( EMT.HEAD == 'H1', MillOffs, abs( SawOffs)) + local LenRef = MillOffs + vtE = Vector3d( EMT.EXTR) * Len - Z_AX() * LenRef + else + local Len = ChSawLen + MillOffs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2) + vtE = Vector3d( vtAux) * Len - Z_AX() * LenRef + end + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - DeltaTabY - vtE:getY() + EMT.L3 = EMT.L3 - DeltaTabZ - vtE:getZ() + end + + if EMT.X_OFF then EMT.L1 = EMT.L1 + EMT.X_OFF end + + EmtAdjustLinearAxes() + + if not EMT.REFLOC then + EMT.L2 = - EMT.L2 + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function MyOutputNoNum( sOut) + local bNum = EMT.NUM + EMT.NUM = false + EmtOutput( sOut) + EMT.NUM = bNum +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + LoadT + if EMT.X_OFF then xS = xS + EMT.X_OFF end + local ptS = Point3d( xS, 0, 0) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H3' then + vtE = Vector3d( EMT.EXTR) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --EmtOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local _, dAngV, dAngO = SphericalFromVector( vtE) + local dAngO2 = EmtGetAngO2( EMT.IPLGLFR:getVersZ(), EMT.IPLGLFR:getVersX(), dAngV, dAngO) + dAngO = dAngO + 90 + while dAngO >= 360 do + dAngO = dAngO - 360 + end + EMT.IPLGLSTR = ' EX0 EY'..EmtLenToString( xS)..' EZ0'.. + ' EA0'..' EB'..EgtNumToString(dAngV)..' EC'..EgtNumToString(dAngO)..' ED'..EgtNumToString(dAngO2) + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function EmitZmax() + local sOut = 'G101 Z' .. EgtGetAxisHomePos('Z') .. ' L0=0' + EmtOutput( sOut) + sOut = 'G101ET1001' + EmtOutput( sOut) + sOut = 'G101ET2001' + EmtOutput( sOut) +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE, 0) +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.TPA.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.TPA.mlpe new file mode 100644 index 0000000..68e00b9 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.TPA.mlpe @@ -0,0 +1,2152 @@ +-- Processore macchina Essetre-PF1250 by EgalTech s.r.l. 2022/03/24 +-- Con controllo numerico TPA + +-- Variabili di modulo +local MLE_INFO = 'Essetre-PF1250.TPA.mlpe ver.'..PP_VER..' by EgalTech s.r.l.' +local TEST_USE = false + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + -- controllo versione programma + if not EMT.VER or EMT.VER < '2.3h1' then + EmtSetLastError( 1200, 'A newer version of the program is required (minimum 2.3h1)') + end + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.DECNUM = 5 -- numero di decimali dopo la virgola + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.FMAXPINZE = 116000 -- feed massima pinze + SetToParkLine() -- si inizia con linee da parcheggiare su stack +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Intestazioni + if EMT.INFO then + EmitRemark( EMT.INFO) + else + EmitRemark( 'Program Start') + end + EmitRemark( MLE_INFO) + -- Se modalità test, aggiungo linee per muovere tappeto e alzare la testa (in automatico viene fatto dal main residente) + if TEST_USE then + MyOutput( 'M199') + end + -- Dichiaro inizio + EMT.FIRST = true + -- Inizializzazioni varie + MyOutput( 'G49') + -- Inizio lista utensili + MyOutput( 'M993 (Tool List Start)') + -- Dichiaro cabine con rulli in posizione di parcheggio + EMT.V1POS = ParkV1 + EMT.V2POS = ParkV2 +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Arresto mandrino + MyOutput( 'M05') + -- Emissione scarico + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + end + if #EMT.MDCHAR > 0 then + if EMT.AUXTYPE == 'S' then + EmitMoveStartChars( 3) + EmitMoveWaitChars( 3) + elseif EMT.AUXTYPE == 'R' then + EmitMoveDataChars( { Y1=ParkY1, Y2=ParkY2, V1=ParkV1, V2=ParkV2, BeamVise=0, MoveType=3}) + EmitMoveStartChars( 3) + EmitMoveWaitChars( 3) + elseif EMT.AUXTYPE == 'U' then + EmitMoveStartChars( EgtIf( EMT.CHY_ON, 3, 2)) + EmitMoveWaitChars( EgtIf( EMT.CHY_ON, 3, 2), true) + -- emissione conclusione pezzo precedente (se non si è in test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + end + end + EMT.MDCHAR = {} + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.RELOAD = nil + EMT.RELOAD2 = nil + -- Termino il programma + MyOutput( 'M202') + MyOutput( 'M02') +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensile (esclusa sega a catena) + if EMT.HEAD ~= 'H13' then + local dAddLen = EgtIf( EMT.HEAD == 'H12', -SawOffsZ, 0) + local sOut = 'M992 P1=' .. EMT.TCPOS:gsub( 'T', '') .. ' P2=' .. EmtLenToString( dAddLen + EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( dAddLen + EMT.TTOTLEN, 3) + MyOutput( sOut) + -- emissione dati sega a catena + else + local sData = ' P2=' .. EmtLenToString( ChSawLen, 3) .. ' P3=' .. EmtLenToString( EMT.TLEN, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( ChSawLen, 3) + MyOutput( 'M992 P1=101' .. sData) + MyOutput( 'M992 P1=102' .. sData) + MyOutput( 'M992 P1=103' .. sData) + MyOutput( 'M992 P1=104' .. sData) + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione, se impostati + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') or EMT.TPOS + EMT.Y1POS = EgtGetInfo( EMT.DISPID, 'Y1POS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- terminazione lista utensili + MyOutput( 'G990 (Tool List End)') + MyOutput( 'M28') + -- emissione dati di macchina + local sOut = 'M114'..' P1='..EmtLenToString( LoadT, 2)..' P2='..EmtLenToString( MinMchY1, 2)..' P3='..EmtLenToString( MaxY1, 2).. + ' P4='..EmtLenToString( MinY2, 2)..' P5='..EmtLenToString( MaxMchY2, 2)..' P6='..EmtLenToString( MillOffs, 2).. + ' P7='..EmtLenToString( Mill2Offs, 2)..' P8='..EmtLenToString( ParkMchY1, 2)..' P9='..EmtLenToString( ParkMchY2, 2).. + ' P10='..EmtLenToString( -TurnerOffs, 2)..' P11='..EmtLenToString( MinV1, 2)..' P12='..EmtLenToString( MaxV1, 2).. + ' P13='..EmtLenToString( MinV2, 2)..' P14='..EmtLenToString( MaxV2, 2).. + ' P15='..EmtLenToString( -DeltaTabY, 2)..' P16='..EmtLenToString( DeltaTabZ - MillOffs, 2).. + ' P17='..EmtLenToString( Delta2TabY, 2)..' P18='..EmtLenToString( -Delta2TabZ - Mill2Offs, 2) + MyOutput( sOut) + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + if IsEnd2Phase( EMT.PHASE - 1) then + EMT.RELOAD = true + EMT.RELOAD2 = false + end + end +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- reset recupero sovramateriale in X non più presente + EMT.X_OFF = nil + -- gruppo con info da BTL + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL + -- dati del grezzo + local LBarra = EMT.LB + local HBarra = EMT.HB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- calcolo dati pinze + local AccPinze, AccMaxPinze, RidFeed = CalcDinamicaPinze( HTrave, STrave, LBarra) + local AccPinz1, AccMaxPinz1, RidFeed1 = CalcDinamicaPinze( HTrave, STrave, LBarra - LTrave) + local AccPinz2, AccMaxPinz2, RidFeed2 = CalcDinamicaPinze( HTrave, STrave, LTrave) + if IdTrave >= 0 then + local sRem = ' SN=' .. IdTrave .. ' LBarra=' .. EmtLenToString( LBarra, 3) .. ' L='..EmtLenToString( LTrave, 3) .. + ' H=' .. EmtLenToString( HTrave, 3) .. ' S=' .. EmtLenToString( STrave, 3) .. ' ' + EMT.PRODID = EgtGetInfo( BtlInfoId, 'PRODID', 'i') or 0 + EMT.PATTID = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 0 + if EMT.PARTTYPE ~= 1 then + EMT.CUTID = EgtGetInfo( EMT.IDT, 'CUTID', 'i') or 0 + else + EMT.CUTID = -1 + end + local sStart = 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=1' + EmitRemark( sRem) + if not TEST_USE then MyOutput( sStart) end + else + EmitRemark( 'REMAIN UNLOAD') + EMT.PRODID = nil + EMT.PATTID = nil + EMT.CUTID = nil + end + -- se carico barra + if EMT.LOAD or EMT.RELOAD then + local nLoad90 = EgtGetInfo( BtlInfoId, 'LOAD90', 'i') or 0 + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( max( HTrave, HBarra), 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( nLoad90) .. ' P6=' .. EmtLenToString( LTrave, 2) .. + ' P7=' .. EgtNumToString( AccPinze, 2) .. ' P8=' .. EgtNumToString( AccPinz2, 2) .. ' P9=' .. EgtNumToString( AccPinz1, 2) .. + ' P10=' .. EgtNumToString( EMT.PARTTYPE or 0, 0) + MyOutput( sOut) + if EMT.LOAD then + SetStartValue( 1, LBarra) + SetStartValue( 2, max( HTrave, HBarra)) + SetStartValue( 3, STrave) + SetStartValue( 6, HOverM) + end + -- altrimenti recupero rimanenza + else + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( HTrave, 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( 0) .. ' P6=' .. EmtLenToString( EgtIf( IdTrave >= 0, LTrave, LBarra), 2) .. + ' P7=' .. EgtNumToString( AccPinze, 2) .. ' P8=' .. EgtNumToString( AccPinz2, 2) .. ' P9=' .. EgtNumToString( AccPinz1, 2).. + ' P10=' .. EgtNumToString( EMT.PARTTYPE or 0, 0) + MyOutput( sOut) + -- determino la quota di parcheggio della trave + local ParkT = GetParkT() + -- aggiorno dati aggancio carrelli alla trave + EMT.Y1DELTA = EMT.Y1POS - ParkT + EMT.Y2DELTA = nil + EmitBeamHeadData( { T=ParkT, Y1=EMT.Y1POS, SetHead=1, F=0}) + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- verifico se sono diverse + if nRot ~= nPrevRot then + if nRot > nPrevRot then nRot = nRot - 4 end + local nDeltaRot = nRot - nPrevRot + -- rotazione automatica o manuale (sempre con il medesimo comando) + local sOut = 'M180 P1=' .. tostring( -nDeltaRot) + MyOutput( sOut) + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + if #EMT.MDCHAR > 0 then + EmitRemark( 'PART UNLOAD') + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + if EMT.MDCHAR[i].Y1 then EMT.CHY_ON = true end + end + if #EMT.MDCHAR > 0 then + local nMoveType = EgtIf( EMT.CHY_ON, 3, 2) + EmitMoveStartChars( nMoveType) + -- se dopo c'è scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE + 1) then + EmitMoveWaitChars( nMoveType) + else + EmitMoveWaitChars( nMoveType, true) + end + -- emissione conclusione pezzo precedente (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + end + EMT.MDCHAR = {} + EMT.AUXTYPE = nil + end + + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- se primo grezzo, reset lunghezza barra + if EMT.RAWIND == 1 then + EMT.LB = 0 + EMT.HB = 0 + end + -- aggiungo la lunghezza del grezzo (solo se movimento in corner) + if EMT.RAWTYPE == 1 then + local b3Raw = EgtGetBBoxGlob( EgtGetFirstNameInGroup( EMT.RAWID, 'RawSolid'), GDB_BB.STANDARD) + local LBarra = b3Raw:getDimX() + EMT.LB = EMT.LB + LBarra + local HBarra = b3Raw:getDimY() + EMT.HB = max( EMT.HB, HBarra) + end + -- se primo grezzo, calcolo dati del pezzo + if EMT.RAWIND == 1 then + local PartId = EgtGetFirstPartInRawPart( EMT.RAWID) + if PartId then + EMT.IDT = PartId + EMT.IT = EgtGetInfo( PartId, 'PDN', 'i') or 0 + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box'), GDB_BB.STANDARD) + EMT.LT = b3Part:getDimX() + EMT.HT = b3Part:getDimY() + EMT.ST = b3Part:getDimZ() + EMT.HOVM = EgtGetInfo( EMT.RAWID, 'HOVM', 'd') or 0 + EMT.PARTTYPE = 0 + local sMaterial = EgtGetInfo( PartId, 'MATERIAL') + if sMaterial and sMaterial:find( 'CLT-', 1, true) == 1 then + EMT.PARTTYPE = 1 + elseif sMaterial and sMaterial:find( 'UT-', 1, true) == 1 then + EMT.PARTTYPE = 2 + end + else + EMT.IDT = GDB_ID.NULL + EMT.IT = -1 + EMT.LT = 0 + EMT.HT = EMT.HT or 0 + EMT.ST = EMT.ST or 0 + EMT.HOVM = 0 + end + end + end +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + --EMT.MCHNAME = EgtGetMachiningParam( MCH_MP.NAME) + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) + -- se sega a catena, aggiusto subito angolo scelto per asse virtuale A + if EMT.HEAD == 'H13' then + -- valore dell'asse virtuale + dPosA = GetCurrChainSawingVirtualAxis() + -- imposto home dell'asse C1 (A=0 -> T101, A=90 -> T104) + local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA) + EmtModifyAxisHome( 'C1', MyParkCSawC1) + end +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + --MyOutput( ';Mach End') + -- Emissione split + if #EMT.MDCHAR > 0 then + if EMT.AUXTYPE == 'S' then + EmitRemark( 'PART SPLIT') + EMT.LB = EMT.LT + elseif EMT.AUXTYPE == 'U' then + EmitRemark( 'PART UNLOAD') + elseif EMT.AUXTYPE == 'P' then + if EMT.PREROT then + EmitZmax( false, true, EMT.R1, EMT.R2) + EMT.ZMAX = true + EmitRemark( 'PART ROTATION') + elseif EMT.FALL then + if EMT.TO_ZMAX and not EMT.ZMAX then + EmitZmax( false, true, EMT.R1, EMT.R2) + EMT.ZMAX = true + EMT.TO_ZMAX = nil + end + EmitRemark( 'PART FALL') + else + EmitZmax( false, true, EMT.R1, EMT.R2) + EMT.ZMAX = true + EmitRemark( 'PART SPLIT 2') + end + end + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + end + if #EMT.MDCHAR > 0 then + if EMT.AUXTYPE == 'S' then + EmitMoveStartChars( 1) + EmitMoveWaitChars( 1) + elseif EMT.AUXTYPE == 'U' then + local nMoveType = EgtIf( EMT.CHY_ON, 3, 2) + EmitMoveStartChars( nMoveType) + -- se dopo cè scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE + 1) then + EmitMoveWaitChars( nMoveType) + else + EmitMoveWaitChars( nMoveType, true) + end + -- emissione conclusione pezzo precedente (se non è modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + elseif EMT.AUXTYPE == 'P' then + EmitMoveStartChars( 3) + EmitMoveWaitChars( 3) + if EMT.FALL then + MyOutput( 'M155') + -- emissione conclusione pezzo (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + elseif not EMT.PREROT then + MyOutput( 'M77') + end + end + end + EMT.MDCHAR = {} + EMT.AUXTYPE = nil + EMT.TO_ZMAX = nil + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStart() + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + EMT.MCHFIRSTFEED = true + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false + -- leggo se ancora presa iniziale carrello + --EMT.CNT = EgtGetInfo( EMT.PATHID, 'CNT', 'i') + --MyOutput( 'CNT='.. tostring( EMT.CNT or 0)) + -- se utensile non cambiato, salvo eventuali precedenti rotanti + if EMT.TOOL == EMT.PREVTOOL and not EMT.ZMAX then + EMT.R1pp = EMT.R1p + EMT.R2pp = EMT.R2p + else + EMT.R1pp = nil + EMT.R2pp = nil + end + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.MDCHAR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + if not EMT.ZMAX then + EmitResetMachining() + end + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.MDCHAR = {} + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- salvo il comando per processarlo successivamente + table.insert( EMT.AUXCMD, EMT.AUX) + -- gestione speciale per richiesta di movimento a ZMAX + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '4' then + EMT.TO_ZMAX = true + end +end + +--------------------------------------------------------------------- +function ProcessPathStartAux( sCmd, nInd) + -- se richiesto, preparo il carico barra + if EMT.LOAD or EMT.RELOAD then + PrepareLoad( sCmd, nInd, true) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( sCmd, nInd) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( sCmd, nInd) + end +end + +--------------------------------------------------------------------- +function OnPathEndAux() + --EgtOutLog( 'OnPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'P' + if Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.FALL = true + end + end + elseif EMT.AUXTYPE == 'P' then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.CHY_ON = true + EMT.AUXTYPE = 'U' + end + end + end + -- preparo a seconda del tipo + if EMT.AUXTYPE == 'R' then + -- per il carico della rimanenza dopo rotazione speciale + if EMT.RELOAD and not EMT.RELOAD2 then + PrepareLoad( EMT.AUX, EMT.AUXIND, false) + -- per lo scarico della rimanenza + else + PrepareResidue( EMT.AUX, EMT.AUXIND) + end + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX, EMT.AUXIND) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX, EMT.AUXIND) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX, EMT.AUXIND) + end +end + +--------------------------------------------------------------------- +function OnRapid() + -- gruppo della testa + local nHSet = GetHeadSet( EMT.HEAD) + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + local HomeR1 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'C1', 'C2')) + local HomeR2 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'B1', 'B2')) + local PrevR1 = EMT.R1p or EMT.R1pp or HomeR1 + local PrevR2 = EMT.R2p or EMT.R2pp or HomeR2 + EmtResetPrev() + -- se prima lavorazione + if EMT.LOAD then + EMT.V2POS = ParkV2 + -- primo posizionamento + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H12', 1, 1.65) + local bOnlyCharY = true + for i = 1, #EMT.AUXCMD do + ProcessPathStartAux( EMT.AUXCMD[i], i) + end + EMT.AUXCMD = {} + -- se Split e non misura laser lascio agganciata solo la pinza Y2 alla fine dei movimenti + local bSplitCut = ( EMT.MCHUSERNOTES:find( 'Split', 1, true) ~= nil) + if bSplitCut and #EMT.MDCHAR > 0 and EMT.MDCHAR[#EMT.MDCHAR].IniStatY1 ~= -76 then + EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = 1 + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + if EMT.MDCHAR[i].MovType ~= 1 then bOnlyCharY = false end + end + EMT.MDCHAR = {} + EmitMoveStartChars( EgtIf( bOnlyCharY, 1, 3)) + EmitRemark( ' *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** ') + -- se testa 1 + if nHSet == 1 then + -- selezione testa (posso muovere X solo a Zmax) + local MaxZ1 = EgtGetAxisMax( 'Z1') + EmitMoveDataHead( 1, { X=EMT.L2, Z=MaxZ1, S=Speed}) + EmitMoveStartHead( 1) + EmitMoveWaitHead( 1) + EmitMoveWaitChars( EgtIf( bOnlyCharY, 1, 3)) + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, EMT.R1, EMT.R2) or + EMT.V1POS < EMT.V1NEXTPOS - 1 or EMT.V2POS > EMT.V2NEXTPOS + 1 then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, bSplitCut) + end + -- eseguo movimenti + local dSafeZ1 = EgtGetAxisHomePos( 'Z1') + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H12', 1, 1.65) + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + local Z_EXTRA = EgtIf( EMT.HEAD == 'H11', 250, 160) + local dZref + if EMT.R2 > -60 then + dZref = dSafeZ1+Z_EXTRA + EmitMoveDataHead( 1, { Z=dZref, B=min(EMT.R2,60), S=Speed}) + if EMT.R2 > 60 then + dZref = dSafeZ1 + Z_EXTRA * ( 90 - abs( EMT.R2)) / 30 + EmitMoveDataHead( 1, { Z=dZref, B=min(EMT.R2,90), S=Speed}) + end + else + dZref = dSafeZ1 + Z_EXTRA * ( 90 - abs( EMT.R2)) / 30 + EmitMoveDataHead( 1, { Z=dZref, B=EMT.R2, S=Speed}) + end + if dZref and EMT.L3 < dZref + 0.1 then + EmitMoveDataHead( 1, { C=EMT.R1, S=Speed}) + end + -- altrimenti sega a catena + else + local bXSpec = ( EMT.L2 < -DeltaTabY) + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), S=Speed}) + EmitMoveDataHead( 1, { Z=dSafeZ1, S=Speed}) + if bXSpec then + EmitMoveDataHead( 1, { B=EMT.R2, C=EMT.R1, S=Speed}) + end + end + EmitMoveDataHead( 1, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 1) + -- eventuale preselezione successiva testa 2 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 1 + EmitMoveWaitHead( 1) + -- altrimenti testa 2 + else + -- selezione testa (non posso muovere X) + EmitMoveDataHead( 2, { X=ParkX2, S=Speed}) + EmitMoveStartHead( 2) + EmitMoveWaitHead( 2) + EmitMoveWaitChars( EgtIf( bOnlyCharY, 1, 3)) + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, EMT.R1, EMT.R2) or + EMT.V1POS < EMT.V1NEXTPOS - 1 or EMT.V2POS > EMT.V2NEXTPOS + 1 then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, bSplitCut) + end + -- eseguo movimenti + local dSafeZ2 = EgtGetAxisHomePos( 'Z2') + local Speed = EMT.S + EmitMoveDataHead( 2, { Z=-dSafeZ2, S=Speed}) + EmitMoveDataHead( 2, { X=EMT.L2, S=Speed}) + EmitMoveDataHead( 2, { X=EMT.L2, Z=EMT.L3, S=Speed}) + EmitMoveDataHead( 2, { B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 2) + -- eventuale preselezione successiva testa 1 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 2 + EmitMoveWaitHead( 2) + end + -- se pezzo a destra, dichiaro cabina sinistra da parcheggiare + if not EMT.Y1DELTA then + EMT.V1NEXTPOS = ParkV1 + end + -- dati aggancio a trave + local BhData = { T=EMT.L1, SetHead=0} + if EMT.Y1DELTA then + BhData.Y1 = EMT.L1 + EMT.Y1DELTA + BhData.ViseY1 = 1 + else + BhData.Y1 = ParkY1 + BhData.ViseY1 = 2 + end + if bSplitCut and EMT.Y2DELTA then + BhData.ViseY1 = 3 + end + if EMT.Y2DELTA then + BhData.Y2 = EMT.L1 + EMT.Y2DELTA + BhData.ViseY2 = 1 + else + BhData.Y2 = ParkY2 + BhData.ViseY2 = 2 + end + if GetV1ToClose() then + BhData.V1 = EMT.V1NEXTPOS ; EMT.V1POS = BhData.V1 + BhData.StatV1 = -2 + elseif abs( EMT.V1POS - ParkV1) > 0.1 then + BhData.V1 = ParkV1 ; EMT.V1POS = BhData.V1 + BhData.StatV1 = 1 + end + if GetV2ToClose() then + BhData.V2 = EMT.V2NEXTPOS ; EMT.V2POS = BhData.V2 + BhData.StatV2 = -2 + elseif abs( EMT.V2POS - ParkV2) > 0.1 then + BhData.V2 = ParkV2 ; EMT.V2POS = BhData.V2 + BhData.StatV2 = 1 + end + EmitBeamHeadData( BhData) + EMT.LOAD = false + -- emissione prime linee speciali e linee parcheggiate + EmitStartValues() + local ProdId = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PRODID', 'i') or 0 + MyOutput( ';LISTA = ' .. tostring( ProdId)) + EmitParkedLines() + -- altrimenti lavorazione successiva + else + --MyOutput( string.format( 'V1Pos=%.3f V2Pos=%.3f', EMT.V1POS, EMT.V2POS)) + if not EMT.RELOAD and not EMT.ZMAX and #EMT.AUXCMD > 0 and EMT.TO_ZMAX then + EmitZmax( false, false, PrevR1, PrevR2) + EMT.ZMAX = true + EMT.TO_ZMAX = nil + PrevR1 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'C1', 'C2')) + PrevR2 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'B1', 'B2')) + end + EmitRemark( ' *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** ') + -- se Split lascio agganciata solo la pinza Y2 alla fine dei movimenti + local bSplitCut = ( EMT.MCHUSERNOTES:find( 'Split', 1, true) ~= nil) + -- eventuale movimento carrelli + for i = 1, #EMT.AUXCMD do + ProcessPathStartAux( EMT.AUXCMD[i], i) + end + EMT.AUXCMD = {} + if bSplitCut and #EMT.MDCHAR > 0 then + EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = 1 + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + end + if #EMT.MDCHAR > 0 then + local nMoveType = EgtIf( EMT.POSTROT or EMT.RELOAD, 1, 3) + EmitMoveStartChars( nMoveType) + EmitMoveWaitChars( nMoveType) + end + EMT.MDCHAR = {} + -- se pezzo a destra, dichiaro cabina sinistra da parcheggiare + if not EMT.Y1DELTA then + EMT.V1NEXTPOS = ParkV1 + end + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, EMT.R1, EMT.R2) or + EMT.V1POS < EMT.V1NEXTPOS - 1 or EMT.V2POS > EMT.V2NEXTPOS + 1 then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, bSplitCut) + end + -- se taglio di coda senza residuo da scaricare, emetto M175 per accelerare il carico della barra successiva + if EMT.MCHUSERNOTES and EMT.MCHUSERNOTES:find( 'Cut', 1, true) then + MyOutput( ';M175') + end + -- se testa 1 + if nHSet == 1 then + local dSafeZ1 = EgtGetAxisHomePos( 'Z1') + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H12', 1, 1.65) + if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + EmitMoveDataHead( 1, { X=EMT.L2, S=Speed}) + local Z_EXTRA = EgtIf( EMT.HEAD == 'H11', 250, 160) + local dZref + if EMT.R2 > -60 then + dZref = dSafeZ1+Z_EXTRA + EmitMoveDataHead( 1, { Z=dZref, B=min(EMT.R2,60), S=Speed}) + if EMT.R2 > 60 then + dZref = dSafeZ1 + Z_EXTRA * ( 90 - abs( EMT.R2)) / 30 + EmitMoveDataHead( 1, { Z=dZref, B=min(EMT.R2,90), S=Speed}) + end + else + dZref = dSafeZ1 + Z_EXTRA * ( 90 - abs( EMT.R2)) / 30 + EmitMoveDataHead( 1, { Z=dZref, B=EMT.R2, S=Speed}) + end + if dZref and EMT.L3 < dZref + 0.1 then + EmitMoveDataHead( 1, { C=EMT.R1, S=Speed}) + end + -- altrimenti sega a catena + else + local bXSpec = ( EMT.L2 < -DeltaTabY) + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), S=Speed}) + EmitMoveDataHead( 1, { Z=dSafeZ1, S=Speed}) + if bXSpec then + EmitMoveDataHead( 1, { B=EMT.R2, C=EMT.R1, S=Speed}) + end + end + end + EmitMoveDataHead( 1, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 1) + -- eventuale preselezione successiva testa 2 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 1 + EmitMoveWaitHead( 1) + -- altrimenti testa 2 + else + local dSafeZ2 = EgtGetAxisHomePos( 'Z2') + local Speed = EMT.S + if EMT.ZMAX then + EmitMoveDataHead( 2, { Z=-dSafeZ2, S=Speed}) + EmitMoveDataHead( 2, { X=EMT.L2, S=Speed}) + end + EmitMoveDataHead( 2, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 2) + -- eventuale preselezione successiva testa 1 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 2 + EmitMoveWaitHead( 2) + end + -- dati aggancio a trave + local BhData = { T=EMT.L1} + if EMT.Y1DELTA then + BhData.Y1 = EMT.L1 + EMT.Y1DELTA - ( EMT.X_OFF or 0) + BhData.ViseY1 = 1 + else + BhData.Y1 = ( EMT.Y1POS or ParkY1) + BhData.ViseY1 = 2 + end + if bSplitCut and EMT.Y2DELTA then + BhData.ViseY1 = 3 + end + if EMT.Y2DELTA then + BhData.Y2 = EMT.L1 + EMT.Y2DELTA - ( EMT.X_OFF or 0) + BhData.ViseY2 = 1 + else + BhData.Y2 = ParkY2 + BhData.ViseY2 = 2 + end + if GetV1ToClose() then + BhData.V1 = EMT.V1NEXTPOS ; EMT.V1POS = BhData.V1 + BhData.StatV1 = -2 + elseif abs( EMT.V1POS - ParkV1) > 0.1 then + BhData.V1 = ParkV1 ; EMT.V1POS = BhData.V1 + BhData.StatV1 = 1 + end + if GetV2ToClose() then + BhData.V2 = EMT.V2NEXTPOS ; EMT.V2POS = BhData.V2 + BhData.StatV2 = -2 + elseif abs( EMT.V2POS - ParkV2) > 0.1 then + BhData.V2 = ParkV2 ; EMT.V2POS = BhData.V2 + BhData.StatV2 = 1 + end + EmitBeamHeadData( BhData) + EMT.POSTROT = false + EMT.RELOAD = false + EMT.RELOAD2 = nil + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se standard + elseif EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + MyOutput( 'M105 P1=' .. GetFaceCode() .. ' P2='..EgtIf( EMT.HEAD ~= 'H21', '1', '2')..' P3=0') + MyOutput( 'M98') + sOut = 'M6 ' .. EgtIf( EMT.HEAD ~= 'H21', 'T101', 'T202') .. AdjustTcPos( true) + MyOutput( sOut) + MyOutput( 'G24' .. EMT.IPLGLSTR) + -- forzo successiva emissione assi rotanti + EMT.R1p = nil + EMT.R2p = nil + else + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + end + -- emissione movimento + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + if #sAxes > 0 then + MyOutput( 'G0' .. sAxes) + end + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + -- se Split lascio agganciata solo la pinza Y2 alla fine dei movimenti + local bSplitCut = ( EMT.MCHUSERNOTES:find( 'Split', 1, true) ~= nil) + EmitZmax( true, true, EMT.R1p, EMT.R2p, bSplitCut) + -- aggiorno quota finale trave dopo Zmax + EMT.L1o = EMT.TPOS + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- altrimenti errore + else + error( "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EMT.TPOS = EMT.L1o + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente (se presente devo annullare l'offset in X per sovramateriale di testa) + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + if EMT.X_OFF then EMT.L1 = EMT.L1 - EMT.X_OFF end + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + MyOutput( 'M105 P1=' .. GetFaceCode() .. ' P2='..EgtIf( EMT.HEAD ~= 'H21', '1', '2')..' P3=0') + MyOutput( 'M98') + local sPos = EMT.TCPOS:gsub( 'T', '') + if #sPos == 1 then + sPos = '00' .. sPos + elseif #sPos == 2 then + sPos = '0' .. sPos + elseif sPos == '101' and abs( EMT.R3 - 90) < 0.1 then + sPos = '104' + end + local sOut = 'M6 ' .. EgtIf( EMT.HEAD ~= 'H21', 'T101', 'T202') .. sPos + MyOutput( sOut) + MyOutput( 'G24' .. EMT.IPLGLSTR) + -- emissione movimento + EMT.R1p = nil + EMT.R2p = nil + sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + MyOutput( sOut) + -- aggiorno precedenti + EMT.MOVE = 0 + EmtUpdatePrev() + EMT.MOVE = 1 + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + MyOutput( 'M97') + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- feed + local sFeed = EmtGetFeed() + -- se da emettere + if #sAxes > 0 then + MyOutput( "G1" .. sAxes .. sFeed) + end + + -- aggiorno valori come precedenti + EMT.TPOS = EMT.L1o + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + MyOutput( 'M97') + end + + -- non modale su archi + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString( EMT.RR, EMT.DECNUM) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- emetto arco + MyOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EMT.TPOS = EMT.L1o + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcDinamicaPinze( dH, dS, dL) + local MinTempoAcc = 0.3 -- [s] + local MaxTempoAcc = 4.0 -- [s] + local KgMtCubo= 550 -- densità legno [Kg / metro cubo] + local Massa = ( dH * dS * dL * KgMtCubo ) / 1e9 -- massa [Kg] + local FMaxPinze = EMT.FMAXPINZE -- Feed massima pinze [mm/min] + local ForzaAttrito = 350 * 9.8 * 0.2 -- Forza chiusura pinze [Kgf] * g * Coeff_Attrito -> [N] + local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAttrito) / 1000) + if ( TempoAcc < MinTempoAcc) then TempoAcc = MinTempoAcc end + if ( TempoAcc > MaxTempoAcc) then TempoAcc = MaxTempoAcc end + local AccMaxPinze = FMaxPinze / ( 60 * MinTempoAcc) + local AccPinze = FMaxPinze / ( 60 * TempoAcc) + local RidFeed = 100 / Massa * 100 + if RidFeed > 100 then + RidFeed = 100 + elseif RidFeed < 10 then + RidFeed = 10 + end + return AccPinze, AccMaxPinze, RidFeed +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + else + return '-1' + end +end + +--------------------------------------------------------------------- +function CalcCharStatusN( sCmd) + -- aperto + if sCmd == '0' then + return 1 + -- chiuso + elseif sCmd == '1' then + return -1 + end +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd, nInd, bStart) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if nInd == 1 then + -- imposto stato pinze + EMT.ISY1 = 1 + EMT.FSY1 = EMT.ISY1 -- ??? -1 + EMT.ISY2 = 1 + EMT.FSY2 = EMT.ISY2 + EMT.BV = 0 + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + if bStart then + EMT.RELOAD = false + else + EMT.RELOAD2 = true + end + for i = 1, #EMT.MDCHAR do + EMT.MDCHAR[i].MovType = 3 + end + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.Y1POS = MoveY1 or EMT.Y1POS + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + end + elseif Cmd[1] == '2' then + -- se in riposizionamento carrelli + if #EMT.MDCHAR > 0 and EMT.MDCHAR[1].MovType == 3 then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[2] == 'Y1' then + local MoveY1 = tonumber( Cmd[3]) + TurnerOffs + local MDChar = { Y1=MoveY1, V1=ParkV1, IniStatY1=-75, FinStatY1=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + SetStartValue( 4, MoveY1) + SetStartValue( 5, 110) + EMT.V1POS = ParkV1 + elseif Cmd[2] == 'T' then + local MDChar = { Y1=tonumber(Cmd[3]), IniStatY1=-76, FinStatY1=EMT.FSY1, FinStatV1=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + end + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '4' then + -- richiesta movimento a ZMAX già gestita + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = EMT.FSY1 end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + if not FindReadHeadWithLaser( EMT.MDCHAR) then + local MDChar = { Y1=LoadT, IniStatY1=-76, FinStatY1=EMT.FSY1, FinStatV1=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if nInd == 1 then + -- imposto stato pinze + EMT.ISY1 = EgtIf( EMT.Y1DELTA, -1, 1) + EMT.FSY1 = EMT.ISY1 + EMT.ISY2 = EgtIf( EMT.Y2DELTA, -1, 1) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( EMT.Y1DELTA, 1, 2) + EMT.ROLL_IN = nil + EMT.ROLL_OPEN = true + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + else + if MoveY1 and EMT.V1POS > MoveY1 - MinDeltaYV - 0.1 then + MDChar.V1 = min( MoveY1 - MinDeltaYV, ParkV1) ; EMT.V1POS = MDChar.V1 + end + if MoveY2 and EMT.V2POS < MoveY2 + MinDeltaYV + 0.1 then + MDChar.V2 = max( MoveY2 + MinDeltaYV, ParkV2) ; EMT.V2POS = MDChar.V2 + end + end + if EMT.ROLL_OPEN then + MDChar.IniStatV1 = 1 + MDChar.IniStatV2 = 1 + EMT.ROLL_OPEN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.Y1POS = MoveY1 or EMT.Y1POS + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + end + elseif Cmd[1] == '2' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + else + if MoveY1 and EMT.V1POS > MoveY1 - MinDeltaYV - 0.1 then + MDChar.V1 = min( MoveY1 - MinDeltaYV, ParkV1) ; EMT.V1POS = MDChar.V1 + end + if MoveY2 and EMT.V2POS < MoveY2 + MinDeltaYV + 0.1 then + MDChar.V2 = max( MoveY2 + MinDeltaYV, ParkV2) ; EMT.V2POS = MDChar.V2 + end + end + if EMT.ROLL_OPEN then + MDChar.IniStatV1 = 1 + MDChar.IniStatV2 = 1 + EMT.ROLL_OPEN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + else + if MoveY1 and EMT.V1POS > MoveY1 - MinDeltaYV - 0.1 then + MDChar.V1 = min( MoveY1 - MinDeltaYV, ParkV1) ; EMT.V1POS = MDChar.V1 + end + if MoveY2 and EMT.V2POS < MoveY2 + MinDeltaYV + 0.1 then + MDChar.V2 = max( MoveY2 + MinDeltaYV, ParkV2) ; EMT.V2POS = MDChar.V2 + end + end + if EMT.ROLL_OPEN then + MDChar.IniStatV1 = 1 + MDChar.IniStatV2 = 1 + EMT.ROLL_OPEN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '4' then + -- richiesta movimento a ZMAX già gestita + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = EMT.FSY1 end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if nInd <= 2 then + EMT.ISY1 = EgtIf( EMT.Y1DELTA, -1, 1) + EMT.FSY1 = EMT.ISY1 + EMT.ISY2 = EgtIf( EMT.Y2DELTA, -1, 1) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( EMT.Y1DELTA, 1, 2) + EMT.ROLL_IN = nil + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar + if not EMT.UNL then + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + else + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY2=1, FinStatY2=-84, BeamVise=0} + end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '2' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, IniStatV2=1, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, IniStatV1=1, IniStatV2=1, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + if Cmd[6] ~= 'T' then MDChar[Cmd[6]] = tonumber( Cmd[7]) end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '4' then + EMT.TO_ZMAX = true + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = EMT.FSY1 end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + if Cmd[2] == 'Y1' then + local MDChar = { Y1=tonumber(Cmd[3]), V1=ParkV1, IniStatY1=-1, FinStatY1=-1, BeamVise=2, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + EMT.Y1POS = tonumber( Cmd[3]) + EMT.V1POS = ParkV1 + end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd, nInd) + + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + if Cmd[2] == 'Y2' then + -- se non è ultima fase e non è fase successiva a scarico su carico c'è una barra sulla pinza Y1 + local bBarOnY = ( EMT.PHASE < EgtGetPhaseCount() and not IsEnd2Phase( EMT.PHASE)) + local MDChar = { Y2=tonumber(Cmd[3]), V2=ParkV2, IniStatY2=1, FinStatY2=-84, BeamVise=EgtIf( bBarOnY, 1, 0), MovType=EgtIf( EMT.CHY_ON, 3, 2)} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '2' then + if Cmd[4] == 'Y2' then + -- se non è ultima fase c'è una barra sulla pinza Y1 + local bBarOnY = ( EMT.PHASE < EgtGetPhaseCount() and not IsEnd2Phase( EMT.PHASE)) + local MDChar = { Y2=tonumber(Cmd[5]), IniStatY1=EgtIf( bBarOnY, -1, 1), FinStatY1=EgtIf( bBarOnY, -1, 1), IniStatY2=-1, FinStatY2=1, IniStatV2=1, BeamVise=2, MovType=EgtIf( EMT.CHY_ON, 3, 2)} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '3' then + -- non interessa + elseif Cmd[1] == '4' then + -- non interessa + elseif Cmd[1] == '11' then + -- non interessa + elseif Cmd[1] == '12' then + -- non interessa + elseif Cmd[1] == '21' then + -- non interessa + elseif Cmd[1] == '22' then + -- non interessa ?? + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if nInd <= 2 then + EMT.ISY1 = EgtIf( EMT.Y1DELTA, -1, 1) + EMT.FSY1 = EMT.ISY1 + EMT.ISY2 = EgtIf( EMT.Y2DELTA, -1, 1) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( EMT.Y1DELTA, 1, 2) + end + -- se è pre-rotazione + if Cmd[2] == 'Pre-Rotation' then + EMT.PREROT = true + elseif Cmd[2] == 'SplitRot' then + EMT.SPLITROT = true + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar + if not EMT.PREROT then + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + else + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY1=86, FinStatY1=87, IniStatY2=1, BeamVise=0} + end + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '2' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + if Cmd[6] ~= 'T' then MDChar[Cmd[6]] = tonumber( Cmd[7]) end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '4' then + EMT.TO_ZMAX = true + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + if EMT.SPLITROT then + EMT.ISY1 = EgtIf( Cmd[2] ~= '0', CalcCharStatusN( Cmd[2]), 86) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + else + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + end + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = CalcCharStatusN( Cmd[2]) end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd, nInd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if nInd == 1 then + -- imposto stato pinze + EMT.FSY1 = -1 + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + EMT.POSTROT = false + for i = 1, #EMT.MDCHAR do + EMT.MDCHAR[i].MovType = 3 + end + end + elseif Cmd[1] == '1' then + -- non interessa + elseif Cmd[1] == '2' then + if Cmd[2] == 'Y1' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + local MDChar = { Y1=tonumber(Cmd[3])-EMT.HOVM, IniStatY2=-75, FinStatY2=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '3' then + -- non interessa + elseif Cmd[1] == '11' then + EMT.FSY1 = CalcCharStatusN( Cmd[2]) + elseif Cmd[1] == '12' then + -- non interessa + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + local MDChar = { Y1=LoadT, IniStatY1=-76, FinStatY1=EMT.FSY1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function GetV1ToClose() + --MyOutput( string.format( 'L1m=%.3f L1M=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1])) + --MyOutput( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT)) + return ( EMT.MAXMAX[1] <= EMT.V1NEXTPOS + RollCageMin and EMT.MAXMIN[1] + EMT.LB >= EMT.V1NEXTPOS + RollCageMax) +end + +--------------------------------------------------------------------- +function GetV2ToClose() + --MyOutput( string.format( 'L1m=%.3f L1M=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1])) + --MyOutput( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT)) + return ( EMT.MAXMAX[1] <= EMT.V2NEXTPOS - RollCageMax and EMT.MAXMIN[1] + EMT.LB >= EMT.V2NEXTPOS - RollCageMin) +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + local MyL1o = EMT.L1 + local MyL2o = EMT.L2 + local MyL3o = EMT.L3 + if EMT.REFLOC then + local vtE + if EMT.HEAD ~= 'H13' then + local dAddLen = EgtIf( EMT.HEAD == 'H12', -SawOffsZ, 0) + if EMT.HEAD ~= 'H21' then + local Len = EMT.TLEN + dAddLen + MillOffs + local LenRef = MillOffs + vtE = Vector3d( EMT.TDIR) * Len - Z_AX() * LenRef + else + local Len = EMT.TLEN + dAddLen + Mill2Offs + local LenRef = Mill2Offs + vtE = Vector3d( EMT.TDIR) * Len + Z_AX() * LenRef + end + else + local Len = ChSawLen + MillOffs + local LenRef = MillOffs + vtE = Vector3d( EMT.ADIR) * Len - Z_AX() * LenRef + end + if EMT.HEAD ~= 'H21' then + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - DeltaTabY - vtE:getY() + EMT.L3 = EMT.L3 - DeltaTabZ - vtE:getZ() + else + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - Delta2TabY - vtE:getY() + EMT.L3 = EMT.L3 - Delta2TabZ - vtE:getZ() + end + end + + if EMT.X_OFF then EMT.L1 = EMT.L1 + EMT.X_OFF end + + EmtAdjustLinearAxes() + + EMT.L1o = MyL1o + EMT.L2o = MyL2o + EMT.L3o = MyL3o + + if not EMT.REFLOC then + if EMT.HEAD ~= 'H21' then + EMT.L2 = -EMT.L2 + else + EMT.L3 = -EMT.L3 + end + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function AdjustTcPos( bLen3, sTcPos, dAxR3) + if not sTcPos then sTcPos = EMT.TCPOS end + local sPos = sTcPos:gsub( 'T', '') + if bLen3 then + if #sPos == 1 then + sPos = '00' .. sPos + elseif #sPos == 2 then + sPos = '0' .. sPos + end + end + if sPos == '101' then + if not dAxR3 then dAxR3 = EMT.R3 end + if abs( dAxR3 - 0) < 0.1 then + sPos = '101' + elseif abs( dAxR3 - 270) < 0.1 then + sPos = '102' + elseif abs( dAxR3 - 180) < 0.1 then + sPos = '103' + elseif abs( dAxR3 - 90) < 0.1 then + sPos = '104' + else + EmtSetLastError( 1210, 'Chain saw orientation not allowed') + end + end + return sPos +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + LoadT + if EMT.X_OFF then xS = xS + EMT.X_OFF end + local ptS = Point3d( xS, 0, 0) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H13' then + vtE = Vector3d( EMT.EXTR) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --MyOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local vtX = EMT.IPLGLFR:getVersX() + local vtY = EMT.IPLGLFR:getVersY() + local vtZ = EMT.IPLGLFR:getVersZ() + if EMT.HEAD ~= 'H21' then + EMT.IPLGLSTR = ' X0 Y' .. EmtLenToString( xS, EMT.DECNUM) .. ' Z0' .. + ' A' .. EgtNumToString( -vtX:getY(), 6) .. ' B' .. EgtNumToString( vtX:getX(), 6) .. ' C' .. EgtNumToString( vtX:getZ(), 6) .. + ' I' .. EgtNumToString( -vtY:getY(), 6) .. ' J' .. EgtNumToString( vtY:getX(), 6) .. ' K' .. EgtNumToString( vtY:getZ(), 6) .. + ' P' .. EgtNumToString( -vtZ:getY(), 6) .. ' Q' .. EgtNumToString( vtZ:getX(), 6) .. ' R' .. EgtNumToString( vtZ:getZ(), 6) + else + EMT.IPLGLSTR = ' X0 Y' .. EmtLenToString( xS, EMT.DECNUM) .. ' Z0' .. + ' A' .. EgtNumToString( vtX:getY(), 6) .. ' B' .. EgtNumToString( vtX:getX(), 6) .. ' C' .. EgtNumToString( -vtX:getZ(), 6) .. + ' I' .. EgtNumToString( vtY:getY(), 6) .. ' J' .. EgtNumToString( vtY:getX(), 6) .. ' K' .. EgtNumToString( -vtY:getZ(), 6) .. + ' P' .. EgtNumToString( vtZ:getY(), 6) .. ' Q' .. EgtNumToString( vtZ:getX(), 6) .. ' R' .. EgtNumToString( -vtZ:getZ(), 6) + end + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function GetFaceCode() + if EMT.Y1DELTA and EMT.Y2DELTA then + return '3' + elseif EMT.Y1DELTA then + return '6' + else + return '5' + end +end + +--------------------------------------------------------------------- +function EmitZmax( bReset, bEnd, PrevR1, PrevR2, bSplitCut) + if bReset then + EmitResetMachining() + end + -- se testa 1 + if EMT.HEAD ~= 'H21' then + -- posizioni sicure + local dMaxZ1 = EgtGetAxisMax( 'Z1') + local dSafeZ1 = EgtGetAxisHomePos( 'Z1') + local dSafeB1 = EgtGetAxisHomePos( 'B1') + local dSafeC1 = EgtGetAxisHomePos( 'C1') + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, dSafeC1, dSafeB1) then + local dPosT = EgtIf( bEnd, EMT.L1o, EMT.TPOS or EMT.L1op) + EmitParkRoller( dPosT, bSplitCut) + end + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + -- eseguo la salita a Z1max (oriento solo se assi rotanti non già a posto) + if abs( dSafeC1 - PrevR1) > 0.1 or abs( dSafeB1 - PrevR2) > 0.1 then + local Z_EXTRA = EgtIf( EMT.HEAD == 'H11', 250, 160) + if abs( PrevR2) < 60 then + local dZref = dSafeZ1 + Z_EXTRA + EmitMoveDataHead( 1, { Z=dZref, Fmt=1}) + elseif abs( PrevR2) < 90 then + local dZref = dSafeZ1 + Z_EXTRA * ( 90 - abs( PrevR2)) / 30 + EmitMoveDataHead( 1, { Z=dZref, Fmt=1}) + end + local ANG_LIM_DOWN = EgtIf( EMT.HEAD == 'H11', 0, -45) + local ANG_LIM_OPPO = 90 + if PrevR2 > ANG_LIM_DOWN then + if PrevR2 > ANG_LIM_OPPO then + EmitMoveDataHead( 1, { Z=dSafeZ1, B=ANG_LIM_OPPO, Fmt=1}) + end + if PrevR2 > 60 then + EmitMoveDataHead( 1, { Z=dSafeZ1+Z_EXTRA, B=60, Fmt=1}) + end + EmitMoveDataHead( 1, { Z=dSafeZ1+Z_EXTRA, B=ANG_LIM_DOWN, Fmt=1}) + end + EmitMoveDataHead( 1, { Z=dSafeZ1, B=dSafeB1, Fmt=1}) + EmitMoveDataHead( 1, { C=dSafeC1, Fmt=1}) + end + EmitMoveDataHead( 1, { Z=dMaxZ1, Fmt=1}) + EmitMoveStartHead( 1) + EmitMoveWaitHead( 1) + -- altrimenti sega a catena + else + EmitMoveDataHead( 1, { Z=dSafeZ1, B=dSafeB1, Fmt=1}) + if EMT.L2o > DeltaTabY then + EmitMoveDataHead( 1, { X=-DeltaTabY, Fmt=1}) + end + EmitMoveDataHead( 1, { C=dSafeC1, Fmt=1}) + EmitMoveDataHead( 1, { Z=dMaxZ1, Fmt=1}) + EmitMoveStartHead( 1) + EmitMoveWaitHead( 1) + end + -- altrimenti testa 2 + else + -- posizioni sicure + local dSafeX2 = EgtGetAxisHomePos( 'X2') + local dSafeZ2 = EgtGetAxisHomePos( 'Z2') + local dSafeB2 = EgtGetAxisHomePos( 'B2') + local dSafeC2 = EgtGetAxisHomePos( 'C2') + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, dSafeC2, dSafeB2) then + local dPosT = EgtIf( bEnd, EMT.L1o, EMT.TPOS or EMT.L1op) + EmitParkRoller( dPosT, bSplitCut) + end + -- eseguo la discesa a Z2max + EmitMoveDataHead( 2, { Z=-dSafeZ2, Fmt=1}) + EmitMoveDataHead( 2, { B=dSafeB2, C=dSafeC2, Fmt=1}) + EmitMoveDataHead( 2, { X=dSafeX2, Fmt=1}) + EmitMoveStartHead( 2) + EmitMoveWaitHead( 2) + end +end + +--------------------------------------------------------------------- +function EmitResetMachining() + MyOutput( 'G27') + local sP12 = '' + if EMT.TOOL ~= GetNextTool( EMT.MCHID) then sP12 = EgtIf( EMT.HEAD ~= 'H21', ' P1=0', ' P2=0') end + local sP4 = EgtIf( EMT.MCHUSERNOTES:find( 'Split', 1, true), ' P4=1', '') + MyOutput( 'M99'..sP12..sP4) +end + +--------------------------------------------------------------------- +function EmitParkRoller( dPosT, bSplitCut) + -- se entrambe già parcheggiate, non devo fare alcunché + if ( EMT.V1POS - ParkV1) > -0.1 and ( EMT.V2POS - ParkV2) < 0.1 then return end + -- Parcheggi pinze + local MyParkY1 = ParkY1 + AggLoad + local MyParkY2 = ParkY2 + -- le parcheggio + local MDChar = {} + if EMT.Y1DELTA and EMT.Y2DELTA then + local dPosY1 = dPosT + EMT.Y1DELTA + local dPosY2 = dPosT + EMT.Y2DELTA + local DiffY1 = MyParkY1 - dPosY1 + local DiffY2 = MyParkY2 - dPosY2 + --MyOutput( string.format( 'PosT=%.3f DiffY1=%.3f DiffY2=%.3f', dPosT, DiffY1, DiffY2)) + if bSplitCut then + if DiffY1 > 0.1 then + MDChar.Y1 = dPosY1 + DiffY1 + end + if DiffY2 < -0.1 then + MDChar.Y2 = dPosY2 + DiffY2 + dPosT = dPosT + DiffY2 + end + elseif DiffY1 > 0.1 and DiffY2 < -0.1 then + EmtSetLastError( 1201, 'Error Collision in ParkRoller') + elseif DiffY1 > 0.1 then + if dPosY2 + DiffY1 > MyParkY2 + 0.1 then + EmtSetLastError( 1201, 'Error Collision Y2 in ParkRoller') + else + MDChar.Y1 = dPosY1 + DiffY1 + MDChar.Y2 = dPosY2 + DiffY1 + dPosT = dPosT + DiffY1 + end + elseif DiffY2 < -0.1 then + if dPosY1 + DiffY2 < MyParkY1 - 0.1 then + EmtSetLastError( 1201, 'Error Collision Y1 in ParkRoller') + else + MDChar.Y1 = dPosY1 + DiffY2 + MDChar.Y2 = dPosY2 + DiffY2 + dPosT = dPosT + DiffY2 + end + end + MDChar.MovType = 3 + MDChar.BeamVise = ( EMT.BV or 1) + elseif EMT.Y1DELTA then + local dMoveV1 = ParkV1 - EMT.V1POS + local dPosY1 = dPosT + EMT.Y1DELTA + local DiffY1 = MyParkY1 - dPosY1 + local dMoveY1 = EgtIf( DiffY1 > 0.1, dMoveV1, 0) + local dTryMoveY1 = ParkV1 - dPosT - EgtIf( bSplitCut or EMT.FALL, EMT.LT, 0) + if ( dPosT > ParkV2 - ExtraParkV and dPosT < ParkV1 and dPosY1 + dTryMoveY1 < MaxY1) then dMoveY1 = max( dMoveY1, dTryMoveY1) end + --MyOutput( string.format( 'PosT=%.3f PosY1=%.3f V1POS=%.3f Split=%s', dPosT, dPosY1, EMT.V1POS, EgtIf( bSplitCut, '1', '0'))) + MDChar.Y1 = dPosY1 + dMoveY1 + MDChar.MovType = 1 + MDChar.BeamVise = 1 + dPosT = dPosT + dMoveY1 + elseif EMT.Y2DELTA then + local dMoveV2 = ParkV2 - EMT.V2POS + local dPosY2 = dPosT + EMT.Y2DELTA + local DiffY2 = MyParkY2 - dPosY2 + local dMoveY2 = EgtIf( DiffY2 < -0.1, dMoveV2, 0) + local dTryMoveY2 = ParkV2 - dPosT - EMT.LT + if ( dPosT + EMT.LT < ParkV1 + ExtraParkV and dPosT + EMT.LT > ParkV2 and dPosY2 + dTryMoveY2 > MinY2) then dMoveY2 = min( dMoveY2, dTryMoveY2) end + --MyOutput( string.format( 'PosT=%.3f LT=%.3f PosY2=%.3f V2POS=%.3f', dPosT, EMT.LT, dPosY2, EMT.V2POS)) + MDChar.Y2 = dPosY2 + dMoveY2 + MDChar.MovType = 2 + MDChar.BeamVise = 2 + dPosT = dPosT + dMoveY2 + end + if abs( ParkV1 - EMT.V1POS) > 0.1 then + MDChar.V1 = ParkV1 + MDChar.IniStatV1 = 1 + end + if abs( ParkV2 - EMT.V2POS) > 0.1 then + MDChar.V2 = ParkV2 + MDChar.IniStatV2 = 1 + end + EmitMoveDataChars( MDChar) + EmitMoveStartChars( MDChar.MovType) + EmitMoveWaitChars( MDChar.MovType) + EMT.V1POS = ParkV1 + EMT.V2POS = ParkV2 + EMT.TPOS = dPosT +end + +--------------------------------------------------------------------- +function GetNextTool( nMchId) + -- inizializzo prossimo utensile + local sNextTool + -- recupero lavorazione successiva + local nNextMchId = EgtGetNextActiveOperation( nMchId) + while nNextMchId do + if EgtGetOperationType( nNextMchId) ~= MCH_OY.DISP then + break + end + nNextMchId = EgtGetNextActiveOperation( nNextMchId) + end + -- se trovata + if nNextMchId and EgtSetCurrMachining( nNextMchId) then + sNextTool = EgtGetMachiningParam( MCH_MP.TOOL) + end + -- ripristino stato corrente + EgtSetCurrMachining( EMT.MCHID) + EgtTdbSetCurrTool( EMT.TOOL) + return sNextTool +end + +--------------------------------------------------------------------- +function PreselectNextDiffHead( nMchId, sHead) + -- se in uso testa 1, verifico di non scendere troppo in Z per evitare collisioni + local nHSet = GetHeadSet( sHead) + if nHSet == 1 then + if EMT.MAXMIN[3] < MinZ1ToChangeH2 then return end + end + -- recupero lavorazione successiva + local nNextMchId = EgtGetNextActiveOperation( nMchId) + while nNextMchId do + if EgtGetOperationType( nNextMchId) ~= MCH_OY.DISP then break end + nNextMchId = EgtGetNextActiveOperation( nNextMchId) + end + if not nNextMchId then return end + -- se esiste ed appartiene a gruppo diverso + if EgtSetCurrMachining( nNextMchId) then + local sNextTool = EgtGetMachiningParam( MCH_MP.TOOL) + if EgtTdbSetCurrTool( sNextTool) then + local sNextHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local nNextHSet = GetHeadSet( sNextHead) + if nNextHSet ~= nHSet then + local sNextTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + if nNextHSet == 1 then + -- Recupero quota X1 (nostro L2) + local dNextX = GetStartMachiningXaxis( nNextMchId) + -- Emetto preselezione + if sNextHead == 'H11' then + EmitMoveDataHead( 1, { X=dNextX, B=ParkB1, C=ParkC1, TPos=AdjustTcPos( false, sNextTcPos), Fmt=2}) + EmitMoveStartHead( 1) + elseif sNextHead == 'H12' then + EmitMoveDataHead( 1, { X=dNextX, B=ParkB1, C=ParkC1, TPos=AdjustTcPos( false, sNextTcPos), Fmt=2}) + EmitMoveStartHead( 1) + elseif sNextHead == 'H13' then + -- recupero il valore dell'asse virtuale bloccato A + local dPosA = GetCurrChainSawingVirtualAxis() + local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA) + local bXSpec = ( dNextX < -DeltaTabY) + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, dNextX), B=ParkCSawB1, C=MyParkCSawC1, TPos=AdjustTcPos( false, sNextTcPos, dPosA), Fmt=2}) + EmitMoveStartHead( 1) + end + else + EmitMoveDataHead( 2, { B=ParkB2, C=ParkC2, TPos=AdjustTcPos( false, sNextTcPos), Fmt=2}) + EmitMoveStartHead( 2) + end + end + end + end + -- ripristino stato corrente + EgtSetCurrMachining( EMT.MCHID) + EgtTdbSetCurrTool( EMT.TOOL) +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE / 1000, 0) +end + +--------------------------------------------------------------------- +function FindReadHeadWithLaser( vMDChar) + for i = 1, #vMDChar do + if vMDChar[i].IniStatY1 == -76 then + return true + end + end + return false +end + +--------------------------------------------------------------------- +function EmitRemark( sOut) + sOut = string.gsub( string.gsub( sOut, '%(', '['), '%)', ']') + MyOutput( '(' .. sOut .. ')') +end + +--------------------------------------------------------------------- +function EmitMoveDataHead( nHead, MoData) + local sOut = EgtIf( nHead == 1, 'M101', 'M102') .. ' P1=1' + if MoData.X then sOut = sOut .. ' P2=' .. EmtLenToString( MoData.X, 3) end + if MoData.Z then sOut = sOut .. ' P3=' .. EmtLenToString( MoData.Z, 3) end + if MoData.B then sOut = sOut .. ' P4=' .. EmtLenToString( MoData.B, 3) end + if MoData.C then sOut = sOut .. ' P5=' .. EmtLenToString( MoData.C, 3) end + if MoData.TPos then sOut = sOut .. ' P6=' .. MoData.TPos elseif EMT.TCPOS then sOut = sOut .. ' P6=' .. AdjustTcPos( false) end + if MoData.S then sOut = sOut .. ' P7=' .. EgtNumToString( MoData.S, 0) end + if not MoData.Fmt then + if MoData.F then sOut = sOut .. ' P8=' .. EmtLenToString( MoData.F, 0) else sOut = sOut .. ' P8=0' end + sOut = sOut .. ' P9=0 P10=4 P11=1' + elseif MoData.Fmt == 1 then + sOut = sOut .. ' P10=4 P11=1' + end + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveStartHead( nHead) + local sOut = EgtIf( nHead == 1, 'M101', 'M102') .. ' P1=2' + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveWaitHead( nHead) + local sOut = EgtIf( nHead == 1, 'M101', 'M102') .. ' P1=3' + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveDataChars( MoData) + local sOut = 'M111' + if MoData.MovType == 1 then sOut = sOut .. ' P1=11' elseif MoData.MovType == 2 then sOut = sOut .. ' P1=12' else sOut = sOut .. ' P1=10' end + if MoData.Y1 then sOut = sOut .. ' P2=' .. EmtLenToString( MoData.Y1, 3) end + if MoData.Y2 then sOut = sOut .. ' P3=' .. EmtLenToString( MoData.Y2, 3) end + if MoData.IniStatY1 then sOut = sOut .. ' P4=' .. EgtNumToString( MoData.IniStatY1, 0) end + if MoData.FinStatY1 then sOut = sOut .. ' P5=' .. EgtNumToString( MoData.FinStatY1, 0) end + if MoData.IniStatY2 then sOut = sOut .. ' P6=' .. EgtNumToString( MoData.IniStatY2, 0) end + if MoData.FinStatY2 then sOut = sOut .. ' P7=' .. EgtNumToString( MoData.FinStatY2, 0) end + if MoData.BeamVise then sOut = sOut .. ' P8=' .. EgtNumToString( MoData.BeamVise, 0) end + if MoData.F then sOut = sOut .. ' P9=' .. EmtLenToString( MoData.F, 0) else sOut = sOut .. ' P9=' .. GetFmaxClamp() end + if MoData.V1 then sOut = sOut .. ' P15=' .. EmtLenToString( MoData.V1, 3) end + if MoData.V2 then sOut = sOut .. ' P16=' .. EmtLenToString( MoData.V2, 3) end + if MoData.IniStatV1 then local sVal = EgtNumToString( MoData.IniStatV1, 0) ; sOut = sOut .. ' P17=' .. sVal .. ' P18=' .. sVal end + if MoData.FinStatV1 then local sVal = EgtNumToString( MoData.FinStatV1, 0) ; sOut = sOut .. ' P19=' .. sVal .. ' P20=' .. sVal end + if MoData.IniStatV2 then local sVal = EgtNumToString( MoData.IniStatV2, 0) ; sOut = sOut .. ' P21=' .. sVal .. ' P22=' .. sVal end + if MoData.FinStatV2 then local sVal = EgtNumToString( MoData.FinStatV2, 0) ; sOut = sOut .. ' P23=' .. sVal .. ' P24=' .. sVal end + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveStartChars( MovType) + local sMovType = ' P1=20' + if MovType == 1 then + sMovType = ' P1=21' + elseif MovType == 2 then + sMovType = ' P1=22' + end + MyOutput( 'M111' .. sMovType) +end + +--------------------------------------------------------------------- +function EmitMoveWaitChars( MovType, bRun) + local sMovType = ' P1=30' + if MovType == 1 then + sMovType = ' P1=31' + elseif MovType == 2 then + sMovType = ' P1=32' + end + if bRun == nil or bRun then + MyOutput( 'M111' .. sMovType) + else + MyOutput( ';M111' .. sMovType) + end +end + +--------------------------------------------------------------------- +function EmitBeamHeadData( BhData) + local sOut = 'M112' + if BhData.T then sOut = sOut .. ' P1=' .. EmtLenToString( BhData.T, 3) end + if BhData.ViseY1 then sOut = sOut .. ' P3=' .. EgtNumToString( BhData.ViseY1, 0) end + if BhData.ViseY2 then sOut = sOut .. ' P4=' .. EgtNumToString( BhData.ViseY2, 0) end + if BhData.SetHead then sOut = sOut .. ' P5=' .. EgtNumToString( BhData.SetHead, 0) end + if BhData.Y1 then sOut = sOut .. ' P6=' .. EmtLenToString( BhData.Y1, 3) end + if BhData.Y2 then sOut = sOut .. ' P7=' .. EmtLenToString( BhData.Y2, 3) end + if BhData.F then sOut = sOut .. EgtIf( BhData.F >= 1, ' P9=' .. EmtLenToString( BhData.F, 0), '') else sOut = sOut .. ' P9=' .. GetFmaxClamp() end + if BhData.StatV1 then sOut = sOut .. ' P10=' .. EgtNumToString( BhData.StatV1, 0) end + if BhData.V1 then sOut = sOut .. ' P11=' .. EmtLenToString( BhData.V1, 3) end + if BhData.StatV1 then sOut = sOut .. ' P12=' .. EgtNumToString( BhData.StatV1, 0) end + if BhData.StatV2 then sOut = sOut .. ' P13=' .. EgtNumToString( BhData.StatV2, 0) end + if BhData.V2 then sOut = sOut .. ' P14=' .. EmtLenToString( BhData.V2, 3) end + if BhData.StatV2 then sOut = sOut .. ' P15=' .. EgtNumToString( BhData.StatV2, 0) end + if BhData.ViseY1 == 3 then sOut = sOut .. ' P16=1' end + if BhData.ViseY2 == 3 then sOut = sOut .. ' P17=1' end + MyOutput( sOut) +end + +--------------------------------------------------------------------- +--------------------------------------------------------------------- +local bToPark = true + +--------------------------------------------------------------------- +function SetToParkLine() + bToPark = true +end + +--------------------------------------------------------------------- +function MyOutput( sOut) + if not bToPark then + EmtOutput( sOut) + else + ParkLine( sOut) + end +end + +--------------------------------------------------------------------- +--------------------------------------------------------------------- +local ParkedLines = {} + +--------------------------------------------------------------------- +function ParkLine( sLine) + table.insert( ParkedLines, sLine) +end + +--------------------------------------------------------------------- +function EmitParkedLines() + bToPark = false + for i = 1, #ParkedLines do + EmtOutput( ParkedLines[i]) + end + ParkedLines = {} +end + +--------------------------------------------------------------------- +--------------------------------------------------------------------- +local StartValues = {} + +--------------------------------------------------------------------- +function SetStartValue( nI, dVal) + StartValues[nI] = dVal +end + +--------------------------------------------------------------------- +function EmitStartValues() + bToPark = false + local sLine = '' + for i = 1, 10 do + sLine = sLine .. string.format( ';V%02d=', i) .. EgtNumToString( StartValues[i] or 0, 3) + end + EmtOutput( sLine) + StartValues = {} +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.ini new file mode 100644 index 0000000..3c22471 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.ini @@ -0,0 +1,64 @@ +; Commento per evitare BOM con UTF-8 +[General] +Material=Beam + +[Tools] +Drillbit=1 +Sawblade=1 +Mill=1 +Mortise=1 +Chisel=0 +DrillMaker=MakeWoodDrill.lua +SawbladeMaker=MakeSawblade.lua +MillMaker=MakeWoodCylMill.lua +MortiseMaker=MakeMortise.lua +ChiselMaker=MakeChisel.lua +Active=1 + +[ToolHolder] +H11.1=Standard.nge +H11.1:MILL_NOTIP=MillNoTip.nge +H12.1=Saw.nge +H13.1=ChainSaw.nge +H21.1=Standard.nge +H21.1:MILL_NOTIP=MillNoTip.nge +H21.1:SAW_FLAT=SawH2.nge + +[Machinings] +Drilling=1 +Sawing=1 +Milling=1 +Pocketing=1 +Mortising=1 +Chiseling=0 +SawRoughing=0 +SawFinishing=0 + +[Machining] +InitScript=InitMach.lua +ExitScript=ExitMach.lua + +[Disposition] +;InitScript=InitDisp.lua + +[Heads] +; 5 axis head +H11=6608 +; 5 axis saw +H12=6615 +; Chainsaw +H13=6616 +; Second 5 axis head +H21=6620 + +[SetUp] +Default=Standard + +[Estimations] +Enable=1 +WinPlace=0,514,138,628,810 + +[VMill] +Enable=1 +Save=0 + diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.mlde b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.mlde new file mode 100644 index 0000000..eb1af78 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.mlde @@ -0,0 +1,870 @@ +-- Descrizione macchina Essetre-PF1250 by EgalTech s.r.l. 2022/03/24 +-- 2021/08/03 ver 2.3h1 Prima versione. +-- 2021/09/14 ver 2.3i9 Estesa gestione sega a catena. +-- 2021/09/15 ver 2.3i10 Correzione gestione posizione rimanenza. +-- 2021/09/21 ver 2.3i11 Correzione gestione ultima lavorazione di pareti. Gestione AggLoad. +-- Correzione movimento pezzi rimanenti allo split. Aggiunta gestione Uso Trieste (UT- in info MATERIAL del pezzo). +-- 2021/09/21 ver 2.3i12 Correzione mancata rilevazione collisioni (un solido nella lista è nullo). +-- 2021/09/21 ver 2.3i13 Correzione apertura pinze dopo split. +-- 2021/09/22 ver 2.3i14 Testa 2 movimento a Zmax prima in Z poi muove gli assi rotanti. +-- 2021/09/23 ver 2.3i15 Migliorata gestione aggiuntivo al carico con miglior controllo di EMC.CNT. +-- 2021/09/24 ver 2.3i18 Aggiunta gestione secondo TC per testa sopra. +-- 2021/10/01 ver 2.3j1 Ripristinata risalita lama a Z sicura se troppo bassa indipendentemente da Flag e Flag2 (mlse). +-- 2021/10/04 ver 2.3j2 Aggiunto controllo Z1 minima per abilitare durante la lavorazione il cambio di H2. +-- 2021/10/08 ver 2.3j3 Corretto controllo apertura paratie rulli all'avvio con testa 2. +-- 2021/10/21 ver 2.3j6 Modificato movimento testa/coda pezzo all'apertura pareti. Controllata posizione rotazione sega a catena. +-- 2021/10/20 ver 2.3l1 Correzioni in EmitParkRoller di generazione CNC e in movimenti carrelli di mlse. +-- 2022/01/25 ver 2.4a1 Migliorata simulazione carico/scarico sega a catena. +-- 2022/03/01 ver 2.4c1 Corretto assegnamento CUTID con pareti. +-- 2022/03/23 ver 2.4c2 Correzione per carico pezzo a caduta senza taglio di testa. +-- 2022/03/24 ver 2.4c3 Correzioni in generazione CN per primo movimento non taglio di testa. + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +PP_VER = '2.4c3' + +-- Parametri macchina +NumericalControl = 'TPA' -- NUM o TPA +MinMchY1 = 335 +MaxMchY1 = 5790.0 +ParkMchY1 = 970.0 +MinMchY2 = -5775.0 +MaxMchY2 = -324 +ParkMchY2 = -955.0 +MinV1 = 5.0 +MaxV1 = 640.0 +ParkV1 = 610.0 +MinV2 = -635.0 +MaxV2 = -5.0 +ParkV2 = -610.0 +MinDeltaYV = 317 + 0.1 +ExtraParkV = 600 +MinY1 = MinV1 + MinDeltaYV +MaxY1 = MaxMchY1 +MaxY2 = MaxV2 - MinDeltaYV +MinY2 = MinMchY2 +ParkY1 = ParkV1 + MinDeltaYV +ParkY2 = ParkV2 - MinDeltaYV +LoadT = 2172.8 +UnloadT = -2400 +UnloadSmT = UnloadT - 300 +MaxHoOpen = 1300 +MaxVeOpen = 420 +RollCageMin = 120 +RollCageMax = 250 +MillOffs = 170.0 +SawOffsX = 111.0 +SawOffsY = 0 +SawOffsZ = -150.25 +SawC1Offs = 0 +SawB1Offs = 0 +ChSawLen = 91.0 +Mill2Offs = 170.0 +SawC2Offs = 0 +SawB2Offs = 0 +MinX1 = 0 +MaxX1 = 3300 +MinZ1 = -1550 +MaxZ1 = -100 +MinC1 = -275 +MaxC1 = 275 +MinB1 = -127 +MaxB1 = 127 +MinB1b = -119 +MaxB1b = 119 +ParkX1 = 250 +ParkTc2X1 = 3100 +ParkZ1 = -535 +ParkC1 = -90 +ParkB1 = -90 +ParkCSawX1 = 1500 +ParkCSawZ1 = -100 +ParkCSaw0Z1 = -400 +ParkCSawC1 = -90 +ParkCSaw0C1 = 0 +ParkCSawB1 = 0 +MinZ1ToChangeH2 = -1400 +MinX2 = -2760 +MaxX2 = 0 +MinZ2 = 0 +MaxZ2 = 795 +MinC2 = -275 +MaxC2 = 275 +MinB2 = -127 +MaxB2 = 127 +ParkX2 = -100 +ParkZ2 = 0 +ParkC2 = -90 +ParkB2 = -90 +TurnerOffs = 120.0 +AggLoad = 50 +DeltaTabY = 2467.0 +DeltaTabZ = -1137.5 + MillOffs -- per TPA : -1128.0 + MillOffs -- per NUM : -958.0 +DeltaRulliTraveZ = -903 +DimTabY = 1400 +DimTabX = 24000 +Delta2TabY = -967.3 +Delta2TabZ = 395.2 - Mill2Offs -- per TPA : 378.0 - Mill2Offs -- per NUM : 208.0 +Head2X = 0 +Head2Y = DeltaTabY - Delta2TabY +Head2Z = DeltaTabZ - Delta2TabZ +DefTcPos1 = 'T1' +DefTcPos2 = 'T30' +CoeffVM = 0.5 +Tc2Active = true + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Beam', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-PF1250.data" +local sData = EgtGetSourceDir().."\\Beam\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Offsets then + --NumericalControl = EgtIf( Machine.Offsets.TIPO_CN == 0, 'NUM', 'TPA') + if Machine.Offsets.X1_POS then MinX1 = -Machine.Offsets.X1_POS end + if Machine.Offsets.X1_NEG then MaxX1 = -Machine.Offsets.X1_NEG end + if Machine.Offsets.Z1_NEG then MinZ1 = Machine.Offsets.Z1_NEG end + if Machine.Offsets.Z1_POS then MaxZ1 = min( MaxZ1, Machine.Offsets.Z1_POS) end + if Machine.Offsets.PARK_Z1 then ParkZ1 = Machine.Offsets.PARK_Z1 end + if Machine.Offsets.C1_NEG then MinC1 = Machine.Offsets.C1_NEG end + if Machine.Offsets.C1_POS then MaxC1 = Machine.Offsets.C1_POS end + if Machine.Offsets.B1_NEG then MinB1 = Machine.Offsets.B1_NEG end + if Machine.Offsets.B1_POS then MaxB1 = Machine.Offsets.B1_POS end + if Machine.Offsets.B1_NEG1 then MinB1b = Machine.Offsets.B1_NEG1 end + if Machine.Offsets.B1_POS1 then MaxB1b = Machine.Offsets.B1_POS1 end + if Machine.Offsets.X2_NEG then MinX2 = Machine.Offsets.X2_NEG end + if Machine.Offsets.X2_POS then MaxX2 = Machine.Offsets.X2_POS end + if Machine.Offsets.Z2_POS then MinZ2 = -Machine.Offsets.Z2_POS end + if Machine.Offsets.Z2_NEG then MaxZ2 = -Machine.Offsets.Z2_NEG end + if Machine.Offsets.PARK_Z2 then ParkZ2 = -Machine.Offsets.PARK_Z2 end + if Machine.Offsets.C2_NEG then MinC2 = Machine.Offsets.C2_NEG end + if Machine.Offsets.C2_POS then MaxC2 = Machine.Offsets.C2_POS end + if Machine.Offsets.B2_NEG then MinB2 = Machine.Offsets.B2_NEG end + if Machine.Offsets.B2_POS then MaxB2 = Machine.Offsets.B2_POS end + if Machine.Offsets.MIN_Y1 then MinMchY1 = Machine.Offsets.MIN_Y1 end + if Machine.Offsets.MAX_Y1 then MaxMchY1 = Machine.Offsets.MAX_Y1 end + if Machine.Offsets.PARK_Y1 then ParkMchY1 = Machine.Offsets.PARK_Y1 end + if Machine.Offsets.MIN_V1 then MinV1 = Machine.Offsets.MIN_V1 end + if Machine.Offsets.MAX_V1 then MaxV1 = Machine.Offsets.MAX_V1 end + if Machine.Offsets.MIN_Y2 then MinMchY2 = Machine.Offsets.MIN_Y2 end + if Machine.Offsets.MAX_Y2 then MaxMchY2 = Machine.Offsets.MAX_Y2 end + if Machine.Offsets.PARK_Y2 then ParkMchY2 = Machine.Offsets.PARK_Y2 end + if Machine.Offsets.MIN_V2 then MinV2 = Machine.Offsets.MIN_V2 end + if Machine.Offsets.MAX_V2 then MaxV2 = Machine.Offsets.MAX_V2 end + if Machine.Offsets.DIST_FTZERO then LoadT = Machine.Offsets.DIST_FTZERO end + if Machine.Offsets.DELTA_CARICZERO then TurnerOffs = Machine.Offsets.DELTA_CARICZERO end + if Machine.Offsets.MIN_DELTAVY then MinDeltaYV = Machine.Offsets.MIN_DELTAVY + 0.1 end + if Machine.Offsets.DIST_UNLOAD then UnloadT = Machine.Offsets.DIST_UNLOAD end + if Machine.Offsets.PIVOT_T1 then MillOffs = Machine.Offsets.PIVOT_T1 end + if Machine.Offsets.PIVOT_T2 then Mill2Offs = Machine.Offsets.PIVOT_T2 end + if Machine.Offsets.OFFSETCLAMAT1 then SawC1Offs= Machine.Offsets.OFFSETCLAMAT1 end + if Machine.Offsets.OFFSETBLAMAT1 then SawB1Offs= Machine.Offsets.OFFSETBLAMAT1 end + if Machine.Offsets.OFFSETCLAMAT2 then SawC2Offs= Machine.Offsets.OFFSETCLAMAT2 end + if Machine.Offsets.OFFSETBLAMAT2 then SawB2Offs= Machine.Offsets.OFFSETBLAMAT2 end + if Machine.Offsets.OFFSETXT1 then DeltaTabY = -Machine.Offsets.OFFSETXT1 end + if Machine.Offsets.OFFSETZT1 then DeltaTabZ = Machine.Offsets.OFFSETZT1 + MillOffs end + if Machine.Offsets.OFFSETXT2 then Delta2TabY = Machine.Offsets.OFFSETXT2 end + if Machine.Offsets.OFFSETZT2 then Delta2TabZ = -Machine.Offsets.OFFSETZT2 - Mill2Offs end + if Machine.Offsets.OFFSETZSOTTOTRAVE then DeltaRulliTraveZ = -abs( Machine.Offsets.OFFSETZSOTTOTRAVE) end + -- aggiustamenti + MinY1 = MinV1 + MinDeltaYV + MaxY1 = MaxMchY1 + ParkV1 = MaxV1 + ParkY1 = ParkV1 + MinDeltaYV + MinY2 = MinMchY2 + MaxY2 = MaxV2 - MinDeltaYV + ParkV2 = MinV2 + ParkY2 = ParkV2 - MinDeltaYV + UnloadSmT = UnloadT - 300 + Head2Y = DeltaTabY - Delta2TabY + Head2Z = DeltaTabZ - Delta2TabZ + ParkCSawZ1 = min( ParkCSawZ1, MaxZ1) + end + end +end + +EmtGeneral { + File='Essetre-PF1250.nge', + Offset = Vector3d(0.0,1360.0,-2130.0), + AxisMaxAdjust = 300, + ExitMaxAdjust = 300, + AngDeltaMinForHome = 80, + Special = 'Essetre-PF1250.mlse', + Processor = 'Essetre-PF1250.mlpe'} +local sBaseAux = {'BASE/SOLID', 'BASE/CONVOYER', 'BASE/COLLISION', 'BASE/TC1', 'BASE/TCR', 'BASE/TC3'} +if Tc2Active then table.insert( sBaseAux, 5, 'BASE/TC2') end +local BaseId = EmtBase { + Name = 'Base', + Geo = 'BASE/GEO', + Aux = sBaseAux} +local X1Id = EmtAxis { + Name = 'X1', + Parent = 'Base', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(207.0,-300.0,104.0), + Stroke = {MinX1, MaxX1}, + Home = ParkX1, + Invert = true, + Geo = 'X1_AXIS/GEO', + Aux = 'X1_AXIS/SOLID'} +-- *** Testa 1 *** +EmtAxis { + Name = 'Z1', + Parent = 'X1', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(0.0,-140.1,113.0), + Stroke = {MinZ1, MaxZ1}, + Home = ParkZ1, + Geo = 'Z1_AXIS/GEO', + Aux = {'Z1_AXIS/SOLID', 'Z1_AXIS/COLLISION'}} +EmtAxis { + Name = 'C1', + Parent = 'Z1', + Token = 'C', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d(0.0,0.0,503.0), + Stroke = {MinC1, MaxC1}, + Home = ParkC1, + Geo = 'C1_AXIS/GEO', + Aux = {'C1_AXIS/SOLID', 'C1_AXIS/COLLISION'}} +EmtAxis { + Name = 'B1', + Parent = 'C1', + Token = 'B', + Type = MCH_AT.ROTARY, + Dir = X_AX(), + Pos = Point3d(-108.4,0.0,MillOffs), + Stroke = {MinB1, MaxB1}, + Home = ParkB1, + Geo = 'B1_AXIS/GEO', + Aux = {'B1_AXIS/SOLID', 'B1_AXIS/COLLISION'}} +-- Frese +local H11Id = EmtHead { + Name = 'H11', + Parent = 'B1', + HSet = 'H11', + Type = MCH_HT.STD, + Pos = Point3d(0,0,0), + TDir = Z_AX(), + ADir = -Y_AX(), + Rot1W = 0.2, + Rot2Stroke = { MinB1, MaxB1}, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H11_HEAD/GEO'} +EgtSetInfo( H11Id, 'ZEXTRA', '250,60') +-- Lama +local H12Id = EmtHead { + Name = 'H12', + Parent = 'B1', + HSet = 'H11', + Type = MCH_HT.STD, + Pos = Point3d(SawOffsX,SawOffsY,SawOffsZ), + TDir = Z_AX(), + ADir = -X_AX(), + Rot1W = 0.5, + Rot2Stroke = { MinB1b, MaxB1b}, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H12_HEAD/GEO'} +EgtSetInfo( H12Id, 'ZEXTRA', '160,60') +EgtSetInfo( H12Id, 'ZMAXONROT', '1,190') +-- Sega a catena +EmtAxis { + Name = 'A', + Parent = 'B1', + Token = '**', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = { 0, 270}, + Home = 0, + Geo = 'A_AXIS/GEO'} +local H13Id = EmtHead { + Name = 'H13', + Parent = 'A', + HSet = 'H11', + Type = MCH_HT.STD, + Pos = Point3d(0,0,-ChSawLen), + TDir = -X_AX(), + ADir = Z_AX(), + Rot1W = 0.2, + Rot2Stroke = { -90.1, 90.1}, + SolCh = MCH_SCC.ADIR_NEAR, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H13_HEAD/GEO'} +EgtSetInfo( H13Id, 'ZEXTRA', '200') +EgtSetInfo( H13Id, 'ZSAFEDELTA', '60') +EgtSetInfo( H13Id, 'ZMAXONROT', '1,80') +-- Dummy +EmtHead { + Name = 'H14', + Parent = 'B1', + HSet = 'H14', + Type = MCH_HT.STD, + Pos = Point3d(0,0,0), + TDir = Z_AX(), + ADir = X_AX(), + Rot1W = 0.2, + Geo = 'H14_HEAD/GEO'} +-- *** Testa 2 *** +local Z2Id = EmtAxis { + Name = 'Z2', + Parent = 'Base', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(291.0,-140.1,-2056.3), + Stroke = {MinZ2, MaxZ2}, + Home = ParkZ2, + Invert = true, + Geo = 'Z2_AXIS/GEO', + Aux = {'Z2_AXIS/SOLID', 'Z2_AXIS/COLLISION'}} +local X2Id = EmtAxis { + Name = 'X2', + Parent = 'Z2', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(115.8,3065.9,-1738.0), + Stroke = {MinX2, MaxX2}, + Home = ParkX2, + Geo = 'X2_AXIS/GEO', + Aux = {'X2_AXIS/SOLID', 'X2_AXIS/COLLISION'}} +local C2Id = EmtAxis { + Name = 'C2', + Parent = 'X2', + Token = 'C', + Type = MCH_AT.ROTARY, + Dir = -Z_AX(), + Pos = Point3d( Head2X, Head2Y, Head2Z-485), + Stroke = {MinC2, MaxC2}, + Home = ParkC2, + Geo = 'C2_AXIS/GEO', + Aux = {'C2_AXIS/SOLID', 'C2_AXIS/COLLISION'}} +local B2Id = EmtAxis { + Name = 'B2', + Parent = 'C2', + Token = 'B', + Type = MCH_AT.ROTARY, + Dir = X_AX(), + Pos = Point3d( Head2X, Head2Y, Head2Z-Mill2Offs), + Stroke = {MinB2, MaxB2}, + Home = ParkB2, + Geo = 'B2_AXIS/GEO', + Aux = {'B2_AXIS/SOLID', 'B2_AXIS/COLLISION'}} +local vtMoveZ2 = Vector3d( 0, 0, Head2Z + 1181.0) +EgtMove( EgtGetFirstNameInGroup( Z2Id, 'SOLID'), vtMoveZ2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Z2Id, 'COLLISION'), vtMoveZ2, GDB_RT.GLOB) +local vtMoveX2 = Vector3d( 0, Head2Y - 3435.9, Head2Z + 1181.0) +EgtMove( EgtGetFirstNameInGroup( X2Id, 'SOLID'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X2Id, 'COLLISION'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( C2Id, 'SOLID'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( C2Id, 'COLLISION'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( B2Id, 'SOLID'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( B2Id, 'COLLISION'), vtMoveX2, GDB_RT.GLOB) +-- Frese +local H21Id = EmtHead { + Name = 'H21', + Parent = 'B2', + HSet = 'H21', + Type = MCH_HT.STD, + Pos = Point3d( Head2X, Head2Y, Head2Z), + TDir = -Z_AX(), + Rot1W = 0.2, + Rot2Stroke = { MinB2, MaxB2}, + OthColl = {'B2/SOLID', 'C2/SOLID'}, + Geo = 'H21_HEAD/GEO'} +EgtSetInfo( H21Id, 'ABOVE', '0') +EgtSetInfo( H21Id, 'ZHOMEDOWN', '1') +-- *** Carrelli *** +-- Morse +local Y1Id = EmtAxis { + Name = 'Y1', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(-865.7,2626.8,-866.0), + Stroke = { MinY1, MaxY1}, + Home = ParkY1, + Geo = 'Y1_AXIS/GEO', + Aux = 'Y1_AXIS/SOLID'} +local PY1Id = EmtAxis { + Name = 'PY1', + Parent = 'Y1', + Type = MCH_AT.LINEAR, + Dir = -Y_AX(), + Pos = Point3d(-469.6,2367.5,-751.6), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PY1_AXIS/GEO', + Aux = 'PY1_AXIS/SOLID'} +local Y2Id = EmtAxis { + Name = 'Y2', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(865.7,2626.8,-866.0), + Stroke = { MinY2, MaxY2}, + Home = ParkY2, + Geo = 'Y2_AXIS/GEO', + Aux = 'Y2_AXIS/SOLID'} +local PY2Id = EmtAxis { + Name = 'PY2', + Parent = 'Y2', + Type = MCH_AT.LINEAR, + Dir = -Y_AX(), + Pos = Point3d(469.6,2367.5,-751.6), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PY2_AXIS/GEO', + Aux = 'PY2_AXIS/SOLID'} +-- Rulli +local V1Id = EmtAxis { + Name = 'V1', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(-875.5,1072.0,-1509.1), + Stroke = { MinV1, MaxV1}, + Home = ParkV1, + Geo = 'V1_AXIS/GEO', + Aux = {'V1_AXIS/SOLID', 'V1_AXIS/COLLISION'}} +local PV1Id = EmtAxis { + Name = 'PV1', + Parent = 'V1', + Type = MCH_AT.LINEAR, + Dir = -Y_AX(), + Pos = Point3d(-194.0,2364.7,-879.1), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PV1_AXIS/GEO', + Aux = 'PV1_AXIS/SOLID'} +local QV1Id = EmtAxis { + Name = 'QV1', + Parent = 'V1', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(-287.0,2481.0,-943.0), + Stroke = {0, MaxVeOpen}, + Home = MaxVeOpen, + Geo = 'QV1_AXIS/GEO', + Aux = 'QV1_AXIS/SOLID'} +local V2Id = EmtAxis { + Name = 'V2', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(875.5,1072.0,-1509.1), + Stroke = { MinV2, MaxV2}, + Home = ParkV2, + Geo = 'V2_AXIS/GEO', + Aux = {'V2_AXIS/SOLID', 'V2_AXIS/COLLISION'}} +local PV2Id = EmtAxis { + Name = 'PV2', + Parent = 'V2', + Type = MCH_AT.LINEAR, + Dir = -Y_AX(), + Pos = Point3d(194.0,2364.7,-879.1), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PV2_AXIS/GEO', + Aux = 'PV2_AXIS/SOLID'} +local QV2Id = EmtAxis { + Name = 'QV2', + Parent = 'V2', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(287.0,2481.0,-943.0), + Stroke = {0, MaxVeOpen}, + Home = MaxVeOpen, + Geo = 'QV2_AXIS/GEO', + Aux = 'QV2_AXIS/SOLID'} +-- *** Tavola *** +EmtAxis { + Name = 'T', + Parent = 'Base', + --Token = '**', + Type = MCH_AT.LINEAR, + Dir = - X_AX(), + Pos = Point3d(0.0,2450.0,-958.0), + Stroke = {-20000, 20000}, + Home = LoadT, + Geo = 'T_AXIS/GEO'} +EmtTable { + Name = 'Tab', + Parent = 'T', + Type = MCH_TT.FLAT, + Ref1 = Point3d( - DimTabX, DeltaTabY - DimTabY, DeltaTabZ), + Geo = 'TABLE/GEO', + Aux = 'TABLE/SOLID'} +-- *** ToolChanger *** +local ptTc1 = Point3d( 150, -151, -221 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) +local vtDt1 = Vector3d( 0, 0, - 102.5) +EmtTcPos { + Name = 'T1', + Parent = 'Base', + Pos = ptTc1 + Vector3d( SawOffsX, SawOffsZ, 0), + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T1'} +EmtTcPos { + Name = 'T3', + Parent = 'Base', + Pos = ptTc1 + 2 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T3'} +EmtTcPos { + Name = 'T4', + Parent = 'Base', + Pos = ptTc1 + 3 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T4'} +EmtTcPos { + Name = 'T5', + Parent = 'Base', + Pos = ptTc1 + 4 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T5'} +EmtTcPos { + Name = 'T6', + Parent = 'Base', + Pos = ptTc1 + 5 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T6'} +EmtTcPos { + Name = 'T7', + Parent = 'Base', + Pos = ptTc1 + 6 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T7'} +EmtTcPos { + Name = 'T8', + Parent = 'Base', + Pos = ptTc1 + 7 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T8'} +EmtTcPos { + Name = 'T9', + Parent = 'Base', + Pos = ptTc1 + 8 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T9'} +EmtTcPos { + Name = 'T10', + Parent = 'Base', + Pos = ptTc1 + 9 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T10'} +if Tc2Active then + local ptTc2 = Point3d( 150, 3617, -118.5 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) + local vtDt2 = Vector3d( 0, 0, - 102.5) + EmtTcPos { + Name = 'T11', + Parent = 'Base', + Pos = ptTc2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T11'} + EmtTcPos { + Name = 'T12', + Parent = 'Base', + Pos = ptTc2 + 1 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T12'} + EmtTcPos { + Name = 'T13', + Parent = 'Base', + Pos = ptTc2 + 2 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T13'} + EmtTcPos { + Name = 'T14', + Parent = 'Base', + Pos = ptTc2 + 3 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T14'} + EmtTcPos { + Name = 'T15', + Parent = 'Base', + Pos = ptTc2 + 4 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T15'} +end +local ptTc3 = Point3d( 480, 529, -200.8) +EmtTcPos { + Name = 'T101', + Parent = 'Base', + Pos = ptTc3, + TDir = -X_AX(), + ADir = Z_AX(), + Geo = 'BASE/T101'} +local ptTcR = Point3d( -0.5, 3815, -1571.2) +EmtTcPos { + Name = 'T20', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -30, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T20'} +EmtTcPos { + Name = 'T21', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -60, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T21'} +EmtTcPos { + Name = 'T22', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -90, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T22'} +EmtTcPos { + Name = 'T23', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -120, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T23'} +EmtTcPos { + Name = 'T24', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -150, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T24'} +EmtTcPos { + Name = 'T25', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -180, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T25'} +EmtTcPos { + Name = 'T26', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -210, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T26'} +EmtTcPos { + Name = 'T27', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -240, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T27'} +EmtTcPos { + Name = 'T28', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -270, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T28'} +EmtTcPos { + Name = 'T29', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -300, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T29'} +EmtTcPos { + Name = 'T30', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -330, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T30'} + +-- Aggiusto posizioni geometriche +local vtMovB = Vector3d( 0, 0, ( DeltaTabZ - DeltaRulliTraveZ + 55)) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SOLID'), vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'COLLISION'), vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SIGN') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC1') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC1S') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC2') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC3') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'MTC') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC3') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X1Id, 'SOLID'), vtMovB, GDB_RT.GLOB) +local vtMove = Vector3d( 0, ( DeltaTabY - 2450.0), ( DeltaTabZ + 958.0)) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'CONVOYER'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Y1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PY1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Y2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PY2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( V1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PV1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( QV1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( V2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PV2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( QV2Id, 'SOLID'), vtMove, GDB_RT.GLOB) + +-- Assegno identificativi alle spie delle morse +PY1LightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( Y1Id, 'SOLID') or GDB_ID.NULL, 'Light') +PY2LightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( Y2Id, 'SOLID') or GDB_ID.NULL, 'Light') + +--------------------------------------------------------------------- +-- Funzioni richiamate per modificare i dati macchina in casi particolari +--function OnSetTable() +--end + +--------------------------------------------------------------------- +function OnSetHead() + -- se testa H11 (fresa) + if EMC.HEAD == 'H11' then + if GetTcForTopHeadTool( EMC.TCPOS) ~= 2 then + EmtModifyAxisHome( 'X1', ParkX1) + else + EmtModifyAxisHome( 'X1', ParkTc2X1) + end + EmtModifyAxisHome( 'Z1', ParkZ1) + EmtModifyAxisHome( 'C1', ParkC1) + EmtModifyAxisHome( 'B1', ParkB1) + -- se testa H12 (lama) + elseif EMC.HEAD == 'H12' then + EmtModifyAxisHome( 'X1', ParkX1) + EmtModifyAxisHome( 'Z1', ParkZ1) + EmtModifyAxisHome( 'C1', ParkC1) + EmtModifyAxisHome( 'B1', ParkB1) + -- se testa H13 (sega a catena) + elseif EMC.HEAD == 'H13' then + -- recupero valore asse A bloccato + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + CSawPosA = tonumber( sVal:sub( 3) or '') + EmtModifyAxisHome( 'X1', ParkCSawX1) + EmtModifyAxisHome( 'Z1', GetChainSawZHomeFromVirtualAxis( CSawPosA)) + EmtModifyAxisHome( 'C1', GetChainSawCHomeFromVirtualAxis( CSawPosA)) + EmtModifyAxisHome( 'B1', ParkCSawB1) + end +end + +--------------------------------------------------------------------- +-- Funzione che riconosce TC per utensili testa sopra +function GetTcForTopHeadTool( sTcPos) + if sTcPos == 'T1' or sTcPos == 'T3' or sTcPos == 'T4' or sTcPos == 'T5' or + sTcPos == 'T6' or sTcPos == 'T7' or sTcPos == 'T8' or sTcPos == 'T9' or sTcPos == 'T10' then + return 1 + elseif sTcPos == 'T11' or sTcPos == 'T12' or sTcPos == 'T13' or sTcPos == 'T14' or sTcPos == 'T15' then + return 2 + else + return 0 + end +end + +--------------------------------------------------------------------- +-- Funzione che riconosce testa per sega a catena +function HeadIsChainSaw( sHead) + return ( sHead == 'H13' or sHead == 'H15') +end + +--------------------------------------------------------------------- +-- Funzione che calcola la posizione Home di Z per la sega a catena dal valore dell'asse virtuale +function GetChainSawZHomeFromVirtualAxis( dPosA) + -- se A=0 -> T101 -> HomeZ = -400 + if abs( dPosA) < 0.1 then + return ParkCSaw0Z1 + -- altrimenti A=-90 -> T102 o A=90 -> T104 -> HomeZ = -100 + else + return ParkCSawZ1 + end +end + +--------------------------------------------------------------------- +-- Funzione che calcola l'angolo Home di C per la sega a catena dal valore dell'asse virtuale +--------------------------------------------------------------------- +function GetChainSawCHomeFromVirtualAxis( dPosA) + -- se A=0 -> T101 -> HomeC = 0 + if abs( dPosA) < 0.1 then + return ParkCSaw0C1 + -- altrimenti A=90 -> T104 -> HomeC = -90 + else + return ParkCSawC1 + end +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello Y1 +function SetPY1Light( bClosed) + if not PY1LightId then return end + EgtSetColor( PY1LightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PY1LightId, 'On', '1') + else + EgtRemoveInfo( PY1LightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello Y1 +function GetPY1Light() + if not PY1LightId then return false end + return ( EgtGetInfo( PY1LightId, 'On') == '1') +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello Y2 +function SetPY2Light( bClosed) + if not PY2LightId then return end + EgtSetColor( PY2LightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PY2LightId, 'On', '1') + else + EgtRemoveInfo( PY2LightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello Y2 +function GetPY2Light() + if not PY2LightId then return false end + return ( EgtGetInfo( PY2LightId, 'On') == '1') +end + + +--------------------------------------------------------------------- +-- Funzione per resettare tutte le attivazioni della macchina +function OnResetMachine() + EmtUnlinkAllRawPartsFromGroups() + EmtUnlinkAllFixturesFromGroups() + SetPY1Light( false) + SetPY2Light( false) + -- nascondo Vmill + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nVmId = EgtGetFirstNameInGroup( nRawId, 'VMill') + local nId = EgtGetFirstInGroup( nRawId) + while nId do + EgtSetStatus( nId, EgtIf( nId ~= nVmId, GDB_ST.ON, GDB_ST.OFF)) + nId = EgtGetNext( nId) + end + nRawId = EgtGetNextRawPart( nRawId) + end + EgtSetStatus( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') or GDB_ID.NULL, GDB_ST.OFF) +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.mlpe new file mode 100644 index 0000000..dc04ad5 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.mlpe @@ -0,0 +1,2002 @@ +-- Processore macchina Essetre-PF1250 by EgalTech s.r.l. 2022/01/25 +-- Funzioni generiche indipendenti dal controllo + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +local sBaseDir = EgtGetSourceDir() +if NumericalControl == 'NUM' then + dofile( sBaseDir .. 'Essetre-PF1250.NUM.mlpe') +elseif NumericalControl == 'TPA' then + dofile( sBaseDir .. 'Essetre-PF1250.TPA.mlpe') +else + error( 'Numerical Control error : unkwnown type') +end + +--------------------------------------------------------------------- +-- *** SIMULATION *** +--------------------------------------------------------------------- +local COLL_SAFE_DIST = 4 + +--------------------------------------------------------------------- +function OnSimulStart() + -- controllo versione programma + if not EMT.VER or EMT.VER < '2.3h1' then + EmtSetLastError( 1200, 'A newer version of the program is required (minimum 2.3h1)') + end + ExecStartHome() + -- Carico gli utensili sulle barre portautensili + local vTcPos = EgtGetAllTcPosNames() + if vTcPos then + for i = 1, #vTcPos do + local vTools = EgtGetToolsInCurrSetupPos( vTcPos[i]) + if vTools and vTools[1] and #(vTools[1]) > 0 then + EgtLoadTool( vTcPos[i], 1, vTools[1]) + ShowToolInTcPos( vTcPos[i], true) + end + end + end + -- Se reset o home, esco + if EMT.SIM1ST then return end + -- Creo o svuoto gruppo per copia finale degli oggetti virtual milling + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + if nVmGrpId then + EgtSetStatus( nVmGrpId, GDB_ST.ON) + EgtEmptyGroup( nVmGrpId) + else + nVmGrpId = EgtGroup( GDB_ID.ROOT) + EgtSetName( nVmGrpId, 'VMill') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + -- Preparo lista oggetti da verificare per collisioni + EMT.COLLOBJ = {} + AddToCollisionCheck( 'Z1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'B1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'X2', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C2', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'B2', 'COLLISION', EMT.COLLOBJ) + DumpCollisionCheck( EMT.COLLOBJ, 'Collision Objects :', 4) + -- Preparo lista solidi macchina con cui possono collidere gli oggetti sopra riportati (in aggiunta a VMill) + EMT.MCODET = {} + EMT.MCODET[1] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'V1'), 'COLLISION'), 'STM') + EMT.MCODET[2] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'V2'), 'COLLISION'), 'STM') + EMT.MCODET[3] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'TRAV') + EMT.MCODET[4] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'COL1') + EMT.MCODET[5] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'COL2') + EMT.MCODET[6] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'CHSAW') + EMT.MCODET[7] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Z2'), 'COLLISION'), 'COL1') + EMT.MCODET[8] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Z2'), 'COLLISION'), 'CHAIN') + EMT.MCODET[9] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Z2'), 'COLLISION'), 'COL2') + for i = #EMT.MCODET, 1, -1 do + if not EMT.MCODET[i] then + table.remove( EMT.MCODET, i) + EgtOutLog( 'Warning : MCODET element (' .. tostring( i) .. ') is null') + end + end + -- Preparo lista collisioni vuota + EMT.COLLIDE = {} +end + +--------------------------------------------------------------------- +function OnSimulEnd() + EMT.Y1DELTA = nil + EMT.Y2DELTA = nil + ExecParkRoller() +end + +--------------------------------------------------------------------- +function OnSimulDispositionStarting() + EmtUnlinkAllRawPartsFromGroups() + if EMT.PHASE > 1 then + if IsStartOrRestPhase( EMT.PHASE) then + local ParkT = GetParkT() + EgtSetAxisPos( 'T', ParkT) + end + end +end + +--------------------------------------------------------------------- +function OnSimulDispositionStart() + EMT.OPEISDISP = true + + -- Se prima disposizione + if EMT.PHASE == 1 then + -- Determino sezione del grezzo + local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL + local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + EMT.SB = 0 + EMT.HB = 0 + if b3Sol then + EMT.SB = b3Sol:getDimY() + EMT.HB = b3Sol:getDimZ() + end + -- Carico gli utensili iniziali o di default sulle due teste + LoadFirstTool( 1, DefTcPos1) + LoadFirstTool( 2, DefTcPos2) + -- Se vero inizio e abilitato creo gli Zmap + EMT.VMILL = {} + if not EMT.SIM1ST and EgtGetInfo( EgtGetCurrMachGroup(), 'Vm', 'b') then + local nLastOrd = GetPhaseOrd( EgtGetPhaseCount()) + local nPartRawId = EgtGetFirstRawPart() + while nPartRawId do + -- se è lo scarto finale tagliato a pezzi, esco + local nRawOrd = EgtGetInfo( nPartRawId, 'ORD', 'i') + if nRawOrd == nLastOrd + 1 then break end + -- elimino eventuale vecchio Zmap + EgtErase( EgtGetFirstNameInGroup( nPartRawId, 'VMill') or GDB_ID.NULL) + -- recupero il solido + local nSolId = EgtGetFirstNameInGroup( nPartRawId, 'RawSolid') + local b3Raw = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + -- aggiungo eventuale scrap successivo + if nRawOrd == nLastOrd then + local nScrapId = EgtGetNextRawPart( nPartRawId) + if nScrapId then + local nScrapSolId = EgtGetFirstNameInGroup( nScrapId, 'RawSolid') + local b3ScrapRaw = EgtGetBBoxGlob( nScrapSolId, GDB_BB.STANDARD) + if b3ScrapRaw then + b3Raw:Add( b3ScrapRaw) + end + end + end + -- determino la risoluzione dello Zmap + local dArea = b3Raw:getDimX() * b3Raw:getDimY() + b3Raw:getDimX() * b3Raw:getDimZ() + b3Raw:getDimY() * b3Raw:getDimZ() + local dTol = 4.51 + if dArea < CoeffVM * 0.5e6 then + dTol = 1.01 + elseif dArea < CoeffVM * 1.2e6 then + dTol = 1.51 + elseif dArea < CoeffVM * 2.5e6 then + dTol = 1.97 + elseif dArea < CoeffVM * 5.0e6 then + dTol = 2.81 + elseif dArea < CoeffVM * 10.0e6 then + dTol = 3.77 + end + -- creo lo Zmap + local VMillId = EgtVolZmapBox( nPartRawId, b3Raw:getMin(), b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol, true, GDB_RT.GLOB) + if VMillId then + EgtSetName( VMillId, 'VMill') + EgtSetLevel( VMillId, GDB_LV.TEMP) + EgtSetColor( VMillId, EgtGetColor( nSolId), false) + -- nascondo le altre geometrie + local nId = EgtGetFirstInGroup( nPartRawId) + while nId do + if nId ~= VMillId then + EgtSetStatus( nId, GDB_ST.OFF) + end + nId = EgtGetNext( nId) + end + table.insert( EMT.VMILL, VMillId) + end + nPartRawId = EgtGetNextRawPart( nPartRawId) + end + -- imposto eventuale utensile corrente + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + end + end + + -- Nascondo tutte le lavorazioni + local nMchId = EgtGetFirstOperation() + while nMchId do + if EgtGetOperationType( nMchId) ~= MCH_OY.DISP then + EgtSetOperationStatus( nMchId, false) + end + nMchId = EgtGetNextOperation( nMchId) + end + + -- Se fase inizio o rimanenza, aggancio grezzi della fase alla tavola + if IsStartOrRestPhase( EMT.PHASE) then + -- se fase inizio, segnalo giacitura del grezzo + if IsStartPhase( EMT.PHASE) then + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + local nScrapOrd = GetPhaseOrd( EgtGetPhaseCount()) + 1 + local b3Raw = BBox3d() + local b3Bar = BBox3d() + local b3Part = BBox3d() + local nPartRawId, nScrapRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + local b3Tmp = EgtGetRawPartBBox( nRawId) + b3Bar:Add( b3Tmp) + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + b3Raw:Add( b3Tmp) + b3Part:Add( b3Tmp) + nPartRawId = nRawId + elseif nRawOrd == nOrd + 1 and nRawOrd == nScrapOrd then + b3Raw:Add( b3Tmp) + nScrapRawId = nRawId + end + end + nRawId = nNextRawId + end + -- gestione eventuale scarto affettato successivo + if EMT.VMILL and #EMT.VMILL > 0 then + EMT.SCRAP = nScrapRawId + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + else + EMT.SCRAP = nil + end + EMT.LB = b3Bar:getDimX() + EMT.LT = b3Part:getDimX() + EMT.CUTID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + EMT.Y1SPEC = nil + -- se vero inizio, assegno solidi per verifica collisione + if not EMT.SIM1ST then + EMT.CODET = {} + for i = 1, #EMT.MCODET do + EMT.CODET[i] = EMT.MCODET[i] + end + for i = 1, #( EMT.VMILL or {}) do + table.insert( EMT.CODET, EMT.VMILL[i]) + end + end + -- se altrimenti fase intermedia, aggancio grezzi della fase alla tavola + elseif IsMidPhase( EMT.PHASE) then + -- se cambiata giacitura, lo segnalo + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= nPrevRot then + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- eseguo aggancio + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + end + nRawId = nNextRawId + end + -- se Vmill, nascondo eventuale scrap + if EMT.VMILL and #EMT.VMILL > 0 then + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + end + + -- se altrimenti fasi intermedia o finale speciali, aggancio primo grezzo alla tavola e gli altri in posizione pre-carico + elseif IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se cambiata giacitura, lo segnalo + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= nPrevRot then + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- verifico posizione di carico + local ParkT = GetParkT() + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + -- ricerco vettore movimento per i successivi + local vtMove = Vector3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then + vtMove = Vector3d( - ParkT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + local b3Bar = BBox3d() + nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then + EmtLinkRawPartToGroup( nRawId, 'Tab') + b3Bar = EgtGetRawPartBBox( nRawId) + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EgtSetStatus( nRawId, GDB_ST.OFF) + end + end + nRawId = nNextRawId + end + EMT.LB = b3Bar:getDimX() + + -- altrimenti fase finale, aggancio primo grezzo alla tavola e gli altri in posizione carico al carro Y + else + -- verifico posizione di carico + local ParkT = GetParkT() + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + -- ricerco vettore movimento per i successivi + local vtMove = Vector3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then + vtMove = Vector3d( - ParkT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + local b3Bar = BBox3d() + nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then + EmtLinkRawPartToGroup( nRawId, 'Tab') + b3Bar = EgtGetRawPartBBox( nRawId) + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EmtLinkRawPartToGroup( nRawId, 'Y1') + end + end + nRawId = nNextRawId + end + EMT.LB = b3Bar:getDimX() + end +end + +--------------------------------------------------------------------- +function OnSimulDispositionEnd() + if EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + EMT.TO_FALL = false + end + EMT.SPLIT = false + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnSimulToolSelect( dPosA) + -- se utensile non definito, è disposizione ed esco + if EMT.TOOL == '' then return end + -- recupero dati utensile + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + -- se sega a catena, imposto subito angolo scelto per asse virtuale A + if EMT.HEAD == 'H13' then + -- valore dell'asse virtuale + dPosA = dPosA or GetNextChainSawingVirtualAxis( EMT.MCHID) + -- imposto il valore di A + EgtSetAxisPos( 'A', dPosA) + -- imposto home dell'asse C1 (A=0 -> T101, A=90 -> T104) + local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA) + EmtModifyAxisHome( 'C1', MyParkCSawC1) + EgtSetAxisPos( 'C1', MyParkCSawC1) + -- Imposto visualizzazione + EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD) + end + -- carico utensile, con breve pausa + EgtPause( 100) + EgtOutText( '') + -- lo nascondo sul portautensili + ShowToolInTcPos( EMT.TCPOS, false) + -- dichiaro assi ausiliari da visualizzare + EMT.AuxAxes = 4 + EMT.A1n = 'Y1' + EMT.A2n = 'Y2' + EMT.A3n = 'V1' + EMT.A4n = 'V2' + -- se attivo Vmill + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + -- se attivo Collision Check + EMT.SAFEDIST = COLL_SAFE_DIST + if EMT.COLLOBJ then + local nInd = EgtIf( EMT.HEAD ~= 'H21', 1001, 1011) + AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd) + AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd + 1) + for i, Coll in ipairs( EMT.COLLOBJ or {}) do + EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3) + end + end +end + +--------------------------------------------------------------------- +function OnSimulToolDeselect( dPrevA) + -- se prossimo utensile dummy, non faccio alcunché + if EMT.NEXTHEAD == 'H14' then return end + -- se prossimo utensile non cambia e non è sega a catena, esco + if ( EMT.NEXTTOOL == EMT.PREVTOOL_H1 or EMT.NEXTTOOL == EMT.PREVTOOL_H2) and EMT.NEXTHEAD ~= 'H13' then return end + -- deposito utensile + EgtOutText( 'Tool change in progress...') + -- recupero il gruppo + local nSetHead = GetHeadSet( EMT.NEXTHEAD) + -- per testa gruppo 2 + if nSetHead == 2 then + -- visualizzo utensile su TcPos + ShowToolInTcPos( EMT.PREVTCPOS_H2, true) + -- nascondo l'utensile sulla testa + EgtSetStatus( EgtGetHeadId( EMT.PREVHEAD_H2 or '') or GDB_ID.NULL, GDB_ST.OFF) + return + end + -- per testa gruppo 1... + local RapSimStep = 4 * EMT.SIMSTEP + -- deposito utensile fresa + if EMT.PREVHEAD_H1 == 'H11' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, RapSimStep/10, 'C1', ParkC1, RapSimStep/10) + local dPosX = EgtIf( GetTcForTopHeadTool( EMT.PREVTCPOS_H1) ~= 2, ParkX1, ParkTc2X1) + SimulMoveAxis( 'X1', dPosX, RapSimStep) + -- deposito utensile lama + elseif EMT.PREVHEAD_H1 == 'H12' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, RapSimStep/10, 'C1', ParkC1, RapSimStep/10) + SimulMoveAxis( 'X1', ParkX1, RapSimStep) + -- deposito utensile sega a catena + elseif EMT.PREVHEAD_H1 == 'H13' then + -- simulo movimento + local ParkC1 = EgtGetAxisHomePos( 'C1') + if dPrevA then + ParkC1 = GetChainSawCHomeFromVirtualAxis( dPrevA) + end + SimulMoveAxes( 'B1', ParkCSawB1, RapSimStep/10, 'C1', ParkC1, RapSimStep/10) + SimulMoveAxis( 'X1', ParkCSawX1, RapSimStep) + end + -- breve pausa + EgtPause( 100) + -- visualizzo utensile su TcPos + ShowToolInTcPos( EMT.PREVTCPOS_H1, true) + -- nascondo l'utensile sulla testa + EgtSetMode( EgtGetHeadId( EMT.PREVHEAD_H1 or '') or GDB_ID.NULL, GDB_MD.HIDDEN) + -- prendo utensile fresa + if EMT.NEXTHEAD == 'H11' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, RapSimStep/10, 'C1', ParkC1, RapSimStep/10) + local dPosX = EgtIf( GetTcForTopHeadTool( EMT.NEXTTCPOS) ~= 2, ParkX1, ParkTc2X1) + SimulMoveAxis( 'X1', dPosX, RapSimStep) + SimulMoveAxis( 'Z1', 0, RapSimStep) + -- prendo utensile lama + elseif EMT.NEXTHEAD == 'H12' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, RapSimStep/10, 'C1', ParkC1, RapSimStep/10) + SimulMoveAxis( 'X1', ParkX1, RapSimStep) + -- prendo utensile sega a catena + elseif EMT.NEXTHEAD == 'H13' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkCSawB1, RapSimStep/10, 'C1', EgtGetAxisHomePos( 'C1'), RapSimStep/10) + SimulMoveAxis( 'X1', ParkCSawX1, RapSimStep) + end +end + +--------------------------------------------------------------------- +function OnSimulMachiningStart() + -- se lavorazione attuale e precedente con sega a catena con angolo A diverso, devo scaricare e ricaricare + if EMT.HEAD == 'H13' and EMT.HEAD == EMT.PREVHEAD_H1 then + local dPrevA = EgtGetAxisPos( 'A') + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + local dPosA = tonumber( sVal:sub( 3)) + if abs( dPosA - dPrevA) > 1 then + OnSimulToolDeselect( dPrevA) + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON) + OnSimulToolSelect( dPosA) + end + end + -- salvo dati utensile + local nSetHead = GetHeadSet( EMT.HEAD) + -- per gruppo testa 1 + if nSetHead == 1 then + EMT.PREVTOOL_H1 = EMT.TOOL + EMT.PREVHEAD_H1 = EMT.HEAD + EMT.PREVTCPOS_H1 = EMT.TCPOS + -- per gruppo testa 2 + elseif nSetHead == 2 then + EMT.PREVTOOL_H2 = EMT.TOOL + EMT.PREVHEAD_H2 = EMT.HEAD + EMT.PREVTCPOS_H2 = EMT.TCPOS + end + -- recupero alcuni dati della lavorazione + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + EMT.VMRS = ( EMT.MCHTYPE ~= MCH_MY.DRILLING and not ( sNotes and sNotes:find( 'VMRS=0;', 1, true))) + EMT.MCHSPLIT = ( sNotes and sNotes:find( 'Split;', 1, true)) + -- recupero TASKID e CUTID della feature lavorata (CUTID va recuperato qui per le pareti) + local vId = EgtGetMachiningGeometry() + if vId and #vId > 0 and #vId[1] > 0 then + local nPartId = EgtGetParent( EgtGetParent( vId[1][1]) or GDB_ID.NULL) + EMT.CUTID = EgtGetInfo( nPartId or GDB_ID.NULL, 'CUTID', 'i') or 0 + EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ; + else + EMT.CUTID = 0 + EMT.TASKID = 0 + end + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true +end + +--------------------------------------------------------------------- +function OnSimulMachiningEnd() + if EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + EMT.TO_FALL = false + end + EMT.MCHSPLIT = nil + EMT.SPLIT = nil +end + +--------------------------------------------------------------------- +function OnSimulPathStart() + -- se taglio di separazione, verifico se ci sarà caduta + if EMT.MCHSPLIT then + local sCmd = EgtGetInfo( EMT.PATHID, 'AE1') or '' + if sCmd:find( 'Fall', 1, true) then + EMT.TO_FALL = true + end + end +end + +--------------------------------------------------------------------- +function OnSimulPathEnd() + -- rimozione sfridi + RemoveScraps() + -- se non ci sono comandi ausiliari associati e richiesta risalita a Zmax + if EMT.AUXTOT == 0 and EMT.TO_ZMAX then + if EMT.MCHSPLIT and not EMT.TO_FALL then + EMT.SPLIT_Y1DELTA = EMT.Y1DELTA + EMT.Y1DELTA = nil + SetPY1Light( false) + end + ExecMoveZmax( EMT.MCHSPLIT) + EMT.TO_ZMAX = nil + end +end + +--------------------------------------------------------------------- +function OnSimulPathStartAux() + -- eseguo il comando + ExecAuxCmd( EMT.AUX) + -- se ultimo comando e lavorazione di split, sgancio il carro Y1 + if EMT.AUXIND == EMT.AUXTOT and EMT.MCHSPLIT and not EMT.TO_FALL then + EMT.SPLIT_Y1DELTA = EMT.Y1DELTA + EMT.Y1DELTA = nil + SetPY1Light( false) + end +end + +--------------------------------------------------------------------- +function OnSimulPathEndAux() + -- eseguo il comando + ExecAuxCmd( EMT.AUX) + -- se ultimo comando e richiesta risalita a Zmax + if EMT.AUXIND == EMT.AUXTOT and EMT.TO_ZMAX then + ExecMoveZmax( EMT.MCHSPLIT) + EMT.TO_ZMAX = nil + end +end + +--------------------------------------------------------------------- +function OnSimulMoveStart() + if EMT.MCHFIRST then EgtOutText( '') end + -- step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + local RapSimRotStep = RapSimStep / 10 + local CollSimRotStep = min( RapSimRotStep, 10) + -- set della testa + local nSetHead = GetHeadSet( EMT.HEAD) + -- Posizioni correnti + local Y1Pos = EgtGetAxisPos( 'Y1') + local Y2Pos = EgtGetAxisPos( 'Y2') + local V1Pos = EgtGetAxisPos( 'V1') + local V2Pos = EgtGetAxisPos( 'V2') + -- Imposto movimento pinze e rulli insieme con la tavola : + EMT.AuxAxes = 4 + -- pinze + EMT.A1n = 'Y1' + if EMT.Y1DELTA then + EMT.A1m = 'T' + EMT.A1 = EMT.L1 + EMT.Y1DELTA + else + EMT.A1m = nil + EMT.A1 = EgtIf( EMT.Y1SPEC, EgtGetAxisPos( 'Y1'), ParkY1) + end + EMT.A2n = 'Y2' + if EMT.Y2DELTA then + EMT.A2m = 'T' + EMT.A2 = EMT.L1 + EMT.Y2DELTA + else + EMT.A2m = nil + EMT.A2 = ParkY2 + end + -- Controllo scorrimento pinze chiuse Y1 e Y2 + if EMT.Y1DELTA then + local dY1DeltaP = Y1Pos - EMT.L1p + if abs( EMT.Y1DELTA - dY1DeltaP) > 0.1 then + EMT.ERR = 2 + local sErr = 'Y1 slide : ' .. EmtLenToString( dY1DeltaP, 3) .. ' -> ' .. EmtLenToString( EMT.Y1DELTA, 3) + EmtSetLastError( 1202, sErr) + end + end + if EMT.Y2DELTA then + local dY2DeltaP = Y2Pos - EMT.L1p + if abs( EMT.Y2DELTA - dY2DeltaP) > 0.1 then + EMT.ERR = 2 + local sErr = 'Y2 slide : ' .. EgtNumToString( dY2DeltaP, 3) .. ' -> ' .. EgtNumToString( EMT.Y2DELTA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- rulli + EMT.A3n = 'V1' + EMT.A3 = EgtIf( GetV1ToClose(), EMT.V1NEXTPOS, ParkV1) + EMT.A4n = 'V2' + EMT.A4 = EgtIf( GetV2ToClose(), EMT.V2NEXTPOS, ParkV2) + local bParkV = false + if EMT.MCHFIRST then + -- se rulli più chiusi del richiesto o cambio direzione utensile (tranne solo asse B con C0 o equivalenti) devo mettere i rulli in parcheggio + if V1Pos < EMT.V1NEXTPOS - 1 or V2Pos > EMT.V2NEXTPOS + 1 or RollerParkingNeeded( EMT.HEAD, EMT.R1p, EMT.R2p, EMT.R1, EMT.R2) then + bParkV = true + EMT.A3 = ParkV1 + EMT.A4 = ParkV2 + end + end + -- Controllo corse assi ausiliari + VerifyY1Stroke( EMT.A1) + VerifyY2Stroke( EMT.A2) + VerifyV1Stroke( EMT.A3) + VerifyV2Stroke( EMT.A4) + -- se devo subito parcheggiare i rulli + local nRes = 0 + if bParkV then + nRes = ExecParkRoller( Y1Pos, Y2Pos, V1Pos, V2Pos, false, true) + end + -- se movimento in rapido + if EMT.MOVE == 0 then + -- se testa 1 + if nSetHead == 1 then + -- Dati + local B1Pos = EgtGetAxisPos( 'B1') + local Z1Pos = EgtGetAxisPos( 'Z1') + local Z1Home = EgtGetAxisHomePos( 'Z1') + -- se movimento iniziale da Zmax con lama o fresa + if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + SimulMoveAxis( 'X1', EMT.L2, RapSimStep) + local Z_EXTRA = EgtIf( EMT.HEAD == 'H11', 250, 160) + local dZref + if EMT.R2 > -60 then + dZref = Z1Home + Z_EXTRA + SimulMoveAxes( 'Z1', dZref, RapSimStep, 'B1', min( EMT.R2, 60), CollSimRotStep) + if EMT.R2 > 60 then + dZref = Z1Home + Z_EXTRA * ( 90 - abs( EMT.R2)) / 30 + SimulMoveAxes( 'Z1', dZref, RapSimStep, 'B1', min( EMT.R2, 90), CollSimRotStep) + end + else + dZref = Z1Home + Z_EXTRA * ( 90 - abs( EMT.R2)) / 30 + SimulMoveAxes( 'Z1', dZref, RapSimStep, 'B1', EMT.R2, CollSimRotStep) + end + if dZref and EMT.L3 < dZref + 0.1 then + SimulMoveAxis( 'C1', EMT.R1, CollSimRotStep) + end + -- altrimenti sega a catena + else + local bXSpec = ( EMT.L2 > DeltaTabY) + SimulMoveAxis( 'X1', EgtIf( bXSpec, DeltaTabY, EMT.L2), RapSimStep) + SimulMoveAxis( 'Z1', Z1Home, RapSimStep) + if bXSpec then + SimulMoveAxes( 'C1', EMT.R1, CollSimRotStep, 'B1', EMT.R2, CollSimRotStep) + end + end + end + -- altrimenti testa 2 + else + -- Porto la X alla giusta quota + local X2Pos = EgtGetAxisPos( 'X2') + local X2Home = EgtGetAxisHomePos( 'X2') + if X2Pos > X2Home - 1 then + SimulMoveAxis( 'X2', EMT.L2, RapSimStep) + end + end + end + EMT.ZMAX = nil + -- se lavorazione split, muovo per riaggancio del carro Y1 + if EMT.SPLIT_Y1DELTA then + EMT.Y1DELTA = EMT.SPLIT_Y1DELTA + EMT.A1 = EMT.L1 + EMT.Y1DELTA + end + -- se Zmax dopo fine lavorazione + if EMT.MOVE == 0 and EMT.FLAG == 3 then + -- demando movimento completo a MoveEnd + EMT.EnabAxes = false + EMT.ShowAxes = true + end + -- se necessario ... + if EMT.MCHFIRST then + if nSetHead == 1 then + SimulMoveAxes( 'X1', EMT.L2, RapSimStep, + 'Z1', EMT.L3, RapSimStep, + 'C1', EMT.R1, RapSimRotStep, + 'B1', EMT.R2, RapSimRotStep) + else + SimulMoveAxes( 'X2', EMT.L2, RapSimStep, + 'Z2', EMT.L3, RapSimStep, + 'C2', EMT.R1, RapSimRotStep, + 'B2', EMT.R2, RapSimRotStep) + end + end + if nRes ~= 0 then + EMT.A3 = EgtIf( GetV1ToClose(), EMT.V1NEXTPOS, ParkV1) + EMT.A4 = EgtIf( GetV2ToClose(), EMT.V2NEXTPOS, ParkV2) + end +end + +--------------------------------------------------------------------- +function OnSimulMoveEnd() + -- se primo rapido della lavorazione + if EMT.MCHFIRST and EMT.MOVE == 0 then + -- se lavorazione split, dichiaro carro Y1 riagganciato + if EMT.SPLIT_Y1DELTA then + EMT.SPLIT_Y1DELTA = nil + SetPY1Light( true) + end + -- chiusura o apertura rulli V1 + if GetV1ToClose() then + ExecCloseRoller( 1) + else + ExecOpenRoller( 1) + end + -- chiusura o apertura rulli V2 + if GetV2ToClose() then + ExecCloseRoller( 2) + else + ExecOpenRoller( 2) + end + EMT.MCHFIRST = false + EgtOutText( '') + end + -- se Zmax dopo fine lavorazione + if EMT.MOVE == 0 and EMT.FLAG == 3 then + -- eventuale rimozione sfridi + RemoveScraps() + -- eseguo + ExecMoveZmax( EMT.MCHSPLIT) + EMT.TO_ZMAX = nil + end +end + +--------------------------------------------------------------------- +function OnSimulCollision() + -- se prima collisione della lavorazione, la segnalo + if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then + local Class = '' + if EMT.SIMCOBIND == 1001 or EMT.SIMCOBIND == 1011 then + Class = 'T_'..EMT.HEAD + elseif EMT.SIMCOBIND == 1002 or EMT.SIMCOBIND == 1012 then + Class = 'TH_'..EMT.HEAD + else + Class = EMT.COLLOBJ[EMT.SIMCOBIND].Cl + end + table.insert( EMT.COLLIDE, { Mc = EMT.MCHNAME, Cl = Class, Vm = EMT.SIMVMID}) + EMT.LAST_MCHNAME_COLLIDE = EMT.MCHNAME + EMT.ERR = 11 + local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Class='..Class..'; VMill='..EMT.SIMVMID + EmtSetLastError( 1221, sErr, true) + EgtOutLog( 'Collision : ' .. sErr, 1) + end +end + +--------------------------------------------------------------------- +function ExecAuxCmd( sCmd) + -- step di simulazione per rapido + local RapSimStep = 4 * EMT.SIMSTEP + -- analizzo il comando + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + if Cmd[2] == 'Unloading' then + EMT.UNLOADING = true + elseif Cmd[2] == 'Split' then + EMT.SPLIT = true + elseif Cmd[2] == 'Fall' then + EMT.FALL = true + end + EgtOutText( Cmd[2]) + elseif Cmd[1] == '1' then + if EMT.SPLIT then ExecOpenRoller( 1) end + if EMT.UNLOADING or EMT.TO_FALL then ExecOpenRoller( 2) end + local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd) + local bOk, bOk1, bOk2, bOk3 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), RapSimStep, + sV1, MoveV1, RapSimStep, + sV2, MoveV2, RapSimStep) + if not bOk then + if not bOk1 then + if VerifyY1Y2Stroke( Cmd[2], tonumber( Cmd[3])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + elseif not bOk2 then + VerifyV1V2Stroke( sV1, MoveV1) + elseif not bOk3 then + VerifyV1V2Stroke( sV2, MoveV2) + end + end + elseif Cmd[1] == '2' then + -- Verifico movimento carrello con trave agganciata + VerifyOneChariotSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5]) + -- Eseguo i movimenti necessari + if EMT.SPLIT then ExecOpenRoller( 1) end + if EMT.UNLOADING or EMT.TO_FALL then ExecOpenRoller( 2) end + local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd) + local bOk, bOk1, bOk2, bOk3, bOk4 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), RapSimStep, + Cmd[4], tonumber( Cmd[5]), RapSimStep, + sV1, MoveV1, RapSimStep, + sV2, MoveV2, RapSimStep) + if not bOk then + if not bOk1 or not bOk2 then + local nI = EgtIf( not bOk1, 2, 4) + if VerifyY1Y2Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + elseif not bOk3 then + VerifyV1V2Stroke( sV1, MoveV1) + elseif not bOk4 then + VerifyV1V2Stroke( sV2, MoveV2) + end + end + elseif Cmd[1] == '3' then + -- Verifico movimento carrelli con trave agganciata + VerifyTwoChariotsSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5], Cmd[6], Cmd[7]) + -- Eseguo i movimenti necessari + if EMT.SPLIT then ExecOpenRoller( 1) end + if EMT.UNLOADING or EMT.TO_FALL then ExecOpenRoller( 2) end + local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd) + local bOk, bOk1, bOk2, bOk3, bOk4, bOk5 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), RapSimStep, + Cmd[4], tonumber( Cmd[5]), RapSimStep, + Cmd[6], tonumber( Cmd[7]), RapSimStep, + sV1, MoveV1, RapSimStep, + sV2, MoveV2, RapSimStep) + if not bOk then + if not bOk1 or not bOk2 or not bOk3 then + local nI = EgtIf( not bOk1, 2, EgtIf( not bOk2, 4, 6)) + if VerifyY1Y2Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + elseif not bOk4 then + VerifyV1V2Stroke( sV1, MoveV1) + elseif not bOk5 then + VerifyV1V2Stroke( sV2, MoveV2) + end + end + elseif Cmd[1] == '4' then + ExecMoveHome( Cmd[2] == '1') + elseif Cmd[1] == '11' then + SimulMoveAxes( 'PY1', EgtIf( Cmd[2] == '0', MaxHoOpen, EMT.SB), RapSimStep) + SetPY1Light( Cmd[2] ~= '0') + elseif Cmd[1] == '12' then + SimulMoveAxes( 'PY2', EgtIf( Cmd[2] == '0', MaxHoOpen, EMT.SB), RapSimStep) + SetPY2Light( Cmd[2] ~= '0') + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + EMT.Y1DELTA = EgtIf( nY1Delta > 0.01, nY1Delta, nil) + EMT.Y2DELTA = EgtIf( nY2Delta > 0.01, nY2Delta, nil) + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + elseif Cmd[1] == '31' then + local nRawId = tonumber( Cmd[2]) + EmtUnlinkRawPartFromGroup( nRawId) + EmtLinkRawPartToGroup( nRawId, Cmd[3]) + EMT.Y1SPEC = true + elseif Cmd[1] == '99' then + EMT.ERR = Cmd[2] + EmtSetLastError( 1200 + EMT.ERR, Cmd[3]) + end +end + +--------------------------------------------------------------------- +function CalcMoveV1V2ForAuxCmd( Cmd) + -- verifico se necessario muovere V1 + local MoveV1 + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local V1Pos = EgtGetAxisPos( 'V1') + if MoveY1 and V1Pos > MoveY1 - MinDeltaYV + 0.1 then + MoveV1 = MoveY1 - MinDeltaYV + end + local sV1 = EgtIf( MoveV1, 'V1', nil) + -- verifico se necessario muovere V2 + local MoveV2 + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + local V2Pos = EgtGetAxisPos( 'V2') + if MoveY2 and V2Pos < MoveY2 + MinDeltaYV - 0.1 then + MoveV2 = MoveY2 + MinDeltaYV + end + local sV2 = EgtIf( MoveV2, 'V2', nil) + -- restituisco i risultati + if MoveV1 and MoveV2 then + return sV1, MoveV1, sV2, MoveV2 + elseif MoveV1 then + return sV1, MoveV1 + elseif MoveV2 then + return sV2, MoveV2 + end +end + +--------------------------------------------------------------------- +function ExecStartHome() + -- posizioni di home + local HomeX = EgtGetAxisHomePos( 'X1') + local HomeC = EgtGetAxisHomePos( 'C1') + local HomeB = EgtGetAxisHomePos( 'B1') + local MaxZ = 0 + -- posizionamento istantaneo + EgtSetAxisPos( 'X1', HomeX) + EgtSetAxisPos( 'C1', HomeC) + EgtSetAxisPos( 'B1', HomeB) + EgtSetAxisPos( 'Z1', MaxZ) +end + +--------------------------------------------------------------------- +function ExecMoveHome( bNearV) + -- risalita a Zmax + ExecMoveZmax( false) + -- step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + -- se testa sotto + if GetHeadSet( EMT.HEAD) == 2 then + if not SimulMoveAxis( 'X2', ParkX2, RapSimStep) then + EgtOutLog( 'Error on MoveHome : X2') + end + end + -- se richiesto, avvicino i rulli + if bNearV then + ExecOpenRoller( 1) + ExecOpenRoller( 2) + if not SimulMoveAxes( 'V1', MinV1, RapSimStep, + 'V2', MaxV2, RapSimStep) then + EgtOutLog( 'Error on MoveHome : NearV1V2') + end + end +end + +--------------------------------------------------------------------- +function ExecMoveZmax( bMchSplit) + -- step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + local RapSimRotStep = RapSimStep / 10 + local CollSimRotStep = min( RapSimRotStep, 10) + -- set della testa + local nSetHead = GetHeadSet( EMT.HEAD) + -- posizioni correnti degli assi testa + local CurrX = EgtGetAxisPos( EgtIf( nSetHead == 1, 'X1', 'X2')) + local CurrZ = EgtGetAxisPos( EgtIf( nSetHead == 1, 'Z1', 'Z2')) + local CurrC = EgtGetAxisPos( EgtIf( nSetHead == 1, 'C1', 'C2')) + local CurrB = EgtGetAxisPos( EgtIf( nSetHead == 1, 'B1', 'B2')) + -- posizioni home degli assi testa + local HomeZ = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'Z1', 'Z2')) + local HomeC = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'C1', 'C2')) + local HomeB = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'B1', 'B2')) + -- verifico se necessario ruotare la testa + local bRot = ( abs( HomeC - CurrC) > 1 or abs( HomeB - CurrB) > 1) + -- se necessario ruotare la testa, allargo i carrelli + if RollerParkingNeeded( EMT.HEAD, CurrC, CurrB, HomeC, HomeB) then + ExecOpenRoller( 1) + ExecOpenRoller( 2) + ExecParkRoller( nil, nil, nil, nil, bMchSplit, true) + end + -- se testa sopra + if nSetHead == 1 then + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + if abs( HomeC - CurrC) > 0.1 or abs( HomeB - CurrB) > 0.1 then + local Z_EXTRA = EgtIf( EMT.HEAD == 'H11', 250, 160) + if abs( CurrB) < 60 then + local dZref = HomeZ + Z_EXTRA + SimulMoveAxis( 'Z1', dZref, RapSimStep) + elseif abs( CurrB) < 90 then + local dZref = HomeZ + Z_EXTRA * ( 90 - abs( CurrB)) / 30 + SimulMoveAxis( 'Z1', dZref, RapSimStep) + end + local ANG_LIM_DOWN = EgtIf( EMT.HEAD == 'H11', 0, -45) + local ANG_LIM_OPPO = 90 + if CurrB > ANG_LIM_DOWN then + if CurrB > ANG_LIM_OPPO then + SimulMoveAxes( 'Z1', HomeZ, RapSimStep, 'B1', ANG_LIM_OPPO, CollSimRotStep) + end + if CurrB > 60 then + SimulMoveAxes( 'Z1', HomeZ + Z_EXTRA, RapSimStep, 'B1', 60, CollSimRotStep) + end + SimulMoveAxes( 'Z1', HomeZ + Z_EXTRA, RapSimStep, 'B1', ANG_LIM_DOWN, CollSimRotStep) + end + SimulMoveAxes( 'Z1', HomeZ, RapSimStep, 'B1', HomeB, CollSimRotStep) + SimulMoveAxis( 'C1', HomeC, CollSimRotStep) + end + SimulMoveAxis( 'Z1', MaxZ1, RapSimStep) + -- altrimenti sega a catena + else + SimulMoveAxes( 'Z1', HomeZ, RapSimStep, 'B1', HomeB, CollSimRotStep) + if CurrX > DeltaTabY then + SimulMoveAxis( 'X1', DeltaTabY, RapSimStep) + end + SimulMoveAxis( 'C1', HomeC, CollSimRotStep) + SimulMoveAxis( 'Z1', MaxZ1, RapSimStep) + end + -- altrimenti testa sotto + else + SimulMoveAxes( 'Z2', MinZ2, RapSimStep) + SimulMoveAxes( 'B2', ParkB2, CollSimRotStep, 'C2', ParkC2, CollSimRotStep) + SimulMoveAxis( 'X2', ParkX2, RapSimStep) + end + EMT.ZMAX = true +end + +--------------------------------------------------------------------- +function ExecUnloading() + if EMT.VMILL and #EMT.VMILL > 0 then + local vMillId = EMT.VMILL[1] + -- gruppo dei Vmill + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + -- li sposto per lasciare spazio al nuovo pezzo + local nId = EgtGetFirstInGroup( nVmGrpId) + while nId do + EgtMove( nId, Vector3d( 0, -( EMT.SB + 50.0), 0), GDB_RT.GLOB) + nId = EgtGetNext( nId) + end + -- creo un nuovo layer e vi inserisco il nuovo pezzo + local nLayId = EgtGroup( nVmGrpId, EgtGetGlobFrame( vMillId)) + EgtRelocate( vMillId, nLayId) + local vtMove = Vector3d( 0, -1600, 0) + if EMT.FALL then vtMove = Vector3d( 0, -2600, -1150) end + EgtMove( nLayId, vtMove, GDB_RT.GLOB) + EgtSetLevel( vMillId, GDB_LV.USER) + -- aggiungo gli spigoli + local nFirstId, nCount = EgtVolZmapGetEdges( vMillId, nLayId) + if nFirstId then + for nId = nFirstId, nFirstId + nCount - 1 do + EgtSetColor( nId, Color3d( 96, 96, 96)) + end + end + -- rilascio Vmill + table.remove( EMT.VMILL, 1) + -- aggiorno la visualizzazione + EgtDraw() + -- se finito + if EMT.PHASE == EgtGetPhaseCount() then + -- se impostato di salvare i Vmill, lo faccio + local sMachIni = EgtGetCurrMachineDir() .. '\\' .. EgtGetCurrMachineName() .. '.ini' + if EgtGetStringFromIni( 'VMill', 'Save', '', sMachIni) == '1' then + local sFile = EgtGetCurrFilePath() + if sFile then + local sDir, sName, sExt = EgtSplitPath( sFile) + sName = sName .. '_VM_' .. EgtGetMachGroupName( EgtGetCurrMachGroup()) + EgtSetLevel( nVmGrpId, GDB_LV.USER) + EgtSaveObjToFile( nVmGrpId, sDir .. sName .. '.Nge') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + end + end + end +end + +--------------------------------------------------------------------- +function ExecParkRoller( PosY1, PosY2, PosV1, PosV2, bSpliCut, bAgg) + -- step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + -- Posizioni + local PosT = EgtGetAxisPos( 'T') + PosY1 = PosY1 or EgtGetAxisPos( 'Y1') + PosY2 = PosY2 or EgtGetAxisPos( 'Y2') + PosV1 = PosV1 or EgtGetAxisPos( 'V1') + PosV2 = PosV2 or EgtGetAxisPos( 'V2') + -- Parcheggi pinze + local MyParkY1 = ParkY1 + EgtIf( bAgg, AggLoad, 0) + local MyParkY2 = ParkY2 + -- Eseguo spostamenti + if EMT.Y1DELTA and EMT.Y2DELTA then + local DiffY1 = MyParkY1 - PosY1 + local DiffY2 = MyParkY2 - PosY2 + -- se appena eseguito taglio di separazione + if bSpliCut then + -- aggancio i pezzi rimanenti all'asse Y1 + local nCurrOrd = GetPhaseOrd( EMT.PHASE) + local TabId = EgtGetTableId( 'Tab') + local RawId = EgtGetFirstInGroup( TabId) + while RawId do + local NextRawId = EgtGetNext( RawId) + if EgtGetName( RawId) == 'RawPart' then + local nRawOrd = EgtGetInfo( RawId, 'ORD', 'i') + if nRawOrd and nRawOrd ~= nCurrOrd then + local bUlOk = EmtUnlinkRawPartFromGroup( RawId) + local bLkOk = EmtLinkRawPartToGroup( RawId, 'Y1') + end + end + RawId = NextRawId + end + -- eseguo i movimenti + if not SimulMoveAxes( 'T', PosT + min( DiffY2, 0.0), RapSimStep, + 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', PosY1 + max( DiffY1, 0.0), RapSimStep, + 'Y2', PosY2 + min( DiffY2, 0.0), RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1202, 'Error on MoveAxes in ParkRoller (12A)') + end + return 32 + elseif DiffY1 > 0.1 and DiffY2 < -0.1 then + EMT.ERR = 2 + EmtSetLastError( 1201, 'Error Collision in ParkRoller') + elseif DiffY1 > 0.1 then + if not SimulMoveAxes( 'T', PosT + DiffY1, RapSimStep, + 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', PosY1 + DiffY1, RapSimStep, + 'Y2', PosY2 + DiffY1, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1202, 'Error on MoveAxes in ParkRoller (12B)') + end + return 12 + elseif DiffY2 < -0.1 then + if not SimulMoveAxes( 'T', PosT + DiffY2, RapSimStep, + 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', PosY1 + DiffY2, RapSimStep, + 'Y2', PosY2 + DiffY2, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1203, 'Error on MoveAxes in ParkRoller (12C)') + end + return 21 + else + if not SimulMoveAxes( 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1204, 'Error on MoveAxes in MoveStart') + end + return 30 + end + elseif EMT.Y1DELTA then + local MoveV1 = ParkV1 - PosV1 + local DiffY1 = MyParkY1 - PosY1 + local MoveY1 = EgtIf( DiffY1 > 0.1, MoveV1, 0) + local TryMoveY1 = ParkV1 - PosT - EgtIf( bSpliCut or EMT.FALL, EMT.LT, 0) + if ( PosT > ParkV2 - ExtraParkV and PosT < ParkV1 and PosY1 + TryMoveY1 < MaxY1) then MoveY1 = max( MoveY1, TryMoveY1) end + if not SimulMoveAxes( 'T', PosT + MoveY1, RapSimStep, + 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', PosY1 + MoveY1, RapSimStep, + 'Y2', MyParkY2, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1205, 'Error on MoveAxes in ParkRoller (1)') + end + return 11 + elseif EMT.Y2DELTA then + local MoveV2 = ParkV2 - PosV2 + local DiffY2 = MyParkY2 - PosY2 + local MoveY2 = EgtIf( DiffY2 < -0.1, MoveV2, 0) + local TryMoveY2 = ParkV2 - PosT - EMT.LT + if ( PosT + EMT.LT < ParkV1 + ExtraParkV and PosT + EMT.LT > ParkV2 and PosY2 + TryMoveY2 > MinY2) then MoveY2 = min( MoveY2, TryMoveY2) end + if not SimulMoveAxes( 'T', PosT + MoveY2, RapSimStep, + 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', EgtIf( PosY1 > MyParkY1, PosY1, MyParkY1), RapSimStep, + 'Y2', PosY2 + MoveY2, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1206, 'Error on MoveAxes in ParkRoller (2)') + end + return 22 + else + if not SimulMoveAxes( 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', MyParkY1, RapSimStep, + 'Y2', MyParkY2, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1207, 'Error on MoveAxes in ParkRoller (0)') + end + return 0 + end +end + +--------------------------------------------------------------------- +function ExecCloseRoller( nInd) + EgtSetAxisPos( EgtIf( nInd == 1, 'PV1', 'PV2'), EMT.SB) + EgtSetAxisPos( EgtIf( nInd == 1, 'QV1', 'QV2'), EMT.HB) +end + +--------------------------------------------------------------------- +function ExecOpenRoller( nInd) + EgtSetAxisPos( EgtIf( nInd == 1, 'PV1', 'PV2'), MaxHoOpen) + EgtSetAxisPos( EgtIf( nInd == 1, 'QV1', 'QV2'), MaxVeOpen) +end + +--------------------------------------------------------------------- +function RemoveScraps() + -- se attivo VMILL, lavorazione ed è richiesto di eliminare gli sfridi + if EMT.VMILL and #EMT.VMILL > 0 and not EMT.OPEISDISP and EMT.VMRS then + local vMillId = EMT.VMILL[1] + local nPart = EgtVolZmapPartCount( vMillId) + if nPart > 1 then + -- ricerca del pezzo con massimo volume + local nPartMax = 0 + local dVolMax = 0 + for i = 1, nPart do + local dVol = EgtVolZmapPartVolume( vMillId, i - 1) + if dVol > dVolMax then + dVolMax = dVol + nPartMax = i + end + end + -- eliminazione di tutti i pezzi piccoli + for i = nPart, 1, -1 do + if i ~= nPartMax then + EgtRemoveVolZmapPart( vMillId, i - 1) + end + end + -- aggiorno visualizzazione + EgtDraw() + end + EMT.VMRS = false + end + +end + +--------------------------------------------------------------------- +function VerifyY1Slide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello Y1 + if sName1 == 'T' and sName2 == 'Y1' and GetPY1Light() then + local dY1DeltaP = EgtGetAxisPos( 'Y1') - EgtGetAxisPos( 'T') + local dY1DeltaA = tonumber( dVal2) - tonumber( dVal1) + EgtOutLog( string.format( 'Y1DeltaP=%.3f YDeltaA=%.3f', dY1DeltaP, dY1DeltaA), 5) + if abs( dY1DeltaA - dY1DeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'Y1 slide : ' .. EmtLenToString( dY1DeltaP, 3) .. ' -> ' .. EmtLenToString( dY1DeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Tutto bene + return true +end + +--------------------------------------------------------------------- +function VerifyY2Slide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello Y2 + if sName1 == 'T' and sName2 == 'Y2' and GetPY2Light() then + local dY2DeltaP = EgtGetAxisPos( 'Y2') - EgtGetAxisPos( 'T') + local dY2DeltaA = tonumber( dVal2) - tonumber( dVal1) + EgtOutLog( string.format( 'Y2VDeltaP=%.3f Y2DeltaA=%.3f', dY2DeltaP, dY2DeltaA), 5) + if abs( dY2DeltaA - dY2DeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'Y2 slide : ' .. EmtLenToString( dY2DeltaP, 3) .. ' -> ' .. EmtLenToString( dY2DeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Tutto bene + return true +end + +--------------------------------------------------------------------- +function VerifyOneChariotSlide( sName1, dVal1, sName2, dVal2) + -- Metto in prima posizione la trave + if sName2 == 'T' then + sName1, sName2 = sName2, sName1 + dVal1, dVal2 = dVal2, dVal1 + end + -- Eseguo verifica + if sName2 == 'Y1' then + return VerifyY1Slide( sName1, dVal1, sName2, dVal2) + elseif sName2 == 'Y2' then + return VerifyY2Slide( sName1, dVal1, sName2, dVal2) + end + return true +end + +--------------------------------------------------------------------- +function VerifyTwoChariotsSlide( sName1, dVal1, sName2, dVal2, sName3, dVal3) + -- Metto in prima posizione la trave + if sName2 == 'T' then + sName1, sName2 = sName2, sName1 + dVal1, dVal2 = dVal2, dVal1 + elseif sName3 == 'T' then + sName1, sName3 = sName3, sName1 + dVal1, dVal3 = dVal3, dVal1 + end + -- Eseguo verifica + if sName2 == 'Y1' then + return VerifyY1Slide( sName1, dVal1, sName2, dVal2) and VerifyY2Slide( sName1, dVal1, sName3, dVal3) + elseif sName2 == 'Y2' then + return VerifyY2Slide( sName1, dVal1, sName2, dVal2) and VerifyY1Slide( sName1, dVal1, sName3, dVal3) + end + return true +end + +--------------------------------------------------------------------- +function VerifyY1Stroke( dY1) + if dY1 < MinY1 then + EmtSetOutstrokeInfo( 'Y1', 'Y1', true, dY1 - MinY1, ' (L1-)') + EMT.ERR = 1 + local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY1 - MinY1, 3) + EgtOutLog( sErr) + return false + elseif dY1 > MaxY1 then + EmtSetOutstrokeInfo( 'Y1', 'Y1', true, dY1 - MaxY1, ' (L1+)') + EMT.ERR = 1 + local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY1 - MaxY1, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyY2Stroke( dY2) + if dY2 < MinY2 then + EmtSetOutstrokeInfo( 'Y2', 'Y2', true, dY2 - MinY2, ' (L1-)') + EMT.ERR = 1 + local sErr = 'Y2 axis outstroke ' .. EgtNumToString( dY2 - MinY2, 3) + EgtOutLog( sErr) + return false + elseif dY2 > MaxY2 then + EmtSetOutstrokeInfo( 'Y2', 'Y2', true, dY2 - MaxY2, ' (L1+)') + EMT.ERR = 1 + local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY2 - MaxY2, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyY1Y2Stroke( sName, dVal) + if sName == 'Y1' then + return VerifyY1Stroke( dVal) + elseif sName == 'Y2' then + return VerifyY2Stroke( dVal) + else + return nil + end +end + +--------------------------------------------------------------------- +function VerifyV1Stroke( dV1) + if dV1 < MinV1 then + EmtSetOutstrokeInfo( 'V1', 'V1', true, dV1 - MinV1, ' (L1-)') + EMT.ERR = 1 + local sErr = 'V1 axis outstroke ' .. EgtNumToString( dV1 - MinV1, 3) + EgtOutLog( sErr) + return false + elseif dV1 > MaxV1 then + EmtSetOutstrokeInfo( 'V1', 'V1', true, dV1 - MaxV1, ' (L1+)') + EMT.ERR = 1 + local sErr = 'V1 axis outstroke ' .. EgtNumToString( dV1 - MaxV1, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyV2Stroke( dV2) + if dV2 < MinV2 then + EmtSetOutstrokeInfo( 'V2', 'V2', true, dV2 - MinV2, ' (L1-)') + EMT.ERR = 1 + local sErr = 'V2 axis outstroke ' .. EgtNumToString( dV2 - MinV2, 3) + EgtOutLog( sErr) + return false + elseif dV2 > MaxV2 then + EmtSetOutstrokeInfo( 'V2', 'V2', true, dV2 - MaxV2, ' (L1+)') + EMT.ERR = 1 + local sErr = 'V2 axis outstroke ' .. EgtNumToString( dV2 - MaxV2, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyV1V2Stroke( sName, dVal) + if sName == 'V1' then + return VerifyV1Stroke( dVal) + elseif sName == 'V2' then + return VerifyV2Stroke( dVal) + else + return nil + end +end + +--------------------------------------------------------------------- +function GetV1ToClose() + --EgtOutLog( string.format( 'L1m=%.3f L1M=%.3f V2NP=%.3f LB=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1], EMT.V2NEXTPOS, EMT.LB)) + --EgtOutLog( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT or 0)) + return ( EMT.MAXMAX[1] <= EMT.V1NEXTPOS + RollCageMin and EMT.MAXMIN[1] + EMT.LB >= EMT.V1NEXTPOS + RollCageMax) +end + +--------------------------------------------------------------------- +function GetV2ToClose() + --EgtOutLog( string.format( 'L1m=%.3f L1M=%.3f V2NP=%.3f LB=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1], EMT.V2NEXTPOS, EMT.LB)) + --EgtOutLog( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT or 0)) + return ( EMT.MAXMAX[1] <= EMT.V2NEXTPOS - RollCageMax and EMT.MAXMIN[1] + EMT.LB >= EMT.V2NEXTPOS - RollCageMin) +end + +--------------------------------------------------------------------- +function ShowToolInTcPos( sTcPos, bShow) + -- recupero il gruppo dell'utensile + local TcExitId = EgtGetFirstNameInGroup( EgtGetTcPosId( sTcPos or '') or GDB_ID.NULL, 'T1') + if not TcExitId then return end + -- imposto lo stato di visualizzazione + EgtSetStatus( TcExitId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF)) +end + +--------------------------------------------------------------------- +function LoadFirstTool( nHSet, sTcPosDef) + if nHSet ~= 1 and nHSet ~= 2 then return end + if GetHeadSetFromTcPos( sTcPosDef) ~= nHSet then return end + local sTool, sHead, sTcPos = FindFirstToolOnHeadSet( nHSet) + if not sTool then + local vTools = EgtGetToolsInCurrSetupPos( sTcPosDef) + if vTools and vTools[1] then + sTool = vTools[1] + sTcPos = sTcPosDef + if nHSet == 1 then + sHead = EgtIf( sTcPos == 'T1', 'H12', 'H11') + else + sHead = 'H21' + end + end + end + if sTool then + EgtLoadTool( sHead, 1, sTool) + ShowToolInTcPos( sTcPos, false) + end + return sTool +end + +--------------------------------------------------------------------- +-- *** ESTIMATION T&L *** +--------------------------------------------------------------------- +local RAPID_X_FEED = 70000 -- mm/min +local RAPID_Y_FEED = 100000 -- mm/min +local RAPID_Z_FEED = 32000 -- mm/min +local RAPID_C_FEED = 15000 -- deg/min +local RAPID_B_FEED = 15000 -- deg/min +local RAPID_MIN_T = 0.1 -- s +local LOAD_T = 2 -- s +local CHAR_ONE_MOVE_T = 1 -- s +local ROTATION_T = 40 -- s +local SPLIT_T = 6 -- s +local UNLOAD_T = 4 -- s +local FALL_T = 2 -- s + +--------------------------------------------------------------------- +function OnEstimStart() + EMT.INCHES = not EgtUiUnitsAreMM() -- unità di misura mm/inches +end + +--------------------------------------------------------------------- +function OnEstimEnd() +end + +--------------------------------------------------------------------- +function OnEstimProgramStart() + -- imposto inizio movimenti da Home + EMT.L1 = EgtGetAxisHomePos( 'T') + EMT.L2 = EgtGetAxisHomePos( 'X1') + EMT.L3 = EgtGetAxisHomePos( 'Z1') + EMT.R1 = EgtGetAxisHomePos( 'C1') + EMT.R2 = EgtGetAxisHomePos( 'B1') + -- aggiorno valori come precedenti + EmtUpdatePrev() + -- totalizzatori tempi e lunghezze + EMT.TOTCUTLEN = 0 + EMT.TOTCUTTIME = 0 + EMT.TOTEXTLEN = 0 + EMT.TOTEXTTIME = 0 + -- variabile per lunghezza taglio utensili + EMT.TOOLCUTLEN = {} + -- intestazioni + EmtTleStart( EMT.INFO) +end + +--------------------------------------------------------------------- +function OnEstimProgramEnd() + -- stampa dei totali delle lavorazioni + EmtTleAddTotal( EmtSecToHMS( EMT.TOTCUTTIME + EMT.TOTEXTTIME), EmtLenToMF( EMT.TOTCUTLEN)) + -- stampa dei totali degli utensili + for i = 1, #EMT.TOOLCUTLEN do + local TCL = EMT.TOOLCUTLEN[i] + EmtTleAddTool( TCL.Name, EmtLenToMF( TCL.Len)) + end + -- completo il file + local _, _, sExt = EgtSplitPath( EMT.FILE) + EmtTleEnd( sExt:sub( 2)) + -- salvo i dati principali nel progetto + EgtSetInfo( EgtGetCurrMachGroup(), 'Ttot', EgtNumToString( EMT.TOTCUTTIME + EMT.TOTEXTTIME, 0)) + EgtSetInfo( EgtGetCurrMachGroup(), 'Ltot', EgtNumToString( EMT.TOTCUTLEN, 0)) +end + +--------------------------------------------------------------------- +function OnEstimDispositionStart() + -- inizio disposizione + EMT.OPEISDISP = true + -- sulla prima fase dichiaro carico barra + if EMT.PHASE == 1 then + EMT.LOAD = true + else + EMT.LOAD = false + end +end + +--------------------------------------------------------------------- +function OnEstimDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + ; + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) then + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- verifico se sono diverse + if nRot ~= nPrevRot then + -- imposto stato post-rotazione + EMT.POSTROT = true + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + ; + end + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end + -- termine disposizione + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnEstimToolSelect() + -- reset indice utensile in tabella lunghezze + EMT.TCLIND = 0 + -- verifico che l'utensile sia definito + if #EMT.TOOL == 0 then return end + -- cerco l'utensile nella tabella + for i = 1, #EMT.TOOLCUTLEN do + if EMT.TOOLCUTLEN[i].Name == EMT.TOOL then + EMT.TCLIND = i + break + end + end + -- se non trovato, lo aggiungo + if EMT.TCLIND == 0 then + table.insert( EMT.TOOLCUTLEN, { Name = EMT.TOOL, Len = 0}) + EMT.TCLIND = #EMT.TOOLCUTLEN + end +end + +--------------------------------------------------------------------- +function OnEstimToolDeselect() +end + +--------------------------------------------------------------------- +function OnEstimMachiningStart() + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EgtOutLog( 'Mach : ' .. EMT.MCHNAME, 5) + -- reset contatori di lavorazione + EMT.MCHCUTLEN = 0 + EMT.MCHCUTTIME = 0 + EMT.MCHEXTLEN = 0 + EMT.MCHEXTTIME = 0 +end + +--------------------------------------------------------------------- +function OnEstimMachiningEnd() + -- nel caso di foratura devo dimezzare la lunghezza di taglio perchè comprende anche l'uscita + if EMT.MCHTYPE == MCH_MY.DRILLING then + EMT.MCHCUTLEN = EMT.MCHCUTLEN / 2 + end + local sName = EgtGetName( EMT.MCHID) + EmtTleAddMachining( sName, EmtSecToHMS( EMT.MCHCUTTIME + EMT.MCHEXTTIME), EmtLenToMF( EMT.MCHCUTLEN), EMT.TOOL) + -- aggiorno totali e utensili + EMT.TOTCUTLEN = EMT.TOTCUTLEN + EMT.MCHCUTLEN + EMT.TOTCUTTIME = EMT.TOTCUTTIME + EMT.MCHCUTTIME + EMT.TOTEXTLEN = EMT.TOTEXTLEN + EMT.MCHEXTLEN + EMT.TOTEXTTIME = EMT.TOTEXTTIME + EMT.MCHEXTTIME + EMT.TOOLCUTLEN[EMT.TCLIND].Len = EMT.TOOLCUTLEN[EMT.TCLIND].Len + EMT.MCHCUTLEN + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end +end + +--------------------------------------------------------------------- +function OnEstimPathStart() + EMT.AUXTYPE = nil + EMT.MCHMOVEFIRST = true +end + +--------------------------------------------------------------------- +function OnEstimPathEnd() + EMT.AUXTYPE = nil +end + +--------------------------------------------------------------------- +function OnEstimPathStartAux() + -- se richiesto, preparo il carico barra + if EMT.LOAD then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Loading', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.LOAD = false + end + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = ROTATION_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Rotation', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.POSTROT = false + end + -- altrimenti, spostamento carrelli + else + if EMT.AUXTOT > 3 and EMT.AUXIND == EMT.AUXTOT then + local dTime = ( EMT.AUXTOT - 3) * CHAR_ONE_MOVE_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Charriots move', EmtSecToHMS( dTime), ' - ', ' - ') + end + end +end + +--------------------------------------------------------------------- +function OnEstimPathEndAux() + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.AUXTYPE = 'F' + else + EMT.AUXTYPE = 'P' + end + end + end + -- per lo scarico della rimanenza + if EMT.AUXTYPE == 'R' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Remnant unloading' + EMT.TLE_TIME = dTime + end + -- per lo split + elseif EMT.AUXTYPE == 'S' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = SPLIT_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Splitting' + EMT.TLE_TIME = dTime + end + -- per lo scarico + elseif EMT.AUXTYPE == 'U' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Unloading' + EMT.TLE_TIME = dTime + end + -- per lo scarico a caduta + elseif EMT.AUXTYPE == 'F' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = FALL_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Fall' + EMT.TLE_TIME = dTime + end + -- per la pre-rotazione + elseif EMT.AUXTYPE == 'P' then + ; -- calcolato come parte della rotazione + end +end + +--------------------------------------------------------------------- +function OnEstimRapid() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + local dR1 = 0 + if EMT.R1 and EMT.R1p then dR1 = EMT.R1 - EMT.R1p end + local dR2 = 0 + if EMT.R2 and EMT.R2p then dR2 = EMT.R2 - EMT.R2p end + -- se primo posizionamento della lavorazione il movimento di L1 è già conteggiato in quello dei carrelli + if EMT.MCHMOVEFIRST then + EMT.MCHMOVEFIRST = false + dL1 = 0 + end + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHEXTLEN = EMT.MCHEXTLEN + dLen + -- calcolo tempo + local dTime = RAPID_MIN_T + local dT1 = abs( dL1) / RAPID_X_FEED * 60 + if dT1 > dTime then dTime = dT1 end + local dT2 = abs( dL2) / RAPID_Y_FEED * 60 + if dT2 > dTime then dTime = dT2 end + local dT3 = abs( dL3) / RAPID_Z_FEED * 60 + if dT3 > dTime then dTime = dT3 end + local dT4 = abs( dR1) / RAPID_C_FEED * 60 + if dT4 > dTime then dTime = dT4 end + local dT5 = abs( dR2) / RAPID_B_FEED * 60 + if dT5 > dTime then dTime = dT5 end + EMT.MCHEXTTIME = EMT.MCHEXTTIME + dTime + EgtOutLog( string.format( ' G0 Len=%.0f Rot=%.0f° Time=%.2f', dLen, abs( dR1) + abs( dR2), dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimLinear() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G1 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimArc() + -- dati movimento + local dLxy = EMT.RR * abs( EMT.AC) * pi / 180 + local dLz = abs( ( Point3d( EMT.L1, EMT.L2, EMT.L3) - Point3d( EMT.L1p, EMT.L2p, EMT.L3p)) * Vector3d( EMT.EXTR)) + -- calcolo lunghezza + local dLen = sqrt( dLxy * dLxy + dLz * dLz) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G2 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +-- *** GENERAL *** +--------------------------------------------------------------------- +function IsStartPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START') +end + +--------------------------------------------------------------------- +function IsRestPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'REST') +end + +--------------------------------------------------------------------- +function IsStartOrRestPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START' or sVal == 'REST') +end + +--------------------------------------------------------------------- +function IsMidPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'MID') +end + +--------------------------------------------------------------------- +function IsMid2Phase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'MID2') +end + +--------------------------------------------------------------------- +function IsEnd2Phase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'END2') +end + +--------------------------------------------------------------------- +function GetPhaseType( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '') +end + +--------------------------------------------------------------------- +function GetPhaseOrd( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ORD', 'i') or 0) +end + +--------------------------------------------------------------------- +function GetPhaseRot( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) +end + +--------------------------------------------------------------------- +function GetParkT() + local dTmp = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') or EgtGetInfo( EMT.DISPID, 'TPARK', 'd') + if dTmp then + return dTmp + else + return LoadT + end +end + +--------------------------------------------------------------------- +function GetHeadSet( sHead) + if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' then + return 1 + elseif sHead == 'H21' then + return 2 + else + return 0 + end +end + +--------------------------------------------------------------------- +function GetHeadSetFromTcPos( sTcPos) + local TCPOS_1A = { 'T1', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8', 'T9', 'T10'} + local TCPOS_1B = { 'T101'} + local TCPOS_1C = { 'T11', 'T12', 'T13', 'T14', 'T15', 'T16', 'T17', 'T18'} + local TCPOS_2 = { 'T20', 'T21', 'T22', 'T23', 'T24', 'T25', 'T26', 'T27', 'T28', 'T29', 'T30'} + for _, sVal in ipairs( TCPOS_1A) do + if sVal == sTcPos then return 1, 1 end + end + for _, sVal in ipairs( TCPOS_1B) do + if sVal == sTcPos then return 1, 2 end + end + for _, sVal in ipairs( TCPOS_1C) do + if sVal == sTcPos then return 1, 3 end + end + for _, sVal in ipairs( TCPOS_2) do + if sVal == sTcPos then return 2, 1 end + end + return 0, 0 +end + +--------------------------------------------------------------------- +function FindFirstToolOnHeadSet( nHSet) + -- salvo stato iniziale + local CurrMachId = EgtGetCurrMachining() + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- cerco lavorazione con utensile su gruppo testa indicato + local sTool, sHead, sTcPos + local OpId = EgtGetFirstActiveOperation() + while OpId do + local nType = EgtGetOperationType( OpId) + if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then + if EgtSetCurrMachining( OpId) then + local sTest = EgtGetMachiningParam( MCH_MP.TOOL) + if EgtTdbSetCurrTool( sTest) then + sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if GetHeadSet( sHead) == nHSet then + sTool = sTest + sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + break + end + end + end + end + OpId = EgtGetNextActiveOperation( OpId) + end + -- ripristino stato iniziale + EgtSetCurrMachining( CurrMachId or GDB_ID.NULL) + EgtTdbSetCurrTool( CurrTool or '') + -- restituisco risultato + return sTool, sHead, sTcPos +end + +--------------------------------------------------------------------- +function GetToolTcPos( sTool) + -- salvo stato iniziale + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- recupero la posizione di cambio utensile dell'utensile indicato + local sTcPos + if EgtTdbSetCurrTool( sTool) then + sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + end + -- ripristino stato iniziale + EgtTdbSetCurrTool( CurrTool or '') + -- restituisco risultato + return sTcPos +end + +--------------------------------------------------------------------- +function GetCurrChainSawingVirtualAxis() + -- recupero il valore dell'asse virtuale bloccato A + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) or 'A=0' + local dPosA = tonumber( sVal:sub( 3)) or 0 + return dPosA +end + +--------------------------------------------------------------------- +function GetNextChainSawingVirtualAxis( MchId) + -- recupero la lavorazione successiva + local NextMchId + if MchId then + NextMchId = EgtGetNextActiveOperation( MchId) + else + NextMchId = EgtGetFirstActiveOperation() + end + while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do + NextMchId = EgtGetNextActiveOperation( NextMchId) + end + -- verifico sia un taglio con sega a catena + if EgtGetOperationType( NextMchId) ~= MCH_OY.MORTISING then + return nil + end + -- la imposto come lavorazione corrente + EgtSetCurrMachining( NextMchId) + -- recupero il valore dell'asse virtuale bloccato A + local dPosA = GetCurrChainSawingVirtualAxis() + -- ripristino la lavorazione corrente + if MchId then + EgtSetCurrMachining( MchId) + end + return dPosA +end + +--------------------------------------------------------------------- +function GetStartMachiningXaxis( nMchId) + -- Recupero quota X (nostro -L2) + local nClEntId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nMchId, 'CL') or GDB_ID.NULL, 'P1') or GDB_ID.NULL) + local vAxes = EmtGetAxesPos( nClEntId or GDB_ID.NULL) + if vAxes and #vAxes >= 2 then + return -vAxes[2] + else + return nil + end +end + +--------------------------------------------------------------------- +function RollerParkingNeeded( sHead, dAng1p, dAng2p, dAng1, dAng2) + if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' then + return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1 % 180.0) > 1)) + elseif sHead == 'H21' then + return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1 % 180.0) > 1)) + end +end + +--------------------------------------------------------------------- +function GetCmdAxMove( Cmd, sAx) + if #Cmd >= 3 and Cmd[2] == sAx then + return tonumber( Cmd[3]) + elseif #Cmd >= 5 and Cmd[4] == sAx then + return tonumber( Cmd[5]) + elseif #Cmd >= 7 and Cmd[6] == sAx then + return tonumber( Cmd[7]) + end +end + +--------------------------------------------------------------------- +-- *** END GENERAL *** diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.mlse b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.mlse new file mode 100644 index 0000000..2095bde --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.mlse @@ -0,0 +1,2511 @@ +-- Special Operations macchina Essetre-PF1250 by EgalTech s.r.l. 2021/12/20 +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +-- Carico i dati globali +local sBaseDir = EgtGetSourceDir() +local BD = dofile( sBaseDir .. 'Beam\\BeamData.lua') + +EgtOutLog ( '** Essetre-PF1250 '..PP_VER..' **', 1) + + +---------------------- OnSpecialMoveZup ----------------------------- +--------------------------------------------------------------------- +function OnSpecialMoveZup() + + --EgtOutLog( 'OnSpecialMoveZup : ' .. EMC.HEAD .. '.' .. tostring( EMC.EXIT)) + + -- Inizializzazioni + EMC.ERR = 0 + EMC.MODIF = false + + -- recupero Z1 home + local dZmax = EgtGetAxisHomePos( 'Z1') + + --EgtOutLog( string.format( 'Zhome=%.3f L3=%.3f R2=%.3f Flag=%i', dZmax, EMC.L3, EMC.R2, EMC.FLAG)) + + -- se fresa su testa1 + if EMC.HEAD == 'H11' then + local Z_EXTRA = 250 + -- se inclinata oltre 90 gradi + if abs( EMC.R2) > 89.9 then + -- se troppo in alto + if EMC.L3 > dZmax - 30 then + -- sistemo asse rotante + EMC.R2 = EgtIf( ( EMC.R2 > 0), 90, -90) + -- ricalcolo versore utensile + EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2) + -- porto alla giusta quota + EMC.L3 = dZmax + -- dichiaro modificato + EMC.MODIF = true + end + -- se inclinata oltre i 60 gradi + elseif abs( EMC.R2) > 60 then + local dZref = dZmax + Z_EXTRA * ( 90 - abs( EMC.R2)) / 30 + -- se troppo in basso + if EMC.L3 < dZref - 0.1 then + if ( EMC.FLAG == 2 or EMC.FLAG == 3) and EMC.FLAG2 == 1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + -- se troppo alto + elseif EMC.L3 > dZref + 0.1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + -- altrimenti inclinata meno di 60 gradi + else + local dZref = dZmax + Z_EXTRA + -- se troppo in basso + if EMC.L3 < dZref - 0.1 then + if ( EMC.FLAG == 2 or EMC.FLAG == 3) and EMC.FLAG2 == 1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + -- se troppo alto + elseif EMC.L3 > dZref + 0.1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + end + -- se lama su testa1 + elseif EMC.HEAD == 'H12' then + local Z_EXTRA = 160 + -- se inclinata oltre 90 gradi + if abs( EMC.R2) > 89.9 then + -- se troppo in alto + if EMC.L3 > dZmax - 100 then + -- sistemo asse rotante + EMC.R2 = EgtIf( ( EMC.R2 > 0), 90, -90) + -- ricalcolo versore utensile + EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2) + -- porto alla giusta quota + EMC.L3 = dZmax + -- dichiaro modificato + EMC.MODIF = true + end + -- se inclinata oltre i 60 gradi + elseif abs( EMC.R2) > 60 then + local dZref = dZmax + Z_EXTRA * ( 90 - abs( EMC.R2)) / 30 + -- se troppo in basso + if EMC.L3 < dZref - 0.1 then + --if ( EMC.FLAG == 2 or EMC.FLAG == 3) and EMC.FLAG2 == 1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + --end + -- se troppo alto + elseif EMC.L3 > dZref + 0.1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + -- altrimenti inclinata meno di 60 gradi + else + local dZref = dZmax + Z_EXTRA + -- se troppo in basso + if EMC.L3 < dZref - 0.1 then + --if ( EMC.FLAG == 2 or EMC.FLAG == 3) and EMC.FLAG2 == 1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + --end + -- se troppo alto + elseif EMC.L3 > dZref + 0.1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + end + end +end + + +---------- OnSpecialApplyDisposition & OnPostApplyMachining --------- +----------------------- Costanti ------------------------------------ +local DELTA_SIC = 1 +local MinJoin = BD.MIN_JOIN_S +local MinOther = abs( MinY1) + abs( MaxY2) + MinJoin +local SIC_V = 50 -- sicurezza da testa +local MIN_FRONT_ENG_V = 161 -- ingombro asse Z con cremagliera a destra +local MIN_BACK_ENG_V = 115 -- ingombro asse Z a sinistra +local AGG_V = MinDeltaYV -- ingombro rulli pressori + sicurezza +local MaxLenSmT = 1500 -- massima lunghezza pezzo scaricato con nastri verdi +local DIST_Y1MAX_LOAD = 100 -- distanza carrello Y1 da massimo asse al carico + +----------------------- Variabili ----------------------------------- +local Test = false +local SPLIT + +--------------------------------------------------------------------- +local function PrepareClGroup( nParentId) + + local nClId = EgtGetFirstNameInGroup( nParentId, 'CL') + -- se non c'è, lo aggiungo + if not nClId then + nClId = EgtGroup( EMC.DISPID) + if not nClId then + return nil + end + EgtSetName( nClId, 'CL') + -- altrimenti lo svuoto + else + EgtEmptyGroup( nClId) + end + + return nClId +end + +--------------------------------------------------------------------- +local function IsStartOrRestPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'START' or sVal == 'REST') +end + +--------------------------------------------------------------------- +local function IsMidPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'MID') +end + +--------------------------------------------------------------------- +local function IsEndPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'END') +end + +--------------------------------------------------------------------- +local function GetNextStartOrRestPhase( nPhase) + local nNextPhase = nPhase + 1 + while nNextPhase <= EgtGetPhaseCount() do + if IsStartOrRestPhase( nNextPhase) then + break ; + end + nNextPhase = nNextPhase + 1 + end + return nNextPhase +end + +--------------------------------------------------------------------- +function GetPhaseRot( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) +end + +--------------------------------------------------------------------- +local function IsLastMachiningBeforeRotation( nMchId) + -- se ultima fase, ritorno risultato negativo + if EMC.PHASE == EgtGetPhaseCount() then + return false + end + -- recupero la successiva operazione attiva + local nNextOperId = EgtGetNextActiveOperation( nMchId) + -- se non esiste o non è una disposizione, ritorno risultato negativo + if not nNextOperId or EgtGetOperationType( nNextOperId) ~= MCH_OY.DISP then + return false + end + -- recupero le rotazioni della fase corrente e della prossima fase + local nRot = GetPhaseRot( EMC.PHASE) + local nNextRot = GetPhaseRot( EMC.PHASE + 1) + -- ritorno se sono diverse + return ( nRot ~= nNextRot) +end + +--------------------------------------------------------------------- +local function IsFirstMachiningAfterRotation( nMchId) + -- se prima fase, ritorno risultato negativo + if EMC.PHASE == 1 then + return false + end + -- recupero la precedente operazione attiva + local nPrevOperId = EgtGetPrevActiveOperation( nMchId) + -- se non esiste o non è una disposizione, ritorno risultato negativo + if not nPrevOperId or EgtGetOperationType( nPrevOperId) ~= MCH_OY.DISP then + return false + end + -- recupero le rotazioni della fase corrente e della fase precedente + local nRot = GetPhaseRot( EMC.PHASE) + local nPrevRot = GetPhaseRot( EMC.PHASE - 1) + -- ritorno se sono diverse + return ( nRot ~= nPrevRot) +end + +--------------------------------------------------------------------- +local function UpdateMinJoin() + MinJoin = BD.GetMinJoin( EMC.SB, EMC.HB, EMC.LB) + MinOther = abs( MinY1) + abs( MaxY2) + MinJoin +end + +--------------------------------------------------------------------- +local function GetCUTID() + -- recupero CUTID del pezzo in lavoro + local nOrd = GetPhaseOrd( EMC.PHASE) + local nPartRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + nPartRawId = nRawId + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + local CutID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + return CutID +end + +--------------------------------------------------------------------- +local function GetNextRawInOrd( nCurrRawId) + local nCurrOrd = EgtGetInfo( nCurrRawId, 'ORD', 'i') + if not nCurrOrd then return end + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nCurrOrd + 1 then + return nRawId + end + nRawId = EgtGetNextRawPart( nRawId) + end +end + +----------------------------------------------------------------------- +local function EnsureZmax( bCloseV, vCmd) + -- posizionamento sicuro teste e rulli + table.insert( vCmd, { 4, EgtIf( bCloseV, 1, 0)}) + --if EMC.MCHID then + -- local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + -- if not sNotes:find( 'StartZmax=2', 1, true) then + -- sNotes = EgtAdjustNotes( sNotes, 'StartZmax=', '2') + -- EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- EgtSetInfo( EgtGetCurrMachGroup(), 'RECALC', '1') + -- end + --end + return true +end + +----------------------------------------------------------------------- +local function EnsureZmaxAtEnd( vCmd) + -- posizionamento sicuro teste e rulli + table.insert( vCmd, { 4, 0}) +end + +----------------------------------------------------------------------- +local function EmitComment( vCmd, sOut) + EgtOutLog( ' ' .. sOut) + if Test then + table.insert( vCmd, { 0, sOut}) + end +end + +--------------------------------------------------------------------- +function OnSpecialApplyDisposition() + + EgtOutLog( ' *** Fase : ' .. EgtNumToString( EMC.PHASE, 0) .. ' ***') + + -- Inizializzo codice di errore + EMC.ERR = 0 + + -- Campi obbligatori ma non usati + EMC.HEAD = "H14" + EMC.EXIT = 1 + EMC.TCPOS = "" + EMC.SHIFTS = 0 + EMC.SBH = false + + -- Se disposizione da saltare non devo fare alcunché + if EgtExistsInfo( EMC.DISPID, 'SKIP') then return end + + -- Assegno flag di pezzo separato dal resto del grezzo + SPLIT = IsEndPhase( EMC.PHASE) + + -- Recupero il tipo dell'operazione successiva + local nNextOpeType = EgtGetOperationType( EgtGetNextActiveOperation( EMC.DISPID) or GDB_ID.NULL) + + -- Se ci sono lavorazioni successive non devo fare alcunché + if nNextOpeType ~= MCH_OY.NONE and nNextOpeType ~= MCH_OY.DISP then return end + + -- Imposto gruppo e path di movimento + local nClId = PrepareClGroup( EMC.DISPID) + if not nClId then + EMC.ERR = 3 + EMC.MSG = ' Error : creation CL group failed' + return + end + local nPathId = EgtGroup( nClId) + if not nPathId then + EMC.ERR = 6 + EMC.MSG = ' Error : creation path in CL group failed' + return + end + EgtSetName( nPathId, 'Empty') + EMC.PATHID = nPathId + EMC.SHIFTS = -1 + + -- Se la lavorazione successiva è ancora una disposizione, devo scaricare il pezzo + if nNextOpeType == MCH_OY.DISP and SPLIT then + -- aggiornamento posizioni + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') + EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') + EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1 + EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2 + EMC.CNT = SpecGetCNT( EMC.DISPID) + -- Determinazione delle dimensioni del grezzo in lavoro + local b3Raw = BBox3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) and not EgtVerifyRawPartPhase( nRawId, EMC.PHASE + 1) then + b3Raw = EgtGetRawPartBBox( nRawId) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + EMC.LB = b3Raw:getDimX() + -- Eseguo scarico + local vCmd = SpecCalcUnload() + SpecOutputCmds( vCmd, true) + return + end + + -- Verifico ci sia un solo grezzo nella fase corrente + local nRawCount = 0 + local nCurrRawId = GDB_ID.NULL + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + nRawCount = nRawCount + 1 + nCurrRawId = nRawId + end + nRawId = EgtGetNextRawPart( nRawId) + end + if nRawCount > 1 then + EMC.ERR = 10 + EMC.MSG = ' Error : too many Raw Parts in current Phase' + return + end + + -- Determinazione delle sue dimensioni + local b3Raw = EgtGetRawPartBBox( nCurrRawId) + if b3Raw:isEmpty() then + EMC.ERR = 11 + EMC.MSG = ' Error : null Raw Part' + return + end + EMC.LB = b3Raw:getDimX() + EMC.SB = b3Raw:getDimY() + EMC.HB = b3Raw:getDimZ() + + -- Aggiorno limiti di presa + UpdateMinJoin() + + -- Assegno sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = 0 + EMC.HCING = 0 + EMC.TCING = 0 + + -- Devo scaricare il grezzo rimasto (deve essere unico) + -- Posizione trave + local dPosT + + -- Se fase 1 eseguo carico con carrello Y + local vCmd = {} + if EMC.PHASE == 1 then + dPosT = LoadT + vCmd = SpecCalcLoad( dPosT, 0, 0) + -- se altrimenti fase successiva alla prima di tipo inizio o rimanenza + elseif IsStartOrRestPhase( EMC.PHASE) then + -- recupero posizione trave e quota di aggancio carrello + dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd') + local dPosY1 = EgtGetInfo( EMC.DISPID, 'Y1POS', 'd') + if not dPosY1 then + EMC.ERR = 14 + EMC.MSG = ' Error : Y1 non clamped (start or rest)' + return + end + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dPosY1 - dPosT, 0}) + -- recupero posizione rulli + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + -- recupero contatore pinza 1 + EMC.CNT = SpecGetCNT( EMC.DISPID) + -- altrimenti fase successiva pari + else + EMC.Y2DELTA = EgtGetInfo( EMC.DISPID, 'Y2POS', 'd') + EMC.V1POS = EgtGetInfo( EMC.DISPID, 'V1POS', 'd') + EMC.V2POS = EgtGetInfo( EMC.DISPID, 'V2POS', 'd') + -- recupero contatore pinza 1 + EMC.CNT = SpecGetCNT( EMC.DISPID) + end + -- Se fase inizio o rimanenza, eseguo scambio per avere solo pinza V + local vCmd2 = {} + if IsStartOrRestPhase( EMC.PHASE) then + EMC.TPOS = dPosT + SpecSetCarrPosFromCmds( vCmd) + local dDistFront = EMC.LB - MinJoin + 10 * GEO.EPS_SMALL + local dDistBack = 0 + local dY2DeltaMinUL = EMC.LB + MinY2 - EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) + vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, -EMC.V2POS, EMC.V1POS, nil, dY2DeltaMinUL) + if vCmd and #vCmd > 1 and vCmd2 and #vCmd2 > 1 and SpecTestSomeMoveInCmds( vCmd2) then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + end + -- eseguo scarico + SpecSetCarrPosFromCmds( vCmd2) + local vCmd3 = SpecCalcUnload() + -- unisco ed emetto i comandi + vCmd = EgtJoinTables( vCmd, vCmd2) + vCmd = EgtJoinTables( vCmd, vCmd3) + SpecOutputCmds( vCmd, true) +end + +--------------------------------------------------------------------- +function OnPostApplyMachining() + + EgtOutLog( ' Lavorazione : ' .. EgtGetName( EMC.MCHID) .. ' (' .. tostring( EMC.MCHID) .. ')') + + -- Inizializzo codice di errore + EMC.ERR = 0 + + -- Recupero la posizione della trave e dei carrelli al termine della precedente operazione + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID) + -- se precedente operazione non esiste, errore + if not nPrevOpeId then + EMC.ERR = 1 + EMC.MSG = ' Error : previous Disposition not found' + return + -- se precedente operazione è disposizione + elseif EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP then + if EMC.PHASE == 1 or ( IsMidPhase( EMC.PHASE) and IsFirstMachiningAfterRotation( EMC.MCHID)) then + -- posizioni home + EMC.TPOS = nil + EMC.Y1DELTA = nil + EMC.Y2DELTA = nil + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + EMC.CNT = nil + elseif IsStartOrRestPhase( EMC.PHASE) then + -- carico le posizioni + local dPosT = EgtGetInfo( nPrevOpeId, 'TPOS', 'd') + local dPosY = EgtGetInfo( nPrevOpeId, 'Y1POS', 'd') + EMC.TPOS = dPosT + EMC.Y1DELTA = dPosY - dPosT + EMC.Y2DELTA = nil + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + EMC.CNT = SpecGetCNT( EMC.MCHID) + else + -- aggiornamento posizioni (da lavorazione precedente a disposizione) + local nPrev2OpeId = EgtGetPrevActiveOperation( nPrevOpeId) + if not nPrev2OpeId then + EMC.ERR = 1 + EMC.MSG = ' Error : previous Disposition not found' + return + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrev2OpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') + EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') + EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1 + EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2 + EMC.CNT = SpecGetCNT( EMC.MCHID) + end + -- altrimenti precedente operazione è lavorazione + else + -- aggiornamento posizioni + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local bAtZMax = ( EgtGetClEntMove( nLastEntId) == 0 and EgtGetClEntFlag( nLastEntId) == 3) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') + EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') + EMC.V1POS = EgtIf( bAtZMax, ParkV1, EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1) + EMC.V2POS = EgtIf( bAtZMax, ParkV2, EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2) + EMC.CNT = SpecGetCNT( EMC.MCHID) + end + + -- Verifico se ultima lavorazione della fase + local nNextOpeId = EgtGetNextActiveOperation( EMC.MCHID) + local bMchLast = ( not nNextOpeId or EgtGetOperationPhase( nNextOpeId) ~= EMC.PHASE) + + -- Verifico se ultima lavorazione prima di una rotazione + local bPreRotMch = IsLastMachiningBeforeRotation( EMC.MCHID) and not IsEndPhase( EMC.PHASE) + + -- Verifico flag di separazione e fase di scarico + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + local bPreSplit = ( false and sNotes:find( 'Presplit', 1, true) ~= nil) + local bSplitting = ( sNotes:find( 'Split', 1, true) ~= nil) + local bPreCut = ( sNotes:find( 'Precut', 1, true) ~= nil) + local bCutting = ( sNotes:find( 'Cut', 1, true) ~= nil) + local bUnload = IsEndPhase( EMC.PHASE) + + -- Agisco sui diversi percorsi della lavorazione + local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EMC.MCHID, 'CL') or GDB_ID.NULL) + while nPathId do + -- assegno id percorso da elaborare + EMC.PATHID = nPathId + -- recupero id del successivo + nPathId = EgtGetNext( nPathId) + -- verifico se ultimo percorso di ultima lavorazione della fase + local bLast = ( bMchLast and ( not nPathId)) + -- se ultimo, elimino ritorno in home + if bLast then EgtRemoveOperationHome( EMC.MCHID) end + -- salvo lo stato dei carrelli + local OriTPos = EMC.TPOS + local OriY1Delta = EMC.Y1DELTA + local OriY2Delta = EMC.Y2DELTA + local OriV1Pos = EMC.V1POS + local OriV2Pos = EMC.V2POS + local OriCnt = EMC.CNT + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) + -- se separazione, verifico il risultato + if bSplitting then + -- recupero CUTID del pezzo in lavoro + local CutID = GetCUTID() + -- in caso di errore mancato pinzaggio uscita riprovo dopo aver disabilitato le lavorazioni finali + if EMC.ERR == 18 then + -- segnalazione warning + EMC.ERR = -101 + EMC.MSG = 'Warning : skipped final processes (WRN=101,CUTID='..tostring( CutID)..')' + -- ripristino lo stato originale dei carrelli + EMC.TPOS = OriTPos + EMC.Y1DELTA = OriY1Delta + EMC.Y2DELTA = OriY2Delta + EMC.V1POS = OriV1Pos + EMC.V2POS = OriV2Pos + EMC.CNT = OriCnt + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) + -- pinzaggio ancora impossibile, pezzo a caduta + if EMC.ERR == 18 then + -- segnalazione warning + EMC.ERR = -102 + EMC.MSG = 'Warning : skipped final processes and unload by fall (WRN=102,CUTID='..tostring( CutID)..')' + end + -- scarico standard + elseif EMC.ERR == 0 then + -- segnalazione warning + EMC.ERR = -100 + EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' + end + -- se taglio del residuo finale, scarico standard + elseif bCutting then + -- recupero CUTID del pezzo in lavoro + local CutID = GetCUTID() + -- se non ci sono errori, segnalazione warning + if EMC.ERR == 0 then + EMC.ERR = -100 + EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' + end + end + if EMC.ERR > 0 then return end + -- determino la posizione finale della trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + end + +end + +--------------------------------------------------------------------- +function SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bUnload, bPreRotMch) + + -- Verifico se lavorazione pareti + local bWall = ( EgtGetInfo( EgtGetCurrMachGroup() or GDB_ID.NULL, 'Wall', 'd') == 1) + + -- Assegno flag di pezzo separato dal resto del grezzo + SPLIT = IsEndPhase( EMC.PHASE) + + -- Determinazione delle dimensioni totali dei grezzi e del grezzo in lavoro + local b3Tot = BBox3d() + local b3Raw = BBox3d() + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + local nCurrRawId = GDB_ID.NULL + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + local b3Tmp = EgtGetRawPartBBox( nRawId) + b3Tot:Add( b3Tmp) + if EgtGetPartInRawPartCount( nRawId) > 0 and not EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + b3Raw = b3Tmp + nCurrRawId = nRawId + end + end + nRawId = EgtGetNextRawPart( nRawId) + end + if b3Tot:isEmpty() then + EMC.ERR = 11 + EMC.MSG = ' Error : null Raw Parts' + return + end + EMC.LB = EgtIf( SPLIT, b3Raw:getDimX(), b3Tot:getDimX()) + EMC.SB = b3Tot:getDimY() + EMC.HB = b3Tot:getDimZ() + EMC.LT = b3Raw:getDimX() + + -- Aggiorno limiti di presa + UpdateMinJoin() + + -- Recupero sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = EgtGetInfo( nCurrRawId, 'HOVM', 'd') or 0 + EMC.HCING = EgtGetInfo( nCurrRawId, 'HCING', 'd') or 0 + EMC.TCING = EgtGetInfo( nCurrRawId, 'TCING', 'd') or 0 + -- Recupero ingombro dei tagli di testa del prossimo pezzo (se esiste) + EMC.NEXT_HCING = 0 + local nNextRawId = GetNextRawInOrd( nCurrRawId) + if nNextRawId then + EMC.NEXT_HCING = EgtGetInfo( nNextRawId, 'HCING', 'd') or 0 + end + + -- Calcolo dell'ingombro della lavorazione + local dDistFront, dDistBack, dRollFront, dRollBack = SpecialCalcMachiningEncumbrance( EMC.MCHID, bPreCut) + if not dDistFront then return end + if bPreSplit or bSplitting then + local dDistF, dDistB, dRollF, dRollB = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + dDistBack = dDistBack + elseif bPreCut or bCutting then + local dDistF, dDistB, dRollF, dRollB = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + dDistBack = min( dDistBack, dDistB) + end + + -- Verifico lunghezza pezzo + if not SPLIT and not VerifyPartLength() then + return + end + + -- Calcolo quali carrelli sono necessari + local nChar + if bPreSplit or bSplitting then + nChar = 2 + elseif bPreCut or bCutting then + nChar = 3 + end + local dY1DeltaMaxSP + if nChar == 2 then + dY1DeltaMaxSP = MaxY1 - LoadT + EMC.LT + end + local dY2DeltaMinUL + if ( nChar == 2 or nChar == 3) and not bWall then + dY2DeltaMinUL = EMC.LT + MinY2 - EgtIf( EMC.LT < MaxLenSmT, UnloadSmT, UnloadT) + end + + -- Se inizio o appena dopo rotazione, eseguo il carico + if not EMC.TPOS then + local dPosT = LoadT + if IsFirstMachiningAfterRotation( EMC.MCHID) then dPosT = dPosT + TurnerOffs end + local vCmd = SpecCalcLoad( dPosT, dDistFront, max( dDistBack, MinJoin, EMC.LB - ( MaxY1 - MinY1) + 6)) + local vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar) + if bSplitting and EMC.ERR == 18 then + table.insert( vCmd, { 22, dRollBack, -dRollFront}) + end + if vCmd2 and #vCmd2 > 1 and SpecTestSomeMoveInCmds( vCmd2) then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + EgtJoinTables( vCmd, vCmd2) + SpecOutputCmds( vCmd) + + -- Se altrimenti non eseguito SPLIT, eseguo calcoli per carrelli + elseif not SPLIT then + local vCmd = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar) + -- Se non ci sono spostamenti, confermo i parametri di aggancio e di posizione roller + if SpecTestOnlyRemarkInCmds( vCmd) then + table.insert( vCmd, { 21, EgtIf( EMC.Y1DELTA, EMC.Y1DELTA, 0), EgtIf( EMC.Y2DELTA, EMC.Y2DELTA, 0)}) + table.insert( vCmd, { 22, dRollBack, -dRollFront}) + end + SpecOutputCmds( vCmd) + + -- Altrimenti, non muovo i carrelli rispetto alla trave ma impongo la posizione dei rulli + else + local vCmd = {} + table.insert( vCmd, { 21, EgtIf( EMC.Y1DELTA, EMC.Y1DELTA, 0), EgtIf( EMC.Y2DELTA, EMC.Y2DELTA, 0)}) + table.insert( vCmd, { 22, dRollBack, -dRollFront}) + SpecOutputCmds( vCmd) + end + + -- Se taglio di separazione + local vCmd = {} + if bSplitting then + -- rimuovo eventuale vecchia info di Skip + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) or GDB_ID.NULL + EgtRemoveInfo( NextDispId, 'SKIP') + -- verifico se separazione con caduta + if not EMC.Y2DELTA then + EgtOutLog( ' Warning SPLITTING -> separazione con caduta pezzo') + SpecOutputCNT() + if IsEndPhase( EMC.PHASE + 1) then + EgtSetInfo( NextDispId, 'SKIP', '1') + local NextOpeId = EgtGetNextOperation( NextDispId) + while NextOpeId and EgtGetOperationPhase( NextOpeId) == EMC.PHASE + 1 do + EgtSetOperationMode( NextOpeId, false) + NextOpeId = EgtGetNextOperation( NextOpeId) + end + end + -- rimane impostato l'errore 18 + -- verifico che la barra sia agganciata ad entrambi i carrelli + elseif not EMC.Y1DELTA or not EMC.Y2DELTA then + EMC.ERR = 19 + EMC.MSG = ' Error SPLIT : Y1 or Y2 not clamped' + return false + end + -- eseguo la separazione + local dMaxLenLeft = EMC.LT - dDistFront - AGG_V - dRollFront + EgtOutLog( 'MaxLenLeft=' .. EgtNumToString( dMaxLenLeft, 1)) + vCmd = SpecCalcSplit( b3Raw:getDimX(), dMaxLenLeft) + end + -- Se taglio finale di grezzo a perdere + if bCutting then + -- salvo distanza carrello Y2 da inizio grezzo rimasto nella disposizione della prossima fase + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if NextDispId then + EgtSetInfo( NextDispId, 'Y2POS', EMC.Y2DELTA) + EgtSetInfo( NextDispId, 'V1POS', EMC.V1POS) + EgtSetInfo( NextDispId, 'V2POS', EMC.V2POS) + end + end + + -- Se previsto scarico, lo eseguo + if bUnload then + EMC.LB = b3Raw:getDimX() + local vCmdTmp = SpecCalcUnload() + vCmd = EgtJoinTables( vCmd, vCmdTmp) + end + + -- Se ritorno al carico per rotazione + if bPreRotMch then + local vCmdTmp = SpecCalcPreRot() + vCmd = EgtJoinTables( vCmd, vCmdTmp) + end + + -- Emetto eventuali comandi di separazione e/o scarico + if #vCmd > 0 then + SpecOutputCmds( vCmd, true) + end + +end --SpecApplyPath( bLast) + +--------------------------------------------------------------------- +function SpecialCalcMachiningEncumbrance( nMchId, bPreCut) + -- gruppi della lavorazione + local nClId = EgtGetFirstNameInGroup( nMchId, 'CL') + local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) + if not nPathId then + EMC.ERR = 12 + EMC.MSG = ' Error : CL group path not found' + return + end + -- recupero ptMin ptMax della lavorazione + local ptMin = EgtGetInfo( nClId, 'MMIN', 'p') + local ptMax = EgtGetInfo( nClId, 'MMAX', 'p') + if not ptMin or not ptMax then + EMC.ERR = 13 + EMC.MSG = ' Error : machining Min or Max not found' + return + end + -- se pre-taglio, aggiorno ptMax con quello del taglio finale + if bPreCut then + local ptFinMax = GetFinalCutPmax( nMchId) + if ptFinMax then + ptMax = ptFinMax + end + end + -- Recupero testa + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + -- Recupero valore assi macchina + local nSecId = EgtGetNext( EgtGetFirstInGroup( nPathId)) + local vAxes = EmtGetAxesPos( nSecId) + if not vAxes or #vAxes < 5 or ( sHead == 'H13' and #vAxes < 6) then + EMC.ERR = 15 + EMC.MSG = ' Error : machine axes values not found' + return + end + -- Calcolo dell'ingombro della testa rispetto allo Zero Macchina + local b3Enc + if sHead ~= 'H21' then + EgtSetAxisPos( 'C1', vAxes[4]) + EgtSetAxisPos( 'B1', vAxes[5]) + if sHead == 'H13' then + EgtSetAxisPos( 'A', vAxes[6]) + end + b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C1'), GDB_BB.ONLY_VISIBLE) + else + EgtSetAxisPos( 'C2', vAxes[4]) + EgtSetAxisPos( 'B2', vAxes[5]) + b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C2'), GDB_BB.ONLY_VISIBLE) + end + local dRollFront = max( b3Enc:getMax():getX(), MIN_FRONT_ENG_V) + SIC_V + local dRollBack = max( -b3Enc:getMin():getX(), MIN_BACK_ENG_V) + SIC_V + EgtOutLog( ' RollFront = ' .. EgtNumToString( dRollFront, 1) .. ' RollBack = ' .. EgtNumToString( dRollBack, 1), 3) + -- Calcolo della posizione della Punta Utensile rispetto allo Zero Macchina + local ptTip + ptTip = EgtGetCalcTipFromPositions( 0, 0, 0, vAxes[4], vAxes[5], vAxes[6] or 0, false) + EgtOutLog( ' ToolTip = ' .. tostring( ptTip), 5) + -- Calcolo dell'ingombro della testa rispetto alla Punta Utensile + local dHeadFront = dRollFront + AGG_V - ptTip:getX() + local dHeadBack = dRollBack + AGG_V + ptTip:getX() + EgtOutLog( ' HeadFront = ' .. EgtNumToString( dHeadFront, 1) .. ' HeadBack = ' .. EgtNumToString( dHeadBack, 1), 5) + -- Distanze limiti della pinza di destra da testa trave e della pinza di sinistra da coda trave + local dDistFront = - ptMax:getX() - LoadT - dHeadFront + local dDistBack = ptMin:getX() + LoadT + EMC.LB - dHeadBack + EgtOutLog( ' DistFront = ' .. EgtNumToString( dDistFront, 1) .. ' DistBack = ' .. EgtNumToString( dDistBack, 1), 3) + return dDistFront, dDistBack, dRollFront, dRollBack +end + +--------------------------------------------------------------------- +function SpecialCalcPhaseEncumbrance( nPhase) + -- Deve essere la fase finale di lavorazione di un pezzo (già staccato dal resto della trave) + local dDistFront = EMC.LB + local dDistBack = EMC.LB + local dRollFront = 0 + local dRollBack = 0 + -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine + local nOrigMchId = EgtGetCurrMachining() + local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + local sOrigHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + -- Ciclo sulle lavorazioni + local nMchId = EgtGetNextActiveOperation( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL) + while nMchId and EgtGetOperationPhase( nMchId) == nPhase do + -- imposto lavorazione e utensile correnti + EgtSetCurrMachining( nMchId) + local sTool = EgtGetMachiningParam( MCH_MP.TOOL) + EgtTdbSetCurrTool( sTool) + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + EgtSetCalcTool( sTool, sHead, 1) + -- calcolo ingombri + local dDistF, dDistB, dRollF, dRollB = SpecialCalcMachiningEncumbrance( nMchId) + if dDistF and dDistB then + dDistFront = min( dDistFront, dDistF) + dDistBack = min( dDistBack, dDistB) + dRollFront = max( dRollFront, dRollF) + dRollBack = max( dRollBack, dRollB) + end + nMchId = EgtGetNextActiveOperation( nMchId) + end + -- Ripristino lavorazione e utensile correnti + if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end + if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end + if sOrigTool and sOrigHead then EgtSetCalcTool( sOrigTool, sOrigHead, 1) end + -- Restituisco gli ingombri trovati + return dDistFront, dDistBack, dRollFront, dRollBack +end + +--------------------------------------------------------------------- +function GetFinalCutPmax( nMchId) + local nFinalCutId + local nId = EgtGetNextActiveOperation( nMchId) + while nId and EgtGetOperationPhase( nId) == EMC.PHASE do + nFinalCutId = nId + nId = EgtGetNextActiveOperation( nId) + end + if not nFinalCutId then return end + local nCLId = EgtGetFirstNameInGroup( nFinalCutId, 'CL') + if not nCLId then return end + return EgtGetInfo( nCLId, 'MMAX', 'p') +end + +--------------------------------------------------------------------- +function VerifyPartLength() + + -- Verifico lunghezza pezzo + if EMC.LB < MinJoin + MinOther + AggLoad + EMC.HCING + EMC.HOVM then + EMC.ERR = 17 + EMC.MSG = ' Error CLAMP : part too short' + return false + end + + return true +end + +--------------------------------------------------------------------- +function SpecCalcLoad( dPosT, dDistFront, dDistBack) + --[L] + local dNewY1min = max( EMC.LB - dDistBack, MinOther + AggLoad + EMC.HCING + EMC.HOVM) + local dNewY1max = min( ( MaxY1 - MinY1) - 5, EMC.LB - MinJoin) + if dNewY1min > dNewY1max then return nil end + local dNewY1Delta = dNewY1max + local dNewY2Delta = nil + local dNewY1 = dPosT + dNewY1Delta + local vCmd = {} + EgtOutLog( ' *[L]') + -- [L-1] + if dNewY1 + TurnerOffs + DIST_Y1MAX_LOAD - MaxY1 > 0 then + dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs - DIST_Y1MAX_LOAD) + EgtOutLog( ' *[L1]') + end --[L-2] + if EMC.LB - dNewY1Delta < MinJoin then + dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs - DIST_Y1MAX_LOAD) + EgtOutLog( ' *[L2]') + end + -- Commento + table.insert( vCmd, { 0, 'Loading'}) + -- posizionamento sicuro teste e rulli + EnsureZmax( false, vCmd) + -- Apro entrambe le morse + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 12, 0}) + -- Sposto il carrello Y per il carico + table.insert( vCmd, { 2, 'Y1', dPosT + dNewY1Delta, 'Y2', ParkY2}) + -- Chiudo morsa Y + table.insert( vCmd, { 11, 1}) + -- Sposto il carrello Y con la testa trave al parcheggio V1 + table.insert( vCmd, { 2, 'T', ParkV1, 'Y1', ParkV1 + dNewY1Delta}) + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dNewY1Delta, 0}) + -- Inizializzo contatore globale + EMC.CNT = 1 + SpecOutputCNT() + -- Assegno stato corrente + EMC.TPOS = ParkV1 + EMC.Y1DELTA = dNewY1Delta + EMC.Y2DELTA = nil + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + -- Restituisco i comandi + return vCmd +end -- SpecAdjustLoad [L] + +--------------------------------------------------------------------- +function SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar) + + local MinFrontJoin = MinJoin + EMC.HCING + EMC.HOVM + local MyMinOther = MinOther + EgtIf( EMC.CNT == 1, AggLoad, 0) + + local sMaxSplit = '' + if dY1DeltaMaxSP then sMaxSplit = '/'..EgtNumToString( dY1DeltaMaxSP, 1)..'(MaxSplit)' end + local sMinUnload = '' + if dY2DeltaMinUL then sMinUnload = '/'..EgtNumToString( dY2DeltaMinUL, 1)..'(MinUnload)' end + EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBack, 1) .. '/' .. EgtNumToString( MinJoin, 1) .. sMaxSplit .. + ' Front=' .. EgtNumToString( dDistFront, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1) .. sMinUnload, 3) + + -- [A] se non richiesto solo carrello Y2 e posso mettere solo carrello Y1 + --if nChar ~= 3 and dDistBack > MinJoin - GEO.EPS_SMALL and dDistFront < MinFrontJoin then + if nChar ~= 2 and nChar ~= 3 and dDistBack > MinJoin - GEO.EPS_SMALL then + + local WorkTab = {} + WorkTab.dTPosI = EMC.TPOS + WorkTab.dY1DeltaI = EMC.Y1DELTA + WorkTab.dY2DeltaI = EMC.Y2DELTA + WorkTab.dV1PosI = EMC.V1POS + WorkTab.bV1CloseI = false + WorkTab.dV2PosI = EMC.V2POS + WorkTab.bV2CloseI = false + + WorkTab.dTPosF = nil + WorkTab.dY1DeltaMinF = max( EMC.LB - dDistBack, MyMinOther + EMC.HCING + EMC.HOVM) + WorkTab.dY1DeltaMaxF = min( EMC.LB - MinJoin, MaxY1 + dDistFront + dRollFront + AGG_V) + WorkTab.dY2DeltaMinF = nil + WorkTab.dY2DeltaMaxF = nil + WorkTab.dV1PosF = dRollBack + WorkTab.bV1CloseF = false + WorkTab.dV2PosF = -dRollFront + WorkTab.bV2CloseF = false + + -- aggiuntivo per non avere problemi con pezzi a caduta + if WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 5 * BD.CHAR_EXTRA_DIST then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + 4 * BD.CHAR_EXTRA_DIST + elseif WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 2.5 * BD.CHAR_EXTRA_DIST then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + 2 * BD.CHAR_EXTRA_DIST + elseif WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 1.5 * BD.CHAR_EXTRA_DIST then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + BD.CHAR_EXTRA_DIST + end + + -- verifico validità intervallo ammesso per Y1 + if WorkTab.dY1DeltaMinF > WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y1 impossible' + return {} + end + + return SpecAdjustCarriages( WorkTab) + + -- [B] se richiesti entrambi e posso metterli + elseif nChar == 2 and + dDistBack > MinJoin - GEO.EPS_SMALL and + dDistFront > MinFrontJoin - GEO.EPS_SMALL then + + local WorkTab = {} + WorkTab.dTPosI = EMC.TPOS + WorkTab.dY1DeltaI = EMC.Y1DELTA + WorkTab.dY2DeltaI = EMC.Y2DELTA + WorkTab.dV1PosI = EMC.V1POS + WorkTab.bV1CloseI = false + WorkTab.dV2PosI = EMC.V2POS + WorkTab.bV2CloseI = false + + WorkTab.dTPosF = nil + WorkTab.dY1DeltaMinF = max( EMC.LB - dDistBack, MyMinOther + EMC.HCING + EMC.HOVM, EMC.LT + MyMinOther + EMC.NEXT_HCING) + WorkTab.dY1DeltaMaxF = min( EMC.LB - MinJoin, MaxY1 + dDistFront + dRollFront + AGG_V) + WorkTab.dY2DeltaMinF = max( MinJoin + EMC.HCING + EMC.HOVM, EMC.LB + MinY2 - dDistBack - AGG_V - dRollBack) + WorkTab.dY2DeltaMaxF = min( dDistFront, EMC.LB - MyMinOther - EMC.TCING) + if dY1DeltaMaxSP then WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMaxF, dY1DeltaMaxSP) end + if dY2DeltaMinUL then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMinF, dY2DeltaMinUL) end + WorkTab.dV1PosF = dRollBack + WorkTab.bV1CloseF = false + WorkTab.dV2PosF = -dRollFront + WorkTab.bV2CloseF = false + + -- aggiuntivo per minimizzare scambi carrelli + if WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 5 * BD.CHAR_EXTRA_DIST then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + 4 * BD.CHAR_EXTRA_DIST + elseif WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 2.5 * BD.CHAR_EXTRA_DIST then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + 2 * BD.CHAR_EXTRA_DIST + elseif WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 1.5 * BD.CHAR_EXTRA_DIST then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + BD.CHAR_EXTRA_DIST + end + + -- verifico validità intervallo ammesso per Y1 + if WorkTab.dY1DeltaMinF > WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y1 impossible' + return {} + end + + -- verifico validità intervallo ammesso per Y2 + if WorkTab.dY2DeltaMinF > WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y2 impossible' + return {} + end + + return SpecAdjustCarriages( WorkTab) + + -- [C] se non richiesti entrambi e posso mettere carrello Y2 + elseif dDistFront > MinFrontJoin - GEO.EPS_SMALL then + + local WorkTab = {} + WorkTab.dTPosI = EMC.TPOS + WorkTab.dY1DeltaI = EMC.Y1DELTA + WorkTab.dY2DeltaI = EMC.Y2DELTA + WorkTab.dV1PosI = EMC.V1POS + WorkTab.bV1CloseI = false + WorkTab.dV2PosI = EMC.V2POS + WorkTab.bV2CloseI = false + + WorkTab.dTPosF = nil + WorkTab.dY1DeltaMinF = nil + WorkTab.dY1DeltaMaxF = nil + WorkTab.dY2DeltaMinF = max( MinJoin + EMC.HCING + EMC.HOVM, EMC.LB + MinY2 - dDistBack - AGG_V - dRollBack) + WorkTab.dY2DeltaMaxF = min( dDistFront, EMC.LB - MyMinOther - EMC.TCING) + if dY2DeltaMinUL then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMinF, dY2DeltaMinUL) end + WorkTab.dV1PosF = dRollBack + WorkTab.bV1CloseF = false + WorkTab.dV2PosF = -dRollFront + WorkTab.bV2CloseF = false + + -- verifico validità intervallo ammesso per Y2 + if WorkTab.dY2DeltaMinF > WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y2 impossible' + return {} + end + + return SpecAdjustCarriages( WorkTab) + + -- altrimenti errore + else + if EgtGetDebugLevel() < 3 then + EgtOutLog( ' DistFront=' .. EgtNumToString( dDistFront) .. ' DistBack=' .. EgtNumToString( dDistBack) .. + ' MinJoin=' .. EgtNumToString( MinJoin) .. ' MinFrontJoin=' .. EgtNumToString( MinFrontJoin)) + end + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP impossible' + return {} + end +end + +--------------------------------------------------------------------- +function SpecCalcSplit( dLenRaw, dMaxLenLeft) + local vCmd = {} + local bSplit = ( EMC.Y2DELTA ~= nil) + local ParkT = EgtIf( bSplit and dMaxLenLeft > ParkV1 - 50, LoadT, ParkV1) + table.insert( vCmd, { 0, EgtIf( bSplit, 'Split', 'Fall')}) + if not bSplit then EnsureZmaxAtEnd( vCmd) end + -- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari) + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + table.insert( vCmd, { 31, nRawId, 'Y1'}) + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- riporto il carrello Y al carico con il resto della trave + local dLDelta = EMC.Y1DELTA - dLenRaw + table.insert( vCmd, { 1, 'Y1', ParkT + dLDelta}) + table.insert( vCmd, { 21, 0, EMC.Y2DELTA or 0}) + -- imposto subito Y non più attaccato alla trave in lavoro + EMC.Y1DELTA = nil + -- salvo posizione carrello Y in disposizione del pezzo dopo split + local PostDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if PostDispId then + if not bSplit then + EgtSetInfo( PostDispId, 'TPOS', ParkT) + else + EgtRemoveInfo( PostDispId, 'TPOS') + EgtSetInfo( PostDispId, 'TPARK', ParkT) + end + EgtSetInfo( PostDispId, 'Y1POS', ParkT + dLDelta) + end + -- salvo posizione grezzo rimasto e posizione carrello Y nella disposizione iniziale del pezzo succ (prossima fase dispari) + local NextDispId = EgtGetPhaseDisposition( nNextOddPhase) + if NextDispId then + EgtSetInfo( NextDispId, 'TPOS', ParkT) + EgtSetInfo( NextDispId, 'Y1POS', ParkT + dLDelta) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcUnload() + local vCmdPre = {} + EgtOutLog( ' *[U]') + if not EMC.Y1DELTA and not EMC.Y2DELTA then + EMC.ERR = 21 + EMC.MSG = ' Error : Y1 and Y2 not clamped for unloading' + return {} + end + local dY2DeltaMinUL = EMC.LB + MinY2 - EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) + -- Se pinza Y1 chiusa o Y2 troppo a destra, devo effettuare uno scambio + if EMC.Y1DELTA or EMC.Y2DELTA < dY2DeltaMinUL then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + if not nLastEntId then + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL')) + nLastEntId = EgtGetLastInGroup( nPathId) + end + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + -- imposto quote aggancio per avere solo pinza V + local dDistFront = EMC.LB - MinJoin - EMC.HOVM + 10 * GEO.EPS_SMALL + local dDistBack = 0 + -- imposto rulli aperti (in ogni caso pezzo sicuramente grande) + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack, 0, 0, nil, dY2DeltaMinUL) + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' *[U1]') + end + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Unloading'}) + -- posizionamento sicuro teste e rulli (non serve ?) + --table.insert( vCmd, { 4, 0}) + -- Se pinza Y chiusa, la apro + if EMC.Y1DELTA then + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + end + -- Sposto il pezzo in posizione di scarico + local dFinT = EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) - EMC.LB + local dFinY2 = dFinT + EMC.Y2DELTA + table.insert( vCmd, { 2, 'T', dFinT, 'Y2', dFinY2}) + EgtOutLog( ' Y2PosF=' .. EgtNumToString( dFinY2)) + -- apro la morsa + table.insert( vCmd, { 12, 0}) + -- riporto il carrello in home + table.insert( vCmd, { 1, 'Y2', ParkY2}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcPreRot() + local vCmdPre = {} + EgtOutLog( ' *[PR]') + -- Se pinza Y2 chiusa , devo effettuare uno scambio + if EMC.Y2DELTA then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + -- imposto quote aggancio per avere solo pinza Y + local dDistFront = 0 + local dDistBack = EMC.LB - MinOther - EMC.HOVM + 10 * GEO.EPS_SMALL + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack, 0, 0) + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' [PR1]') + end + -- porto il pezzo alla zona di rotazione con il carro Y1 + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Pre Rotation'}) + -- posizionamento sicuro teste e rulli + EnsureZmax( true, vCmd) + -- Se pinza V chiusa, la apro + if EMC.Y2DELTA then + table.insert( vCmd, { 12, 0}) + end + -- riporto la trave al carico + local RotT = LoadT + TurnerOffs + table.insert( vCmd, { 2, 'Y1', RotT + EMC.Y1DELTA, 'T', RotT}) + -- apro la morsa + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + -- riporto il carrello in home + table.insert( vCmd, { 1, 'Y1', ParkY1}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +local function ChangedTool( nMchId) + local bChanged = false + -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine + local nOrigMchId = EgtGetCurrMachining() + local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- Recupero l'utensile della lavorazione precedente + local nPrevMchId = EgtGetPrevActiveOperation( nMchId or GDB_ID.NULL) + if nPrevMchId and EgtGetOperationType( nPrevMchId) ~= MCH_OY.DISP then + EgtSetCurrMachining( nPrevMchId) + local sTool = EgtGetMachiningParam( MCH_MP.TOOL) + bChanged = ( sTool ~= sOrigTool) + end + -- Ripristino lavorazione e utensile correnti + if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end + if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end + return bChanged +end + +-------------------------------------------------------------------------------------------------------- +-- **CHIAMATA DELLE FUNZIONI Spec** +-------------------------------------------------------------------------------------------------------- +function SpecAdjustCarriages( WorkTab) + + --EgtOutLog( ' --->>> CNT=' .. EgtIf( EMC.CNT, '1', '_')) + + -- Aggiorno la posizione dei rulli per eventuale cambio utensile + if ChangedTool( EMC.MCHID) then + WorkTab.dV1PosI = ParkV1 + WorkTab.dV2PosI = ParkV2 + end + -- Verifico se compattare i rulli + local bCloseV = false + if WorkTab.dY1DeltaI then + if WorkTab.dY1DeltaI <= MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + EMC.HCING + EMC.HOVM + EgtIf( EMC.CNT == 1, AggLoad, 0) then + bCloseV = true + end + end + if WorkTab.dY2DeltaI then + if EMC.LB - WorkTab.dY2DeltaI <= MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V then + bCloseV = true + end + end + WorkTab.bCloseV = bCloseV + + -- |POSIZIONO Y1| **[A]** + if WorkTab.dY1DeltaMinF and ( not WorkTab.dY2DeltaMinF) then + -- [A1]/[A2] continuazione da morsa Y1 ( Y1 -> Y1 ) scambio Y2 (Y2 -> Y1) + if ( WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI)) or ( WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI)) then + WorkTab.bY1Parked = not WorkTab.dY1DeltaI + WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) + WorkTab.bY2Parked = not WorkTab.dY2DeltaI + WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) + return SpecAdjustCarrA( WorkTab) + else + EgtOutLog( ' Error CLAMP NULL-> Y1 impossibile') + error( 'Error CLAMP NULL-> Y1 impossibile') + end + + -- |POSIZIONO Y1Y2| **[B]** + elseif WorkTab.dY1DeltaMinF and WorkTab.dY2DeltaMinF then + -- [B1] passo da carrello Y1 a entrambi + if WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI) then + WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) + return SpecAdjustCarrB1( WorkTab) + -- [B2] passo da carrello Y2 a entrambi + elseif WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI) then + WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) + return SpecAdjustCarrB2(WorkTab) + -- [B3] rimango con due carrelli ( per ora accetto solo il caso in cui le posizioni sono già valide) + elseif WorkTab.dY1DeltaI > WorkTab.dY1DeltaMinF - 10 * GEO.EPS_SMALL and WorkTab.dY1DeltaI < WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and + WorkTab.dY2DeltaI > WorkTab.dY2DeltaMinF - 10 * GEO.EPS_SMALL and WorkTab.dY2DeltaI < WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then + EgtOutLog( '*[B3]') + return {} + else + EgtOutLog( ' Error CLAMP NULL-> Y1+Y2 impossibile') + error( 'Error CLAMP NULL-> Y1+Y2 impossibile') + end + + -- |POSIZIONO Y2| **[C]** + elseif not WorkTab.dY1DeltaMinF and WorkTab.dY2DeltaMinF then + -- [C1]/[C2] continuazione da morsa Y2 ( Y2 -> Y2 ) sacmbio Y1 (Y1 -> Y2) + if ( WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI)) or ( WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI)) then + WorkTab.bY1Parked = not WorkTab.dY1DeltaI + WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) + WorkTab.bY2Parked = not WorkTab.dY2DeltaI + WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) + return SpecAdjustCarrC( WorkTab) + else + EgtOutLog( ' Error CLAMP NULL-> Y2 impossibile') + error( 'Error CLAMP NULL-> Y2 impossibile') + end + end + +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y1 (aperta) e Y2 (chiusa) in **accentramento** +local function PosForCent1FY1( dY1a, dY2a, dTa, dExtraY1, dCorsaY1c, dCorsaY2Tc) + local dY2Delta = dY2a - dTa + local dDispl = dCorsaY1c - dExtraY1 + if dDispl / 2 <= dCorsaY2Tc then + if dDispl / 2 <= dCorsaY1c then + dY1a = dY1a - dDispl / 2 + dY2a = dY2a + dDispl / 2 + else + dY1a = dY1a - dCorsaY1c + dY2a = dY2a + dDispl - dCorsaY1c + end + else + dY2a = dY2a + dCorsaY2Tc + dY1a = dY1a - (dDispl - dCorsaY2Tc) + end + dTa = dY2a - dY2Delta + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y2 (aperta) e Y1 (chiusa) in **accentramento** +local function PosForCent1FY2( dY1a, dY2a, dTa, dExtraY2, dCorsaY1Tc, dCorsaY2c) + local dY1Delta = dY1a - dTa + local dDispl = dCorsaY2c + dExtraY2 + if dDispl / 2 <= dCorsaY1Tc then + if dDispl / 2 <= dCorsaY2c then + dY1a = dY1a - dDispl / 2 + dY2a = dY2a + dDispl / 2 + else + dY2a = dY2a + dCorsaY2c + dY1a = dY1a - min( dDispl - dCorsaY2c, dCorsaY1Tc) + end + else + dY1a = dY1a - dCorsaY1Tc + dY2a = dY2a + min( dDispl - dCorsaY1Tc, dCorsaY2c) + end + dTa = dY1a - dY1Delta + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y1 (aperta) e Y2 (chiusa) in **allontanamento** +local function PosForEnl1FY1( dY1a, dY2a, dTa, dExtra, dCorsaY1e, dCorsaY2Te) + local dDispl = MaxY1 - dY1a + dExtra + -- eseguo il posizionamento di Y1 allontanando Y1 e (Y2+T) + if dDispl/2 <= dCorsaY2Te then + if dDispl/2 <= dCorsaY1e then + dY1a = dY1a + dDispl / 2 + dY2a = dY2a - dDispl / 2 + dTa = dTa - dDispl / 2 + else + dY1a = dY1a + dCorsaY1e + dY2a = dY2a - (dDispl - dCorsaY1e) + dTa = dTa - (dDispl - dCorsaY1e) + end + else + dY2a = dY2a - dCorsaY2Te + dTa = dTa - dCorsaY2Te + dY1a = dY1a + (dDispl - dCorsaY2Te) + end + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y2 (aperta) e Y1 (chiusa) in **allontanamento** +local function PosForEnl1FY2( dY1a, dY2a, dTa, dExtra, dCorsaY1Te, dCorsaY2e) + local dDispl = dY2a - MinY2 - dExtra + -- eseguo il posizionamento di Y2 allontanando (Y1+T) e Y2 + if dDispl/2 <= dCorsaY1Te then + if dDispl/2 <= dCorsaY2e then + dY1a = dY1a + dDispl / 2 + dTa = dTa + dDispl / 2 + dY2a = dY2a - dDispl / 2 + else + dY2a = dY2a - dCorsaY2e + dY1a = dY1a + (dDispl - dCorsaY2e) + dTa = dTa + (dDispl - dCorsaY2e) + end + else + dY1a = dY1a + dCorsaY1Te + dTa = dTa + dCorsaY1Te + dY2a = dY2a - (dDispl - dCorsaY1Te) + end + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +local function MaxDispl( TabI, vCmd, sType) + local dY1a, dY2a + local dTa = TabI.dTPosI + -- **[M1]** = allontanamento dei trascinatori con Y1 in presa + if sType == 'M1' then + EmitComment( vCmd, '[M1]') + -- ev' chiudo Y1, apro Y2 + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- allontano (Y1+T) e (Y2) + dY1a = MaxY1 + dY2a = MinY2 + dTa = ( MaxY1 - TabI.dY1PosI) + dTa + -- **[M2]** = allontanamento dei trascinatori con Y2 in presa + elseif sType == 'M2' then + EmitComment( vCmd, '[M2]') + -- ev' chiudo Y2, apro Y1 + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + -- allontano (Y2+T) e (Y1) + dY1a = MaxY1 + dY2a = MinY2 + dTa = ( MinY2 - TabI.dY2PosI) + dTa + -- **[M3]** = accentramento dei trascinatori con Y1 in presa + elseif sType == 'M3' then + EmitComment( vCmd, '[M3]') + -- ev' chiudo Y1, apro Y2 + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- accentro (Y1+T) e (Y2) + dY1a = TabI.MyMinY1V1 + dY2a = TabI.MaxY2V2 + dTa = ( TabI.MyMinY1V1 - TabI.dY1PosI) + dTa + -- **[M4]** = accentramento dei trascinatori con Y2 in presa + elseif sType == 'M4' then + EmitComment( vCmd, '[M4]') + -- ev' chiudo Y2, apro Y1 + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + -- accentro (Y2+T) e (Y1) + dY1a = TabI.MyMinY1V1 + dY2a = TabI.MaxY2V2 + dTa = ( TabI.MaxY2V2 - TabI.dY2PosI) + dTa + end + -- + table.insert( vCmd, { 3, 'Y1', dY1a, 'Y2', dY2a, 'T', dTa}) + TabI.dY1PosI = dY1a + TabI.dY2PosI = dY2a + TabI.dTPosI = dTa +end -- MaxDisplForRiXw + +----------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y1** +------------------------------------------------------------------------------------------------------------------ +local function PosY1FromY2A( TabI, vCmd) + EmitComment( vCmd, '[PosY1FromY2A]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY1New = (TabI.dTPosI + t.dY1NewDelta) - MaxY1 --se > 0, la posizione non è raggiunginile + -- corse disponibili in allontanamento (enlargement) dalle posizioni attuali per Y1 e (Y2+T) + t.dCorsaY1eI = MaxY1 - TabI.dY1PosI + t.dCorsaY2TeI= TabI.dY2PosI - MinY2 + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y1 già entro l'intervallo : non si deve muovere + t.dY1DeltaI = TabI.dY1PosI-TabI.dTPosI + if t.dY1DeltaI < TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY1DeltaI > TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y1(0)] ') + --return t.dY1DeltaI + -- **[ri]** = posY1New non raggiungibile direttamente -> muovo fino a fine corsa + elseif t.dExtraY1New > t.dCorsaY2TeI then + EmitComment( vCmd, '[Y1A-ri]') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M2') + --t.bXW = true + else + -- **[rp]** = raggiungo il punto medio Y1New dell'intervallo + EmitComment( vCmd, '[Y1A-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- **1:** calcolo pos. di allontanamento per (Y1) e (Y2+T) (da posizioni iniziali) + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForEnl1FY1( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY1New, t.dCorsaY1eI, t.dCorsaY2TeI) + -- aggiornamento posizioni e dY1Delta dopo + -- chiusura di Y1, apertura e parcheggio di Y2 a fine funzione + -- ev' chiudo Y2 e apro Y1 ed eseguo allontanamento + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + t.dY1DeltaA = TabI.dY1PosI - TabI.dTPosI + -- chiusura di Y1, ev' apertura e parcheggio di Y2 : in funzioni chiamanti + return t.dY1DeltaA +end -- PosY1FromY2A + +-------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y2** +-------------------------------------------------------------------------------------------------------- +local function PosY2FromY1A( TabI, vCmd) + EmitComment( vCmd, '[PosY2FromY1A]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY2New = ( TabI.dTPosI + t.dY2NewDelta) - MinY2 --se < 0, la posizione non è raggiunginile + -- corse disponibili in allontanamento (enlargement) dalle posizioni attuali per (Y1+T) e Y2 + t.dCorsaY1Te = MaxY1 - TabI.dY1PosI + t.dCorsaY2e = TabI.dY2PosI - MinY2 + -- + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y2 già entro l'intervallo : non si deve muovere + t.dY2DeltaI = TabI.dY2PosI- TabI.dTPosI + if t.dY2DeltaI < TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY2DeltaI > TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y2(0)] ') + -- **[ri]** = posY2New non raggiungibile direttamente -> muovo fino a fine corsa + elseif -t.dExtraY2New > t.dCorsaY1Te then + EmitComment( vCmd, '[Y2A-ri]' ) + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M1') + else + -- **[rp]** = raggiungo il punto medio Y2New dell'intervallo + EmitComment( vCmd, '[Y2A-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- **1:** calcolo pos. di allontanamento per (Y1+T) e (Y2) (da posizioni iniziali) + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForEnl1FY2( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY2New, t.dCorsaY1Te, t.dCorsaY2e) + -- chiudo Y1 e apro Y2 ed eseguo allontanamento (finale) + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + t.dY2DeltaA = TabI.dY2PosI - TabI.dTPosI + -- chiusura di Y2, ev' apertura e parcheggio di Y1 : in funzioni chiamanti + return t.dY2DeltaA +end -- PosY2FromY1A + +------------------------------------------------------------------------------------------------------------ +-- **ACCENTRAMENTO di Y1** +------------------------------------------------------------------------------------------------------------ +local function PosY1FromY2B( TabI, vCmd) + EmitComment( vCmd, '[PosY1FromY2B]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY1New = (TabI.dTPosI + t.dY1NewDelta) - TabI.MyMinY1V1 -- se < 0, la posizione non è raggiunginile + -- corse in accentramento disponibili per Y1 e (Y2+T) dalle posizioni iniziali + t.dCorsaY1cI = TabI.dY1PosI - TabI.MyMinY1V1 + t.dCorsaY2TcI = TabI.MaxY2V2 - TabI.dY2PosI + -- + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y1 già entro l'intervallo : non si deve muovere + t.dY1DeltaI = TabI.dY1PosI-TabI.dTPosI + if t.dY1DeltaI < TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY1DeltaI > TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y1(0)] ') + -- **[ri]** = posY1New non raggiungibile direttamente -> muovo fino a fine corsa + elseif -t.dExtraY1New > t.dCorsaY2TcI then + EmitComment( vCmd, '[Y1B-ri]') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M4') + else + -- **[rp]** = raggiungo il punto medio Y1New dell'intervallo + EmitComment( vCmd, '[Y1B-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- **1: calcolo accentramento di (Y1) e (Y2+T)** + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForCent1FY1( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY1New, t.dCorsaY1cI, t.dCorsaY2TcI) + -- posizionamento efettivo e aggiornamento di vCmd e dY1Delta dopo + -- ch. di Y1 e ap. e parcheggio di Y2 a fine funzione chiamante + -- chiudo Y2 e apro Y1 ed eseguo accentramento (finale) + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + t.dY1DeltaA = TabI.dY1PosI - TabI.dTPosI + -- chiusura di Y1, ev' apertura e parcheggio di Y2 : in funzioni chiamanti + return t.dY1DeltaA +end -- PosY1FromY2B + +-------------------------------------------------------------------------------------------------------- +-- **ACCENTRAMENTO di Y2** +-------------------------------------------------------------------------------------------------------- +local function PosY2FromY1B( TabI, vCmd) + EmitComment( vCmd, '[PosY2FromY1B]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY2New = (TabI.dTPosI + t.dY2NewDelta) - TabI.MaxY2V2 -- se > 0 la posizione non è raggiunginile + -- corse in accentramento disponibili per (Y1+T) e (Y2) dalle posizioni iniziali + t.dCorsaY1TcI = TabI.dY1PosI - TabI.MyMinY1V1 + t.dCorsaY2cI = TabI.MaxY2V2 - TabI.dY2PosI + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y2 già entro l'intervallo : non si deve muovere + t.dY2DeltaI = TabI.dY2PosI-TabI.dTPosI + if t.dY2DeltaI < TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY2DeltaI > TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y2(0)] ') + -- **[ri]** = posY2New non raggiungibile direttamente -> muovo fino a fine corsa + elseif t.dExtraY2New > t.dCorsaY1TcI then + EmitComment( vCmd, '[Y2B-ri]' ) + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M3') + else + -- **[rp]** = raggiungo il punto medio Y2New dell'intervallo + EmitComment( vCmd, '[Y2B-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- Y1 chiuso, Y2 aperto + -- **1: calcolo accentramento di (Y1+T) e (Y2)** + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForCent1FY2( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY2New, t.dCorsaY1TcI, t.dCorsaY2cI) + -- ev' chiudo Y1 e apro Y2 ed eseguo movimento accentramento + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + t.dY2DeltaA = TabI.dY2PosI - TabI.dTPosI + -- chiusura di Y2, apertura e parcheggio di Y1 : in funzioni chiamanti + return t.dY2DeltaA +end -- PosY2FromY1B + +-------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y1 per pos. di Y2 o Y2+Y1** - chiamata da [B2] e [C] +-------------------------------------------------------------------------------------------------------- +local function PosY1Y2A( TabI, vCmd) + EmitComment( vCmd, '[PosY1Y2A]') + -- |RICONOSCO I CASI| + repeat + local dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 + local bXW = true + -- se intervallo per Y1 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 <=> ( -ExtraI1MaxF < Corsa Y2Tc) + -- e Y2 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 1| in **allontanamento** + PosY1FromY2A( TabI, vCmd) + -- |POSIZIONO MORSA 2| + if (TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- in **allontanamento** + PosY2FromY1A( TabI, vCmd) + else + -- in **accentramento** + PosY2FromY1B( TabI, vCmd) + end + bXW = false + else + -- |POSIZIONO MORSA 2| e poi MORSA 1 + -- in **allontanamento** + if (TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- se intervallo per Y2 raggiungibile in una sola fase + if - (( TabI.dTPosI + TabI.dY2DeltaMaxF) - MinY2) < MaxY1 - TabI.dY1PosI then + PosY2FromY1A( TabI, vCmd) + PosY1FromY2A( TabI, vCmd) + bXW = false + end + else + -- in **accentramento** + -- sempre se intervallo per Y2 raggiungibile in una sola fase + if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 then + PosY2FromY1B( TabI, vCmd) + PosY1FromY2A( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione negativa ( casi **[xw]**) + EmitComment( vCmd, '[Y1A-xw]') + if TabI.dY1PosI ~= TabI.MyMinY1V1 then + -- accentramento morse, trascinamento trave con Y1 + MaxDispl( TabI, vCmd, 'M3') + else + -- allontanamento morse, trascinamento trave con Y2 + MaxDispl( TabI, vCmd, 'M2') + end + end + until ( not bXW) + -- chiusura/parcheggio dei trascinatori in funzioni chiamanti + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY1Y2A + +-------------------------------------------------------------------------------------------------------- +-- **ACCENTRAMENTO di Y1 per pos. di Y2 o Y2+Y1** - chiamata da [B2] e [C] +-------------------------------------------------------------------------------------------------------- +local function PosY1Y2B( TabI, vCmd) + EmitComment( vCmd, '[PosY1Y2B]') + -- |RICONOSCO I CASI| + local nCnt = 0 + repeat + local dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF) / 2 + local bXW = true + -- se intervallo per Y1 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 <=> ( -ExtraI1MaxF < Corsa Y2Tc) + -- e Y2 è in posizione per aggancio su T + if -(( TabI.dTPosI + TabI.dY1DeltaMaxF) - TabI.MyMinY1V1) < TabI.MaxY2V2 - TabI.dY2PosI and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 1| in **accentramento** + PosY1FromY2B( TabI, vCmd) + -- |POSIZIONO MORSA 2| + local dY2DeltaI = TabI.dY2PosI - TabI.dTPosI + -- Se il trascinatore 2 non è già nell'intervallo richiesto + if dY2DeltaI > TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL or dY2DeltaI < TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then + if ( TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- in **allontanamento** + PosY2FromY1A( TabI, vCmd) + else + -- in **accentramento** + PosY2FromY1B( TabI, vCmd) + end + end + bXW = false + -- se posso posizionare 'direttamente' Y2 all'interno dell'intervallo I2 (casi [rp] o [ri]) + else + -- |POSIZIONO MORSA 2| e poi MORSA 1 + -- in **allontanamento** + if ( TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- se intervallo per Y2 è raggiungibile in una sola fase e Y1 è in posizione per aggancio su T + if -(( TabI.dTPosI + TabI.dY2DeltaMaxF) - MinY2) < MaxY1 - TabI.dY1PosI and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + PosY2FromY1A( TabI, vCmd) + PosY1FromY2B( TabI, vCmd) + bXW = false + end + -- in **accentramento** + else + -- sempre se intervallo per Y2 è raggiungibile in una sola fase e Y1 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 and + TabI.dY1PosI <= TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + PosY2FromY1B( TabI, vCmd) + PosY1FromY2B( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione positiva (casi **[xw]** ) + -- se Y1 non è a f.c. e se Y1 può afferrare la trave + EmitComment( vCmd, '[Y1B-xw]') + if TabI.dY1PosI ~= MaxY1 and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + -- allontanamento morse, trascinamento trave con Y1 + MaxDispl( TabI, vCmd, 'M1') + else + -- accentramento morse, trascinamento trave con Y2 + MaxDispl( TabI, vCmd, 'M4') + end + end + nCnt = nCnt + 1 + if nCnt > 5 then return end + until ( not bXW) + -- chiusura/parcheggio dei trascinatori in funzioni chiamanti + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY1Y2B + +-------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y2 per pos. di Y1 o Y1+Y2** - chiamata da [A] e [B1] +-------------------------------------------------------------------------------------------------------- +local function PosY2Y1A( TabI, vCmd) + EmitComment( vCmd, '[PosY2Y1A]') + -- |RICONOSCO I CASI| + repeat + local dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 + local bXW = true + -- se intervallo per Y2 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y2 all'interno dell'intervallo <=> ( -ExtraI2MaxF < Corsa Y1Te and) + -- e Y1 è in posizione per aggancio su T + if MinY2 - ( TabI.dTPosI + TabI.dY2DeltaMaxF) < MaxY1 - TabI.dY1PosI and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 2| in **allontanamento** + PosY2FromY1A( TabI, vCmd) + -- |POSIZIONO MORSA 1| + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- in **allontanamento** + PosY1FromY2A( TabI, vCmd) + else + -- in **accentramento** + PosY1FromY2B( TabI, vCmd) + end + bXW = false + else + -- |POSIZIONO MORSA 1| e poi MORSA 2 + -- caso di allontanamento + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- se l'intervallo per Y1 è raggiungibile in una sola fase + if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 then + PosY1FromY2A( TabI, vCmd) + PosY2FromY1A( TabI, vCmd) + bXW = false + end + -- in **accentramento** + else + -- sempre se l'intervallo per Y1 è raggiungibile in una sola fase + if TabI.MyMinY1V1 - ( TabI.dTPosI + TabI.dY1DeltaMaxF) < TabI.MaxY2V2 - TabI.dY2PosI then + PosY1FromY2B( TabI, vCmd) + PosY2FromY1A( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione positiva (casi **[xw]**) + EmitComment( vCmd, '[Y2A-xw]') + -- accentramento morse, trascinamento trave con Y2 + if TabI.dY2PosI ~= TabI.MaxY2V2 then + MaxDispl( TabI, vCmd, 'M4') + -- allontanamento morse, trascinamento trave con Y1 + else + MaxDispl( TabI, vCmd, 'M1') + end + end + + until ( not bXW) + -- chiusura/parcheggio dei trascinatori in funzioni chiamanti + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY2Y1A + +-------------------------------------------------------------------------------------------------------- +-- **ACCENTRAMENTO di Y2 per pos. di Y1 o Y1+Y2** - chiamata da [A] e [B1] +-------------------------------------------------------------------------------------------------------- +local function PosY2Y1B( TabI, vCmd) + EmitComment( vCmd, '[PosY2Y1B]') + -- |RICONOSCO I CASI| + local nCnt = 0 + repeat + local dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF) / 2 + local bXW = true + -- se intervallo per Y2 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y2 all'interno dell'intervallo I2 <=> (-ExtraI2MinF < Corsa Y1Tc) + -- e Y1 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 2| in **accentramento** + PosY2FromY1B( TabI, vCmd) + -- |POSIZIONO MORSA 1| + local dY1DeltaI = TabI.dY1PosI - TabI.dTPosI + -- Se il trascinatore 1 non è già nell'intervallo richiesto + if dY1DeltaI > TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL or dY1DeltaI < TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- in **allontanamento** + PosY1FromY2A( TabI, vCmd) + else + -- in **accentramento** + PosY1FromY2B( TabI, vCmd) + end + end + bXW = false + -- se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 (casi [rp] o [ri]) + else + -- |POSIZIONO MORSA 1| e poi MORSA 2 + -- in **allontanamento** + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- se intervallo per Y1 è raggiungibile in una sola fase e Y2 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + PosY1FromY2A( TabI, vCmd) + PosY2FromY1B( TabI, vCmd) + bXW = false + end + -- in **accentramento** + else + -- se (-ExtraI1MaxF < Corsa Y2Tc) e (Y2 è in posizione per aggancio su T) + if TabI.MyMinY1V1 - ( TabI.dTPosI + TabI.dY1DeltaMaxF) < TabI.MaxY2V2 - TabI.dY2PosI and + TabI.dY2PosI >= TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + PosY1FromY2B( TabI, vCmd) + PosY2FromY1B( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione negativa (casi x[w]) + EmitComment( vCmd, '[Y2B-xw]') + -- se Y2 non è a f.c. e se Y2 può afferrare la trave + if TabI.dY2PosI > MinY2 and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HOVM + EMC.HCING - 10 * GEO.EPS_SMALL then + -- allontanamento morse, trascinamento trave con Y2 + MaxDispl( TabI, vCmd, 'M2') + else + -- accentramento morse, trascinamento trave con Y1 + MaxDispl( TabI, vCmd, 'M3') + end + end + nCnt = nCnt + 1 + if nCnt > 5 then return end + until ( not bXW) + -- la chiusura delle morse è fatta sopra + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY2Y1FromY1B + +--------------------------------------------------------------------- +-- **[A] Posizionamento trascinatore Y1 da (Y1 o Y2) <=> Y1/Y2 -> Y1** +--------------------------------------------------------------------- +function SpecAdjustCarrA( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y1/Y2 -> Y1'}) + EmitComment( vCmd, '*[A]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + -- recupero le posizioni correnti + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY1DeltaF + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + EgtOutLog( ' Y1DeltaI=' .. EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI=' .. EgtNumToString( WorkTab.dY2DeltaI)) + EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF)) + + -- [A(1)] - Se il trascinatore Y1 non è nell'intervallo valido, devo posizionarlo + if WorkTab.dY1DeltaI < WorkTab.dY1DeltaMinF - GEO.EPS_SMALL or WorkTab.dY1DeltaI > WorkTab.dY1DeltaMaxF + GEO.EPS_SMALL then + EmitComment( vCmd, '*[A(1)]') + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + -- eseguo eventuale posizionamento sicuro di teste e rulli + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + -- ------------------------------------------ + -- |DEFINISCO INTERVALLO 2| + -- ------------------------------------------ + WorkTab.dY2DeltaMaxF = WorkTab.dY1DeltaMinF - ( MyMinY1V1 - MaxY2V2) + ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF) + WorkTab.dY2DeltaMinF = WorkTab.dY1DeltaMaxF - ( MaxY1 - MinY2) - ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF) + -- se Y2 deve allontanarsi assegno il primo punto valido (altrimenti mantengo tutto l'intervallo valido) + if WorkTab.dY2DeltaI > WorkTab.dY2DeltaMaxF then + WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMaxF - ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF), MinJoin + EMC.HCING + EMC.HOVM) + end + -- se la trave è più 'corta' dell'intervallo per Y2 aggiorno l'intervallo (potrei essere comunque in un punto valido) + if WorkTab.dY2DeltaMinF < MinJoin + EMC.HCING + EMC.HOVM then + WorkTab.dY2DeltaMinF = MinJoin + EMC.HCING + EMC.HOVM + -- se Y2 deve accentrarsi + if WorkTab.dY2DeltaI < WorkTab.dY2DeltaMinF then + WorkTab.dY2DeltaMaxF = 2 * ( MinJoin + EMC.HCING + EMC.HOVM) + end + end + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 + local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 + -------------------------------------------- + -- |RICONOSCO I CASI| + -------------------------------------------- + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } + if WorkTab.dY1DeltaI > dY1NewDelta then + --[A(1)B] **ACCENTRAMENTO** (dall'origine) del trascinatore Y1 + EmitComment( vCmd, '[A-Y1B]') + dY1DeltaF = PosY1Y2B( TabValI, vCmd) + else + --[A(1)A] **ALLONTANAMENTO** (dall'origine) del trascinatore Y1 + EmitComment( vCmd, '[AY1A]') + dY1DeltaF = PosY1Y2A( TabValI, vCmd) + end + -- chiudo Y1 + table.insert( vCmd, { 11, 1}) + -- dichiaro Y2 da parcheggiare + WorkTab.bY2Parked = false + + -- [A(0)] - Se Y1 è già nell'intervallo valido, si lascia dove è + else + EmitComment( vCmd, '*[A(0)]') + if not WorkTab.bY2Parked then + -- dichiaro posizione di Y2 e T + table.insert( vCmd, { 2, 'T', WorkTab.dTPosI, 'Y2', dY2PosI}) + end + if WorkTab.bY1Parked then + -- chiudo Y1 + table.insert( vCmd, { 11, 1}) + end + dY1DeltaF = WorkTab.dY1DeltaI + end + + if not WorkTab.bY2Parked then + -- apro e parcheggio Y2 + table.insert( vCmd, { 12, 0}) + table.insert( vCmd, { 1, 'Y2', ParkY2}) + end + + -- aggiorno e segnalo la posizione finale Y1Delta + table.insert( vCmd, { 21, dY1DeltaF, 0}) + EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF)) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end +-- SpecAdjustCarrAA + +-------------------------------------------------------------------- +-- **[B1] da trascinatore Y1 a entrambi <=> Y1 -> Y1+Y2** +-------------------------------------------------------------------- +function SpecAdjustCarrB1( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y1 -> Y1+Y2'}) + EmitComment( vCmd, '*[B1]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + + -- recupero le posizioni correnti + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY1DeltaF, dY2DeltaF + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 + local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 + -- + EgtOutLog( ' Y1DeltaI='..EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI='..EgtNumToString( WorkTab.dY2DeltaI)) + EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF)) + EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF)) + + -- Il controllo che i trascinatori non siano già nell'intervallo valido è svolto nelle funzioni a valle + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + + -- ----------------------------------------- + -- |RICONOSCO I CASI| + -- ------------------------------------------ + -- definisco la tabella delle posizioni iniziali + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } + -- [B1-Y2A] **ALLONTANAMENTO** del trascinatore **Y2** e (eventuale) posizionamento di Y1 + if WorkTab.dY2DeltaI > dY2NewDelta then + EmitComment( vCmd, '[B1-Y2A]') + dY1DeltaF, dY2DeltaF = PosY2Y1A( TabValI, vCmd) + else + -- [B1-Y2B] **ACCENTRAMENTO** del trascinatore **Y2** e (eventuale) posizionamento di Y1 + EmitComment( vCmd, '[B1-Y2B] ') + dY1DeltaF, dY2DeltaF = PosY2Y1B( TabValI, vCmd) + end + -- ----------------------------------------- + -- |CHIUSURA MORSE| + -- ------------------------------------------ + if not SpecTestSomeMoveInCmds( vCmd) then + table.insert( vCmd, { 3, 'Y1', dY1PosI, 'Y2', dY2PosI, 'T', WorkTab.dTPosI}) + end + table.insert( vCmd, { 11, 1}) -- chiudo Y1 + table.insert( vCmd, { 12, 1}) -- Chiudo Y2 + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dY1DeltaF, dY2DeltaF}) + EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF) .. ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF)) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end +-- SpecAdjustCarrB1 + +--------------------------------------------------------------------- +-- **[B2] da trascinatore Y2 a entrambi <=> Y2 -> Y1+Y2** +-------------------------------------------------------------------- +function SpecAdjustCarrB2( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y2 -> Y1+Y2'}) + EmitComment( vCmd, '*[B2]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + + -- definisco le posizioni **Iniziali** (= recupero le posizioni correnti) + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY2DeltaF, dY1DeltaF + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 + local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 + -- + EgtOutLog( ' Y1DeltaI='..EgtNumToString( WorkTab.dY1DeltaI)..' Y2DeltaI='..EgtNumToString( WorkTab.dY2DeltaI) ) + EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF)) + EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF)) + + -- Il controllo che i trascinatori non siano già nell'intervallo valido è svolto nelle funzioni a valle + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + -- eseguo eventuale posizionamento sicuro di teste e rulli + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + + -- ----------------------------------------- + -- |RICONOSCO I CASI| + -- ------------------------------------------ + -- definisco la tabella delle posizioni iniziali + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } + -- [B2-Y1A] **ALLONTANAMENTO** del trascinatore **Y1** e (eventuale) posizionamento di Y2 + if WorkTab.dY1DeltaI < dY1NewDelta then + EmitComment( vCmd, '[B2-Y1A]') + dY1DeltaF, dY2DeltaF = PosY1Y2A( TabValI, vCmd) + else + -- [B2-Y1B] **ACCENTRAMENTO** del trascinatore **Y1** e (eventuale) posizionamento di Y2 + EmitComment( vCmd, '[B2-Y1B]') + dY1DeltaF, dY2DeltaF = PosY1Y2B( TabValI, vCmd) + end + + -- ----------------------------------------- + -- |CHIUSURA MORSE| + -- ------------------------------------------ + if not SpecTestSomeMoveInCmds( vCmd) then + table.insert( vCmd, { 3, 'Y1', dY1PosI, 'Y2', dY2PosI, 'T', WorkTab.dTPosI}) + end + table.insert( vCmd, { 11, 1}) -- chiudo Y1 + table.insert( vCmd, { 12, 1}) -- Chiudo Y2 + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dY1DeltaF, dY2DeltaF}) + EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF) .. ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF)) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end +-- SpecAdjustCarrB2 + +--------------------------------------------------------------------- +-- **[C] ex[C1]/[C2] Posizionamento trascinatore Y2 da (Y1 o Y2) <=> Y1/Y2 -> Y2** +--------------------------------------------------------------------- +function SpecAdjustCarrC( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y1/Y2 -> Y2'}) + EmitComment( vCmd, '*[C]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + local MyTCING = EgtIf( SPLIT, EMC.TCING, 0) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + -- recupero le posizioni correnti + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY2DeltaF + -- + EgtOutLog( ' Y1DeltaI=' .. EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI=' .. EgtNumToString( WorkTab.dY2DeltaI)) + EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF)) + + -- [C(1)] - Se il trascinatore Y2 non è nell'intervallo valido, devo posizionarlo + if WorkTab.dY2DeltaI < WorkTab.dY2DeltaMinF - GEO.EPS_SMALL or WorkTab.dY2DeltaI > WorkTab.dY2DeltaMaxF + GEO.EPS_SMALL then + EmitComment( vCmd, '*[C(1)]') + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + -- eseguo eventuale posizionamento sicuro di teste e rulli + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + -- ------------------------------------------ + -- |DEFINISCO INTERVALLO 1| + -- ------------------------------------------ + WorkTab.dY1DeltaMaxF = WorkTab.dY2DeltaMinF + (MaxY1 - MinY2) + (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF) + WorkTab.dY1DeltaMinF = WorkTab.dY2DeltaMaxF + (MyMinY1V1 - MaxY2V2) - (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF) + -- se Y1 deve allontanarsi assegno il primo punto valido (altrimenti lascio l'intervallo) + if WorkTab.dY1DeltaI < WorkTab.dY1DeltaMinF then + WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMinF + (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF), EMC.LB - MinJoin - MyTCING) + end + -- se la trave è più 'corta' dell'intervallo per Y1 aggiorno l'intervallo (potrei essere comunque in un punto valido) + if WorkTab.dY1DeltaMaxF > EMC.LB - ( MinJoin + MyTCING) then + WorkTab.dY1DeltaMaxF = EMC.LB - ( MinJoin + MyTCING) + -- se Y1 deve accentrarsi + if WorkTab.dY1DeltaI > WorkTab.dY1DeltaMaxF then + WorkTab.dY1DeltaMinF = EMC.LB - 2 *( MinJoin + MyTCING) + end + end + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = (WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF)/2 + local dY2NewDelta = (WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF)/2 + + -- ------------------------------------------ + -- |RICONOSCO I CASI| + -- ------------------------------------------ + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF} + if WorkTab.dY2DeltaI < dY2NewDelta then + -- [C-Y2B] **ACCENTRAMENTO** (dall'origine) del trascinatore Y2 + EmitComment( vCmd, '[C-Y2B]') + _, dY2DeltaF = PosY2Y1B( TabValI, vCmd) + else + -- [C-Y2A] **ALLONTANAMENTO** (dall'origine) del trascinatore Y2 + EmitComment( vCmd, '[C-Y2A]') + _, dY2DeltaF = PosY2Y1A( TabValI, vCmd) + end + -- chiudo Y2 + table.insert( vCmd, { 12, 1}) + -- dichiaro Y1 da parcheggiare + WorkTab.bY1Parked = false + + -- [C(0)] - Se Y2 è già nell'intervallo valido, si lascia dove è + else + EmitComment( vCmd, '*[C(0)]') + if not WorkTab.bY1Parked then + -- dichiaro posizione di Y1 e T + table.insert( vCmd, { 2, 'T', WorkTab.dTPosI, 'Y1', dY1PosI}) + end + if WorkTab.bY2Parked then + -- chiudo Y2 + table.insert( vCmd, { 12, 1}) + end + dY2DeltaF = WorkTab.dY2DeltaI + end + + if not WorkTab.bY1Parked then + -- apro e parcheggio Y1 + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 1, 'Y1', ParkY1}) + end + + -- aggiorno e segnalo la posizione finale Y2Delta + table.insert( vCmd, { 21, 0, dY2DeltaF}) + EgtOutLog( ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF)) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end -- SpecAdjustCarrC2 + +--------------------------------------------------------------------- +function SpecOutputCNT() + if EMC.CNT == 1 then + EgtSetInfo( EMC.PATHID, 'CNT', 1) + else + EgtRemoveInfo( EMC.PATHID, 'CNT') + end +end + +--------------------------------------------------------------------- +function SpecGetCNT( CurrOpeId) + while CurrOpeId do + local nPrevOpeId = EgtGetPrevActiveOperation( CurrOpeId) + if not nPrevOpeId then + return nil + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + if nLastPathId then + return EgtGetInfo( nLastPathId, 'CNT', 'i') + end + CurrOpeId = nPrevOpeId + end + return nil +end + +--------------------------------------------------------------------- +function SpecOutputCmds( vCmd, bEnd) + local sRoot = EgtIf( not bEnd, 'AS', 'AE') + -- Registro il numero di comandi + if #vCmd > 0 then + EgtSetInfo( EMC.PATHID, sRoot..'#', #vCmd) + else + EgtRemoveInfo( EMC.PATHID, sRoot..'#') + end + -- Registro i comandi + for i = 1, #vCmd do + local Cmd = vCmd[i] + local sKey = sRoot .. tostring( i) + -- commento + if Cmd[1] == 0 then + local sInfo = '0,'..Cmd[2] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 1 asse + elseif Cmd[1] == 1 then + local sInfo = '1,'..Cmd[2]..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 2 assi + elseif Cmd[1] == 2 then + local sInfo = '2,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 3 assi + elseif Cmd[1] == 3 then + local sInfo = '3,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3)..','.. + Cmd[6]..','..EgtNumToString( Cmd[7],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- posizione sicura per movimento carrelli + elseif Cmd[1] == 4 then + local sInfo = '4,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- apertura/chiusura morsa Y + elseif Cmd[1] == 11 then + local sInfo = '11,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- apertura/chiusura morsa V + elseif Cmd[1] == 12 then + local sInfo = '12,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- impostazione nuovo stato dei carrelli + elseif Cmd[1] == 21 then + local sInfo = '21,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = nil + elseif Cmd[3] > 0 then + EMC.Y1DELTA = nil + EMC.Y2DELTA = Cmd[3] + end + -- impostazione nuova posizione dei rulli + elseif Cmd[1] == 22 then + local sInfo = '22,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + EMC.V1POS = Cmd[2] + EMC.V2POS = Cmd[3] + -- aggancio grezzo a carrello + elseif Cmd[1] == 31 then + local sInfo = '31,'..EgtNumToString( Cmd[2],0)..','..Cmd[3] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- segnalazione errore + elseif Cmd[1] == 99 then + local sInfo = '99,' .. Cmd[2] .. ',' .. Cmd[3] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + end + end + + -- Salvo i nuovi delta dei carrelli + if EMC.Y1DELTA then + EgtSetInfo( EMC.PATHID, 'Y1DELTA', EMC.Y1DELTA) + else + EgtRemoveInfo( EMC.PATHID, 'Y1DELTA') + end + if EMC.Y2DELTA then + EgtSetInfo( EMC.PATHID, 'Y2DELTA', EMC.Y2DELTA) + else + EgtRemoveInfo( EMC.PATHID, 'Y2DELTA') + end + + --Salvo le nuove posizioni dei rulli + EgtSetInfo( EMC.PATHID, 'V1POS', EMC.V1POS) + EgtSetInfo( EMC.PATHID, 'V2POS', EMC.V2POS) + -- Se comandi finali + if bEnd then + -- Se operazione successiva è disposizione, salvo anche lì le posizioni dei rulli + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if NextDispId and NextDispId == EgtGetNextActiveOperation( EMC.DISPID or EMC.MCHID) then + EgtSetInfo( NextDispId, 'V1POS', EMC.V1POS) + EgtSetInfo( NextDispId, 'V2POS', EMC.V2POS) + end + end + +end + +--------------------------------------------------------------------- +function SpecSetCarrPosFromCmds( vCmd) + -- recupero nuova posizione carrelli + for i = 1, #vCmd do + local Cmd = vCmd[i] + if Cmd[1] == 21 then + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = nil + elseif Cmd[3] > 0 then + EMC.Y1DELTA = nil + EMC.Y2DELTA = Cmd[3] + end + elseif Cmd[1] == 22 then + EMC.V1POS = Cmd[2] + EMC.V2POS = Cmd[3] + end + end +end + +--------------------------------------------------------------------- +function SpecTestOnlyRemarkInCmds( vCmd) + if not vCmd then return true end + -- verifico se nella lista dei comandi ci sono solo commenti + for i = 1, #vCmd do + if vCmd[i][1] ~= 0 then + return false + end + end + return true +end + +--------------------------------------------------------------------- +function SpecTestSomeMoveInCmds( vCmd) + if not vCmd then return false end + -- verifico se nella lista dei comandi c'è almeno un movimento + for i = 1, #vCmd do + if vCmd[i][1] == 1 or vCmd[i][1] == 2 or vCmd[i][1] == 3 then + return true + end + end + return false +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.nge new file mode 100644 index 0000000..d0f2aa1 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Essetre-PF1250.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Machinings/Machinings.data b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Machinings/Machinings.data new file mode 100644 index 0000000..17f0bcb Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Machinings/Machinings.data differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Machinings/Machinings.data.bak b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Machinings/Machinings.data.bak new file mode 100644 index 0000000..48ffe6e Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Machinings/Machinings.data.bak differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Scripts/ExitMach.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Scripts/ExitMach.lua new file mode 100644 index 0000000..18f86ad --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Scripts/ExitMach.lua @@ -0,0 +1,36 @@ +-- 2018/11/21 17:30:00 +-- Machining Exit for Essetre-FAST machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Uscita da Lavorazioni *** + +-- Nascondo il pezzo così marcato e le geometrie aggiunte, visualizzo il Box +local function ProcessPart( PartId) + -- visualizzo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.ON) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice (già chiusi tutti i gruppi di lavoro) +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +EgtZoom( SCE_ZM.ALL, false) + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Scripts/InitMach.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Scripts/InitMach.lua new file mode 100644 index 0000000..6ac761b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Scripts/InitMach.lua @@ -0,0 +1,44 @@ +-- 2018/11/21 16:30:00 +-- Machining Init for Essetre-FAST machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Ingresso in Lavorazioni *** + +-- Rendo visibile il pezzo e le geometrie aggiunte, nascondo il Box +local function ProcessPart( PartId) + -- nascondo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.OFF) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +-- Processo i pezzi già nei gruppi di lavoro (quando appena lanciata Process) +local GhostId = EgtGetFirstGhostPart() +while GhostId do + local PartId = EgtGetInfo( GhostId, GDB_SI.SOURCE, 'i') + if PartId then + ProcessPart( PartId) + end + GhostId = EgtGetNextGhostPart( GhostId) +end + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Scripts/SetUp.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Scripts/SetUp.lua new file mode 100644 index 0000000..6cdd4b5 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Scripts/SetUp.lua @@ -0,0 +1,240 @@ +-- 2020/12/10 +-- Gestione attrezzaggio per Essetre-PF1250 + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Tavola di passaggio valori +local STU = {} +STU.TUUID = "" +STU.TCPOS = "" +STU.HEAD = "" +STU.GROUP = "" +STU.POS = "" +STU.EXIT = 0 +STU.INDEX = 0 +STU.HEAD1 = "" +STU.HEAD2 = "" +STU.ISVALID = false +STU.ERR = 0 +_G.STU = STU + +local INVALIDPOS = "" +local POS = "Pos" + +-- Geom Set +local GS = {} + +-- Configurazione posizioni (con o senza TC2) +local PositionTable = {} +local bTc2Active = EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'TC2') +if bTc2Active then + PositionTable = {{Pos = "Pos1", TcPos = "T1", Head = "H12", Group = "G1"}, + {Pos = "Pos2", TcPos = "T3", Head = "H11", Group = "G1"}, + {Pos = "Pos3", TcPos = "T4", Head = "H11", Group = "G1"}, + {Pos = "Pos4", TcPos = "T5", Head = "H11", Group = "G1"}, + {Pos = "Pos5", TcPos = "T6", Head = "H11", Group = "G1"}, + {Pos = "Pos6", TcPos = "T7", Head = "H11", Group = "G1"}, + {Pos = "Pos7", TcPos = "T8", Head = "H11", Group = "G1"}, + {Pos = "Pos8", TcPos = "T9", Head = "H11", Group = "G1"}, + {Pos = "Pos9", TcPos = "T10", Head = "H11", Group = "G1"}, + {Pos = "Pos10", TcPos = "T101", Head = "H13", Group = "G2"}, + {Pos = "Pos11", TcPos = "T11", Head = "H11", Group = "G3"}, + {Pos = "Pos12", TcPos = "T12", Head = "H11", Group = "G3"}, + {Pos = "Pos13", TcPos = "T13", Head = "H11", Group = "G3"}, + {Pos = "Pos14", TcPos = "T14", Head = "H11", Group = "G3"}, + {Pos = "Pos15", TcPos = "T15", Head = "H11", Group = "G3"}, + {Pos = "Pos16", TcPos = "T20", Head = "H21", Group = "G4"}, + {Pos = "Pos17", TcPos = "T21", Head = "H21", Group = "G4"}, + {Pos = "Pos18", TcPos = "T22", Head = "H21", Group = "G4"}, + {Pos = "Pos19", TcPos = "T23", Head = "H21", Group = "G4"}, + {Pos = "Pos20", TcPos = "T24", Head = "H21", Group = "G4"}, + {Pos = "Pos21", TcPos = "T25", Head = "H21", Group = "G4"}, + {Pos = "Pos22", TcPos = "T26", Head = "H21", Group = "G4"}, + {Pos = "Pos23", TcPos = "T27", Head = "H21", Group = "G4"}, + {Pos = "Pos24", TcPos = "T28", Head = "H21", Group = "G4"}, + {Pos = "Pos25", TcPos = "T29", Head = "H21", Group = "G4"}, + {Pos = "Pos26", TcPos = "T30", Head = "H21", Group = "G4"}} +else + PositionTable = {{Pos = "Pos1", TcPos = "T1", Head = "H12", Group = "G1"}, + {Pos = "Pos2", TcPos = "T3", Head = "H11", Group = "G1"}, + {Pos = "Pos3", TcPos = "T4", Head = "H11", Group = "G1"}, + {Pos = "Pos4", TcPos = "T5", Head = "H11", Group = "G1"}, + {Pos = "Pos5", TcPos = "T6", Head = "H11", Group = "G1"}, + {Pos = "Pos6", TcPos = "T7", Head = "H11", Group = "G1"}, + {Pos = "Pos7", TcPos = "T8", Head = "H11", Group = "G1"}, + {Pos = "Pos8", TcPos = "T9", Head = "H11", Group = "G1"}, + {Pos = "Pos9", TcPos = "T10", Head = "H11", Group = "G1"}, + {Pos = "Pos10", TcPos = "T101", Head = "H13", Group = "G2"}, + {Pos = "Pos11", TcPos = "T20", Head = "H21", Group = "G3"}, + {Pos = "Pos12", TcPos = "T21", Head = "H21", Group = "G3"}, + {Pos = "Pos13", TcPos = "T22", Head = "H21", Group = "G3"}, + {Pos = "Pos14", TcPos = "T23", Head = "H21", Group = "G3"}, + {Pos = "Pos15", TcPos = "T24", Head = "H21", Group = "G3"}, + {Pos = "Pos16", TcPos = "T25", Head = "H21", Group = "G3"}, + {Pos = "Pos17", TcPos = "T26", Head = "H21", Group = "G3"}, + {Pos = "Pos18", TcPos = "T27", Head = "H21", Group = "G3"}, + {Pos = "Pos19", TcPos = "T28", Head = "H21", Group = "G3"}, + {Pos = "Pos20", TcPos = "T29", Head = "H21", Group = "G3"}, + {Pos = "Pos21", TcPos = "T30", Head = "H21", Group = "G3"}} +end + +local UsePositionHead = true + +local function IsInGeomSet( ToolHead, PosHead) + for GsIndex = 1, #GS do + local bToolHead = false + local bPosHead = false + for HIndex = 1, #GS[GsIndex] do + if GS[GsIndex][HIndex] == ToolHead then + bToolHead = true + elseif GS[GsIndex][HIndex] == PosHead then + bPosHead = true + end + if bToolHead and bPosHead then + return true + end + end + if bToolHead and bPosHead then + return true + end + end + return false +end + +function STU.IsCompatibleHeads() + STU.ISVALID = false + if IsInGeomSet(STU.HEAD1, STU.HEAD2) then + STU.ISVALID = true + else + STU.ISVALID = false + end +end + +function STU.GetValidHeadExitForPos() + -- se TUUID non valido restituisco errore + local ToolName = EgtTdbGetToolFromUUID( STU.TUUID) + if ToolName == nill then + STU.ERR = 1 + return + end + EgtTdbSetCurrTool( ToolName) + local CurrToolHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + STU.EXIT = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + -- recupero testa predefinita per la posizione corrente + local CurrPosHead + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + CurrPosHead = PositionTable[i].Head + break + end + end + -- verifico se la testa è quella della posizione predefinita + if CurrPosHead == CurrToolHead then + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + -- verifico se la testa è compatibile con quella della posizione predefinita + elseif IsInGeomSet( CurrToolHead, CurrPosHead) then + if UsePositionHead then + STU.HEAD = CurrPosHead + STU.ERR = 0 + return + else + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + end + -- la testa non è compatibile con quella della posizione predefinita + else + STU.HEAD = INVALIDPOS + STU.ERR = 0 + return + end +end + +function STU.IsValidTcPosFromHead() + STU.ISVALID = false + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + if PositionTable[i].Head == STU.HEAD then + STU.ISVALID = true + STU.ERR = 0 + return + elseif IsInGeomSet(PositionTable[i].Head, STU.HEAD) then + STU.ISVALID = true + STU.ERR = 0 + return + end + STU.ISVALID = false + STU.ERR = 0 + return + end + end +end + +function STU.GetTcPosHeadGroupFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.HEAD = PositionTable[i].Head + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.HEAD = INVALIDPOS + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetPosFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.POS = PositionTable[i].Pos + STU.ERR = 0 + return + end + end + STU.POS = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetGroupFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetHeadFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.HEAD = PositionTable[i].Head + STU.ERR = 0 + return + end + end + STU.HEAD = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetTcPosFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.ERR = 1 +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/SetUp/SetupImage.qqq.PNG b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/SetUp/SetupImage.qqq.PNG new file mode 100644 index 0000000..a8d5b53 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/SetUp/SetupImage.qqq.PNG differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/SetUp/Standard.stu b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/SetUp/Standard.stu new file mode 100644 index 0000000..21f28d6 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/SetUp/Standard.stu @@ -0,0 +1,28 @@ +; Commento per evitare BOM con UTF-8 +[General] +Pos1=T1;H12;1/6CB00A83-DDCD-49E6-A301-E1A0482615CA/Lama550 +Pos2=T3;H11;1/E7F6A2BB-1F66-48B9-9561-496231C33403/FresaDT60_H1 +Pos3=T4;H11;1/6EBB8C90-3B4A-498D-B971-1D1EBE6BE77F/Fresa20x50_H1 +Pos4=T5;H11;1/8B729108-7A53-4D8E-8394-379BA211C597/Fresa25x130_H1 +Pos5=T6 +Pos6=T7;H11;1/0147ED47-EB5D-44D6-9CE2-5282B484B5BD/Smusso45x40_H1 +Pos7=T8 +Pos8=T9 +Pos9=T10;H11;1/73EA9F19-5634-447D-8A23-8EEC777983E6/Fresa200x60_H1 +Pos10=T101;H13;1/A6CFDA65-DABB-441E-990A-776B5C24C2E4/ChainSaw +Pos11=T11 +Pos12=T12 +Pos13=T13 +Pos14=T14 +Pos15=T15 +Pos16=T20;H21;1/80F536B5-E4A6-4B60-8BF4-0EF2D0B7FC0E/Lama450_H2 +Pos17=T21 +Pos18=T22 +Pos19=T23 +Pos20=T24 +Pos21=T25 +Pos22=T26 +Pos23=T27;H21;1/B83BAE62-B8B5-45DC-AD00-E03ED19B49BE/FresaDT60_H2 +Pos24=T28;H21;1/0A54F32E-C48D-45DB-8502-953CA94FD7A0/Fresa25x130_H2 +Pos25=T29;H21;1/877C9B3A-9078-42B6-808D-5ED5CF5C505B/Fresa20x50_H2 +Pos26=T30;H21;1/D077C810-A58B-41DE-A3F5-D2187EBB1B67/Fresa100x60_H2 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/ChainSaw.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/ChainSaw.nge new file mode 100644 index 0000000..d29af27 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/ChainSaw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/MillNoTip.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/MillNoTip.nge new file mode 100644 index 0000000..5b2fe8a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/MillNoTip.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/Saw.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/Saw.nge new file mode 100644 index 0000000..5d6b54b Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/Saw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/SawH2.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/SawH2.nge new file mode 100644 index 0000000..ad8bd11 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/SawH2.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/Standard.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/Standard.nge new file mode 100644 index 0000000..23ee6c6 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/THolders/Standard.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge new file mode 100644 index 0000000..4cd588b Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/03242F51-4173-42DB-BD65-67CD8C5843FF.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/03242F51-4173-42DB-BD65-67CD8C5843FF.nge new file mode 100644 index 0000000..9e5264a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/03242F51-4173-42DB-BD65-67CD8C5843FF.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge new file mode 100644 index 0000000..db5ec5c Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/114F6F77-E1FA-4F04-94EE-6827CBD6C6EB.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/114F6F77-E1FA-4F04-94EE-6827CBD6C6EB.nge new file mode 100644 index 0000000..26c7b8b Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/114F6F77-E1FA-4F04-94EE-6827CBD6C6EB.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/21A0DB6A-2D6C-448D-B99E-CEF42CA7CC53.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/21A0DB6A-2D6C-448D-B99E-CEF42CA7CC53.nge new file mode 100644 index 0000000..3a4d25e Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/21A0DB6A-2D6C-448D-B99E-CEF42CA7CC53.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/2D9E802F-94D3-446F-BF28-AFE01EF3A84C.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/2D9E802F-94D3-446F-BF28-AFE01EF3A84C.nge new file mode 100644 index 0000000..8daf3f7 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/2D9E802F-94D3-446F-BF28-AFE01EF3A84C.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/469FD23B-6019-4B3D-A9A4-D653BD2A4BD7.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/469FD23B-6019-4B3D-A9A4-D653BD2A4BD7.nge new file mode 100644 index 0000000..969b885 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/469FD23B-6019-4B3D-A9A4-D653BD2A4BD7.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/4977094F-DC0A-480C-8830-9947A31994B5.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/4977094F-DC0A-480C-8830-9947A31994B5.nge new file mode 100644 index 0000000..34e484d Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/4977094F-DC0A-480C-8830-9947A31994B5.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge new file mode 100644 index 0000000..488e637 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/6EBB8C90-3B4A-498D-B971-1D1EBE6BE77F.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/6EBB8C90-3B4A-498D-B971-1D1EBE6BE77F.nge new file mode 100644 index 0000000..c97450a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/6EBB8C90-3B4A-498D-B971-1D1EBE6BE77F.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/6EBE3E36-1AD8-42B2-979A-2FBF4E6E4809.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/6EBE3E36-1AD8-42B2-979A-2FBF4E6E4809.nge new file mode 100644 index 0000000..631a9be Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/6EBE3E36-1AD8-42B2-979A-2FBF4E6E4809.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/73EA9F19-5634-447D-8A23-8EEC777983E6.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/73EA9F19-5634-447D-8A23-8EEC777983E6.nge new file mode 100644 index 0000000..7f84d62 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/73EA9F19-5634-447D-8A23-8EEC777983E6.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/80F536B5-E4A6-4B60-8BF4-0EF2D0B7FC0E.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/80F536B5-E4A6-4B60-8BF4-0EF2D0B7FC0E.nge new file mode 100644 index 0000000..8573662 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/80F536B5-E4A6-4B60-8BF4-0EF2D0B7FC0E.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge new file mode 100644 index 0000000..48fbb9f Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/8B729108-7A53-4D8E-8394-379BA211C597.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/8B729108-7A53-4D8E-8394-379BA211C597.nge new file mode 100644 index 0000000..778a223 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/8B729108-7A53-4D8E-8394-379BA211C597.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/9253DA3D-4740-4537-B376-E034D20130A7.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/9253DA3D-4740-4537-B376-E034D20130A7.nge new file mode 100644 index 0000000..ad1ae34 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/9253DA3D-4740-4537-B376-E034D20130A7.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/982D1B6F-6F27-45B4-B365-B693CBD1E1C1.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/982D1B6F-6F27-45B4-B365-B693CBD1E1C1.nge new file mode 100644 index 0000000..b01ff9a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/982D1B6F-6F27-45B4-B365-B693CBD1E1C1.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge new file mode 100644 index 0000000..bf6f9fc Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/A7F539EE-F305-4857-B0EC-179E177937CF.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/A7F539EE-F305-4857-B0EC-179E177937CF.nge new file mode 100644 index 0000000..5c98311 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/A7F539EE-F305-4857-B0EC-179E177937CF.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/B5B974EF-D18A-45DE-9842-05B91639BE91.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/B5B974EF-D18A-45DE-9842-05B91639BE91.nge new file mode 100644 index 0000000..dd0804e Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/B5B974EF-D18A-45DE-9842-05B91639BE91.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/B83BAE62-B8B5-45DC-AD00-E03ED19B49BE.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/B83BAE62-B8B5-45DC-AD00-E03ED19B49BE.nge new file mode 100644 index 0000000..330cc9e Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/B83BAE62-B8B5-45DC-AD00-E03ED19B49BE.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/CC17A26B-0D69-430A-BA6A-91F069CB6B85.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/CC17A26B-0D69-430A-BA6A-91F069CB6B85.nge new file mode 100644 index 0000000..9c7772d Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/CC17A26B-0D69-430A-BA6A-91F069CB6B85.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/CF0294F8-2783-40D5-9197-DC83F744549B.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/CF0294F8-2783-40D5-9197-DC83F744549B.nge new file mode 100644 index 0000000..861e430 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/CF0294F8-2783-40D5-9197-DC83F744549B.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge new file mode 100644 index 0000000..330752d Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/D450FB15-A0FC-42F8-9751-E82951D33E90.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/D450FB15-A0FC-42F8-9751-E82951D33E90.nge new file mode 100644 index 0000000..6aab9bc Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/D450FB15-A0FC-42F8-9751-E82951D33E90.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/D78EB339-2600-46DB-A4DC-47AC8B2E2040.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/D78EB339-2600-46DB-A4DC-47AC8B2E2040.nge new file mode 100644 index 0000000..9ff3572 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/D78EB339-2600-46DB-A4DC-47AC8B2E2040.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge new file mode 100644 index 0000000..2059450 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/Tools.data b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/Tools.data new file mode 100644 index 0000000..830f3e5 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/Tools.data differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/Tools.data.bak b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/Tools.data.bak new file mode 100644 index 0000000..73ebf1d Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/Tools.data.bak differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/penna.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/penna.nge new file mode 100644 index 0000000..ccfc123 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Tools/penna.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/CutData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/CutData.lua new file mode 100644 index 0000000..7d3c486 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/CutData.lua @@ -0,0 +1,10 @@ +-- CutData.lua by Egaltech s.r.l. 02/03/2021 18:18:17 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local CutData = { + { On = true, Name = 'Sawing550', Type = 'Standard'} +} + +--------------------------------------------------------------------- +return CutData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/DrillData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/DrillData.lua new file mode 100644 index 0000000..f490cce --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/DrillData.lua @@ -0,0 +1,11 @@ +-- DrillData.lua by Egaltech s.r.l. 02/03/2021 18:18:05 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local DrillData = { + { On = true, Name = 'DrillD20_H1', Type = 'Drill'}, + { On = true, Name = 'DrillPock25x130_H1', Type = 'Pocket'} +} + +--------------------------------------------------------------------- +return DrillData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/MachData.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/MachData.ini new file mode 100644 index 0000000..558fe47 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/MachData.ini @@ -0,0 +1,81 @@ +; PIndex = Type, PName, Default, Description +; Type : d=double, l=length, s=string + +[1] +Name=Offsets +1=l,X1_NEG,-3450.0,X1_NEG +2=l,X1_POS,34,X1_POS +3=l,PARK_X1,125,PARK_X1 +4=l,Z1_NEG,1550.0,Z1_NEG +5=l,Z1_POS,0.0,Z1_POS +6=l,PARK_Z1,-535.0,PARK_Z1 +7=l,PARK_SAWZ1,-150.0,PARK_SAWZ1 +8=l,B1_NEG,-127.0,B1_NEG +9=l,B1_NEG1,-119.0,B1_NEG1 +10=l,B1_POS,127.0,B1_POS +11=l,B1_POS1,119.0,B1_POS1 +12=l,PARK_B1,-90.0,PARK_B1 +13=l,PARK_SAWB1,0.0,PARK_SAWB1 +14=l,C1_NEG,-275.0,C1_NEG +15=l,C1_POS,275.0,C1_POS +16=d,PARK_C1,-90.0,PARK_C1 +17=d,PARK_SAWC1,-90.0,PARK_SAWC1 +18=d,X2_NEG,-2760.0,X2_NEG +19=d,X2_POS,0.0,X2_POS +20=l,PARK_X2,-70.0,PARK_X2 +21=l,PIVOT_T1,170.0,PIVOT_T1 +22=d,Z2_NEG,-795.0,Z2_NEG +23=d,Z2_POS,0.0,Z2_POS +24=d,PARK_Z2,-10.0,PARK_Z2 +25=d,B2_NEG,-127.0,B2_NEG1 +26=d,B2_NEG1,-119.0,B2_NEG1 +27=d,B2_POS,127.0,B2_POS +28=d,B2_POS1,119.0,B2_POS1 +29=d,PARK_B2,-90.0,PARK_B2 +30=l,C2_NEG,-275.0,C2_NEG +31=l,C2_POS,275.0,C2_POS +32=d,PARK_C2,-90.0,PARK_C2 +33=d,MIN_Y1,317,MIN_Y1 +34=d,MAX_Y1,5772.0,MAX_Y1 +35=d,PARK_Y1,952.0,PARK_Y1 +36=d,MIN_V1,5.0,MIN_V1 +37=d,MAX_V1,635.0,MAX_V1 +38=d,PIVOT_T2,170.0,PIVOT_T2 +39=d,X1P_NEG,30.0,X1P_NEG +40=l,X1P_POS,1330.0,X1P_POS +41=l,DIST_FTZERO,2167.6,DIST_FTZERO +42=d,DELTA_CARICZERO,120.0,DELTA_CARICZERO +43=d,X2P_NEG,35.0,X2P_NEG +44=d,X2P_POS,1330.0,X2P_POS +45=d,Z2P_NEG,30.0,Z2P_NEG +46=d,Z2P_POS,350.0,Z2P_POS +47=d,X3P_NEG,35.0,X3P_NEG +48=d,X3P_POS,1330.0,X3P_POS +49=d,Z3P_NEG,30.0,Z3P_NEG +50=l,Z3P_POS,350.0,Z3P_POS +51=l,MIN_V2,-635.0,MIN_V2 +52=d,MAX_V2,-5.0,MAX_V2 +53=d,X4P_NEG,30.0,X4P_NEG +54=d,X4P_POS,1330.0,X4P_POS +55=d,MIN_Y2,-5772.0,MIN_Y2 +56=d,MAX_Y2,-321.0,MAX_Y2 +57=d,PARK_Y2,-952.0,PARK_Y2 +58=d,MIN_DELTAVY,317,MIN_DELTAVY +59=d,DIST_UNLOAD,-2400,DIST_UNLOAD +60=l,OFFSETBLAMAT1,0,OFFSETBLAMAT1 +61=l,OFFSETCLAMAT1,0,OFFSETCLAMAT1 +62=d,OFFSETBLAMAT2,0,OFFSETBLAMAT2 +63=d,OFFSETCLAMAT2,0,OFFSETCLAMAT2 +64=d,OFFSETXT1,-2466.7,OFFSETXT1 +65=d,OFFSETZT1,-1140.6,OFFSETZT1 +66=d,OFFSETXT2,-967.3,OFFSETXT2 +67=d,OFFSETZT2,-394.3,OFFSETZT2 +68=d,Zzz,1,Zzz + +[2] +Name=Trave +1=l,XMIN,30,XMIN +2=l,XMAX,1251,XMAX +3=l,ZMIN,30,ZMIN +4=l,ZMAX,300,ZMAX +68=d,Zzz,1,Zzz diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/MachiningTypes.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/MachiningTypes.ini new file mode 100644 index 0000000..414615b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/MachiningTypes.ini @@ -0,0 +1,23 @@ +[Cut] +1=Standard + +[Drill] +1=Drill +2=Pocket + +[Milling] +1=FreeContour +2=Side +3=SideGroove +4=DtMortise +5=Mark +6=Text +7=CleanCorner60 +8=CleanCorner30 + +[Pocketing] +1=Pocket +2=OpenPocket + +[Sawing] +1=Sawing diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/MillingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/MillingData.lua new file mode 100644 index 0000000..7981b31 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/MillingData.lua @@ -0,0 +1,10 @@ +-- MillingData.lua by Egaltech s.r.l. 02/03/2021 19:11:10 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local MillingData = { + { On = true, Name = 'FreeWall25x130_H1_1', Type = 'FreeContour'} +} + +--------------------------------------------------------------------- +return MillingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/PocketingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/PocketingData.lua new file mode 100644 index 0000000..1c0d982 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/PocketingData.lua @@ -0,0 +1,12 @@ +-- PocketingData.lua by Egaltech s.r.l. 02/03/2021 18:19:34 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local PocketingData = { + { On = true, Name = 'DrillPock25x130_H1', Type = 'Pocket'}, + { On = true, Name = 'DrillPock20x50_H1', Type = 'Pocket'}, + { On = true, Name = 'Svuot200x60_H1', Type = 'OpenPocket'} +} + +--------------------------------------------------------------------- +return PocketingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/SawingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/SawingData.lua new file mode 100644 index 0000000..7ef7340 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/SawingData.lua @@ -0,0 +1,10 @@ +-- SawingData.lua by Egaltech s.r.l. 18/02/2021 18:55:40 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local SawingData = { + { On = true, Name = 'TaglioCatena', Type = 'Sawing'} +} + +--------------------------------------------------------------------- +return SawingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/Ts3Data.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/Ts3Data.lua new file mode 100644 index 0000000..0d5c528 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/Ts3Data.lua @@ -0,0 +1,118 @@ +-- C:\TechnoEssetre7\EgtData\Essetre-PF1250.data + +local Offsets = { + X1_NEG=-3450.0, + X1_POS=0.0, + PARK_X1=250.0, + Z1_NEG=-1550.0, + Z1_POS=0.0, + PARK_Z1=-535.0, + PARK_SAWZ1=-150.0, + B1_NEG=-127.0, + B1_NEG1=-119.0, + B1_POS=127.0, + B1_POS1=119.0, + PARK_B1=-90.0, + PARK_SAWB1=0.0, + C1_NEG=-275.0, + C1_POS=275.0, + PARK_C1=-90.0, + PARK_SAWC1=-90.0, + X2_NEG=-2760.0, + X2_POS=0.0, + PARK_X2=-70.0, + PIVOT_T1=170.0, + Z2_NEG=-795.0, + Z2_POS=0.0, + PARK_Z2=-10.0, + B2_NEG=-127.0, + B2_NEG1=-119.0, + B2_POS=127.0, + B2_POS1=119.0, + PARK_B2=-90.0, + C2_NEG=-275.0, + C2_POS=275.0, + PARK_C2=-90.0, + MIN_Y1=317.0, + MAX_Y1=5772.0, + PARK_Y1=952.0, + MIN_V1=5.0, + MAX_V1=635.0, + PIVOT_T2=170.0, + X1P_NEG=30.0, + X1P_POS=1330.0, + DIST_FTZERO=2167.6, + DELTA_CARICZERO=120.0, + X2P_NEG=35.0, + X2P_POS=1330.0, + Z2P_NEG=30.0, + Z2P_POS=350.0, + X3P_NEG=35.0, + X3P_POS=1330.0, + Z3P_NEG=30.0, + Z3P_POS=350.0, + MIN_V2=-635.0, + MAX_V2=-5.0, + X4P_NEG=30.0, + X4P_POS=1330.0, + MIN_Y2=-5772.0, + MAX_Y2=-321.0, + PARK_Y2=-952.0, + MIN_DELTAVY=317, + DIST_UNLOAD=-2400, + OFFSETBLAMAT1=0, + OFFSETCLAMAT1=0, + OFFSETBLAMAT2=0, + OFFSETCLAMAT2=0, + OFFSETXT1=-2466.7, + OFFSETZT1=-1140.6, + OFFSETXT2=-967.3, + OFFSETZT2=-394.3, + Zzz=1 +} + +local Trave = { + XMIN=30, + XMAX=1251, + ZMIN=30, + ZMAX=300, + Zzz=1 +} + +local User = { + NESTING_MATERIAL=1, + NESTING_TYPEEXTERNALOP=1, + NESTING_FROM_BTL=0, + SAFETY_DISTANCE_ZSAVE=30, + OPTIMIZATIONS_ENABLE_SLICES_F5=1, + OPTIMIZATIONS_ENABLE_SLICES_F6=1, + OPTIMIZATIONS_LENGTH_SLICES=100, + L056_ACTIVE_AS=1, + L055_ADD_P13=0, + L055_ACTIVE_AS=1, + L050_ADDDEPTH=3, + L060_PEN_F2=2, + L060_PEN_F1=2, + L138_TOLLERANZA=0, + L037_TOOL_WIDTH=0, + L032_LENGTH_MIN_DIV=0, + T055_ACTIVE_AS=1, + L040_ADD_P11=0, + L040_ADD_P11_PASS=3, + L040_OFFSET_P1=0, + L040_TYPEDRILLING=0, + L012_LIM=0, + L012_LENGTH_MIN_DIV=950, + L010_LIM=3, + L010_LENGTH_MIN_DIV=1000, + L020_DIAM_HOLE=12, + L030_AUM_DIM=0, + L030_LENGTH_MIN_DIV=0, + T010_ALTCATENA=361, + T010_OFFSETPIANOCATENA=20, + L036_LENGTH_MIN_DIV=900, + Zzz=1 +} + +local Machine = { Offsets=Offsets, Trave=Trave, User=User} +return Machine diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/WallData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/WallData.lua new file mode 100644 index 0000000..b81e38a --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/WallData.lua @@ -0,0 +1,62 @@ +-- WallData.lua by Egaltech s.r.l. 2021/03/08 +-- Raccolta dati generali per Pareti + +EgtOutLog( ' WALL-WallData started', 1) + +-- Tabella per definizione modulo +local WallData = { + MIN_LENGTH = 4000, -- lunghezza minima del grezzo + MIN_WIDTH = 100, -- larghezza minima del grezzo + MIN_HEIGHT = 10, -- altezza minima del grezzo + MAX_LENGTH = 14000, -- lunghezza massima del grezzo + MAX_WIDTH = 1250, -- larghezza massima del grezzo + MAX_HEIGHT = 300, -- altezza massima del grezzo + STD_RAW_LENGTH = 10000, -- lunghezza standard del grezzo + STD_RAW_WIDTH = 1250, -- larghezza standard del grezzo + OVM_HEAD = 60, -- sovramateriale testa + OVM_MID = 50, -- sovramateriale intermedio + COLL_SIC = 5, -- distanza di sicurezza per collisioni + CUT_SIC = 20, -- distanza di sicurezza per tagli + CUT_EXTRA = 0, -- affondamento extra standard per tagli di lama e fresature + CUT_EXTRA_MIN = 0, -- affondamento extra ridotto per tagli di lama e fresature + NZ_MINA = 0.5, -- componente limite in Z normale di una faccia (-30deg) + NZ_MINB = -0.4, -- componente limite in Z normale di un insieme di facce (-23deg) + DRILL_TOL = 0.5, -- tolleranza tra diametro foro e diametro punta + DRILL_VZ_MIN = 0.5, -- componente limite in Z del versore di un foro + DRILL_VX_MAX = 0.866, -- componente limite in X del versore di un foro sulle facce laterali + DRILL_OVERLAP = 5, -- sovrapposizione tra due mezze forature + MILL_OVERLAP = 5, -- sovrapposizione tra due mezze fresature + RAWCOL = { 255, 160, 32, 30}, -- colore del grezzo + ORIG_CORNER = 'TR', -- angolo tavola per origine di battuta (BR (defualt), TR, BL, TL) + MAX_CLEAN_CRN30 = 120, -- massimo spessore per pulitura angolo con fresa 30deg + MIN_DIM_ALLOW_CLEAN = 200, -- apertura minima per lavorazione pulitura spigolo + MILL_MAX_DEPTH_AS_MAT = true, -- massimo affondamento frese uguale ad altezza tagliente (max materiale) + CUT_MAX_LENGTH = 3000, -- massima lunghezza di un taglio + BEAM_MACHINE = true -- lavorazione pareti su macchina travi (PF...) +} + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Wall', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-PF1250.data" +local sData = EgtGetSourceDir().."\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Trave then + WallData.MIN_LENGTH = Machine.Trave.YMIN or WallData.MIN_LENGTH + WallData.MIN_WIDTH = Machine.Trave.XMIN or WallData.MIN_WIDTH + WallData.MIN_HEIGHT = Machine.Trave.ZMIN or WallData.MIN_HEIGHT + WallData.MAX_LENGTH = Machine.Trave.YMAX or WallData.MAX_LENGTH + WallData.MAX_WIDTH = Machine.Trave.XMAX or WallData.MAX_WIDTH + WallData.MAX_HEIGHT = Machine.Trave.ZMAX or WallData.MAX_HEIGHT + end + end +end + +--------------------------------------------------------------------- +return WallData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/WallTableTemplate.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/WallTableTemplate.ini new file mode 100644 index 0000000..ccb02c1 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250/Wall/WallTableTemplate.ini @@ -0,0 +1,9 @@ +-- %TABLE_NAME%.lua by Egaltech s.r.l. %DATE_TIME% +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local %TABLE_NAME% = { +} + +--------------------------------------------------------------------- +return %TABLE_NAME% diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/BeamData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/BeamData.lua new file mode 100644 index 0000000..6ed41a9 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/BeamData.lua @@ -0,0 +1,137 @@ +-- BeamData.lua by Egaltech s.r.l. 2021/09/14 +-- Raccolta dati generali per Travi + +EgtOutLog( ' PF1250-BeamData started') + +-- Tabella per definizione modulo +local BeamData = { + RIGHT_LOAD = true, -- flag carico da destra + SIMUL_VIEW_DIR = 1, -- direzione di vista predefinita per la simulazione (1=NW, 2=SW, 3=NE, 4=SE) + MIN_WIDTH = 40, -- larghezza minima del grezzo + MIN_HEIGHT = 40, -- altezza minima del grezzo + MAX_WIDTH = 1250, -- larghezza massima del grezzo + MAX_HEIGHT = 300, -- altezza massima del grezzo + LEN_SHORT_PART = 1200, -- lunghezza massima pezzo piccolo + MAX_RAW = 20000, -- massima lunghezza grezzo (deve essere minore di LenTable - RAW_OFFSET) + STD_RAW = 14000, -- lunghezza standard della barra di grezzo + OVM_HEAD = 10, -- sovramateriale testa + OVM_MID = 5.4, -- sovramateriale intermedio (spessore lama) + MIN_JOIN_S = 100, -- minima presa pinza per pezzo piccolo + MIN_JOIN_L = 450, -- minima presa pinza per pezzo grande + MINRAW_S = 960, -- minimo grezzo in coda scaricabile per sezioni piccole + MINRAW_L = 1660, -- minimo grezzo in coda scaricabile per sezioni grandi + CHAR_EXTRA_DIST = 400, -- distanza aggiuntiva per minimizzare scambi di carrelli + MAX_LEN_SCRAP = 150, -- massima lunghezza scarto di coda + MAX_LEN_SCRAP_START = 150, -- massima lunghezza scarto di testa + MAX_DIM_HTCUT = 185, -- larghezza massima taglio di testa o coda + MAX_DIM_HTCUT_HBEAM = 185, -- larghezza massima taglio di testa o coda con trave alta + MIN_DIM_HBEAM = 610, -- altezza minima di trave alta + MAX_DIM_DICE = 160, -- dimensione trasversale massima cubetto + MAX_LEN_DICE = 400, -- lunghezza massima cubetto + DECR_VERT_CUT = 25, -- riduzione profondità per affondamento verticale in taglio orizzontale + COLL_SIC = 5, -- distanza di sicurezza per collisioni + CUT_SIC = 28, -- distanza di sicurezza per tagli + CUT_EXTRA = 5, -- affondamento extra standard per tagli di lama e fresature + CUT_EXTRA_MIN = 2, -- affondamento extra ridotto per tagli di lama e fresature + NZ_MINA = -0.6, -- componente limite in Z normale di una faccia (-30deg) + NZ_MINB = -0.4, -- componente limite in Z normale di un insieme di facce (-23deg) + DRILL_TOL = 0.2, -- tolleranza tra diametro foro e diametro punta + DRILL_VZ_MIN = - 0.51, -- componente limite in Z del versore di un foro + DRILL_VX_MAX = 0.867, -- componente limite in X del versore di un foro sulle facce laterali + DRILL_OVERLAP = 5, -- sovrapposizione tra due mezze forature + MILL_OVERLAP = 5, -- sovrapposizione tra due mezze fresature + MAX_DIST_HTFEA = 50.0, -- massima distanza di feature da testa o coda per essere considerata tale + MAX_LEN_HTFEA = 2550.0, -- massima lunghezza di feature di testa o coda + LONGCUT_ENDLEN = 1200, -- lunghezza lavoro estremi iniziale e finale + LONGCUT_MAXLEN = 3000, -- lunghezza massima sezione di taglio longitudinale + MAX_LEN_RIDGELAP_FROM_BOTTOM = 0, -- massima lunghezza ridgelap lavorabile da sotto + MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM = 0, -- massima lunghezza ridgelap lavorabile da sotto con trave alta + DIM_TO_CENTER_STRIP = 0, -- larghezza minima trave per inserimento codolo nel centro della trave; 0 = automatico + DIM_STRIP = 3, -- dimensione codolo sostegno parti lasciate su contorno libero o archi + DIM_STRIP_SMALL = 3, -- dimensione codolo piccolo (quando le parti sostenute sono sicuramente sulla parte sopra del pezzo) + RAWCOL = { 255, 160, 32, 30}, -- colore del grezzo + RAW_OFFSET = 2000, -- spostamento grezzo rimanente dopo split + VICE_MINH = 110, -- altezza minima della morsa + OFFSET_DRILL_TENON = 0, -- offset fori su tenoni verso base degli stessi (0=non fare) + USER_HOLE_DIAM = 0, -- diametro foro per L20 + MAX_TOOL_LEN_FOR_HOR_MACH = 500, -- massima lunghezza ingombro per poter fare forature (fresature) oltre i 10 gradi dalla verticale + DRILL_VZ_MIN_LONG_TOOL = 0.984, -- componente limite per lavorazioni con punta lunga + MAX_TOOL_LEN_BACK_HOR_MACH = 500, -- massima lunghezza utensile per poter eseguire lavorazioni (forature/svuotature) da dietro (faccia 4) + PRESS_ROLLER = true, -- dichiarazione presenza rulli pressori + C_SIMM = true, -- dichiarazione simmetria mensola asse C + DOWN_HEAD = true, -- dichiarazione presenza seconda testa dal basso + DH_MAX_TOP = 370, -- quota massima raggiungibile dalla testa da sotto dal sotto del pezzo + KIOTP = 2 -- coefficiente moltiplicativo per attacco/uscita lama tangente anzichè perpendicolare +} + +local function GetMaxLenRidgeLapFromBottom( dHRaw) + if dHRaw < BeamData.MIN_DIM_HBEAM then + return BeamData.MAX_LEN_RIDGELAP_FROM_BOTTOM + 0.01 + else + return BeamData.MAX_LEN_RIDGELAP_FROM_BOTTOM_HBEAM + 0.01 + end +end +BeamData.GetMaxLenRidgeLapFromBottom = GetMaxLenRidgeLapFromBottom + +local function GetBottomToolMaxTotLen( vtDir) + if not vtDir or vtDir:getZ() < -0.867 then + return 240 + elseif vtDir:getZ() < -0.707 then + return 240 + else + return 280 + end +end +BeamData.GetBottomToolMaxTotLen = GetBottomToolMaxTotLen + +local function GetSectionCoeff( dW, dH, dL) + local SEZ_L = 80000 + local SEZ_S = 20000 + local LEN_SMALL = 2000 + local dSez = dW * dH + if dSez <= SEZ_S then + return 0.0 + elseif dSez < SEZ_L then + if dL and dL < LEN_SMALL then dSez = max( 0.6 * dSez, SEZ_S) end + local dCoeff = ( dSez - SEZ_S) / ( SEZ_L - SEZ_S) + return dCoeff + else + return 1.0 + end +end + +local function GetMinJoin( dW, dH, dL) + local dCoeff = GetSectionCoeff( dW, dH, dL) + return ( 1 - dCoeff) * BeamData.MIN_JOIN_S + dCoeff * BeamData.MIN_JOIN_L +end +BeamData.GetMinJoin = GetMinJoin + +local function GetMinUnloadableRaw( dW, dH) + local dCoeff = GetSectionCoeff( dW, dH) + return BeamData.MINRAW_S + dCoeff * ( BeamData.MINRAW_L - BeamData.MINRAW_S) +end +BeamData.GetMinUnloadableRaw = GetMinUnloadableRaw + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Beam', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-PF1250rl.data" +local sData = EgtGetSourceDir().."\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Trave then + BeamData.MIN_WIDTH = Machine.Trave.XMIN or BeamData.MIN_WIDTH + BeamData.MIN_HEIGHT = Machine.Trave.ZMIN or BeamData.MIN_HEIGHT + BeamData.MAX_WIDTH = Machine.Trave.XMAX or BeamData.MAX_WIDTH + BeamData.MAX_HEIGHT = Machine.Trave.ZMAX or BeamData.MAX_HEIGHT + end + end +end + +--------------------------------------------------------------------- +return BeamData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/BeamTableTemplate.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/BeamTableTemplate.ini new file mode 100644 index 0000000..ccb02c1 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/BeamTableTemplate.ini @@ -0,0 +1,9 @@ +-- %TABLE_NAME%.lua by Egaltech s.r.l. %DATE_TIME% +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local %TABLE_NAME% = { +} + +--------------------------------------------------------------------- +return %TABLE_NAME% diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/CutData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/CutData.lua new file mode 100644 index 0000000..e706c35 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/CutData.lua @@ -0,0 +1,13 @@ +-- CutData.lua by Egaltech s.r.l. 06/10/2021 12:45:09 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local CutData = { + { On = true, Name = 'MiSideInvSaw550', Type = 'HeadSide'}, + { On = true, Name = 'MiSideInvSaw450_H2', Type = 'HeadSide_H2'}, + { On = true, Name = 'MiSideSaw550', Type = 'TailSide'}, + { On = true, Name = 'MiSideSaw450_H2', Type = 'TailSide_H2'} +} + +--------------------------------------------------------------------- +return CutData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/DrillData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/DrillData.lua new file mode 100644 index 0000000..13aa35b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/DrillData.lua @@ -0,0 +1,23 @@ +-- DrillData.lua by Egaltech s.r.l. 13/09/2021 17:41:42 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local DrillData = { + { On = true, Name = 'DrillD8_H2', Type = 'Drill_H2'}, + { On = true, Name = 'DrillD10_H2', Type = 'Drill_H2'}, + { On = true, Name = 'DrillD12_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD12_H2', Type = 'Drill_H2'}, + { On = true, Name = 'DrillD18_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD18-CORTA_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD20_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD20_H2', Type = 'Drill_H2'}, + { On = true, Name = 'DrillD25_H1', Type = 'Drill'}, + { On = true, Name = 'DrillD25_H2', Type = 'Drill_H2'}, + { On = true, Name = 'DrillPock20x50_H1', Type = 'Pocket'}, + { On = true, Name = 'DrillPock20x50_H2', Type = 'Pocket_H2'}, + { On = true, Name = 'DrillPock25x130_H1', Type = 'Pocket'}, + { On = true, Name = 'DrillPock25x130_H2', Type = 'Pocket_H2'} +} + +--------------------------------------------------------------------- +return DrillData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/MachiningTypes.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/MachiningTypes.ini new file mode 100644 index 0000000..eae454b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/MachiningTypes.ini @@ -0,0 +1,56 @@ +[Cut] +1=HeadSide +2=HeadSide_H2 +3=TailSide +4=TailSide_H2 + +[Drill] +1=Drill +2=Drill_H2 +3=Pocket +4=Pocket_H2 + +[Milling] +1=Prof +2=Prof_H2 +3=FreeContour +4=Tenon +5=Tenon_H2 +6=DtTenon +7=DtTenon_H2 +8=DtMortise +9=DtMortise_H2 +10=BirdsMouth +11=BirdsMouth_H2 +12=Chamfer +13=Mark +14=Mark_H2 +15=Text +16=Text_H2 +17=Decor01 +18=Long2Cut +19=Long2Cut_H2 +20=Long2CutDown +21=LongSmallCut +22=LongSmallCut_H2 +23=BHSideMill +24=CleanCorner +25=ProfTCone +26=Long2CutSide +27=SmallToolContour +28=SmallToolContour_H2 +29=AntiSplintMillCut +30=AntiSplintMillCut_H2 +31=SideMillAsBlade +32=SideMillAsBlade_H2 + +[Pocketing] +1=Pocket +2=Pocket_H2 +3=OpenPocket +4=OpenPocket_H2 +5=Mortise +6=Mortise_H2 + +[Sawing] +1=Sawing diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/MillingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/MillingData.lua new file mode 100644 index 0000000..170c326 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/MillingData.lua @@ -0,0 +1,37 @@ +-- MillingData.lua by Egaltech s.r.l. 06/10/2021 17:17:51 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local MillingData = { + { On = true, Name = 'Profiling25x130_H1', Type = 'Prof'}, + { On = true, Name = 'Profiling25x130_H2', Type = 'Prof_H2'}, + { On = true, Name = 'FreeCont25x130_H1', Type = 'FreeContour'}, + { On = true, Name = 'FreeCont25x130_H2', Type = 'FreeContour'}, + { On = true, Name = 'Mill_Tenon200x60_H1', Type = 'Tenon'}, + { On = false, Name = 'Milling20x50_H1', Type = 'Tenon'}, + { On = true, Name = 'Mill_Tenon100x60_H2', Type = 'Tenon_H2'}, + { On = false, Name = 'Milling20x50_H2', Type = 'Tenon_H2'}, + { On = true, Name = 'Mill_DtTen60x130_H1', Type = 'DtTenon'}, + { On = true, Name = 'Mill_DtTen60x130_H2', Type = 'DtTenon_H2'}, + { On = true, Name = 'Mill_DtMrt60x130_H1', Type = 'DtMortise'}, + { On = true, Name = 'Mill_DtMrt60x130_H2', Type = 'DtMortise_H2'}, + { On = true, Name = 'Milling200x60_H1', Type = 'BirdsMouth'}, + { On = true, Name = 'Milling100x60_H2', Type = 'BirdsMouth_H2'}, + { On = true, Name = 'Edge25x130_H1', Type = 'Chamfer'}, + { On = true, Name = 'Edge25x130_H2', Type = 'Chamfer'}, + { On = true, Name = 'Chamf45x40_H1', Type = 'Mark'}, + { On = true, Name = 'Chamf45x40_H2', Type = 'Mark_H2'}, + { On = true, Name = 'Chamf45x40_H1', Type = 'Text'}, + { On = true, Name = 'Chamf45x40_H2', Type = 'Text_H2'}, + { On = true, Name = 'Marking_H1', Type = 'Text'}, + { On = true, Name = 'Marking_H2', Type = 'Text_H2'}, + { On = true, Name = 'Mill_L2C200x60_H1', Type = 'Long2Cut'}, + { On = true, Name = 'Mill_L2C100x60_H2', Type = 'Long2Cut'}, + { On = true, Name = 'Milling25x130_H1', Type = 'LongSmallCut'}, + { On = true, Name = 'Milling25x130_H2', Type = 'LongSmallCut_H2'}, + { On = true, Name = 'Milling25x130_H1', Type = 'AntiSplintMillCut'}, + { On = true, Name = 'Milling25x130_H2', Type = 'AntiSplintMillCut_H2'} +} + +--------------------------------------------------------------------- +return MillingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/PocketingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/PocketingData.lua new file mode 100644 index 0000000..8df3952 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/PocketingData.lua @@ -0,0 +1,19 @@ +-- PocketingData.lua by Egaltech s.r.l. 09/09/2021 11:47:06 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local PocketingData = { + { On = true, Name = 'Svuot200x60_H1', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot100x60_H2', Type = 'OpenPocket_H2'}, + { On = true, Name = 'Svuot25x130_H1', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot25x130_H2', Type = 'OpenPocket_H2'}, + { On = true, Name = 'Svuot20x50_H1', Type = 'OpenPocket'}, + { On = true, Name = 'Svuot20x50_H2', Type = 'OpenPocket_H2'}, + { On = true, Name = 'Svuot25x130_H1', Type = 'Pocket'}, + { On = true, Name = 'Svuot20x50_H1', Type = 'Pocket'}, + { On = true, Name = 'Svuot25x130_H2', Type = 'Pocket_H2'}, + { On = true, Name = 'Svuot20x50_H2', Type = 'Pocket_H2'} +} + +--------------------------------------------------------------------- +return PocketingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/SawingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/SawingData.lua new file mode 100644 index 0000000..fc20cd1 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/SawingData.lua @@ -0,0 +1,11 @@ +-- SawingData.lua by Egaltech s.r.l. 05/08/2021 09:54:57 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local SawingData = { + { On = true, Name = 'TaglioCatena_C', Type = 'Sawing'}, + { On = true, Name = 'TaglioCatena', Type = 'Sawing'} +} + +--------------------------------------------------------------------- +return SawingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/Ts3Data.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/Ts3Data.lua new file mode 100644 index 0000000..7530fc5 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Beam/Ts3Data.lua @@ -0,0 +1,121 @@ +-- C:\TechnoEssetre7\EgtData\Essetre-PF1250RL.data + +local Offsets = { + X1_NEG=-3440, + X1_POS=0, + PARK_X1=-250, + Z1_NEG=-1560, + Z1_POS=-52, + PARK_Z1=-535, + PARK_SAWZ1=-150, + B1_NEG=-127.0, + B1_NEG1=-119.0, + B1_POS=127.0, + B1_POS1=119.0, + PARK_B1=-90.0, + PARK_SAWB1=0.0, + C1_NEG=-275.0, + C1_POS=275.0, + PARK_C1=-90.0, + PARK_SAWC1=-90.0, + X2_NEG=-2955, + X2_POS=0, + PARK_X2=-70, + PIVOT_T1=170, + Z2_NEG=-875, + Z2_POS=0, + PARK_Z2=0, + B2_NEG=-127.0, + B2_NEG1=-119.0, + B2_POS=127.0, + B2_POS1=119.0, + PARK_B2=-90.0, + C2_NEG=-275.0, + C2_POS=275.0, + PARK_C2=-90.0, + MIN_Y1=351, + MAX_Y1=5760, + PARK_Y1=1011, + MIN_V1=10, + MAX_V1=670, + PIVOT_T2=170, + X1P_NEG=30, + X1P_POS=1330, + DIST_FTZERO=2258.5, + DELTA_CARICZERO=50, + X2P_NEG=35, + X2P_POS=1330, + Z2P_NEG=30, + Z2P_POS=440, + X3P_NEG=35, + X3P_POS=1330, + Z3P_NEG=30, + Z3P_POS=440, + MIN_V2=-670, + MAX_V2=-10, + X4P_NEG=30, + X4P_POS=1330, + MIN_Y2=-5746, + MAX_Y2=-351, + PARK_Y2=-1011, + MIN_DELTAVY=341, + DIST_UNLOAD=-2250, + OFFSETBLAMAT1=0, + OFFSETCLAMAT1=0, + OFFSETBLAMAT2=0, + OFFSETCLAMAT2=0, + OFFSETXT1=-1172.4, + OFFSETZT1=-1250.2, + OFFSETXT2=-2458.8, + OFFSETZT2=-437.6, + OFFSETZSOTTOTRAVE=1005, + Zzz=1 +} + +local Trave = { + XMIN=30, + XMAX=1251, + ZMIN=30, + ZMAX=400, + Zzz=1 +} + +local User = { + L010_LENGTH_MIN_DIV=1000, + L010_LIM=3, + L012_LENGTH_MIN_DIV=950, + L012_LIM=0, + L020_DIAM_HOLE=12, + L030_AUM_DIM=0, + L030_LENGTH_MIN_DIV=0, + L032_LENGTH_MIN_DIV=0, + L036_LENGTH_MIN_DIV=900, + L037_TOOL_WIDTH=0, + L040_ADD_P11=0, + L040_ADD_P11_PASS=3, + L040_OFFSET_P1=0, + L040_TYPEDRILLING=0, + L050_ADDDEPTH=3, + L055_ACTIVE_AS=1, + L055_ADD_P13=0, + L056_ACTIVE_AS=1, + L060_PEN_F1=2, + L060_PEN_F2=2, + L138_TOLLERANZA=0, + NESTING_FROM_BTL=0, + NESTING_MATERIAL=1, + NESTING_TYPEEXTERNALOP=1, + OPTIMIZATIONS_ENABLE_SLICES_F5=1, + OPTIMIZATIONS_ENABLE_SLICES_F6=1, + OPTIMIZATIONS_LENGTH_MAX_SCRAP_F5=1200, + OPTIMIZATIONS_LENGTH_SLICES=100, + OPTIMIZATIONS_RECOVERY_PRINT_ONLY=0, + SAFETY_DISTANCE_ZSAVE=30, + T010_ALTCATENA=361, + T010_OFFSETPIANOCATENA=20, + T055_ACTIVE_AS=1, + Zzz=1 +} + +local Machine = { Offsets=Offsets, Trave=Trave, User=User} +return Machine diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.NUM.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.NUM.mlpe new file mode 100644 index 0000000..fc2116f --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.NUM.mlpe @@ -0,0 +1,1176 @@ +-- Processore macchina Essetre-PF1250 by EgalTech s.r.l. 2020/10/21 +-- Con controllo numerico NUM + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +-- Variabili di modulo +local MLE_INFO = 'Essetre-PF1250.NUM.mlpe ver.'..PP_VER..' by EgalTech s.r.l.' +local DELTA_TAKING = 200 +local TEST_USE = false + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.FMAXPINZE = 154000 -- feed massima pinze +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Intestazioni + EmtOutput( "%40.0") + if EMT.INFO then + EmtOutput( '('..EMT.INFO..')') + else + EmtOutput( '(Program Start)') + end + EmtOutput( '('.. MLE_INFO..')\n') + -- Se modalità test, aggiungo linee per muovere tappeto e alzare la testa (in automatico viene fatto dal main residente) + if TEST_USE then + EmtOutput( 'M28') + EmtOutput( 'N1 G101Z-100 L0=0') + EmtOutput( 'N1 G101ET1001') + EmtOutput( 'N1 G101ET2001\n') + end +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Arresto mandrino + EmtOutput( 'M05') + -- Emissione scarico + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' or EMT.AUXTYPE == 'R' then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + elseif EMT.AUXTYPE == 'U' then + EmtOutput( 'G111ET1002') + EmtOutput( 'G111ET2002') + -- emissione conclusione pezzo precedente + local sOut = 'G113 EA0EB1EC1' + EmtOutput( sOut) + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + -- Se modalità test, termino il programma + if TEST_USE then + EmtOutput( 'M02') + end +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensile (esclusa sega a catena) + if EMT.HEAD == 'H1' then + -- output info + local sPos = EgtIf( #EMT.TCPOS == 2, EMT.TCPOS:gsub( 'T', 'N30'), EMT.TCPOS:gsub( 'T', 'N3')) + local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( EMT.TTOTLEN, 1)..' G76H9998.2'..sPos..sPos + EmtOutput( sOut) + -- emissione dati sega a catena + elseif EMT.HEAD == 'H3' then + local sOut = 'L1='..EgtNumToString( EMT.SMAX, 0)..' L2='..EmtLenToString( ChSawLen, 1)..' G76H9998.2N401N404' + EmtOutput( sOut) + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + --EmtOutput( '(Disposition '..EMT.DISPIND..' = '..EMT.DISPID..')') + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') + EMT.Y1POS = EgtGetInfo( EMT.DISPID, 'Y1POS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- emissione dati di macchina + local sOut = 'G114'..'EA'..EmtLenToString(LoadT,-2)..'EB'..EmtLenToString(MinY,-2)..'EC'..EmtLenToString(MaxY,-2).. + 'ED'..EmtLenToString(MinV,-2)..'EE'..EmtLenToString(MaxV,-2)..'EF'..EmtLenToString(MillOffs,-2).. + 'EG'..EmtLenToString(SawOffs,-2)..'EI'..EmtLenToString(ParkY,-2)..'EL'..EmtLenToString(ParkV,-2).. + 'EM'..EmtLenToString(TurnerOffs,-2) + EmtOutput( '\n' .. sOut .. '\n') + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + end +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- reset recupero sovramateriale in X non più presente + EMT.X_OFF = nil + -- dati del grezzo + local LBarra = EMT.LB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- calcolo dati pinze + local MinAccPinze = 0.3 + local MaxAccPinze = 4 + local KgMtCubo= 550 -- densità legno in Kg / metro cubo + local Massa = ( HTrave * STrave * LBarra * KgMtCubo ) / 1000000000 + local FMaxPinze = EMT.FMAXPINZE + local ForzaAtrito = 700 / 2 -- Serve per regolare P32 (700 valore reale pistone) + local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAtrito) / 1000) + if ( TempoAcc < MinAccPinze) then TempoAcc = MinAccPinze end + if ( TempoAcc > MaxAccPinze) then TempoAcc = MaxAccPinze end + local AccPinze = FMaxPinze / ( 60 * TempoAcc) + local RidFeed = 100 / Massa * 100 + if ( RidFeed > 100) then RidFeed = 100 end + if IdTrave >= 0 then + local sOut = '( SN='..IdTrave..' LBarra='..EmtLenToString(LBarra,3)..' L='..EmtLenToString(LTrave,3).. + ' H='..EmtLenToString(HTrave,3)..' S='..EmtLenToString(STrave,3)..' Acc='..EmtLenToString(TempoAcc,1).. + ' RidFeed='..EmtLenToString(RidFeed,3)..' FeedMax='..EmtLenToString(FMaxPinze / 100 * RidFeed,3)..' )' + MyOutputNoNum( sOut) + sOut = 'E30049='..EmtLenToString(AccPinze,0)..' E30050=8555 E30051='..EmtLenToString(AccPinze,0).. + ' E30052=8555'..' E30054='..EmtLenToString(AccPinze,0)..' E30039='..EmtLenToString(RidFeed*1000,0).. + ' E30040='..EmtLenToString(RidFeed*1000,0)..' E30017=E80017'..' E30018=E80018'..' E10012=1' + MyOutputNoNum( sOut) + else + MyOutputNoNum( '(REMAIN UNLOAD)') + end + -- se carico barra + if EMT.LOAD then + -- verifico se sezione già caricata + local sOut = 'IF E30033<'..EmtLenToString(HTrave*1000,0)..' OR E30036<'..EmtLenToString(STrave*1000,0)..' THEN' + EmtOutput( sOut) + sOut = 'M119' + EmtOutput( sOut) + sOut = 'M149' + EmtOutput( sOut) + sOut = 'ENDI' + EmtOutput( sOut) + -- assegnazione dati trave e barra + sOut = 'E30033='..EmtLenToString(HTrave*1000,0)..' E30036='..EmtLenToString(STrave*1000,0).. + ' E30069='..EmtLenToString(LBarra*1000,0) + EmtOutput( sOut) + -- ora abilito numerazione linee + EMT.NUM = true + EMT.LINENBR = 0 + -- altrimenti recupero rimanenza + else + EmtOutput( 'G112 EC1'..' Y'..EmtLenToString( LoadT, 3).. ' EY'..EmtLenToString( EMT.Y1POS, 3)..' EV'..EmtLenToString( ParkV, 3) ..' EF'..GetFmaxClamp()) + -- aggiorno dati aggancio carrelli alla trave + EMT.Y1DELTA = EMT.Y1POS - LoadT + EMT.Y2DELTA = nil + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) then + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- verifico se sono diverse + if nRot ~= nPrevRot then + if nRot > nPrevRot then nRot = nRot - 4 end + local nDeltaRot = nRot - nPrevRot + -- se rotazione automatica richiesta e possibile + if AutomaticRotation and EMT.LB >= AutoRotMinLen then + local sOut = 'M180 L0=' .. tostring( -nDeltaRot) + EmtOutput( sOut) + else + local sOut + if nDeltaRot == -1 then + sOut = 'M151' + elseif nDeltaRot == -2 then + sOut = 'M152' + elseif nDeltaRot == -3 then + sOut = 'M153' + end + EmtOutput( sOut) + EmtOutput( 'M86') + EmtOutput( 'G4F.5') + end + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + MyOutputNoNum( '(PART UNLOAD)') + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + EmtOutput( 'G111ET1002') + EmtOutput( 'G111ET2002') + -- emissione conclusione pezzo precedente + local sOut = 'G113 EA0EB1EC1' + EmtOutput( sOut) + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + end + + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- se primo grezzo, reset lunghezza barra + if EMT.RAWIND == 1 then EMT.LB = 0 end + -- aggiungo la lunghezza del grezzo (solo se movimento in corner) + if EMT.RAWTYPE == 1 then + local b3Raw = EgtGetBBoxGlob( EgtGetFirstNameInGroup( EMT.RAWID, 'RawSolid'), GDB_BB.STANDARD) + local LBarra = b3Raw:getDimX() + EMT.LB = EMT.LB + LBarra + end + -- se primo grezzo, calcolo dati del pezzo + if EMT.RAWIND == 1 then + local PartId = EgtGetFirstPartInRawPart( EMT.RAWID) + if PartId then + EMT.IT = EgtGetInfo( PartId, 'PDN', 'i') or 0 + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box'), GDB_BB.STANDARD) + EMT.LT = b3Part:getDimX() + EMT.HT = b3Part:getDimY() + EMT.ST = b3Part:getDimZ() + EMT.HOVM = EgtGetInfo( EMT.RAWID, 'HOVM', 'd') or 0 + else + EMT.IT = -1 + EMT.LT = 0 + EMT.HT = 0 + EMT.ST = 0 + EMT.HOVM = 0 + end + end + end +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TOOLSEL = EMT.TCPOS..' M06' + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + EMT.MCHNAME = EgtGetMachiningParam(MCH_MP.NAME) + EMT.MCHTYPE = EgtGetMachiningParam(MCH_MP.TYPE) + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + -- la speed della lama va moltiplicata per 6 + if EMT.EXIT == 2 then + EMT.S = EMT.S * 6 + end + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + --EmtOutput( ';Mach End') + -- Emissione split + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + MyOutputNoNum( '(PART SPLIT)') + elseif EMT.AUXTYPE == 'U' then + MyOutputNoNum( '(PART UNLOAD)') + elseif EMT.AUXTYPE == 'P' then + MyOutputNoNum( '(PART ROTATION)') + end + end + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if EMT.AUXTYPE == 'S' then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + elseif EMT.AUXTYPE == 'U' then + EmtOutput( 'G111ET1002') + EmtOutput( 'G111ET2002') + -- emissione conclusione pezzo precedente + local sOut = 'G113 EA0EB1EC1' + EmtOutput( sOut) + elseif EMT.AUXTYPE == 'P' then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + end + end + EMT.AUXSTR = {} + EMT.AUXTYPE = nil + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStart() + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.AUXCMD = {} + EMT.AUXSTR = {} +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + + -- se richiesto, preparo il carico barra + if EMT.LOAD then + PrepareLoad( EMT.AUX) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( EMT.AUX) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnPathEndAux() + --EgtOutLog( 'OnPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'P' + end + end + end + -- preparo a seconda del tipo + if EMT.AUXTYPE == 'R' then + -- per lo scarico della rimanenza + PrepareResidue( EMT.AUX) + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX) + end +end + +--------------------------------------------------------------------- +function OnRapid() + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + if not EMT.LOAD then + if not EMT.ZMAX and #EMT.AUXSTR > 0 then + EmitZmax() + end + EmtOutput( '( *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** )') + end + -- primo posizionamento + EmtResetPrev() + local bZmax = ( #EMT.AUXSTR > 0 or EMT.TOOL ~= EMT.PREVTOOL or EMT.L3 > -1) + local sEE = EgtIf( bZmax, ' EE3', ' EE4') + local sEL = 'EL' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TLEN, ChSawLen), 3) + local sER = 'ER' .. EmtLenToString( EgtIf( EMT.HEAD ~= 'H3', EMT.TDIAM / 2, EMT.TLEN), 3) + local sOut = 'G101' .. EmtGetAxis( 'L2') .. EmtGetAxis( 'L3') .. + EmtGetAxis( 'R2') .. EmtGetAxis( 'R1') .. sEE .. sEL .. sER + if EMT.HEAD == 'H1' then + sOut = sOut..'E'..EMT.TCPOS + elseif EMT.HEAD == 'H2' then + sOut = sOut..'ET42' + elseif EMT.HEAD == 'H3' then + sOut = sOut..'E'..EMT.TCPOS + else + error( "Unknown Head") + end + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H2', 1, 6) + sOut = sOut..'ES'..EgtNumToString( Speed, 0)..' L0=0' + EmtOutput( sOut) + sOut = 'G101ET1001' + EmtOutput( sOut) + -- se prima lavorazione + if EMT.LOAD then + sOut = 'G79 E80060<>0 N9 E10015=0' + EmtOutput( sOut) + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + EMT.AUXSTR = {} + sOut = 'G111ET1001' + EmtOutput( sOut) + sOut = 'G79N9' + EmtOutput( sOut) + sOut = 'E80060=1' + EmtOutput( sOut) + sOut = 'G111ET2001' + EmtOutput( sOut) + EmtOutput( '( *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** )') + sOut = 'G101ET2001' + EmtOutput( sOut) + local sY = EmtLenToString( EMT.L1 + EMT.Y1DELTA) + local sV = EmtLenToString( ParkV) + sOut = 'G112EA1EB2'..EmtGetAxis('L1')..'EY'..sY..'EV'..sV..'EF'..GetFmaxClamp() + EmtOutput( sOut) + EMT.LOAD = false + -- altrimenti lavorazione successiva + else + -- eventuale G111 + --for i = 1, #EMT.AUXCMD do + -- EmtOutput( '( ' .. EMT.AUXCMD[i] .. ' )') + --end + EMT.AUXCMD = {} + for i = 1, #EMT.AUXSTR do + EmtOutput( EMT.AUXSTR[i]) + end + if #EMT.AUXSTR > 0 then + if not EMT.POSTROT then + EmtOutput( 'G111ET1004') + EmtOutput( 'G111ET2004') + else + EmtOutput( 'G111ET1001') + EmtOutput( 'G111ET2001') + end + end + EMT.AUXSTR = {} + local sY, sA + if EMT.Y1DELTA then + sY = EmtLenToString( EMT.L1 + EMT.Y1DELTA - ( EMT.X_OFF or 0)) + sA = '1' + else + sY = EmtLenToString( EgtIf( EMT.Y1POS, EMT.Y1POS, ParkY)) + sA = '2' + end + local sV, sB + if EMT.Y2DELTA then + sV = EmtLenToString( EMT.L1 + EMT.Y2DELTA - ( EMT.X_OFF or 0)) + sB = '1' + else + sV = EmtLenToString( ParkV) + sB = '2' + end + sOut = 'G112EA'..sA..'EB'..sB..EmtGetAxis('L1')..'EY'..sY..'EV'..sV..'EF'..GetFmaxClamp() + EmtOutput( sOut) + sOut = 'G101ET2001' + EmtOutput( sOut) + EMT.POSTROT = false + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se standard + elseif EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + EmtOutput( 'G102'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3')..EMT.IPLGLSTR) + else + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + end + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmitZmax() + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- altrimenti errore + else + error( "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EmtOutput( 'G102'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3')..EMT.IPLGLSTR) + -- emissione movimento + local sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + EmtOutput( sOut) + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R1')..EmtGetAxis('R2') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- aggiungo feed + local sFeed = EmtGetFeed() + -- emetto linea + EmtOutput( "G1"..sAxes..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + -- non modale su archi + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R1')..EmtGetAxis('R2') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString(EMT.RR,3) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- emetto arco + EmtOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd, bSkipPress) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + elseif sCmd == '1' then + return '2' + -- chiuso con pressore attivato + elseif sCmd == '2' then + return EgtIf( bSkipPress, '2', '0') + end +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = 'EB112' + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sYTaking = 'Y'..EmtLenToString( Cmd[3] + DELTA_TAKING) + local sBeamRot = '0+0' + if StartRotation and EMT.LB >= AutoRotMinLen then + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= 0 then + if TEST_USE then + sBeamRot = '0+' .. tostring( -nRot) + else + sBeamRot = '@(LOAD90)+' .. tostring( -nRot) + end + end + end + local sOut = 'G111'..sYTaking..'EA75EB112EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1E80057='..sBeamRot..' E80058=0' + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + local sYLoad = 'Y'..EmtLenToString( LoadT) + local sOut = 'G111'..sYLoad..'EA76'..EMT.SB..'EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1' + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SA = EgtIf( EMT.Y1DELTA, 'EA112', 'EA111') + EMT.SB = EgtIf( EMT.Y1DELTA, 'EB112', 'EB111') + EMT.SC = EgtIf( EMT.Y2DELTA, 'EC142', 'EC141') + EMT.SD = EgtIf( EMT.Y2DELTA, 'ED142', 'ED141') + EMT.SE = EgtIf( EMT.Y1DELTA, 'EE1', 'EE2') + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut = 'G111'..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + if Cmd[2] == 'Y' then EMT.Y1POS = tonumber( Cmd[3]) end + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', Cmd[6] .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'EB11' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = 'EA11' .. CalcCharStatus( Cmd[2]) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE1', 'EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'ED14' .. CalcCharStatus( Cmd[2]) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = 'EC14' .. CalcCharStatus( Cmd[2]) + EMT.SD = 'ED14' .. CalcCharStatus( Cmd[2]) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE2', 'EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.Y1DELTA, 'EA112', 'EA111') + EMT.SB = EgtIf( EMT.Y1DELTA, 'EB112', 'EB111') + EMT.SC = EgtIf( EMT.Y2DELTA, 'EC142', 'EC141') + EMT.SD = EgtIf( EMT.Y2DELTA, 'ED142', 'ED141') + EMT.SE = EgtIf( EMT.Y1DELTA, 'EE1', 'EE2') + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + if not EMT.UNL then + sOut = 'G111'..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + else + sOut = 'G111'..Cmd[2]..Cmd[3]..'EC141ED83EE0EF'..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', Cmd[6] .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'EB11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = 'EA11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE1', 'EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'ED14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = 'EC14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = 'ED14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE2', 'EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + local sOut = 'G111'..Cmd[2]..Cmd[3]..'EA110EB110EC142ED142EE2EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + EMT.Y1POS = tonumber( Cmd[3]) + end + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sEE = EgtIf( EMT.PHASE == EgtGetPhaseCount(), '0', '1') + local sOut = 'G111'..Cmd[2]..Cmd[3]..'EC141ED83EE'..sEE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[4] == 'V' then + -- se non è ultima fase c'è una barra sulla pinza Y (1) + local sEAB = EgtIf( EMT.PHASE == EgtGetPhaseCount(), '111', '112') + local sOut = 'G111'..Cmd[4]..Cmd[5]..'EA'..sEAB..'EB'..sEAB..'EC142ED141EE2EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + -- non interessa + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if EMT.AUXIND <= 2 then + EMT.SA = EgtIf( EMT.Y1DELTA, 'EA112', 'EA111') + EMT.SB = EgtIf( EMT.Y1DELTA, 'EB112', 'EB111') + EMT.SC = EgtIf( EMT.Y2DELTA, 'EC142', 'EC141') + EMT.SD = EgtIf( EMT.Y2DELTA, 'ED142', 'ED141') + EMT.SE = EgtIf( EMT.Y1DELTA, 'EE1', 'EE2') + end + -- se è pre-rotazione + if Cmd[2] == 'Pre-Rotation' then + EMT.PREROT = true + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] ~= 'Z' then + local sOut + if not EMT.PREROT then + sOut = 'G111'..Cmd[2]..Cmd[3]..EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + else + sOut = 'G111'..Cmd[2]..Cmd[3]..'EA86EB87EC141EE0EF'..GetFmaxClamp() + end + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + local sOut = 'G111'..(EgtIf( Cmd[2] ~= 'T', Cmd[2] .. Cmd[3], '')).. + (EgtIf( Cmd[4] ~= 'T', Cmd[4] .. Cmd[5], '')).. + (EgtIf( Cmd[6] ~= 'T', Cmd[6] .. Cmd[7], '')).. + EMT.SA..EMT.SB..EMT.SC..EMT.SD..EMT.SE..'EF'..GetFmaxClamp() + table.insert( EMT.AUXSTR, sOut) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'EB11' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SB, sVal) + end + EMT.SA = 'EA11' .. CalcCharStatus( Cmd[2], true) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE1', 'EE2') + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + if #EMT.AUXSTR > 0 then + local sVal = 'ED14' .. CalcCharStatus( Cmd[2], true) + local sOut = EMT.AUXSTR[#EMT.AUXSTR] + EMT.AUXSTR[#EMT.AUXSTR] = sOut:gsub( EMT.SD, sVal) + end + EMT.SC = 'EC14' .. CalcCharStatus( Cmd[2], true) + EMT.SD = 'ED14' .. CalcCharStatus( Cmd[2], true) + EMT.SE = EgtIf( Cmd[2] ~= '0', 'EE2', 'EE1') + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if EMT.AUXIND == 1 then + -- imposto stato pinze + EMT.SB = 'EB112' + end + elseif Cmd[1] == '1' then + local sMsg = Cmd[2] .. Cmd[3] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '2' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] + table.insert( EMT.AUXCMD, sMsg) + if Cmd[2] == 'Y' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + local sYTaking = 'Y'..EmtLenToString( Cmd[3] - EMT.HOVM) + local sOut = 'G111'..sYTaking..'EA75EB112EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1 E80058=0' + table.insert( EMT.AUXSTR, sOut) + end + elseif Cmd[1] == '3' then + local sMsg = Cmd[2] .. Cmd[3] ..' '.. Cmd[4] .. Cmd[5] ..' '.. Cmd[6] .. Cmd[7] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '11' then + local sMsg = 'PY' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + EMT.SB = 'EB11' .. CalcCharStatus( Cmd[2]) + elseif Cmd[1] == '12' then + local sMsg = 'PV' .. ' ' .. Cmd[2] + table.insert( EMT.AUXCMD, sMsg) + elseif Cmd[1] == '21' then + local nYDelta = tonumber( Cmd[2]) + local nVDelta = tonumber( Cmd[3]) + if nYDelta > 0 and nVDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nVDelta + elseif nYDelta > 0 then + EMT.Y1DELTA = nYDelta + EMT.Y2DELTA = nil + elseif nVDelta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nVDelta + end + local sYLoad = 'Y'..EmtLenToString( LoadT) + local sOut = 'G111'..sYLoad..'EA76'..EMT.SB..'EE0EF'..EmtLenToString(EMT.FMAXPINZE,0)..'ET1' + table.insert( EMT.AUXSTR, sOut) + end +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + if EMT.REFLOC then + local vtE + if EMT.HEAD ~= 'H3' then + local Len = EMT.TLEN + EgtIf( EMT.HEAD == 'H1', MillOffs, abs( SawOffs)) + local LenRef = MillOffs + vtE = Vector3d( EMT.EXTR) * Len - Z_AX() * LenRef + else + local Len = ChSawLen + MillOffs + local LenRef = MillOffs + local vtAux = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2) + vtE = Vector3d( vtAux) * Len - Z_AX() * LenRef + end + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - DeltaTabY - vtE:getY() + EMT.L3 = EMT.L3 - DeltaTabZ - vtE:getZ() + end + + if EMT.X_OFF then EMT.L1 = EMT.L1 + EMT.X_OFF end + + EmtAdjustLinearAxes() + + if not EMT.REFLOC then + EMT.L2 = - EMT.L2 + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function MyOutputNoNum( sOut) + local bNum = EMT.NUM + EMT.NUM = false + EmtOutput( sOut) + EMT.NUM = bNum +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + LoadT + if EMT.X_OFF then xS = xS + EMT.X_OFF end + local ptS = Point3d( xS, 0, 0) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H3' then + vtE = Vector3d( EMT.EXTR) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --EmtOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local _, dAngV, dAngO = SphericalFromVector( vtE) + local dAngO2 = EmtGetAngO2( EMT.IPLGLFR:getVersZ(), EMT.IPLGLFR:getVersX(), dAngV, dAngO) + dAngO = dAngO + 90 + while dAngO >= 360 do + dAngO = dAngO - 360 + end + EMT.IPLGLSTR = ' EX0 EY'..EmtLenToString( xS)..' EZ0'.. + ' EA0'..' EB'..EgtNumToString(dAngV)..' EC'..EgtNumToString(dAngO)..' ED'..EgtNumToString(dAngO2) + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function EmitZmax() + local sOut = 'G101 Z' .. EgtGetAxisHomePos('Z') .. ' L0=0' + EmtOutput( sOut) + sOut = 'G101ET1001' + EmtOutput( sOut) + sOut = 'G101ET2001' + EmtOutput( sOut) +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE, 0) +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.TPA.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.TPA.mlpe new file mode 100644 index 0000000..e38efee --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.TPA.mlpe @@ -0,0 +1,2100 @@ +-- Processore macchina Essetre-PF1250 by EgalTech s.r.l. 2021/09/21 +-- Con controllo numerico TPA + +-- Variabili di modulo +local MLE_INFO = 'Essetre-PF1250.TPA.mlpe ver.'..PP_VER..' by EgalTech s.r.l.' +local TEST_USE = false + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +function OnStart() + -- controllo versione programma + if not EMT.VER or EMT.VER < '2.3h1' then + EmtSetLastError( 1200, 'A newer version of the program is required (minimum 2.3h1)') + end + EMT.USETO1 = false -- abilitazione uso origine tavola + EMT.MODAL = true -- abilitazione emissione modale + EMT.INCHES = false -- unità di misura mm/inches + EMT.DECNUM = 5 -- numero di decimali dopo la virgola + EMT.NUM = false -- abilitazione numerazione linee + --EMT.Nt = 'N' -- token per la numerazione di linea + --EMT.LINENBR = 0 -- numero di linea + --EMT.LINEINC = 1 -- incremento numerazione linee + --EMT.Ft = 'F' -- token per feed + --EMT.St = 'S' -- token per speed + EMT.FMAXPINZE = 116000 -- feed massima pinze + SetToParkLine() -- si inizia con linee da parcheggiare su stack +end + +--------------------------------------------------------------------- +function OnEnd() + -- Ripristino fase iniziale come corrente + EgtSetCurrPhase( 1) +end + +--------------------------------------------------------------------- +function OnProgramStart() + -- Intestazioni + if EMT.INFO then + EmitRemark( EMT.INFO) + else + EmitRemark( 'Program Start') + end + EmitRemark( MLE_INFO) + -- Se modalità test, aggiungo linee per muovere tappeto e alzare la testa (in automatico viene fatto dal main residente) + if TEST_USE then + MyOutput( 'M199') + end + -- Dichiaro inizio + EMT.FIRST = true + -- Inizializzazioni varie + MyOutput( 'G49') + -- Inizio lista utensili + MyOutput( 'M993 (Tool List Start)') + -- Dichiaro cabine con rulli in posizione di parcheggio + EMT.V1POS = ParkV1 + EMT.V2POS = ParkV2 +end + +--------------------------------------------------------------------- +function OnProgramEnd() + -- Arresto mandrino + MyOutput( 'M05') + -- Emissione scarico + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + end + if #EMT.MDCHAR > 0 then + if EMT.AUXTYPE == 'S' then + EmitMoveStartChars( 3) + EmitMoveWaitChars( 3) + elseif EMT.AUXTYPE == 'R' then + EmitMoveDataChars( { Y1=ParkY1, Y2=ParkY2, V1=ParkV1, V2=ParkV2, BeamVise=0, MoveType=3}) + EmitMoveStartChars( 3) + EmitMoveWaitChars( 3) + elseif EMT.AUXTYPE == 'U' then + EmitMoveStartChars( EgtIf( EMT.CHY_ON, 3, 2)) + EmitMoveWaitChars( EgtIf( EMT.CHY_ON, 3, 2), true) + -- emissione conclusione pezzo precedente (se non si è in test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + end + end + EMT.MDCHAR = {} + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.RELOAD = nil + EMT.RELOAD2 = nil + -- Termino il programma + MyOutput( 'M202') + MyOutput( 'M02') +end + +--------------------------------------------------------------------- +function OnToolData() + -- emissione dati utensile (esclusa sega a catena) + if EMT.HEAD ~= 'H13' then + local dAddLen = EgtIf( EMT.HEAD == 'H12', -SawOffsZ, 0) + local sOut = 'M992 P1=' .. EMT.TCPOS:gsub( 'T', '') .. ' P2=' .. EmtLenToString( dAddLen + EMT.TLEN, 3) .. ' P3=' .. EmtLenToString( EMT.TDIAM, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( dAddLen + EMT.TTOTLEN, 3) + MyOutput( sOut) + -- emissione dati sega a catena + else + local sData = ' P2=' .. EmtLenToString( ChSawLen, 3) .. ' P3=' .. EmtLenToString( EMT.TLEN, 3) .. + ' P4=' .. EmtLenToString( EMT.SMAX, 3) .. ' P5=' .. EmtLenToString( ChSawLen, 3) + MyOutput( 'M992 P1=101' .. sData) + MyOutput( 'M992 P1=102' .. sData) + MyOutput( 'M992 P1=103' .. sData) + MyOutput( 'M992 P1=104' .. sData) + end +end + +--------------------------------------------------------------------- +function OnDispositionStart() + EMT.OPEISDISP = true + -- Assegnazione parametri disposizione, se impostati + EMT.TPOS = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') or EMT.TPOS + EMT.Y1POS = EgtGetInfo( EMT.DISPID, 'Y1POS', 'd') + -- Se prima disposizione + if EMT.PHASE == 1 then + -- terminazione lista utensili + MyOutput( 'G990 (Tool List End)') + MyOutput( 'M28') + -- emissione dati di macchina + local sOut = 'M114'..' P1='..EmtLenToString( LoadT, 2)..' P2='..EmtLenToString( MinMchY1, 2)..' P3='..EmtLenToString( MaxY1, 2).. + ' P4='..EmtLenToString( MinY2, 2)..' P5='..EmtLenToString( MaxMchY2, 2)..' P6='..EmtLenToString( MillOffs, 2).. + ' P7='..EmtLenToString( Mill2Offs, 2)..' P8='..EmtLenToString( ParkMchY1, 2)..' P9='..EmtLenToString( ParkMchY2, 2).. + ' P10='..EmtLenToString( -TurnerOffs, 2)..' P11='..EmtLenToString( MinV1, 2)..' P12='..EmtLenToString( MaxV1, 2).. + ' P13='..EmtLenToString( MinV2, 2)..' P14='..EmtLenToString( MaxV2, 2).. + ' P15='..EmtLenToString( -DeltaTabY, 2)..' P16='..EmtLenToString( DeltaTabZ - MillOffs, 2).. + ' P17='..EmtLenToString( Delta2TabY, 2)..' P18='..EmtLenToString( -Delta2TabZ - Mill2Offs, 2) + MyOutput( sOut) + -- carico barra + EMT.LOAD = true + else + EMT.LOAD = false + if IsEnd2Phase( EMT.PHASE - 1) then + EMT.RELOAD = true + EMT.RELOAD2 = false + end + end +end + +--------------------------------------------------------------------- +function OnDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- reset recupero sovramateriale in X non più presente + EMT.X_OFF = nil + -- gruppo con info da BTL + local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL + -- dati del grezzo + local LBarra = EMT.LB + local HBarra = EMT.HB + -- dati del pezzo + local IdTrave = EMT.IT + local LTrave = EMT.LT + local HTrave = EMT.HT + local STrave = EMT.ST + local HOverM = EMT.HOVM + -- calcolo dati pinze + local AccPinze, AccMaxPinze, RidFeed = CalcDinamicaPinze( HTrave, STrave, LBarra) + local AccPinz1, AccMaxPinz1, RidFeed1 = CalcDinamicaPinze( HTrave, STrave, LBarra - LTrave) + local AccPinz2, AccMaxPinz2, RidFeed2 = CalcDinamicaPinze( HTrave, STrave, LTrave) + if IdTrave >= 0 then + local sRem = ' SN=' .. IdTrave .. ' LBarra=' .. EmtLenToString( LBarra, 3) .. ' L='..EmtLenToString( LTrave, 3) .. + ' H=' .. EmtLenToString( HTrave, 3) .. ' S=' .. EmtLenToString( STrave, 3) .. ' ' + EMT.PRODID = EgtGetInfo( BtlInfoId, 'PRODID', 'i') or 0 + EMT.PATTID = EgtGetInfo( BtlInfoId, 'PATTID', 'i') or 0 + EMT.CUTID = EgtGetInfo( EMT.IDT, 'CUTID', 'i') or 0 + local sStart = 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=1' + EmitRemark( sRem) + if not TEST_USE then MyOutput( sStart) end + else + EmitRemark( 'REMAIN UNLOAD') + EMT.PRODID = nil + EMT.PATTID = nil + EMT.CUTID = nil + end + -- se carico barra + if EMT.LOAD or EMT.RELOAD then + local nLoad90 = EgtGetInfo( BtlInfoId, 'LOAD90', 'i') or 0 + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( max( HTrave, HBarra), 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( nLoad90) .. ' P6=' .. EmtLenToString( LTrave, 2) .. + ' P7=' .. EgtNumToString( AccPinze, 2) .. ' P8=' .. EgtNumToString( AccPinz2, 2) .. ' P9=' .. EgtNumToString( AccPinz1, 2) .. + ' P10=' .. EgtNumToString( EMT.PARTTYPE or 0, 0) + MyOutput( sOut) + if EMT.LOAD then + SetStartValue( 1, LBarra) + SetStartValue( 2, max( HTrave, HBarra)) + SetStartValue( 3, STrave) + SetStartValue( 6, HOverM) + end + -- altrimenti recupero rimanenza + else + sOut = 'M115 P1=' .. EmtLenToString( LBarra, 2) .. ' P2=' .. EmtLenToString( HTrave, 2) .. ' P3=' .. EmtLenToString( STrave, 2) .. + ' P4=' .. EmtLenToString( HOverM, 2) .. ' P5=' .. tostring( 0) .. ' P6=' .. EmtLenToString( EgtIf( IdTrave >= 0, LTrave, LBarra), 2) .. + ' P7=' .. EgtNumToString( AccPinze, 2) .. ' P8=' .. EgtNumToString( AccPinz2, 2) .. ' P9=' .. EgtNumToString( AccPinz1, 2).. + ' P10=' .. EgtNumToString( EMT.PARTTYPE or 0, 0) + MyOutput( sOut) + -- determino la quota di parcheggio della trave + local ParkT = GetParkT() + -- aggiorno dati aggancio carrelli alla trave + EMT.Y1DELTA = EMT.Y1POS - ParkT + EMT.Y2DELTA = nil + EmitBeamHeadData( { T=ParkT, Y1=EMT.Y1POS, SetHead=1, F=0}) + end + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- verifico se sono diverse + if nRot ~= nPrevRot then + if nRot > nPrevRot then nRot = nRot - 4 end + local nDeltaRot = nRot - nPrevRot + -- rotazione automatica o manuale (sempre con il medesimo comando) + local sOut = 'M180 P1=' .. tostring( -nDeltaRot) + MyOutput( sOut) + -- imposto stato post-rotazione + EMT.POSTROT = true + -- imposto recupero sovramateriale in X non più presente + EMT.X_OFF = EMT.HOVM + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + if #EMT.MDCHAR > 0 then + EmitRemark( 'PART UNLOAD') + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + end + if #EMT.MDCHAR > 0 then + EmitMoveStartChars( 2) + -- se dopo c'è scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE + 1) then + EmitMoveWaitChars( 2) + else + EmitMoveWaitChars( 2, true) + end + -- emissione conclusione pezzo precedente (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + end + EMT.MDCHAR = {} + EMT.AUXTYPE = nil + end + + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnTableData() +end + +--------------------------------------------------------------------- +function OnFixtureData() +end + +--------------------------------------------------------------------- +function OnRawMoveData() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + -- se primo grezzo, reset lunghezza barra + if EMT.RAWIND == 1 then + EMT.LB = 0 + EMT.HB = 0 + end + -- aggiungo la lunghezza del grezzo (solo se movimento in corner) + if EMT.RAWTYPE == 1 then + local b3Raw = EgtGetBBoxGlob( EgtGetFirstNameInGroup( EMT.RAWID, 'RawSolid'), GDB_BB.STANDARD) + local LBarra = b3Raw:getDimX() + EMT.LB = EMT.LB + LBarra + local HBarra = b3Raw:getDimY() + EMT.HB = max( EMT.HB, HBarra) + end + -- se primo grezzo, calcolo dati del pezzo + if EMT.RAWIND == 1 then + local PartId = EgtGetFirstPartInRawPart( EMT.RAWID) + if PartId then + EMT.IDT = PartId + EMT.IT = EgtGetInfo( PartId, 'PDN', 'i') or 0 + local b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PartId, 'Box'), GDB_BB.STANDARD) + EMT.LT = b3Part:getDimX() + EMT.HT = b3Part:getDimY() + EMT.ST = b3Part:getDimZ() + EMT.HOVM = EgtGetInfo( EMT.RAWID, 'HOVM', 'd') or 0 + EMT.PARTTYPE = 0 + local sMaterial = EgtGetInfo( PartId, 'MATERIAL') + if sMaterial and sMaterial:find( 'CLT-', 1, true) == 1 then + EMT.PARTTYPE = 1 + elseif sMaterial and sMaterial:find( 'UT-', 1, true) == 1 then + EMT.PARTTYPE = 2 + end + else + EMT.IDT = GDB_ID.NULL + EMT.IT = -1 + EMT.LT = 0 + EMT.HT = EMT.HT or 0 + EMT.ST = EMT.ST or 0 + EMT.HOVM = 0 + end + end + end +end + +--------------------------------------------------------------------- +function OnToolSelect() + -- se utensile definito (non definito per disposizioni con movimento) + if EMT.TOOL ~= '' then + -- verifiche su utensile + local sTool = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or "") + if sTool ~= EMT.TOOL then error( "Tool name mismatch") end + -- predefinite EMT.TCPOS EMT.HEAD EMT.EXIT + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + EMT.TDIAM = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + EMT.TTOTDIAM = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + EMT.TLEN = EgtTdbGetCurrToolParam( MCH_TP.LEN) + EMT.TTOTLEN = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) + end +end + +--------------------------------------------------------------------- +function OnToolDeselect() +end + +--------------------------------------------------------------------- +function OnMachiningStart() + --EMT.MCHNAME = EgtGetMachiningParam( MCH_MP.NAME) + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EMT.MCHUSERNOTES = EgtGetMachiningParam( MCH_MP.USERNOTES) + -- se sega a catena, aggiusto subito angolo scelto per asse virtuale A + if EMT.HEAD == 'H13' then + -- valore dell'asse virtuale + dPosA = GetCurrChainSawingVirtualAxis() + -- imposto home dell'asse C1 (A=0 -> T101, A=90 -> T104) + local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA) + EmtModifyAxisHome( 'C1', MyParkCSawC1) + end +end + +--------------------------------------------------------------------- +function OnMachiningEnd() + --MyOutput( ';Mach End') + -- Emissione split + if #EMT.MDCHAR > 0 then + if EMT.AUXTYPE == 'S' then + EmitRemark( 'PART SPLIT') + EMT.LB = EMT.LT + elseif EMT.AUXTYPE == 'U' then + EmitRemark( 'PART UNLOAD') + elseif EMT.AUXTYPE == 'P' then + if EMT.PREROT then + EmitZmax( false, true, EMT.R1, EMT.R2) + EMT.ZMAX = true + EmitRemark( 'PART ROTATION') + elseif EMT.FALL then + if EMT.TO_ZMAX and not EMT.ZMAX then + EmitZmax( false, true, EMT.R1, EMT.R2) + EMT.ZMAX = true + EMT.TO_ZMAX = nil + end + EmitRemark( 'PART FALL') + else + EmitZmax( false, true, EMT.R1, EMT.R2) + EMT.ZMAX = true + EmitRemark( 'PART SPLIT 2') + end + end + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + end + if #EMT.MDCHAR > 0 then + if EMT.AUXTYPE == 'S' then + EmitMoveStartChars( 1) + EmitMoveWaitChars( 1) + elseif EMT.AUXTYPE == 'U' then + local nMoveType = EgtIf( EMT.CHY_ON, 3, 2) + EmitMoveStartChars( nMoveType) + -- se dopo cè scarico spezzone devo mettere attesa termine esecuzione + if IsRestPhase( EMT.PHASE + 1) then + EmitMoveWaitChars( nMoveType) + else + EmitMoveWaitChars( nMoveType, true) + end + -- emissione conclusione pezzo precedente (se non è modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + elseif EMT.AUXTYPE == 'P' then + EmitMoveStartChars( 3) + EmitMoveWaitChars( 3) + if EMT.FALL then + MyOutput( 'M155') + -- emissione conclusione pezzo (se non in modalità test) + if not TEST_USE and EMT.PRODID then + local sEnd= 'M113 P1='..tostring( EMT.PRODID)..' P2='..tostring( EMT.PATTID)..' P3='..tostring( EMT.CUTID)..' P4=2' + MyOutput( sEnd) + end + elseif not EMT.PREROT then + MyOutput( 'M77') + end + end + end + EMT.MDCHAR = {} + EMT.AUXTYPE = nil + EMT.TO_ZMAX = nil + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStart() + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true + EMT.MCHFIRSTFEED = true + -- primo posizionamento sempre in globale + EMT.REFLOC = nil + EMT.IPLGL = false + -- leggo se ancora presa iniziale carrello + --EMT.CNT = EgtGetInfo( EMT.PATHID, 'CNT', 'i') + --MyOutput( 'CNT='.. tostring( EMT.CNT or 0)) + -- se utensile non cambiato, salvo eventuali precedenti rotanti + if EMT.TOOL == EMT.PREVTOOL and not EMT.ZMAX then + EMT.R1pp = EMT.R1p + EMT.R2pp = EMT.R2p + else + EMT.R1pp = nil + EMT.R2pp = nil + end + -- reset valori precedenti (per forzare emissione di tutti gli assi del 1° movimento) + EmtResetPrev() + EMT.AUXCMD = {} + EMT.MDCHAR = {} +end + +--------------------------------------------------------------------- +function OnPathEnd() + if not EMT.ZMAX then + EmitResetMachining() + end + EMT.AUXTYPE = nil + EMT.UNL = nil + EMT.PREROT = nil + EMT.SPLITROT = nil + EMT.CHY_ON = nil + EMT.FALL = nil + EMT.MDCHAR = {} + EMT.PREVTOOL = EMT.TOOL +end + +--------------------------------------------------------------------- +function OnPathStartAux() + --EgtOutLog( 'OnPathStartAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- salvo il comando per processarlo successivamente + table.insert( EMT.AUXCMD, EMT.AUX) + -- gestione speciale per richiesta di movimento a ZMAX + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '4' then + EMT.TO_ZMAX = true + end +end + +--------------------------------------------------------------------- +function ProcessPathStartAux( sCmd, nInd) + -- se richiesto, preparo il carico barra + if EMT.LOAD or EMT.RELOAD then + PrepareLoad( sCmd, nInd, true) + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + PreparePostRotation( sCmd, nInd) + -- altrimenti, preparo lo spostamento carrelli + else + PrepareMoveChar( sCmd, nInd) + end +end + +--------------------------------------------------------------------- +function OnPathEndAux() + --EgtOutLog( 'OnPathEndAux - ' .. EgtNumToString( EMT.AUXIND, 0) .. ' - ' .. EMT.AUX) + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'P' + if Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.FALL = true + end + end + elseif EMT.AUXTYPE == 'P' then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.CHY_ON = true + EMT.AUXTYPE = 'U' + end + end + end + -- preparo a seconda del tipo + if EMT.AUXTYPE == 'R' then + -- per il carico della rimanenza dopo rotazione speciale + if EMT.RELOAD and not EMT.RELOAD2 then + PrepareLoad( EMT.AUX, EMT.AUXIND, false) + -- per lo scarico della rimanenza + else + PrepareResidue( EMT.AUX, EMT.AUXIND) + end + elseif EMT.AUXTYPE == 'S' then + -- per lo split + PrepareSplit( EMT.AUX, EMT.AUXIND) + elseif EMT.AUXTYPE == 'U' then + -- per lo scarico + PrepareUnload( EMT.AUX, EMT.AUXIND) + elseif EMT.AUXTYPE == 'P' then + -- per la pre-rotazione + PreparePreRotation( EMT.AUX, EMT.AUXIND) + end +end + +--------------------------------------------------------------------- +function OnRapid() + -- gruppo della testa + local nHSet = GetHeadSet( EMT.HEAD) + -- se primo movimento della lavorazione, gestione speciale + if EMT.MCHFIRST and not EMT.OPEISDISP then + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + local HomeR1 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'C1', 'C2')) + local HomeR2 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'B1', 'B2')) + local PrevR1 = EMT.R1p or EMT.R1pp or HomeR1 + local PrevR2 = EMT.R2p or EMT.R2pp or HomeR2 + EmtResetPrev() + -- se prima lavorazione + if EMT.LOAD then + EMT.V2POS = ParkV2 + -- primo posizionamento + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H12', 1, 1.65) + local bOnlyCharY = true + for i = 1, #EMT.AUXCMD do + ProcessPathStartAux( EMT.AUXCMD[i], i) + end + EMT.AUXCMD = {} + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + if EMT.MDCHAR[i].MovType ~= 1 then bOnlyCharY = false end + end + EMT.MDCHAR = {} + EmitMoveStartChars( EgtIf( bOnlyCharY, 1, 3)) + EmitRemark( ' *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** ') + -- se testa 1 + if nHSet == 1 then + -- selezione testa (posso muovere X solo a Zmax) + local MaxZ1 = EgtGetAxisMax( 'Z1') + local bXSpec = ( EMT.L2 > -DeltaTabY) + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), Z=MaxZ1, S=Speed}) + EmitMoveStartHead( 1) + EmitMoveWaitHead( 1) + EmitMoveWaitChars( EgtIf( bOnlyCharY, 1, 3)) + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, EMT.R1, EMT.R2) or + EMT.V1POS < EMT.V1NEXTPOS - 1 or EMT.V2POS > EMT.V2NEXTPOS + 1 then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, bSpliCut) + end + EmitMoveDataHead( 1, { Z=EMT.L3, S=Speed}) + EmitMoveDataHead( 1, { B=EMT.R2, C=EMT.R1, S=Speed}) + if bXSpec then EmitMoveDataHead( 1, { X=EMT.L2, S=Speed}) end + EmitMoveStartHead( 1) + -- eventuale preselezione successiva testa 2 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 1 + EmitMoveWaitHead( 1) + -- altrimenti testa 2 + else + -- selezione testa (non posso muovere X) + EmitMoveDataHead( 2, { X=ParkX2, S=Speed}) + EmitMoveStartHead( 2) + EmitMoveWaitHead( 2) + EmitMoveWaitChars( EgtIf( bOnlyCharY, 1, 3)) + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, EMT.R1, EMT.R2) or + EMT.V1POS < EMT.V1NEXTPOS - 1 or EMT.V2POS > EMT.V2NEXTPOS + 1 then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, bSpliCut) + end + EmitMoveDataHead( 2, { X=EMT.L2, Z=EMT.L3, S=Speed}) + EmitMoveDataHead( 2, { B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 2) + -- eventuale preselezione successiva testa 1 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 2 + EmitMoveWaitHead( 2) + end + -- se pezzo a destra, dichiaro cabina sinistra da parcheggiare + if not EMT.Y1DELTA then + EMT.V1NEXTPOS = ParkV1 + end + -- dati aggancio a trave + local BhData = { T=EMT.L1, SetHead=0} + if EMT.Y1DELTA then + BhData.Y1 = EMT.L1 + EMT.Y1DELTA + BhData.ViseY1 = 1 + else + BhData.Y1 = ParkY1 + BhData.ViseY1 = 2 + end + if EMT.Y2DELTA then + BhData.Y2 = EMT.L1 + EMT.Y2DELTA + BhData.ViseY2 = 1 + else + BhData.Y2 = ParkY2 + BhData.ViseY2 = 2 + end + if GetV1ToClose() then + BhData.V1 = EMT.V1NEXTPOS ; EMT.V1POS = BhData.V1 + BhData.StatV1 = -2 + elseif abs( EMT.V1POS - ParkV1) > 0.1 then + BhData.V1 = ParkV1 ; EMT.V1POS = BhData.V1 + BhData.StatV1 = 1 + end + if GetV2ToClose() then + BhData.V2 = EMT.V2NEXTPOS ; EMT.V2POS = BhData.V2 + BhData.StatV2 = -2 + elseif abs( EMT.V2POS - ParkV2) > 0.1 then + BhData.V2 = ParkV2 ; EMT.V2POS = BhData.V2 + BhData.StatV2 = 1 + end + EmitBeamHeadData( BhData) + EMT.LOAD = false + -- emissione prime linee speciali e linee parcheggiate + EmitStartValues() + local ProdId = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PRODID', 'i') or 0 + MyOutput( ';LISTA = ' .. tostring( ProdId)) + EmitParkedLines() + -- altrimenti lavorazione successiva + else + --MyOutput( string.format( 'V1Pos=%.3f V2Pos=%.3f', EMT.V1POS, EMT.V2POS)) + if not EMT.RELOAD and not EMT.ZMAX and #EMT.AUXCMD > 0 and EMT.TO_ZMAX then + EmitZmax( false, false, PrevR1, PrevR2) + EMT.ZMAX = true + EMT.TO_ZMAX = nil + PrevR1 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'C1', 'C2')) + PrevR2 = EgtGetAxisHomePos( EgtIf( nHSet == 1, 'B1', 'B2')) + end + EmitRemark( ' *** '..EMT.MCHNAME..'/'..EMT.TOOL..' *** ') + -- se Split lascio agganciata solo la pinza Y2 alla fine dei movimenti + local bSpliCut = ( EMT.MCHUSERNOTES:find( 'Split', 1, true) ~= nil) + -- eventuale movimento carrelli + for i = 1, #EMT.AUXCMD do + ProcessPathStartAux( EMT.AUXCMD[i], i) + end + EMT.AUXCMD = {} + if bSpliCut and #EMT.MDCHAR > 0 then + EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = 1 + end + for i = 1, #EMT.MDCHAR do + EmitMoveDataChars( EMT.MDCHAR[i]) + end + if #EMT.MDCHAR > 0 then + local nMoveType = EgtIf( EMT.POSTROT or EMT.RELOAD, 1, 3) + EmitMoveStartChars( nMoveType) + EmitMoveWaitChars( nMoveType) + end + EMT.MDCHAR = {} + -- se pezzo a destra, dichiaro cabina sinistra da parcheggiare + if not EMT.Y1DELTA then + EMT.V1NEXTPOS = ParkV1 + end + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, EMT.R1, EMT.R2) or + EMT.V1POS < EMT.V1NEXTPOS - 1 or EMT.V2POS > EMT.V2NEXTPOS + 1 then + local dPosT = EMT.TPOS or EMT.L1op + EmitParkRoller( dPosT, bSpliCut) + end + -- se taglio di coda senza residuo da scaricare, emetto M175 per accelerare il carico della barra successiva + if EMT.MCHUSERNOTES and EMT.MCHUSERNOTES:find( 'Cut', 1, true) then + MyOutput( ';M175') + end + -- se testa 1 + if nHSet == 1 then + local dSafeZ1 = EgtGetAxisHomePos( 'Z1') + local Speed = EMT.S * EgtIf( EMT.HEAD ~= 'H12', 1, 1.65) + if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + -- muovo asse X + local bXSpec = ( EMT.L2 > -DeltaTabY) + EmitMoveDataHead( 1, { X=EgtIf( bXSpec, -DeltaTabY, EMT.L2), S=Speed}) + -- oriento + local Z_EXTRA = EgtIf( EMT.HEAD == 'H11', 250, 160) + local dZref + if EMT.R2 > -60 then + dZref = dSafeZ1+Z_EXTRA + EmitMoveDataHead( 1, { Z=dZref, B=min(EMT.R2,60), S=Speed}) + if EMT.R2 > 60 then + dZref = dSafeZ1 + Z_EXTRA * ( 90 - abs( EMT.R2)) / 30 + EmitMoveDataHead( 1, { Z=dZref, B=min(EMT.R2,90), S=Speed}) + end + else + dZref = dSafeZ1 + Z_EXTRA * ( 90 - abs( EMT.R2)) / 30 + EmitMoveDataHead( 1, { Z=dZref, B=EMT.R2, S=Speed}) + end + if dZref and EMT.L3 < dZref + 0.1 then + EmitMoveDataHead( 1, { C=EMT.R1, S=Speed}) + end + -- altrimenti sega a catena + else + EmitMoveDataHead( 1, { X=EMT.L2, S=Speed}) + EmitMoveDataHead( 1, { Z=dSafeZ1, S=Speed}) + end + end + EmitMoveDataHead( 1, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 1) + -- eventuale preselezione successiva testa 2 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 1 + EmitMoveWaitHead( 1) + -- altrimenti testa 2 + else + local dSafeZ2 = EgtGetAxisHomePos( 'Z2') + local Speed = EMT.S + if EMT.ZMAX then + EmitMoveDataHead( 2, { Z=-dSafeZ2, S=Speed}) + EmitMoveDataHead( 2, { X=EMT.L2, S=Speed}) + end + EmitMoveDataHead( 2, { X=EMT.L2, Z=EMT.L3, B=EMT.R2, C=EMT.R1, S=Speed}) + EmitMoveStartHead( 2) + -- eventuale preselezione successiva testa 1 + PreselectNextDiffHead( EMT.MCHID, EMT.HEAD) + -- aspetto esecuzione movimento testa 2 + EmitMoveWaitHead( 2) + end + -- dati aggancio a trave + local BhData = { T=EMT.L1} + if EMT.Y1DELTA then + BhData.Y1 = EMT.L1 + EMT.Y1DELTA - ( EMT.X_OFF or 0) + BhData.ViseY1 = 1 + else + BhData.Y1 = ( EMT.Y1POS or ParkY1) + BhData.ViseY1 = 2 + end + if bSpliCut and EMT.Y2DELTA then + BhData.ViseY1 = 3 + end + if EMT.Y2DELTA then + BhData.Y2 = EMT.L1 + EMT.Y2DELTA - ( EMT.X_OFF or 0) + BhData.ViseY2 = 1 + else + BhData.Y2 = ParkY2 + BhData.ViseY2 = 2 + end + if GetV1ToClose() then + BhData.V1 = EMT.V1NEXTPOS ; EMT.V1POS = BhData.V1 + BhData.StatV1 = -2 + elseif abs( EMT.V1POS - ParkV1) > 0.1 then + BhData.V1 = ParkV1 ; EMT.V1POS = BhData.V1 + BhData.StatV1 = 1 + end + if GetV2ToClose() then + BhData.V2 = EMT.V2NEXTPOS ; EMT.V2POS = BhData.V2 + BhData.StatV2 = -2 + elseif abs( EMT.V2POS - ParkV2) > 0.1 then + BhData.V2 = ParkV2 ; EMT.V2POS = BhData.V2 + BhData.StatV2 = 1 + end + EmitBeamHeadData( BhData) + EMT.POSTROT = false + EMT.RELOAD = false + EMT.RELOAD2 = nil + end + EMT.REFLOC = 0 + EMT.MCHFIRST = false + EMT.ZMAX = false + -- se standard + elseif EMT.FLAG == 0 or EMT.FLAG == 1 or EMT.FLAG == 2 then + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + MyOutput( 'M105 P1=' .. GetFaceCode() .. ' P2='..EgtIf( EMT.HEAD ~= 'H21', '1', '2')..' P3=0') + MyOutput( 'M98') + sOut = 'M6 ' .. EgtIf( EMT.HEAD ~= 'H21', 'T101', 'T202') .. AdjustTcPos( true) + MyOutput( sOut) + MyOutput( 'G24' .. EMT.IPLGLSTR) + -- forzo successiva emissione assi rotanti + EMT.R1p = nil + EMT.R2p = nil + else + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + end + -- emissione movimento + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + if #sAxes > 0 then + MyOutput( 'G0' .. sAxes) + end + -- se altrimenti risalita a Z max a fine lavorazione + elseif EMT.FLAG == 3 then + EMT.REFLOC = nil + EMT.IPLGL = false + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + -- se Split lascio agganciata solo la pinza Y2 alla fine dei movimenti + local bSpliCut = ( EMT.MCHUSERNOTES:find( 'Split', 1, true) ~= nil) + EmitZmax( true, true, EMT.R1p, EMT.R2p, bSpliCut) + -- aggiorno quota finale trave dopo Zmax + EMT.L1o = EMT.TPOS + EMT.ZMAX = true + -- se altrimenti movimento in Home + elseif EMT.FLAG == 4 then + -- non previsto + -- altrimenti errore + else + error( "Unknown Rapid flag") + end + -- aggiorno valori come precedenti + EMT.TPOS = EMT.L1o + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnLinear() + -- se necessario, impostazione riferimento locale + if EMT.REFLOC == 0 then + -- calcolo per piano generico + CalcInterpPlane() + EMT.REFLOC = 1 + -- salvo posizione attuale + local OldL1 = EMT.L1 + local OldL2 = EMT.L2 + local OldL3 = EMT.L3 + -- imposto posizione precedente (se presente devo annullare l'offset in X per sovramateriale di testa) + EMT.L1 = EMT.L1o + EMT.L2 = EMT.L2o + EMT.L3 = EMT.L3o + if EMT.X_OFF then EMT.L1 = EMT.L1 - EMT.X_OFF end + -- trasformo i punti nel piano + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + EMT.L1p = nil + EMT.L2p = nil + EMT.L3p = nil + MyOutput( 'M105 P1=' .. GetFaceCode() .. ' P2='..EgtIf( EMT.HEAD ~= 'H21', '1', '2')..' P3=0') + MyOutput( 'M98') + local sPos = EMT.TCPOS:gsub( 'T', '') + if #sPos == 1 then + sPos = '00' .. sPos + elseif #sPos == 2 then + sPos = '0' .. sPos + elseif sPos == '101' and abs( EMT.R3 - 90) < 0.1 then + sPos = '104' + end + local sOut = 'M6 ' .. EgtIf( EMT.HEAD ~= 'H21', 'T101', 'T202') .. sPos + MyOutput( sOut) + MyOutput( 'G24' .. EMT.IPLGLSTR) + -- emissione movimento + EMT.R1p = nil + EMT.R2p = nil + sOut = 'G0'..EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + MyOutput( sOut) + -- aggiorno precedenti + EMT.MOVE = 0 + EmtUpdatePrev() + EMT.MOVE = 1 + -- ripristino posizione attuale + EMT.L1 = OldL1 + EMT.L2 = OldL2 + EMT.L3 = OldL3 + end + + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + MyOutput( 'M97') + end + + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- feed + local sFeed = EmtGetFeed() + -- se da emettere + if #sAxes > 0 then + MyOutput( "G1" .. sAxes .. sFeed) + end + + -- aggiorno valori come precedenti + EMT.TPOS = EMT.L1o + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnArc() + -- se primo movimento in feed della lavorazione, dichiaro inizio lavorazione + if EMT.MCHFIRSTFEED then + EMT.MCHFIRSTFEED = nil + MyOutput( 'M97') + end + + -- non modale su archi + EmtResetPrevLinear() + -- aggiustamento valori + MyAdjustLinearAxes() + EmtAdjustRotaryAxes() + + -- valori degli assi + local sAxes = EmtGetAxis('L1')..EmtGetAxis('L2')..EmtGetAxis('L3').. + EmtGetAxis('R2')..EmtGetAxis('R1') + -- se nulla da emettere, esco + if string.len( sAxes) == 0 then + return + end + -- valori delle coordinate del centro + EmtAdjustCenterAxes() + -- coordinate centro (per ora solo archi nel piano XY) + --local sCen = ' ' .. EMT.C1t .. EmtLenToString(EMT.C1,3) .. + -- ' ' .. EMT.C2t .. EmtLenToString(EMT.C2,3) + -- raggio + local sRad = ' ' .. EMT.RRt .. EmtLenToString( EMT.RR, EMT.DECNUM) + -- aggiungo feed + local sFeed = EmtGetFeed() + -- tipo arco + local sArc = 'G' .. EgtNumToString(EMT.MOVE,0) + -- emetto arco + MyOutput( sArc..sAxes..sRad..sFeed) + + -- aggiorno valori come precedenti + EMT.TPOS = EMT.L1o + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function CalcDinamicaPinze( dH, dS, dL) + local MinTempoAcc = 0.3 -- [s] + local MaxTempoAcc = 4.0 -- [s] + local KgMtCubo= 550 -- densità legno [Kg / metro cubo] + local Massa = ( dH * dS * dL * KgMtCubo ) / 1e9 -- massa [Kg] + local FMaxPinze = EMT.FMAXPINZE -- Feed massima pinze [mm/min] + local ForzaAttrito = 350 * 9.8 * 0.2 -- Forza chiusura pinze [Kgf] * g * Coeff_Attrito -> [N] + local TempoAcc = ( ( Massa * FMaxPinze) / ( 60 * ForzaAttrito) / 1000) + if ( TempoAcc < MinTempoAcc) then TempoAcc = MinTempoAcc end + if ( TempoAcc > MaxTempoAcc) then TempoAcc = MaxTempoAcc end + local AccMaxPinze = FMaxPinze / ( 60 * MinTempoAcc) + local AccPinze = FMaxPinze / ( 60 * TempoAcc) + local RidFeed = 100 / Massa * 100 + if RidFeed > 100 then + RidFeed = 100 + elseif RidFeed < 10 then + RidFeed = 10 + end + return AccPinze, AccMaxPinze, RidFeed +end + +--------------------------------------------------------------------- +function CalcCharStatus( sCmd) + -- aperto + if sCmd == '0' then + return '1' + -- chiuso + else + return '-1' + end +end + +--------------------------------------------------------------------- +function CalcCharStatusN( sCmd) + -- aperto + if sCmd == '0' then + return 1 + -- chiuso + elseif sCmd == '1' then + return -1 + end +end + +--------------------------------------------------------------------- +function PrepareLoad( sCmd, nInd, bStart) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if nInd == 1 then + -- imposto stato pinze + EMT.ISY1 = 1 + EMT.FSY1 = EMT.ISY1 -- ??? -1 + EMT.ISY2 = 1 + EMT.FSY2 = EMT.ISY2 + EMT.BV = 0 + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + if bStart then + EMT.RELOAD = false + else + EMT.RELOAD2 = true + end + for i = 1, #EMT.MDCHAR do + EMT.MDCHAR[i].MovType = 3 + end + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.Y1POS = MoveY1 or EMT.Y1POS + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + end + elseif Cmd[1] == '2' then + -- se in riposizionamento carrelli + if #EMT.MDCHAR > 0 and EMT.MDCHAR[1].MovType == 3 then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[2] == 'Y1' then + local MoveY1 = tonumber( Cmd[3]) + TurnerOffs + local MDChar = { Y1=MoveY1, V1=ParkV1, IniStatY1=-75, FinStatY1=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + SetStartValue( 4, MoveY1) + SetStartValue( 5, 110) + EMT.V1POS = ParkV1 + elseif Cmd[2] == 'T' then + local MDChar = { Y1=tonumber(Cmd[3]), IniStatY1=-76, FinStatY1=EMT.FSY1, FinStatV1=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + end + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '4' then + -- richiesta movimento a ZMAX già gestita + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = EMT.FSY1 end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + if not FindReadHeadWithLaser( EMT.MDCHAR) then + local MDChar = { Y1=LoadT, IniStatY1=-76, FinStatY1=EMT.FSY1, FinStatV1=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareMoveChar( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if nInd == 1 then + -- imposto stato pinze + EMT.ISY1 = EgtIf( EMT.Y1DELTA, -1, 1) + EMT.FSY1 = EMT.ISY1 + EMT.ISY2 = EgtIf( EMT.Y2DELTA, -1, 1) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( EMT.Y1DELTA, 1, 2) + EMT.ROLL_IN = nil + EMT.ROLL_OPEN = true + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + else + if MoveY1 and EMT.V1POS > MoveY1 - MinDeltaYV - 0.1 then + MDChar.V1 = min( MoveY1 - MinDeltaYV, ParkV1) ; EMT.V1POS = MDChar.V1 + end + if MoveY2 and EMT.V2POS < MoveY2 + MinDeltaYV + 0.1 then + MDChar.V2 = max( MoveY2 + MinDeltaYV, ParkV2) ; EMT.V2POS = MDChar.V2 + end + end + if EMT.ROLL_OPEN then + MDChar.IniStatV1 = 1 + MDChar.IniStatV2 = 1 + EMT.ROLL_OPEN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.Y1POS = MoveY1 or EMT.Y1POS + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + end + elseif Cmd[1] == '2' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + else + if MoveY1 and EMT.V1POS > MoveY1 - MinDeltaYV - 0.1 then + MDChar.V1 = min( MoveY1 - MinDeltaYV, ParkV1) ; EMT.V1POS = MDChar.V1 + end + if MoveY2 and EMT.V2POS < MoveY2 + MinDeltaYV + 0.1 then + MDChar.V2 = max( MoveY2 + MinDeltaYV, ParkV2) ; EMT.V2POS = MDChar.V2 + end + end + if EMT.ROLL_OPEN then + MDChar.IniStatV1 = 1 + MDChar.IniStatV2 = 1 + EMT.ROLL_OPEN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + if MoveY1 then MDChar.Y1 = MoveY1 end + if MoveY2 then MDChar.Y2 = MoveY2 end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + else + if MoveY1 and EMT.V1POS > MoveY1 - MinDeltaYV - 0.1 then + MDChar.V1 = min( MoveY1 - MinDeltaYV, ParkV1) ; EMT.V1POS = MDChar.V1 + end + if MoveY2 and EMT.V2POS < MoveY2 + MinDeltaYV + 0.1 then + MDChar.V2 = max( MoveY2 + MinDeltaYV, ParkV2) ; EMT.V2POS = MDChar.V2 + end + end + if EMT.ROLL_OPEN then + MDChar.IniStatV1 = 1 + MDChar.IniStatV2 = 1 + EMT.ROLL_OPEN = nil + end + table.insert( EMT.MDCHAR, MDChar) + EMT.TPOS = GetCmdAxMove( Cmd, 'T') or EMT.TPOS + elseif Cmd[1] == '4' then + -- richiesta movimento a ZMAX già gestita + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = EMT.FSY1 end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareResidue( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se non è scarico + if Cmd[2] ~= 'Unloading' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if nInd <= 2 then + EMT.ISY1 = EgtIf( EMT.Y1DELTA, -1, 1) + EMT.FSY1 = EMT.ISY1 + EMT.ISY2 = EgtIf( EMT.Y2DELTA, -1, 1) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( EMT.Y1DELTA, 1, 2) + EMT.ROLL_IN = nil + end + else + EMT.UNL = true + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar + if not EMT.UNL then + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + else + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY2=1, FinStatY2=-84, BeamVise=0} + end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '2' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, IniStatV2=1, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, IniStatV1=1, IniStatV2=1, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + if Cmd[6] ~= 'T' then MDChar[Cmd[6]] = tonumber( Cmd[7]) end + if EMT.ROLL_IN then + MDChar.V1 = MinV1 ; EMT.V1POS = MDChar.V1 + MDChar.V2 = MaxV2 ; EMT.V2POS = MDChar.V2 + EMT.ROLL_IN = nil + end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '4' then + EMT.TO_ZMAX = true + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = EMT.FSY1 end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareSplit( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + if Cmd[2] == 'Y1' then + local MDChar = { Y1=tonumber(Cmd[3]), V1=ParkV1, IniStatY1=-1, FinStatY1=-1, BeamVise=2, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + EMT.Y1POS = tonumber( Cmd[3]) + EMT.V1POS = ParkV1 + end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PrepareUnload( sCmd, nInd) + + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- non interessa + elseif Cmd[1] == '1' then + if Cmd[2] == 'Y2' then + -- se non è ultima fase e non è fase successiva a scarico su carico c'è una barra sulla pinza Y1 + local bBarOnY = ( EMT.PHASE < EgtGetPhaseCount() and not IsEnd2Phase( EMT.PHASE)) + local MDChar = { Y2=tonumber(Cmd[3]), IniStatY2=1, FinStatY2=-84, BeamVise=EgtIf( bBarOnY, 1, 0), MovType=EgtIf( EMT.CHY_ON, 3, 2)} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '2' then + if Cmd[4] == 'Y2' then + -- se non è ultima fase c'è una barra sulla pinza Y1 + local bBarOnY = ( EMT.PHASE < EgtGetPhaseCount() and not IsEnd2Phase( EMT.PHASE)) + local MDChar = { Y2=tonumber(Cmd[5]), IniStatY1=EgtIf( bBarOnY, -1, 1), FinStatY1=EgtIf( bBarOnY, -1, 1), IniStatY2=-1, FinStatY2=1, IniStatV2=1, BeamVise=2, MovType=EgtIf( EMT.CHY_ON, 3, 2)} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '3' then + -- non interessa + elseif Cmd[1] == '4' then + -- non interessa + elseif Cmd[1] == '11' then + -- non interessa + elseif Cmd[1] == '12' then + -- non interessa + elseif Cmd[1] == '21' then + -- non interessa + elseif Cmd[1] == '22' then + -- non interessa ?? + end +end + +--------------------------------------------------------------------- +function PreparePreRotation( sCmd, nInd) + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio o subito dopo, imposto stato iniziale pinze + if nInd <= 2 then + EMT.ISY1 = EgtIf( EMT.Y1DELTA, -1, 1) + EMT.FSY1 = EMT.ISY1 + EMT.ISY2 = EgtIf( EMT.Y2DELTA, -1, 1) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( EMT.Y1DELTA, 1, 2) + end + -- se è pre-rotazione + if Cmd[2] == 'Pre-Rotation' then + EMT.PREROT = true + elseif Cmd[2] == 'SplitRot' then + EMT.SPLITROT = true + end + elseif Cmd[1] == '1' then + if Cmd[2] ~= 'Z' then + local MDChar + if not EMT.PREROT then + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + else + MDChar = { [Cmd[2]]=tonumber(Cmd[3]), IniStatY1=86, FinStatY1=87, IniStatY2=1, BeamVise=0} + end + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '2' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '3' then + local MDChar = { IniStatY1=EMT.ISY1, FinStatY1=EMT.FSY1, IniStatY2=EMT.ISY2, FinStatY2=EMT.FSY2, BeamVise=EMT.BV} + if Cmd[2] ~= 'T' then MDChar[Cmd[2]] = tonumber( Cmd[3]) end + if Cmd[4] ~= 'T' then MDChar[Cmd[4]] = tonumber( Cmd[5]) end + if Cmd[6] ~= 'T' then MDChar[Cmd[6]] = tonumber( Cmd[7]) end + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '4' then + EMT.TO_ZMAX = true + if Cmd[2] == '1' then + EMT.ROLL_IN = true + end + elseif Cmd[1] == '11' then + if EMT.SPLITROT then + EMT.ISY1 = EgtIf( Cmd[2] ~= '0', CalcCharStatusN( Cmd[2]), 86) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + else + EMT.ISY1 = CalcCharStatusN( Cmd[2]) + EMT.FSY1 = EMT.ISY1 + EMT.BV = EgtIf( Cmd[2] ~= '0', 1, 2) + end + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY1 = CalcCharStatusN( Cmd[2]) end + elseif Cmd[1] == '12' then + EMT.ISY2 = CalcCharStatusN( Cmd[2]) + EMT.FSY2 = EMT.ISY2 + EMT.BV = EgtIf( Cmd[2] ~= '0', 2, 1) + if #EMT.MDCHAR > 0 then EMT.MDCHAR[#EMT.MDCHAR].FinStatY2 = EMT.FSY2 end + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function PreparePostRotation( sCmd, nInd) + -- è sostanzialmente un carico + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + -- se inizio + if nInd == 1 then + -- imposto stato pinze + EMT.FSY1 = -1 + end + -- se dichiarazione inizio riposizionamento carrelli + if Cmd[2] == 'CARR_MOVE' then + EMT.POSTROT = false + for i = 1, #EMT.MDCHAR do + EMT.MDCHAR[i].MovType = 3 + end + end + elseif Cmd[1] == '1' then + -- non interessa + elseif Cmd[1] == '2' then + if Cmd[2] == 'Y1' then + -- tolgo eventuale sovramateriale presente sul pezzo in posizione iniziale (la misura laser è ora col finito) + local MDChar = { Y1=tonumber(Cmd[3])-EMT.HOVM, IniStatY2=-75, FinStatY2=-1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + end + elseif Cmd[1] == '3' then + -- non interessa + elseif Cmd[1] == '11' then + EMT.FSY1 = CalcCharStatusN( Cmd[2]) + elseif Cmd[1] == '12' then + -- non interessa + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + if nY1Delta > 0 and nY2Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nY2Delta + elseif nY1Delta > 0 then + EMT.Y1DELTA = nY1Delta + EMT.Y2DELTA = nil + elseif nY2Delta > 0 then + EMT.Y1DELTA = nil + EMT.Y2DELTA = nY2Delta + end + local MDChar = { Y1=LoadT, IniStatY1=-76, FinStatY1=EMT.FSY1, BeamVise=0, MovType=1} + table.insert( EMT.MDCHAR, MDChar) + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + end +end + +--------------------------------------------------------------------- +function GetV1ToClose() + --MyOutput( string.format( 'L1m=%.3f L1M=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1])) + --MyOutput( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT)) + return ( EMT.MAXMAX[1] <= EMT.V1NEXTPOS + RollCageMin and EMT.MAXMIN[1] + EMT.LB >= EMT.V1NEXTPOS + RollCageMax) +end + +--------------------------------------------------------------------- +function GetV2ToClose() + --MyOutput( string.format( 'L1m=%.3f L1M=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1])) + --MyOutput( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT)) + return ( EMT.MAXMAX[1] <= EMT.V2NEXTPOS - RollCageMax and EMT.MAXMIN[1] + EMT.LB >= EMT.V2NEXTPOS - RollCageMin) +end + +--------------------------------------------------------------------- +function MyAdjustLinearAxes() + local MyL1o = EMT.L1 + local MyL2o = EMT.L2 + local MyL3o = EMT.L3 + if EMT.REFLOC then + local vtE + if EMT.HEAD ~= 'H13' then + local dAddLen = EgtIf( EMT.HEAD == 'H12', -SawOffsZ, 0) + if EMT.HEAD ~= 'H21' then + local Len = EMT.TLEN + dAddLen + MillOffs + local LenRef = MillOffs + vtE = Vector3d( EMT.TDIR) * Len - Z_AX() * LenRef + else + local Len = EMT.TLEN + dAddLen + Mill2Offs + local LenRef = Mill2Offs + vtE = Vector3d( EMT.TDIR) * Len + Z_AX() * LenRef + end + else + local Len = ChSawLen + MillOffs + local LenRef = MillOffs + vtE = Vector3d( EMT.ADIR) * Len - Z_AX() * LenRef + end + if EMT.HEAD ~= 'H21' then + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - DeltaTabY - vtE:getY() + EMT.L3 = EMT.L3 - DeltaTabZ - vtE:getZ() + else + EMT.L1 = EMT.L1 - vtE:getX() + EMT.L2 = EMT.L2 - Delta2TabY - vtE:getY() + EMT.L3 = EMT.L3 - Delta2TabZ - vtE:getZ() + end + end + + if EMT.X_OFF then EMT.L1 = EMT.L1 + EMT.X_OFF end + + EmtAdjustLinearAxes() + + EMT.L1o = MyL1o + EMT.L2o = MyL2o + EMT.L3o = MyL3o + + if not EMT.REFLOC then + if EMT.HEAD ~= 'H21' then + EMT.L2 = -EMT.L2 + else + EMT.L3 = -EMT.L3 + end + EMT.L1t = 'Y' + EMT.L2t = 'X' + else + EMT.L1t = 'X' + EMT.L2t = 'Y' + end +end + +--------------------------------------------------------------------- +function AdjustTcPos( bLen3, sTcPos, dAxR3) + if not sTcPos then sTcPos = EMT.TCPOS end + local sPos = sTcPos:gsub( 'T', '') + if bLen3 then + if #sPos == 1 then + sPos = '00' .. sPos + elseif #sPos == 2 then + sPos = '0' .. sPos + end + end + if sPos == '101' then + if not dAxR3 then dAxR3 = EMT.R3 end + if abs( dAxR3 - 0) < 0.1 then + sPos = '101' + elseif abs( dAxR3 - 270) < 0.1 then + sPos = '102' + elseif abs( dAxR3 - 180) < 0.1 then + sPos = '103' + elseif abs( dAxR3 - 90) < 0.1 then + sPos = '104' + else + EmtSetLastError( 1210, 'Chain saw orientation not allowed') + end + end + return sPos +end + +--------------------------------------------------------------------- +function CalcInterpPlane() + -- origine del piano + local xS = EMT.START[1] + LoadT + if EMT.X_OFF then xS = xS + EMT.X_OFF end + local ptS = Point3d( xS, 0, 0) + -- calcolo per piano generico + local vtE + if EMT.HEAD ~= 'H13' then + vtE = Vector3d( EMT.EXTR) + else + vtE = EgtGetCalcAuxDirFromAngles( EMT.R1, EMT.R2, EMT.R3) + end + EMT.IPLGLFR = Frame3d( ptS, vtE) + --MyOutput( 'IPLGLFR='..tostring(EMT.IPLGLFR)) + local vtX = EMT.IPLGLFR:getVersX() + local vtY = EMT.IPLGLFR:getVersY() + local vtZ = EMT.IPLGLFR:getVersZ() + if EMT.HEAD ~= 'H21' then + EMT.IPLGLSTR = ' X0 Y' .. EmtLenToString( xS, EMT.DECNUM) .. ' Z0' .. + ' A' .. EgtNumToString( -vtX:getY(), 6) .. ' B' .. EgtNumToString( vtX:getX(), 6) .. ' C' .. EgtNumToString( vtX:getZ(), 6) .. + ' I' .. EgtNumToString( -vtY:getY(), 6) .. ' J' .. EgtNumToString( vtY:getX(), 6) .. ' K' .. EgtNumToString( vtY:getZ(), 6) .. + ' P' .. EgtNumToString( -vtZ:getY(), 6) .. ' Q' .. EgtNumToString( vtZ:getX(), 6) .. ' R' .. EgtNumToString( vtZ:getZ(), 6) + else + EMT.IPLGLSTR = ' X0 Y' .. EmtLenToString( xS, EMT.DECNUM) .. ' Z0' .. + ' A' .. EgtNumToString( vtX:getY(), 6) .. ' B' .. EgtNumToString( vtX:getX(), 6) .. ' C' .. EgtNumToString( -vtX:getZ(), 6) .. + ' I' .. EgtNumToString( vtY:getY(), 6) .. ' J' .. EgtNumToString( vtY:getX(), 6) .. ' K' .. EgtNumToString( -vtY:getZ(), 6) .. + ' P' .. EgtNumToString( vtZ:getY(), 6) .. ' Q' .. EgtNumToString( vtZ:getX(), 6) .. ' R' .. EgtNumToString( -vtZ:getZ(), 6) + end + EMT.IPLGL = true +end + +--------------------------------------------------------------------- +function GetFaceCode() + if EMT.Y1DELTA and EMT.Y2DELTA then + return '3' + elseif EMT.Y1DELTA then + return '6' + else + return '5' + end +end + +--------------------------------------------------------------------- +function EmitZmax( bReset, bEnd, PrevR1, PrevR2, bSpliCut) + if bReset then + EmitResetMachining() + end + -- se testa 1 + if EMT.HEAD ~= 'H21' then + -- posizioni sicure + local dMaxZ1 = EgtGetAxisMax( 'Z1') + local dSafeZ1 = EgtGetAxisHomePos( 'Z1') + local dSafeB1 = EgtGetAxisHomePos( 'B1') + local dSafeC1 = EgtGetAxisHomePos( 'C1') + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, dSafeC1, dSafeB1) then + local dPosT = EgtIf( bEnd, EMT.L1o, EMT.TPOS or EMT.L1op) + EmitParkRoller( dPosT, bSpliCut) + end + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + -- eseguo la salita a Z1max (oriento solo se assi rotanti non già a posto) + if abs( dSafeC1 - PrevR1) > 0.1 or abs( dSafeB1 - PrevR2) > 0.1 then + local bSafeZ = false + local Z_EXTRA = EgtIf( EMT.HEAD == 'H11', 250, 160) + if abs( PrevR2) < 60 then + local dZref = dSafeZ1 + Z_EXTRA + EmitMoveDataHead( 1, { Z=dZref, Fmt=1}) + bSafeZ = true + elseif abs( PrevR2) < 90 then + local dZref = dSafeZ1 + Z_EXTRA * ( 90 - abs( PrevR2)) / 30 + EmitMoveDataHead( 1, { Z=dZref, Fmt=1}) + bSafeZ = true + end + if EMT.L2o < DeltaTabY then + if not bSafeZ then + EmitMoveDataHead( 1, { Z=dSafeZ1, B=EgtIf( PrevR2 > 0, 90, -90), Fmt=1}) + end + EmitMoveDataHead( 1, { X=-DeltaTabY, Fmt=1}) + end + local ANG_LIM_DOWN = EgtIf( EMT.HEAD == 'H11', 0, -45) + local ANG_LIM_OPPO = 90 + if PrevR2 > ANG_LIM_DOWN then + if PrevR2 > ANG_LIM_OPPO then + EmitMoveDataHead( 1, { Z=dSafeZ1, B=ANG_LIM_OPPO, Fmt=1}) + end + if PrevR2 > 60 then + EmitMoveDataHead( 1, { Z=dSafeZ1+Z_EXTRA, B=60, Fmt=1}) + end + EmitMoveDataHead( 1, { Z=dSafeZ1+Z_EXTRA, B=ANG_LIM_DOWN, Fmt=1}) + end + EmitMoveDataHead( 1, { Z=dSafeZ1, B=dSafeB1, Fmt=1}) + EmitMoveDataHead( 1, { C=dSafeC1, Fmt=1}) + end + EmitMoveDataHead( 1, { Z=dMaxZ1, Fmt=1}) + EmitMoveStartHead( 1) + EmitMoveWaitHead( 1) + -- altrimenti sega a catena + else + EmitMoveDataHead( 1, { Z=dSafeZ1, B=dSafeB1, Fmt=1}) + EmitMoveDataHead( 1, { C=dSafeC1, Fmt=1}) + EmitMoveDataHead( 1, { Z=dMaxZ1, Fmt=1}) + EmitMoveStartHead( 1) + EmitMoveWaitHead( 1) + end + -- altrimenti testa 2 + else + -- posizioni sicure + local dSafeX2 = EgtGetAxisHomePos( 'X2') + local dSafeZ2 = EgtGetAxisHomePos( 'Z2') + local dSafeB2 = EgtGetAxisHomePos( 'B2') + local dSafeC2 = EgtGetAxisHomePos( 'C2') + -- se necessario allargo le cabine + if RollerParkingNeeded( EMT.HEAD, PrevR1, PrevR2, dSafeC2, dSafeB2) then + local dPosT = EgtIf( bEnd, EMT.L1o, EMT.TPOS or EMT.L1op) + EmitParkRoller( dPosT, bSpliCut) + end + -- eseguo la discesa a Z2max + EmitMoveDataHead( 2, { Z=-dSafeZ2, Fmt=1}) + EmitMoveDataHead( 2, { B=dSafeB2, C=dSafeC2, Fmt=1}) + EmitMoveDataHead( 2, { X=dSafeX2, Fmt=1}) + EmitMoveStartHead( 2) + EmitMoveWaitHead( 2) + end +end + +--------------------------------------------------------------------- +function EmitResetMachining() + MyOutput( 'G27') + local sP12 = '' + if EMT.TOOL ~= GetNextTool( EMT.MCHID) then sP12 = EgtIf( EMT.HEAD ~= 'H21', ' P1=0', ' P2=0') end + local sP4 = EgtIf( EMT.MCHUSERNOTES:find( 'Split', 1, true), ' P4=1', '') + MyOutput( 'M99'..sP12..sP4) +end + +--------------------------------------------------------------------- +function EmitParkRoller( dPosT, bSpliCut) + -- se entrambe già parcheggiate, non devo fare alcunché + if ( EMT.V1POS - ParkV1) > -0.1 and ( EMT.V2POS - ParkV2) < 0.1 then return end + -- Parcheggi pinze + local MyParkY1 = ParkY1 + AggLoad + local MyParkY2 = ParkY2 + -- le parcheggio + local MDChar = {} + if EMT.Y1DELTA and EMT.Y2DELTA then + local dPosY1 = dPosT + EMT.Y1DELTA + local dPosY2 = dPosT + EMT.Y2DELTA + local DiffY1 = MyParkY1 - dPosY1 + local DiffY2 = MyParkY2 - dPosY2 + --MyOutput( string.format( 'PosT=%.3f DiffY1=%.3f DiffY2=%.3f', dPosT, DiffY1, DiffY2)) + if bSpliCut then + if DiffY1 > 0.1 then + MDChar.Y1 = dPosY1 + DiffY1 + end + if DiffY2 < -0.1 then + MDChar.Y2 = dPosY2 + DiffY2 + dPosT = dPosT + DiffY2 + end + elseif DiffY1 > 0.1 and DiffY2 < -0.1 then + EmtSetLastError( 1201, 'Error Collision in ParkRoller') + elseif DiffY1 > 0.1 then + MDChar.Y1 = dPosY1 + DiffY1 + MDChar.Y2 = dPosY2 + DiffY1 + dPosT = dPosT + DiffY1 + elseif DiffY2 < -0.1 then + MDChar.Y1 = dPosY1 + DiffY2 + MDChar.Y2 = dPosY2 + DiffY2 + dPosT = dPosT + DiffY2 + end + MDChar.MovType = 3 + MDChar.BeamVise = ( EMT.BV or 1) + elseif EMT.Y1DELTA then + local dMoveV1 = ParkV1 - EMT.V1POS + local dPosY1 = dPosT + EMT.Y1DELTA + local DiffY1 = MyParkY1 - dPosY1 + local bMoveY1 = ( DiffY1 > 0.1 or ( dPosT > ParkV2 and dPosT < ParkV1 and dPosY1 + dMoveV1 < MaxY1)) + local dMoveY1 = EgtIf( bMoveY1, dMoveV1, 0) + --MyOutput( string.format( 'PosT=%.3f PosY1=%.3f V1POS=%.3f', dPosT, dPosY1, EMT.V1POS)) + MDChar.Y1 = dPosY1 + dMoveY1 + MDChar.MovType = 1 + MDChar.BeamVise = 1 + dPosT = dPosT + dMoveY1 + elseif EMT.Y2DELTA then + local dMoveV2 = ParkV2 - EMT.V2POS + local dPosY2 = dPosT + EMT.Y2DELTA + local DiffY2 = MyParkY2 - dPosY2 + local bMoveY2 = ( DiffY2 < -0.1 or ( dPosT + EMT.LT < ParkV1 and dPosT + EMT.LT > ParkV2 and dPosY2 + dMoveV2 > MinY2)) + local dMoveY2 = EgtIf( bMoveY2, dMoveV2, 0) + --MyOutput( string.format( 'PosT=%.3f PosY2=%.3f V2POS=%.3f', dPosT, dPosY2, EMT.V2POS)) + MDChar.Y2 = dPosY2 + dMoveY2 + MDChar.MovType = 2 + MDChar.BeamVise = 2 + dPosT = dPosT + dMoveY2 + end + if abs( ParkV1 - EMT.V1POS) > 0.1 then + MDChar.V1 = ParkV1 + MDChar.IniStatV1 = 1 + end + if abs( ParkV2 - EMT.V2POS) > 0.1 then + MDChar.V2 = ParkV2 + MDChar.IniStatV2 = 1 + end + EmitMoveDataChars( MDChar) + EmitMoveStartChars( MDChar.MovType) + EmitMoveWaitChars( MDChar.MovType) + EMT.V1POS = ParkV1 + EMT.V2POS = ParkV2 + EMT.TPOS = dPosT +end + +--------------------------------------------------------------------- +function GetNextTool( nMchId) + -- inizializzo prossimo utensile + local sNextTool + -- recupero lavorazione successiva + local nNextMchId = EgtGetNextActiveOperation( nMchId) + while nNextMchId do + if EgtGetOperationType( nNextMchId) ~= MCH_OY.DISP then + break + end + nNextMchId = EgtGetNextActiveOperation( nNextMchId) + end + -- se trovata + if nNextMchId and EgtSetCurrMachining( nNextMchId) then + sNextTool = EgtGetMachiningParam( MCH_MP.TOOL) + end + -- ripristino stato corrente + EgtSetCurrMachining( EMT.MCHID) + EgtTdbSetCurrTool( EMT.TOOL) + return sNextTool +end + +--------------------------------------------------------------------- +function PreselectNextDiffHead( nMchId, sHead) + -- se in uso testa 1, verifico di non scendere troppo in Z per evitare collisioni + local nHSet = GetHeadSet( sHead) + if nHSet == 1 then + if EMT.MAXMIN[3] < MinZ1ToChangeH2 then return end + end + -- recupero lavorazione successiva + local nNextMchId = EgtGetNextActiveOperation( nMchId) + while nNextMchId do + if EgtGetOperationType( nNextMchId) ~= MCH_OY.DISP then break end + nNextMchId = EgtGetNextActiveOperation( nNextMchId) + end + if not nNextMchId then return end + -- se esiste ed appartiene a gruppo diverso + if EgtSetCurrMachining( nNextMchId) then + local sNextTool = EgtGetMachiningParam( MCH_MP.TOOL) + if EgtTdbSetCurrTool( sNextTool) then + local sNextHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local nNextHSet = GetHeadSet( sNextHead) + if nNextHSet ~= nHSet then + local sNextTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + if nNextHSet == 1 then + -- Recupero quota X1 (nostro L2) + local dNextX = GetStartMachiningXaxis( nNextMchId) + -- Emetto preselezione + if sNextHead == 'H11' then + EmitMoveDataHead( 1, { X=dNextX, B=ParkB1, C=ParkC1, TPos=AdjustTcPos( false, sNextTcPos), Fmt=2}) + EmitMoveStartHead( 1) + elseif sNextHead == 'H12' then + EmitMoveDataHead( 1, { X=dNextX, B=ParkB1, C=ParkC1, TPos=AdjustTcPos( false, sNextTcPos), Fmt=2}) + EmitMoveStartHead( 1) + elseif sNextHead == 'H13' then + -- recupero il valore dell'asse virtuale bloccato A + local dPosA = GetCurrChainSawingVirtualAxis() + local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA) + EmitMoveDataHead( 1, { X=dNextX, B=ParkCSawB1, C=MyParkCSawC1, TPos=AdjustTcPos( false, sNextTcPos, dPosA), Fmt=2}) + EmitMoveStartHead( 1) + end + else + EmitMoveDataHead( 2, { B=ParkB2, C=ParkC2, TPos=AdjustTcPos( false, sNextTcPos), Fmt=2}) + EmitMoveStartHead( 2) + end + end + end + end + -- ripristino stato corrente + EgtSetCurrMachining( EMT.MCHID) + EgtTdbSetCurrTool( EMT.TOOL) +end + +--------------------------------------------------------------------- +function GetFmaxClamp() + return EmtLenToString( EMT.FMAXPINZE / 1000, 0) +end + +--------------------------------------------------------------------- +function FindReadHeadWithLaser( vMDChar) + for i = 1, #vMDChar do + if vMDChar[i].IniStatY1 == -76 then + return true + end + end + return false +end + +--------------------------------------------------------------------- +function EmitRemark( sOut) + sOut = string.gsub( string.gsub( sOut, '%(', '['), '%)', ']') + MyOutput( '(' .. sOut .. ')') +end + +--------------------------------------------------------------------- +function EmitMoveDataHead( nHead, MoData) + local sOut = EgtIf( nHead == 1, 'M101', 'M102') .. ' P1=1' + if MoData.X then sOut = sOut .. ' P2=' .. EmtLenToString( MoData.X, 3) end + if MoData.Z then sOut = sOut .. ' P3=' .. EmtLenToString( MoData.Z, 3) end + if MoData.B then sOut = sOut .. ' P4=' .. EmtLenToString( MoData.B, 3) end + if MoData.C then sOut = sOut .. ' P5=' .. EmtLenToString( MoData.C, 3) end + if MoData.TPos then sOut = sOut .. ' P6=' .. MoData.TPos elseif EMT.TCPOS then sOut = sOut .. ' P6=' .. AdjustTcPos( false) end + if MoData.S then sOut = sOut .. ' P7=' .. EgtNumToString( MoData.S, 0) end + if not MoData.Fmt then + if MoData.F then sOut = sOut .. ' P8=' .. EmtLenToString( MoData.F, 0) else sOut = sOut .. ' P8=0' end + sOut = sOut .. ' P9=0 P10=4 P11=1' + elseif MoData.Fmt == 1 then + sOut = sOut .. ' P10=4 P11=1' + end + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveStartHead( nHead) + local sOut = EgtIf( nHead == 1, 'M101', 'M102') .. ' P1=2' + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveWaitHead( nHead) + local sOut = EgtIf( nHead == 1, 'M101', 'M102') .. ' P1=3' + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveDataChars( MoData) + local sOut = 'M111' + if MoData.MovType == 1 then sOut = sOut .. ' P1=11' elseif MoData.MovType == 2 then sOut = sOut .. ' P1=12' else sOut = sOut .. ' P1=10' end + if MoData.Y1 then sOut = sOut .. ' P2=' .. EmtLenToString( MoData.Y1, 3) end + if MoData.Y2 then sOut = sOut .. ' P3=' .. EmtLenToString( MoData.Y2, 3) end + if MoData.IniStatY1 then sOut = sOut .. ' P4=' .. EgtNumToString( MoData.IniStatY1, 0) end + if MoData.FinStatY1 then sOut = sOut .. ' P5=' .. EgtNumToString( MoData.FinStatY1, 0) end + if MoData.IniStatY2 then sOut = sOut .. ' P6=' .. EgtNumToString( MoData.IniStatY2, 0) end + if MoData.FinStatY2 then sOut = sOut .. ' P7=' .. EgtNumToString( MoData.FinStatY2, 0) end + if MoData.BeamVise then sOut = sOut .. ' P8=' .. EgtNumToString( MoData.BeamVise, 0) end + if MoData.F then sOut = sOut .. ' P9=' .. EmtLenToString( MoData.F, 0) else sOut = sOut .. ' P9=' .. GetFmaxClamp() end + if MoData.V1 then sOut = sOut .. ' P15=' .. EmtLenToString( MoData.V1, 3) end + if MoData.V2 then sOut = sOut .. ' P16=' .. EmtLenToString( MoData.V2, 3) end + if MoData.IniStatV1 then local sVal = EgtNumToString( MoData.IniStatV1, 0) ; sOut = sOut .. ' P17=' .. sVal .. ' P18=' .. sVal end + if MoData.FinStatV1 then local sVal = EgtNumToString( MoData.FinStatV1, 0) ; sOut = sOut .. ' P19=' .. sVal .. ' P20=' .. sVal end + if MoData.IniStatV2 then local sVal = EgtNumToString( MoData.IniStatV2, 0) ; sOut = sOut .. ' P21=' .. sVal .. ' P22=' .. sVal end + if MoData.FinStatV2 then local sVal = EgtNumToString( MoData.FinStatV2, 0) ; sOut = sOut .. ' P23=' .. sVal .. ' P24=' .. sVal end + MyOutput( sOut) +end + +--------------------------------------------------------------------- +function EmitMoveStartChars( MovType) + local sMovType = ' P1=20' + if MovType == 1 then + sMovType = ' P1=21' + elseif MovType == 2 then + sMovType = ' P1=22' + end + MyOutput( 'M111' .. sMovType) +end + +--------------------------------------------------------------------- +function EmitMoveWaitChars( MovType, bRun) + local sMovType = ' P1=30' + if MovType == 1 then + sMovType = ' P1=31' + elseif MovType == 2 then + sMovType = ' P1=32' + end + if bRun == nil or bRun then + MyOutput( 'M111' .. sMovType) + else + MyOutput( ';M111' .. sMovType) + end +end + +--------------------------------------------------------------------- +function EmitBeamHeadData( BhData) + local sOut = 'M112' + if BhData.T then sOut = sOut .. ' P1=' .. EmtLenToString( BhData.T, 3) end + if BhData.ViseY1 then sOut = sOut .. ' P3=' .. EgtNumToString( BhData.ViseY1, 0) end + if BhData.ViseY2 then sOut = sOut .. ' P4=' .. EgtNumToString( BhData.ViseY2, 0) end + if BhData.SetHead then sOut = sOut .. ' P5=' .. EgtNumToString( BhData.SetHead, 0) end + if BhData.Y1 then sOut = sOut .. ' P6=' .. EmtLenToString( BhData.Y1, 3) end + if BhData.Y2 then sOut = sOut .. ' P7=' .. EmtLenToString( BhData.Y2, 3) end + if BhData.F then sOut = sOut .. EgtIf( BhData.F >= 1, ' P9=' .. EmtLenToString( BhData.F, 0), '') else sOut = sOut .. ' P9=' .. GetFmaxClamp() end + if BhData.StatV1 then sOut = sOut .. ' P10=' .. EgtNumToString( BhData.StatV1, 0) end + if BhData.V1 then sOut = sOut .. ' P11=' .. EmtLenToString( BhData.V1, 3) end + if BhData.StatV1 then sOut = sOut .. ' P12=' .. EgtNumToString( BhData.StatV1, 0) end + if BhData.StatV2 then sOut = sOut .. ' P13=' .. EgtNumToString( BhData.StatV2, 0) end + if BhData.V2 then sOut = sOut .. ' P14=' .. EmtLenToString( BhData.V2, 3) end + if BhData.StatV2 then sOut = sOut .. ' P15=' .. EgtNumToString( BhData.StatV2, 0) end + if BhData.ViseY1 == 3 then sOut = sOut .. ' P16=1' end + if BhData.ViseY2 == 3 then sOut = sOut .. ' P17=1' end + MyOutput( sOut) +end + +--------------------------------------------------------------------- +--------------------------------------------------------------------- +local bToPark = true + +--------------------------------------------------------------------- +function SetToParkLine() + bToPark = true +end + +--------------------------------------------------------------------- +function MyOutput( sOut) + if not bToPark then + EmtOutput( sOut) + else + ParkLine( sOut) + end +end + +--------------------------------------------------------------------- +--------------------------------------------------------------------- +local ParkedLines = {} + +--------------------------------------------------------------------- +function ParkLine( sLine) + table.insert( ParkedLines, sLine) +end + +--------------------------------------------------------------------- +function EmitParkedLines() + bToPark = false + for i = 1, #ParkedLines do + EmtOutput( ParkedLines[i]) + end + ParkedLines = {} +end + +--------------------------------------------------------------------- +--------------------------------------------------------------------- +local StartValues = {} + +--------------------------------------------------------------------- +function SetStartValue( nI, dVal) + StartValues[nI] = dVal +end + +--------------------------------------------------------------------- +function EmitStartValues() + bToPark = false + local sLine = '' + for i = 1, 10 do + sLine = sLine .. string.format( ';V%02d=', i) .. EgtNumToString( StartValues[i] or 0, 3) + end + EmtOutput( sLine) + StartValues = {} +end + +--------------------------------------------------------------------- +-- *** END GENERATION *** +--------------------------------------------------------------------- diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.mlpe b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.mlpe new file mode 100644 index 0000000..9d29383 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.mlpe @@ -0,0 +1,1974 @@ +-- Processore macchina Essetre-PF1250 by EgalTech s.r.l. 2021/10/03 +-- Funzioni generiche indipendenti dal controllo + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +--------------------------------------------------------------------- +-- *** GENERATION *** +--------------------------------------------------------------------- +local sBaseDir = EgtGetSourceDir() +if NumericalControl == 'NUM' then + dofile( sBaseDir .. 'Essetre-PF1250.NUM.mlpe') +elseif NumericalControl == 'TPA' then + dofile( sBaseDir .. 'Essetre-PF1250.TPA.mlpe') +else + error( 'Numerical Control error : unkwnown type') +end + +--------------------------------------------------------------------- +-- *** SIMULATION *** +--------------------------------------------------------------------- +local COLL_SAFE_DIST = 4 + +--------------------------------------------------------------------- +function OnSimulStart() + -- controllo versione programma + if not EMT.VER or EMT.VER < '2.3b4' then + EmtSetLastError( 1200, 'A newer version of the program is required (minimum 2.3b4)') + end + ExecStartHome() + -- Carico gli utensili sulle barre portautensili + local vTcPos = EgtGetAllTcPosNames() + if vTcPos then + for i = 1, #vTcPos do + local vTools = EgtGetToolsInCurrSetupPos( vTcPos[i]) + if vTools and vTools[1] then + EgtLoadTool( vTcPos[i], 1, vTools[1]) + ShowToolInTcPos( vTcPos[i], true) + end + end + end + -- Se reset o home, esco + if EMT.SIM1ST then return end + -- Creo o svuoto gruppo per copia finale degli oggetti virtual milling + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + if nVmGrpId then + EgtSetStatus( nVmGrpId, GDB_ST.ON) + EgtEmptyGroup( nVmGrpId) + else + nVmGrpId = EgtGroup( GDB_ID.ROOT) + EgtSetName( nVmGrpId, 'VMill') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + -- Preparo lista oggetti da verificare per collisioni + EMT.COLLOBJ = {} + AddToCollisionCheck( 'Z1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'B1', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'X2', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'C2', 'COLLISION', EMT.COLLOBJ) + AddToCollisionCheck( 'B2', 'COLLISION', EMT.COLLOBJ) + DumpCollisionCheck( EMT.COLLOBJ, 'Collision Objects :', 4) + -- Preparo lista solidi macchina con cui possono collidere gli oggetti sopra riportati (in aggiunta a VMill) + EMT.MCODET = {} + EMT.MCODET[1] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'V1'), 'COLLISION'), 'STM') + EMT.MCODET[2] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'V2'), 'COLLISION'), 'STM') + EMT.MCODET[3] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'TRAV') + EMT.MCODET[4] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'COL1') + EMT.MCODET[5] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'COL2') + EMT.MCODET[6] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'COLLISION'), 'CHSAW') + EMT.MCODET[7] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Z2'), 'COLLISION'), 'COL1') + EMT.MCODET[8] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Z2'), 'COLLISION'), 'CHAIN') + EMT.MCODET[9] = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( EgtGetAxisId( 'Z2'), 'COLLISION'), 'COL2') + for i = #EMT.MCODET, 1, -1 do + if not EMT.MCODET[i] then + table.remove( EMT.MCODET, i) + EgtOutLog( 'Warning : MCODET element (' .. tostring( i) .. ') is null') + end + end + -- Preparo lista collisioni vuota + EMT.COLLIDE = {} +end + +--------------------------------------------------------------------- +function OnSimulEnd() + EMT.Y1DELTA = nil + EMT.Y2DELTA = nil + ExecParkRoller() +end + +--------------------------------------------------------------------- +function OnSimulDispositionStarting() + EmtUnlinkAllRawPartsFromGroups() + if EMT.PHASE > 1 then + if IsStartOrRestPhase( EMT.PHASE) then + local ParkT = GetParkT() + EgtSetAxisPos( 'T', ParkT) + end + end +end + +--------------------------------------------------------------------- +function OnSimulDispositionStart() + EMT.OPEISDISP = true + + -- Se prima disposizione + if EMT.PHASE == 1 then + -- Determino sezione del grezzo + local nSolId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'RawSolid') or GDB_ID.NULL + local b3Sol = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + EMT.SB = 0 + EMT.HB = 0 + if b3Sol then + EMT.SB = b3Sol:getDimY() + EMT.HB = b3Sol:getDimZ() + end + -- Carico gli utensili iniziali o di default sulle due teste + LoadFirstTool( 1, DefTcPos1) + LoadFirstTool( 2, DefTcPos2) + -- Se vero inizio e abilitato creo gli Zmap + EMT.VMILL = {} + if not EMT.SIM1ST and EgtGetInfo( EgtGetCurrMachGroup(), 'Vm', 'b') then + local nLastOrd = GetPhaseOrd( EgtGetPhaseCount()) + local nPartRawId = EgtGetFirstRawPart() + while nPartRawId do + -- se è lo scarto finale tagliato a pezzi, esco + local nRawOrd = EgtGetInfo( nPartRawId, 'ORD', 'i') + if nRawOrd == nLastOrd + 1 then break end + -- elimino eventuale vecchio Zmap + EgtErase( EgtGetFirstNameInGroup( nPartRawId, 'VMill') or GDB_ID.NULL) + -- recupero il solido + local nSolId = EgtGetFirstNameInGroup( nPartRawId, 'RawSolid') + local b3Raw = EgtGetBBoxGlob( nSolId, GDB_BB.STANDARD) + -- aggiungo eventuale scrap successivo + if nRawOrd == nLastOrd then + local nScrapId = EgtGetNextRawPart( nPartRawId) + if nScrapId then + local nScrapSolId = EgtGetFirstNameInGroup( nScrapId, 'RawSolid') + local b3ScrapRaw = EgtGetBBoxGlob( nScrapSolId, GDB_BB.STANDARD) + if b3ScrapRaw then + b3Raw:Add( b3ScrapRaw) + end + end + end + -- determino la risoluzione dello Zmap + local dArea = b3Raw:getDimX() * b3Raw:getDimY() + b3Raw:getDimX() * b3Raw:getDimZ() + b3Raw:getDimY() * b3Raw:getDimZ() + local dTol = 4.71 + if dArea < CoeffVM * 0.3e6 then + dTol = 1.01 + elseif dArea < CoeffVM * 0.6e6 then + dTol = 1.51 + elseif dArea < CoeffVM * 1.2e6 then + dTol = 1.97 + elseif dArea < CoeffVM * 2.4e6 then + dTol = 2.81 + elseif dArea < CoeffVM * 4.8e6 then + dTol = 3.77 + end + -- creo lo Zmap + local VMillId = EgtVolZmapBox( nPartRawId, b3Raw:getMin(), b3Raw:getDimX(), b3Raw:getDimY(), b3Raw:getDimZ(), dTol, true, GDB_RT.GLOB) + if VMillId then + EgtSetName( VMillId, 'VMill') + EgtSetLevel( VMillId, GDB_LV.TEMP) + EgtSetColor( VMillId, EgtGetColor( nSolId), false) + -- nascondo le altre geometrie + local nId = EgtGetFirstInGroup( nPartRawId) + while nId do + if nId ~= VMillId then + EgtSetStatus( nId, GDB_ST.OFF) + end + nId = EgtGetNext( nId) + end + table.insert( EMT.VMILL, VMillId) + end + nPartRawId = EgtGetNextRawPart( nPartRawId) + end + -- imposto eventuale utensile corrente + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + end + end + + -- Nascondo tutte le lavorazioni + local nMchId = EgtGetFirstOperation() + while nMchId do + if EgtGetOperationType( nMchId) ~= MCH_OY.DISP then + EgtSetOperationStatus( nMchId, false) + end + nMchId = EgtGetNextOperation( nMchId) + end + + -- Se fase inizio o rimanenza, aggancio grezzi della fase alla tavola + if IsStartOrRestPhase( EMT.PHASE) then + -- se fase inizio, segnalo giacitura del grezzo + if IsStartPhase( EMT.PHASE) then + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + local nScrapOrd = GetPhaseOrd( EgtGetPhaseCount()) + 1 + local b3Raw = BBox3d() + local b3Bar = BBox3d() + local nPartRawId, nScrapRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + local b3Tmp = EgtGetRawPartBBox( nRawId) + b3Bar:Add( b3Tmp) + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + b3Raw:Add( b3Tmp) + nPartRawId = nRawId + elseif nRawOrd == nOrd + 1 and nRawOrd == nScrapOrd then + b3Raw:Add( b3Tmp) + nScrapRawId = nRawId + end + end + nRawId = nNextRawId + end + -- gestione eventuale scarto affettato successivo + if EMT.VMILL and #EMT.VMILL > 0 then + EMT.SCRAP = nScrapRawId + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + else + EMT.SCRAP = nil + end + EMT.LB = b3Bar:getDimX() + EMT.LT = b3Raw:getDimX() + EMT.CUTID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + EMT.Y1SPEC = nil + -- se vero inizio, assegno solidi per verifica collisione + if not EMT.SIM1ST then + EMT.CODET = {} + for i = 1, #EMT.MCODET do + EMT.CODET[i] = EMT.MCODET[i] + end + for i = 1, #( EMT.VMILL or {}) do + table.insert( EMT.CODET, EMT.VMILL[i]) + end + end + -- se altrimenti fase intermedia, aggancio grezzi della fase alla tavola + elseif IsMidPhase( EMT.PHASE) then + -- se cambiata giacitura, lo segnalo + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= nPrevRot then + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- eseguo aggancio + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + EmtLinkRawPartToGroup( nRawId, 'Tab') + end + nRawId = nNextRawId + end + -- se Vmill, nascondo eventuale scrap + if EMT.VMILL and #EMT.VMILL > 0 then + EgtSetStatus( EMT.SCRAP or GDB_ID.NULL, GDB_ST.OFF) + end + + -- se altrimenti fasi intermedia o finale speciali, aggancio primo grezzo alla tavola e gli altri in posizione pre-carico + elseif IsMid2Phase( EMT.PHASE) or IsEnd2Phase( EMT.PHASE) then + -- se cambiata giacitura, lo segnalo + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + local nRot = GetPhaseRot( EMT.PHASE) + if nRot ~= nPrevRot then + if nRot ~= 0 then + EgtOutText( 'Barra ruotata di ' .. tostring( -90 * nRot) .. '°') + else + EgtOutText( 'Barra non ruotata') + end + end + -- verifico posizione di carico + local ParkT = GetParkT() + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + -- ricerco vettore movimento per i successivi + local vtMove = Vector3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then + vtMove = Vector3d( - ParkT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + local b3Bar = BBox3d() + nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then + EmtLinkRawPartToGroup( nRawId, 'Tab') + b3Bar = EgtGetRawPartBBox( nRawId) + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EgtSetStatus( nRawId, GDB_ST.OFF) + end + end + nRawId = nNextRawId + end + EMT.LB = b3Bar:getDimX() + + -- altrimenti fase finale, aggancio primo grezzo alla tavola e gli altri in posizione carico al carro Y + else + -- verifico posizione di carico + local ParkT = GetParkT() + -- indice primo grezzo della fase + local nOrd = GetPhaseOrd( EMT.PHASE) + -- ricerco vettore movimento per i successivi + local vtMove = Vector3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd + 1 then + vtMove = Vector3d( - ParkT - EgtGetRawPartBBox( nRawId):getMax():getX(), 0, 0) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- eseguo + local b3Bar = BBox3d() + nRawId = EgtGetFirstRawPart() + while nRawId do + local nNextRawId = EgtGetNextRawPart( nRawId) + if EgtVerifyRawPartPhase( nRawId, EMT.PHASE) then + if EgtGetInfo( nRawId, 'ORD', 'i') == nOrd then + EmtLinkRawPartToGroup( nRawId, 'Tab') + b3Bar = EgtGetRawPartBBox( nRawId) + else + EgtMove( nRawId, vtMove, GDB_RT.GLOB) + EmtLinkRawPartToGroup( nRawId, 'Y1') + end + end + nRawId = nNextRawId + end + EMT.LB = b3Bar:getDimX() + end +end + +--------------------------------------------------------------------- +function OnSimulDispositionEnd() + if EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + EMT.TO_FALL = false + end + EMT.SPLIT = false + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnSimulToolSelect( dPosA) + -- se utensile non definito, è disposizione ed esco + if EMT.TOOL == '' then return end + -- recupero dati utensile + EMT.TOOLTYPE = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + -- se sega a catena, imposto subito angolo scelto per asse virtuale A + if EMT.HEAD == 'H13' then + -- valore dell'asse virtuale + dPosA = dPosA or GetNextChainSawingVirtualAxis( EMT.MCHID) + -- imposto il valore di A + EgtSetAxisPos( 'A', dPosA) + -- imposto home dell'asse C1 (A=0 -> T101, A=90 -> T104) + local MyParkCSawC1 = GetChainSawCHomeFromVirtualAxis( dPosA) + EmtModifyAxisHome( 'C1', MyParkCSawC1) + EgtSetAxisPos( 'C1', MyParkCSawC1) + -- Imposto visualizzazione + EgtSetMode( EgtGetHeadId( EMT.HEAD) or GDB_ID.NULL, GDB_MD.STD) + end + -- carico utensile, con breve pausa + EgtPause( 100) + EgtOutText( '') + -- lo nascondo sul portautensili + ShowToolInTcPos( EMT.TCPOS, false) + -- dichiaro assi ausiliari da visualizzare + EMT.AuxAxes = 4 + EMT.A1n = 'Y1' + EMT.A2n = 'Y2' + EMT.A3n = 'V1' + EMT.A4n = 'V2' + -- se attivo Vmill + SetToolForVmill( EMT.TOOL, EMT.HEAD, EMT.EXIT, EMT.VMILL) + -- se attivo Collision Check + EMT.SAFEDIST = COLL_SAFE_DIST + if EMT.COLLOBJ then + local nInd = EgtIf( EMT.HEAD ~= 'H21', 1001, 1011) + AddToolToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd) + AddToolHolderToCollisionObj( EMT.TOOL, EMT.HEAD, EMT.EXIT, nInd + 1) + for i, Coll in ipairs( EMT.COLLOBJ or {}) do + EmtAddCollisionObjEx( i, Coll.Fr, Coll.Ty, Coll.Mv, Coll.P1, Coll.P2, Coll.P3) + end + end + -- salvo dati utensile + local nSetHead = GetHeadSet( EMT.HEAD) + -- per gruppo testa 1 + if nSetHead == 1 then + EMT.PREVTOOL_H1 = EMT.TOOL + EMT.PREVHEAD_H1 = EMT.HEAD + EMT.PREVTCPOS_H1 = EMT.TCPOS + -- per gruppo testa 2 + elseif nSetHead == 2 then + EMT.PREVTOOL_H2 = EMT.TOOL + EMT.PREVHEAD_H2 = EMT.HEAD + EMT.PREVTCPOS_H2 = EMT.TCPOS + end +end + +--------------------------------------------------------------------- +function OnSimulToolDeselect() + -- se prossimo utensile dummy, non faccio alcunché + if EMT.NEXTHEAD == 'H14' then return end + -- se prossimo utensile non cambia e non è sega a catena, esco + if ( EMT.NEXTTOOL == EMT.PREVTOOL_H1 or EMT.NEXTTOOL == EMT.PREVTOOL_H2) and EMT.NEXTHEAD ~= 'H13' then return end + -- deposito utensile + EgtOutText( 'Tool change in progress...') + -- recupero il gruppo + local nSetHead = GetHeadSet( EMT.NEXTHEAD) + -- per testa gruppo 2 + if nSetHead == 2 then + -- visualizzo utensile su TcPos + ShowToolInTcPos( EMT.PREVTCPOS_H2, true) + -- nascondo l'utensile sulla testa + EgtSetStatus( EgtGetHeadId( EMT.PREVHEAD_H2 or '') or GDB_ID.NULL, GDB_ST.OFF) + return + end + -- per testa gruppo 1... + local RapSimStep = 4 * EMT.SIMSTEP + -- deposito utensile fresa + if EMT.PREVHEAD_H1 == 'H11' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, RapSimStep/10, 'C1', ParkC1, RapSimStep/10) + local dPosX = EgtIf( GetTcForTopHeadTool( EMT.PREVTCPOS_H1) ~= 2, ParkX1, ParkTc2X1) + SimulMoveAxis( 'X1', dPosX, RapSimStep) + -- deposito utensile lama + elseif EMT.PREVHEAD_H1 == 'H12' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, RapSimStep/10, 'C1', ParkC1, RapSimStep/10) + SimulMoveAxis( 'X1', ParkX1, RapSimStep) + -- deposito utensile sega a catena + elseif EMT.PREVHEAD_H1 == 'H13' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkCSawB1, RapSimStep/10, 'C1', EgtGetAxisHomePos( 'C1'), RapSimStep/10) + SimulMoveAxis( 'X1', ParkCSawX1, RapSimStep) + end + -- breve pausa + EgtPause( 100) + -- visualizzo utensile su TcPos + ShowToolInTcPos( EMT.PREVTCPOS_H1, true) + -- nascondo l'utensile sulla testa + EgtSetMode( EgtGetHeadId( EMT.PREVHEAD_H1 or '') or GDB_ID.NULL, GDB_MD.HIDDEN) + -- prendo utensile fresa + if EMT.NEXTHEAD == 'H11' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, RapSimStep/10, 'C1', ParkC1, RapSimStep/10) + local dPosX = EgtIf( GetTcForTopHeadTool( EMT.NEXTTCPOS) ~= 2, ParkX1, ParkTc2X1) + SimulMoveAxis( 'X1', dPosX, RapSimStep) + SimulMoveAxis( 'Z1', 0, RapSimStep) + -- prendo utensile lama + elseif EMT.NEXTHEAD == 'H12' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkB1, RapSimStep/10, 'C1', ParkC1, RapSimStep/10) + SimulMoveAxis( 'X1', ParkX1, RapSimStep) + -- prendo utensile sega a catena + elseif EMT.NEXTHEAD == 'H13' then + -- simulo movimento + SimulMoveAxes( 'B1', ParkCSawB1, RapSimStep/10, 'C1', ParkCSawC1, RapSimStep/10) + SimulMoveAxis( 'X1', ParkCSawX1, RapSimStep) + end +end + +--------------------------------------------------------------------- +function OnSimulMachiningStart() + -- se lavorazione attuale e precedente con sega a catena con angolo A diverso, devo scaricare e ricaricare + if EMT.HEAD == 'H13' and EMT.HEAD == EMT.PREVHEAD_H1 then + local dPrevA = EgtGetAxisPos( 'A') + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + local dPosA = tonumber( sVal:sub( 3)) + if abs( dPosA - dPrevA) > 1 then + OnSimulToolDeselect() + EgtSetStatus( EgtGetHeadId( EMT.HEAD), GDB_ST.ON) + OnSimulToolSelect( dPosA) + end + end + -- recupero alcuni dati della lavorazione + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + EMT.VMRS = ( EMT.MCHTYPE ~= MCH_MY.DRILLING and not ( sNotes and sNotes:find( 'VMRS=0;', 1, true))) + EMT.MCHSPLIT = ( sNotes and sNotes:find( 'Split;', 1, true)) + -- recupero TASKID della feature lavorata + local vId = EgtGetMachiningGeometry() + if vId and #vId > 0 and #vId[1] > 0 then + EMT.TASKID = EgtGetInfo( vId[1][1], 'TASKID', 'i') or 0 ; + else + EMT.TASKID = 0 + end + -- non ancora iniziata la lavorazione + EMT.MCHFIRST = true +end + +--------------------------------------------------------------------- +function OnSimulMachiningEnd() + if EMT.UNLOADING or EMT.FALL then + ExecUnloading() + EMT.UNLOADING = false + EMT.FALL = false + EMT.TO_FALL = false + end + EMT.MCHSPLIT = nil + EMT.SPLIT = nil +end + +--------------------------------------------------------------------- +function OnSimulPathStart() + -- se taglio di separazione, verifico se ci sarà caduta + if EMT.MCHSPLIT then + local sCmd = EgtGetInfo( EMT.PATHID, 'AE1') or '' + if sCmd:find( 'Fall', 1, true) then + EMT.TO_FALL = true + end + end +end + +--------------------------------------------------------------------- +function OnSimulPathEnd() + -- rimozione sfridi + RemoveScraps() + -- se non ci sono comandi ausiliari associati e richiesta risalita a Zmax + if EMT.AUXTOT == 0 and EMT.TO_ZMAX then + if EMT.MCHSPLIT and not EMT.TO_FALL then + EMT.SPLIT_Y1DELTA = EMT.Y1DELTA + EMT.Y1DELTA = nil + SetPY1Light( false) + end + ExecMoveZmax( EMT.MCHSPLIT) + EMT.TO_ZMAX = nil + end +end + +--------------------------------------------------------------------- +function OnSimulPathStartAux() + -- eseguo il comando + ExecAuxCmd( EMT.AUX) + -- se ultimo comando e lavorazione di split, sgancio il carro Y1 + if EMT.AUXIND == EMT.AUXTOT and EMT.MCHSPLIT and not EMT.TO_FALL then + EMT.SPLIT_Y1DELTA = EMT.Y1DELTA + EMT.Y1DELTA = nil + SetPY1Light( false) + end +end + +--------------------------------------------------------------------- +function OnSimulPathEndAux() + -- eseguo il comando + ExecAuxCmd( EMT.AUX) + -- se ultimo comando e richiesta risalita a Zmax + if EMT.AUXIND == EMT.AUXTOT and EMT.TO_ZMAX then + ExecMoveZmax( EMT.MCHSPLIT) + EMT.TO_ZMAX = nil + end +end + +--------------------------------------------------------------------- +function OnSimulMoveStart() + if EMT.MCHFIRST then EgtOutText( '') end + -- step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + -- set della testa + local nSetHead = GetHeadSet( EMT.HEAD) + -- Posizioni correnti + local Y1Pos = EgtGetAxisPos( 'Y1') + local Y2Pos = EgtGetAxisPos( 'Y2') + local V1Pos = EgtGetAxisPos( 'V1') + local V2Pos = EgtGetAxisPos( 'V2') + -- Imposto movimento pinze e rulli insieme con la tavola : + EMT.AuxAxes = 4 + -- pinze + EMT.A1n = 'Y1' + if EMT.Y1DELTA then + EMT.A1 = EMT.L1 + EMT.Y1DELTA + else + EMT.A1 = EgtIf( EMT.Y1SPEC, EgtGetAxisPos( 'Y1'), ParkY1) + end + EMT.A2n = 'Y2' + if EMT.Y2DELTA then + EMT.A2 = EMT.L1 + EMT.Y2DELTA + else + EMT.A2 = ParkY2 + end + -- rulli + EMT.A3n = 'V1' + EMT.A3 = EgtIf( GetV1ToClose(), EMT.V1NEXTPOS, ParkV1) + EMT.A4n = 'V2' + EMT.A4 = EgtIf( GetV2ToClose(), EMT.V2NEXTPOS, ParkV2) + local bParkV = false + if EMT.MCHFIRST then + -- se rulli più chiusi del richiesto o cambio direzione utensile (tranne solo asse B con C0 o equivalenti) devo mettere i rulli in parcheggio + if V1Pos < EMT.V1NEXTPOS - 1 or V2Pos > EMT.V2NEXTPOS + 1 or RollerParkingNeeded( EMT.HEAD, EMT.R1p, EMT.R2p, EMT.R1, EMT.R2) then + bParkV = true + EMT.A3 = ParkV1 + EMT.A4 = ParkV2 + end + end + -- Controllo corse assi ausiliari + VerifyY1Stroke( EMT.A1) + VerifyY2Stroke( EMT.A2) + VerifyV1Stroke( EMT.A3) + VerifyV2Stroke( EMT.A4) + -- se devo subito parcheggiare i rulli + local nRes = 0 + if bParkV then + nRes = ExecParkRoller( Y1Pos, Y2Pos, V1Pos, V2Pos, false, true) + end + -- se movimento in rapido + if EMT.MOVE == 0 then + -- se testa 1 + if nSetHead == 1 then + -- Dati + local B1Pos = EgtGetAxisPos( 'B1') + local Z1Pos = EgtGetAxisPos( 'Z1') + local Z1Home = EgtGetAxisHomePos( 'Z1') + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + -- se movimento iniziale da Zmax con lama o fresa + if EMT.ZMAX or ( EMT.FLAG == 2 and EMT.FLAG2 == 1) then + --EgtOutBox( 'Flag 2,1', 'Info Rapid') + local bXSpec = ( EMT.L2 < DeltaTabY) + SimulMoveAxis( 'X1', EgtIf( bXSpec, DeltaTabY, EMT.L2), RapSimStep) + local Z_EXTRA = EgtIf( EMT.HEAD == 'H11', 250, 160) + local dZref + if EMT.R2 > -60 then + dZref = Z1Home + Z_EXTRA + SimulMoveAxes( 'Z1', dZref, RapSimStep, 'B1', min( EMT.R2, 60), RapSimStep/10) + if EMT.R2 > 60 then + dZref = Z1Home + Z_EXTRA * ( 90 - abs( EMT.R2)) / 30 + SimulMoveAxes( 'Z1', dZref, RapSimStep, 'B1', min( EMT.R2, 90), RapSimStep/10) + end + else + dZref = Z1Home + Z_EXTRA * ( 90 - abs( EMT.R2)) / 30 + SimulMoveAxes( 'Z1', dZref, RapSimStep, 'B1', EMT.R2, RapSimStep/10) + end + if dZref and EMT.L3 < dZref + 0.1 then + SimulMoveAxis( 'C1', EMT.R1, RapSimStep / 10) + end + end + -- altrimenti sega a catena + else + local APos = EgtGetAxisPos( 'A') + -- Porto la Z alla giusta quota + if Z1Pos > Z1Home + 1 and ( abs( B1Pos) > 89.9 or abs( APos) < 0.1) then + SimulMoveAxis( 'X1', EMT.L2, RapSimStep) + SimulMoveAxis( 'Z1', Z1Home, RapSimStep) + end + end + -- altrimenti testa 2 + else + -- Porto la X alla giusta quota + local X2Pos = EgtGetAxisPos( 'X2') + local X2Home = EgtGetAxisHomePos( 'X2') + if X2Pos > X2Home - 1 then + SimulMoveAxis( 'X2', EMT.L2, RapSimStep) + end + end + end + EMT.ZMAX = nil + -- se lavorazione split, muovo per riaggancio del carro Y1 + if EMT.SPLIT_Y1DELTA then + EMT.Y1DELTA = EMT.SPLIT_Y1DELTA + EMT.A1 = EMT.L1 + EMT.Y1DELTA + end + -- se Zmax dopo fine lavorazione + if EMT.MOVE == 0 and EMT.FLAG == 3 then + -- demando movimento completo a MoveEnd + EMT.EnabAxes = false + EMT.ShowAxes = true + end + -- se necessario ... + if EMT.MCHFIRST then + if nSetHead == 1 then + SimulMoveAxes( 'X1', EMT.L2, RapSimStep, + 'Z1', EMT.L3, RapSimStep, + 'C1', EMT.R1, RapSimStep / 10, + 'B1', EMT.R2, RapSimStep / 10) + else + SimulMoveAxes( 'X2', EMT.L2, RapSimStep, + 'Z2', EMT.L3, RapSimStep, + 'C2', EMT.R1, RapSimStep / 10, + 'B2', EMT.R2, RapSimStep / 10) + end + end + if nRes ~= 0 then + EMT.A3 = EgtIf( GetV1ToClose(), EMT.V1NEXTPOS, ParkV1) + EMT.A4 = EgtIf( GetV2ToClose(), EMT.V2NEXTPOS, ParkV2) + end +end + +--------------------------------------------------------------------- +function OnSimulMoveEnd() + -- se primo rapido della lavorazione + if EMT.MCHFIRST and EMT.MOVE == 0 then + -- se lavorazione split, dichiaro carro Y1 riagganciato + if EMT.SPLIT_Y1DELTA then + EMT.SPLIT_Y1DELTA = nil + SetPY1Light( true) + end + -- chiusura o apertura rulli V1 + if GetV1ToClose() then + ExecCloseRoller( 1) + else + ExecOpenRoller( 1) + end + -- chiusura o apertura rulli V2 + if GetV2ToClose() then + ExecCloseRoller( 2) + else + ExecOpenRoller( 2) + end + EMT.MCHFIRST = false + EgtOutText( '') + end + -- se Zmax dopo fine lavorazione + if EMT.MOVE == 0 and EMT.FLAG == 3 then + -- eventuale rimozione sfridi + RemoveScraps() + -- eseguo + ExecMoveZmax( EMT.MCHSPLIT) + EMT.TO_ZMAX = nil + end +end + +--------------------------------------------------------------------- +function OnSimulCollision() + -- se prima collisione della lavorazione, la segnalo + if EMT.MCHNAME ~= EMT.LAST_MCHNAME_COLLIDE then + local Class = '' + if EMT.SIMCOBIND == 1001 or EMT.SIMCOBIND == 1011 then + Class = 'T_'..EMT.HEAD + elseif EMT.SIMCOBIND == 1002 or EMT.SIMCOBIND == 1012 then + Class = 'TH_'..EMT.HEAD + else + Class = EMT.COLLOBJ[EMT.SIMCOBIND].Cl + end + table.insert( EMT.COLLIDE, { Mc = EMT.MCHNAME, Cl = Class, Vm = EMT.SIMVMID}) + EMT.LAST_MCHNAME_COLLIDE = EMT.MCHNAME + EMT.ERR = 11 + local sErr = 'CUTID='..tostring( EMT.CUTID)..'; TASKID='..tostring( EMT.TASKID)..'; Mach='..EMT.MCHNAME..'; Class='..Class..'; VMill='..EMT.SIMVMID + EmtSetLastError( 1221, sErr, true) + EgtOutLog( 'Collision : ' .. sErr, 1) + end +end + +--------------------------------------------------------------------- +function ExecAuxCmd( sCmd) + -- step di simulazione per rapido + local RapSimStep = 4 * EMT.SIMSTEP + -- analizzo il comando + local Cmd = EgtSplitString( sCmd) + if Cmd[1] == '0' then + if Cmd[2] == 'Unloading' then + EMT.UNLOADING = true + elseif Cmd[2] == 'Split' then + EMT.SPLIT = true + elseif Cmd[2] == 'Fall' then + EMT.FALL = true + end + EgtOutText( Cmd[2]) + elseif Cmd[1] == '1' then + if EMT.SPLIT then ExecOpenRoller( 1) end + if EMT.UNLOADING or EMT.TO_FALL then ExecOpenRoller( 2) end + local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd) + local bOk, bOk1, bOk2, bOk3 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), RapSimStep, + sV1, MoveV1, RapSimStep, + sV2, MoveV2, RapSimStep) + if not bOk then + if not bOk1 then + if VerifyY1Y2Stroke( Cmd[2], tonumber( Cmd[3])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + elseif not bOk2 then + VerifyV1V2Stroke( sV1, MoveV1) + elseif not bOk3 then + VerifyV1V2Stroke( sV2, MoveV2) + end + end + elseif Cmd[1] == '2' then + -- Verifico movimento carrello con trave agganciata + VerifyOneChariotSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5]) + -- Eseguo i movimenti necessari + if EMT.SPLIT then ExecOpenRoller( 1) end + if EMT.UNLOADING or EMT.TO_FALL then ExecOpenRoller( 2) end + local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd) + local bOk, bOk1, bOk2, bOk3, bOk4 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), RapSimStep, + Cmd[4], tonumber( Cmd[5]), RapSimStep, + sV1, MoveV1, RapSimStep, + sV2, MoveV2, RapSimStep) + if not bOk then + if not bOk1 or not bOk2 then + local nI = EgtIf( not bOk1, 2, 4) + if VerifyY1Y2Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + elseif not bOk3 then + VerifyV1V2Stroke( sV1, MoveV1) + elseif not bOk4 then + VerifyV1V2Stroke( sV2, MoveV2) + end + end + elseif Cmd[1] == '3' then + -- Verifico movimento carrelli con trave agganciata + VerifyTwoChariotsSlide( Cmd[2], Cmd[3], Cmd[4], Cmd[5], Cmd[6], Cmd[7]) + -- Eseguo i movimenti necessari + if EMT.SPLIT then ExecOpenRoller( 1) end + if EMT.UNLOADING or EMT.TO_FALL then ExecOpenRoller( 2) end + local sV1, MoveV1, sV2, MoveV2 = CalcMoveV1V2ForAuxCmd( Cmd) + local bOk, bOk1, bOk2, bOk3, bOk4, bOk5 = SimulMoveAxes( Cmd[2], tonumber( Cmd[3]), RapSimStep, + Cmd[4], tonumber( Cmd[5]), RapSimStep, + Cmd[6], tonumber( Cmd[7]), RapSimStep, + sV1, MoveV1, RapSimStep, + sV2, MoveV2, RapSimStep) + if not bOk then + if not bOk1 or not bOk2 or not bOk3 then + local nI = EgtIf( not bOk1, 2, EgtIf( not bOk2, 4, 6)) + if VerifyY1Y2Stroke( Cmd[nI], tonumber( Cmd[nI+1])) == nil then + EgtOutLog( 'Error on ExecAuxCmd : ' .. sCmd) + end + elseif not bOk4 then + VerifyV1V2Stroke( sV1, MoveV1) + elseif not bOk5 then + VerifyV1V2Stroke( sV2, MoveV2) + end + end + elseif Cmd[1] == '4' then + ExecMoveHome( Cmd[2] == '1') + elseif Cmd[1] == '11' then + SimulMoveAxes( 'PY1', EgtIf( Cmd[2] == '0', MaxHoOpen, EMT.SB), RapSimStep) + SetPY1Light( Cmd[2] ~= '0') + elseif Cmd[1] == '12' then + SimulMoveAxes( 'PY2', EgtIf( Cmd[2] == '0', MaxHoOpen, EMT.SB), RapSimStep) + SetPY2Light( Cmd[2] ~= '0') + elseif Cmd[1] == '21' then + local nY1Delta = tonumber( Cmd[2]) + local nY2Delta = tonumber( Cmd[3]) + EMT.Y1DELTA = EgtIf( nY1Delta > 0.01, nY1Delta, nil) + EMT.Y2DELTA = EgtIf( nY2Delta > 0.01, nY2Delta, nil) + elseif Cmd[1] == '22' then + EMT.V1NEXTPOS = tonumber( Cmd[2]) + EMT.V2NEXTPOS = tonumber( Cmd[3]) + elseif Cmd[1] == '31' then + local nRawId = tonumber( Cmd[2]) + EmtUnlinkRawPartFromGroup( nRawId) + EmtLinkRawPartToGroup( nRawId, Cmd[3]) + EMT.Y1SPEC = true + elseif Cmd[1] == '99' then + EMT.ERR = Cmd[2] + EmtSetLastError( 1200 + EMT.ERR, Cmd[3]) + end +end + +--------------------------------------------------------------------- +function CalcMoveV1V2ForAuxCmd( Cmd) + -- verifico se necessario muovere V1 + local MoveV1 + local MoveY1 = GetCmdAxMove( Cmd, 'Y1') + local V1Pos = EgtGetAxisPos( 'V1') + if MoveY1 and V1Pos > MoveY1 - MinDeltaYV + 0.1 then + MoveV1 = MoveY1 - MinDeltaYV + end + local sV1 = EgtIf( MoveV1, 'V1', nil) + -- verifico se necessario muovere V2 + local MoveV2 + local MoveY2 = GetCmdAxMove( Cmd, 'Y2') + local V2Pos = EgtGetAxisPos( 'V2') + if MoveY2 and V2Pos < MoveY2 + MinDeltaYV - 0.1 then + MoveV2 = MoveY2 + MinDeltaYV + end + local sV2 = EgtIf( MoveV2, 'V2', nil) + -- restituisco i risultati + if MoveV1 and MoveV2 then + return sV1, MoveV1, sV2, MoveV2 + elseif MoveV1 then + return sV1, MoveV1 + elseif MoveV2 then + return sV2, MoveV2 + end +end + +--------------------------------------------------------------------- +function ExecStartHome() + -- posizioni di home + local HomeX = EgtGetAxisHomePos( 'X1') + local HomeC = EgtGetAxisHomePos( 'C1') + local HomeB = EgtGetAxisHomePos( 'B1') + local MaxZ = 0 + -- posizionamento istantaneo + EgtSetAxisPos( 'X1', HomeX) + EgtSetAxisPos( 'C1', HomeC) + EgtSetAxisPos( 'B1', HomeB) + EgtSetAxisPos( 'Z1', MaxZ) +end + +--------------------------------------------------------------------- +function ExecMoveHome( bNearV) + -- risalita a Zmax + ExecMoveZmax( false) + -- step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + -- se testa sotto + if GetHeadSet( EMT.HEAD) == 2 then + if not SimulMoveAxis( 'X2', ParkX2, RapSimStep) then + EgtOutLog( 'Error on MoveHome : X2') + end + end + -- se richiesto, avvicino i rulli + if bNearV then + ExecOpenRoller( 1) + ExecOpenRoller( 2) + if not SimulMoveAxes( 'V1', MinV1, RapSimStep, + 'V2', MaxV2, RapSimStep) then + EgtOutLog( 'Error on MoveHome : NearV1V2') + end + end +end + +--------------------------------------------------------------------- +function ExecMoveZmax( bMchSplit) + -- step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + -- set della testa + local nSetHead = GetHeadSet( EMT.HEAD) + -- posizioni correnti degli assi testa + local CurrX = EgtGetAxisPos( EgtIf( nSetHead == 1, 'X1', 'X2')) + local CurrZ = EgtGetAxisPos( EgtIf( nSetHead == 1, 'Z1', 'Z2')) + local CurrC = EgtGetAxisPos( EgtIf( nSetHead == 1, 'C1', 'C2')) + local CurrB = EgtGetAxisPos( EgtIf( nSetHead == 1, 'B1', 'B2')) + -- posizioni home degli assi testa + local HomeZ = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'Z1', 'Z2')) + local HomeC = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'C1', 'C2')) + local HomeB = EgtGetAxisHomePos( EgtIf( nSetHead == 1, 'B1', 'B2')) + -- verifico se necessario ruotare la testa + local bRot = ( abs( HomeC - CurrC) > 1 or abs( HomeB - CurrB) > 1) + -- se necessario ruotare la testa, allargo i carrelli + if RollerParkingNeeded( EMT.HEAD, CurrC, CurrB, HomeC, HomeB) then + ExecOpenRoller( 1) + ExecOpenRoller( 2) + ExecParkRoller( nil, nil, nil, nil, bMchSplit, true) + end + -- se testa sopra + if nSetHead == 1 then + -- se fresa o lama + if EMT.HEAD ~= 'H13' then + if abs( HomeC - CurrC) > 0.1 or abs( HomeB - CurrB) > 0.1 then + local bSafeZ = false + local Z_EXTRA = EgtIf( EMT.HEAD == 'H11', 250, 160) + if abs( CurrB) < 60 then + local dZref = HomeZ + Z_EXTRA + SimulMoveAxis( 'Z1', dZref, RapSimStep) + bSafeZ = true + elseif abs( CurrB) < 90 then + local dZref = HomeZ + Z_EXTRA * ( 90 - abs( CurrB)) / 30 + SimulMoveAxis( 'Z1', dZref, RapSimStep) + bSafeZ = true + end + if CurrX < DeltaTabY then + if not bSafeZ then + SimulMoveAxes( 'Z1', HomeZ, RapSimStep, 'B1', EgtIf( CurrB > 0, 90, -90), RapSimStep / 10) + end + SimulMoveAxis( 'X1', DeltaTabY, RapSimStep) + end + local ANG_LIM_DOWN = EgtIf( EMT.HEAD == 'H11', 0, -45) + local ANG_LIM_OPPO = 90 + if CurrB > ANG_LIM_DOWN then + if CurrB > ANG_LIM_OPPO then + SimulMoveAxes( 'Z1', HomeZ, RapSimStep, 'B1', ANG_LIM_OPPO, RapSimStep / 10) + end + if CurrB > 60 then + SimulMoveAxes( 'Z1', HomeZ + Z_EXTRA, RapSimStep, 'B1', 60, RapSimStep / 10) + end + SimulMoveAxes( 'Z1', HomeZ + Z_EXTRA, RapSimStep, 'B1', ANG_LIM_DOWN, RapSimStep / 10) + end + SimulMoveAxes( 'Z1', HomeZ, RapSimStep, 'B1', HomeB, RapSimStep / 10) + SimulMoveAxis( 'C1', HomeC, RapSimStep / 10) + end + SimulMoveAxis( 'Z1', MaxZ1, RapSimStep) + -- altrimenti sega a catena + else + SimulMoveAxes( 'Z1', HomeZ, RapSimStep, 'B1', HomeB, RapSimStep / 10) + SimulMoveAxis( 'C1', HomeC, RapSimStep / 10) + SimulMoveAxis( 'Z1', MaxZ1, RapSimStep) + end + -- altrimenti testa sotto + else + SimulMoveAxes( 'Z2', MinZ2, RapSimStep) + SimulMoveAxes( 'B2', ParkB2, RapSimStep / 10, 'C2', ParkC2, RapSimStep / 10) + SimulMoveAxis( 'X2', ParkX2, RapSimStep) + end + EMT.ZMAX = true +end + +--------------------------------------------------------------------- +function ExecUnloading() + if EMT.VMILL and #EMT.VMILL > 0 then + local vMillId = EMT.VMILL[1] + -- gruppo dei Vmill + local nVmGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') + -- li sposto per lasciare spazio al nuovo pezzo + local nId = EgtGetFirstInGroup( nVmGrpId) + while nId do + EgtMove( nId, Vector3d( 0, ( EMT.SB + 50.0), 0), GDB_RT.GLOB) + nId = EgtGetNext( nId) + end + -- creo un nuovo layer e vi inserisco il nuovo pezzo + local nLayId = EgtGroup( nVmGrpId, EgtGetGlobFrame( vMillId)) + EgtRelocate( vMillId, nLayId) + local vtMove = Vector3d( 0, 1600, 0) + if EMT.FALL then vtMove = Vector3d( 0, 3200, -1150) end + EgtMove( nLayId, vtMove, GDB_RT.GLOB) + EgtSetLevel( vMillId, GDB_LV.USER) + -- aggiungo gli spigoli + local nFirstId, nCount = EgtVolZmapGetEdges( vMillId, nLayId) + if nFirstId then + for nId = nFirstId, nFirstId + nCount - 1 do + EgtSetColor( nId, Color3d( 96, 96, 96)) + end + end + -- rilascio Vmill + table.remove( EMT.VMILL, 1) + -- aggiorno la visualizzazione + EgtDraw() + -- se finito + if EMT.PHASE == EgtGetPhaseCount() then + -- se impostato di salvare i Vmill, lo faccio + local sMachIni = EgtGetCurrMachineDir() .. '\\' .. EgtGetCurrMachineName() .. '.ini' + if EgtGetStringFromIni( 'VMill', 'Save', '', sMachIni) == '1' then + local sFile = EgtGetCurrFilePath() + if sFile then + local sDir, sName, sExt = EgtSplitPath( sFile) + sName = sName .. '_VM_' .. EgtGetMachGroupName( EgtGetCurrMachGroup()) + EgtSetLevel( nVmGrpId, GDB_LV.USER) + EgtSaveObjToFile( nVmGrpId, sDir .. sName .. '.Nge') + EgtSetLevel( nVmGrpId, GDB_LV.TEMP) + end + end + end + end +end + +--------------------------------------------------------------------- +function ExecParkRoller( PosY1, PosY2, PosV1, PosV2, bSpliCut, bAgg) + -- step di simulazione + local RapSimStep = 4 * EMT.SIMSTEP + -- Posizioni + local PosT = EgtGetAxisPos( 'T') + PosY1 = PosY1 or EgtGetAxisPos( 'Y1') + PosY2 = PosY2 or EgtGetAxisPos( 'Y2') + PosV1 = PosV1 or EgtGetAxisPos( 'V1') + PosV2 = PosV2 or EgtGetAxisPos( 'V2') + -- Parcheggi pinze + local MyParkY1 = ParkY1 + EgtIf( bAgg, AggLoad, 0) + local MyParkY2 = ParkY2 + -- Eseguo spostamenti + if EMT.Y1DELTA and EMT.Y2DELTA then + local DiffY1 = MyParkY1 - PosY1 + local DiffY2 = MyParkY2 - PosY2 + -- se appena eseguito taglio di separazione + if bSpliCut then + -- aggancio i pezzi rimanenti all'asse Y1 + local nCurrOrd = GetPhaseOrd( EMT.PHASE) + local TabId = EgtGetTableId( 'Tab') + local RawId = EgtGetFirstInGroup( TabId) + while RawId do + local NextRawId = EgtGetNext( RawId) + if EgtGetName( RawId) == 'RawPart' then + local nRawOrd = EgtGetInfo( RawId, 'ORD', 'i') + if nRawOrd and nRawOrd ~= nCurrOrd then + local bUlOk = EmtUnlinkRawPartFromGroup( RawId) + local bLkOk = EmtLinkRawPartToGroup( RawId, 'Y1') + end + end + RawId = NextRawId + end + -- eseguo i movimenti + if not SimulMoveAxes( 'T', PosT + min( DiffY2, 0.0), RapSimStep, + 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', PosY1 + max( DiffY1, 0.0), RapSimStep, + 'Y2', PosY2 + min( DiffY2, 0.0), RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1202, 'Error on MoveAxes in ParkRoller (12A)') + end + return 32 + elseif DiffY1 > 0.1 and DiffY2 < -0.1 then + EMT.ERR = 2 + EmtSetLastError( 1201, 'Error Collision in ParkRoller') + elseif DiffY1 > 0.1 then + if not SimulMoveAxes( 'T', PosT + DiffY1, RapSimStep, + 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', PosY1 + DiffY1, RapSimStep, + 'Y2', PosY2 + DiffY1, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1202, 'Error on MoveAxes in ParkRoller (12B)') + end + return 12 + elseif DiffY2 < -0.1 then + if not SimulMoveAxes( 'T', PosT + DiffY2, RapSimStep, + 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', PosY1 + DiffY2, RapSimStep, + 'Y2', PosY2 + DiffY2, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1203, 'Error on MoveAxes in ParkRoller (12C)') + end + return 21 + else + if not SimulMoveAxes( 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1204, 'Error on MoveAxes in MoveStart') + end + return 30 + end + elseif EMT.Y1DELTA then + local MoveV1 = ParkV1 - PosV1 + local DiffY1 = MyParkY1 - PosY1 + local bMoveY1 = ( DiffY1 > 0.1 or ( PosT > ParkV2 and PosT < ParkV1 and PosY1 + MoveV1 < MaxY1)) + local MoveY1 = EgtIf( bMoveY1, MoveV1, 0) + if not SimulMoveAxes( 'T', PosT + MoveY1, RapSimStep, + 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', PosY1 + MoveY1, RapSimStep, + 'Y2', MyParkY2, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1205, 'Error on MoveAxes in ParkRoller (1)') + end + return 11 + elseif EMT.Y2DELTA then + local MoveV2 = ParkV2 - PosV2 + local DiffY2 = MyParkY2 - PosY2 + local bMoveY2 = ( DiffY2 < -0.1 or ( PosT + EMT.LT < ParkV1 and PosT + EMT.LT > ParkV2 and PosY2 + MoveV2 > MinY2)) + local MoveY2 = EgtIf( bMoveY2, MoveV2, 0) + if not SimulMoveAxes( 'T', PosT + MoveY2, RapSimStep, + 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', EgtIf( PosY1 > MyParkY1, PosY1, MyParkY1), RapSimStep, + 'Y2', PosY2 + MoveY2, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1206, 'Error on MoveAxes in ParkRoller (2)') + end + return 22 + else + if not SimulMoveAxes( 'V1', ParkV1, RapSimStep, + 'V2', ParkV2, RapSimStep, + 'Y1', MyParkY1, RapSimStep, + 'Y2', MyParkY2, RapSimStep) then + EMT.ERR = 2 + EmtSetLastError( 1207, 'Error on MoveAxes in ParkRoller (0)') + end + return 0 + end +end + +--------------------------------------------------------------------- +function ExecCloseRoller( nInd) + EgtSetAxisPos( EgtIf( nInd == 1, 'PV1', 'PV2'), EMT.SB) + EgtSetAxisPos( EgtIf( nInd == 1, 'QV1', 'QV2'), EMT.HB) +end + +--------------------------------------------------------------------- +function ExecOpenRoller( nInd) + EgtSetAxisPos( EgtIf( nInd == 1, 'PV1', 'PV2'), MaxHoOpen) + EgtSetAxisPos( EgtIf( nInd == 1, 'QV1', 'QV2'), MaxVeOpen) +end + +--------------------------------------------------------------------- +function RemoveScraps() + -- se attivo VMILL, lavorazione ed è richiesto di eliminare gli sfridi + if EMT.VMILL and #EMT.VMILL > 0 and not EMT.OPEISDISP and EMT.VMRS then + local vMillId = EMT.VMILL[1] + local nPart = EgtVolZmapPartCount( vMillId) + if nPart > 1 then + -- ricerca del pezzo con massimo volume + local nPartMax = 0 + local dVolMax = 0 + for i = 1, nPart do + local dVol = EgtVolZmapPartVolume( vMillId, i - 1) + if dVol > dVolMax then + dVolMax = dVol + nPartMax = i + end + end + -- eliminazione di tutti i pezzi piccoli + for i = nPart, 1, -1 do + if i ~= nPartMax then + EgtRemoveVolZmapPart( vMillId, i - 1) + end + end + -- aggiorno visualizzazione + EgtDraw() + end + EMT.VMRS = false + end + +end + +--------------------------------------------------------------------- +function VerifyY1Slide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello Y1 + if sName1 == 'T' and sName2 == 'Y1' and GetPY1Light() then + local dY1DeltaP = EgtGetAxisPos( 'Y1') - EgtGetAxisPos( 'T') + local dY1DeltaA = tonumber( dVal2) - tonumber( dVal1) + EgtOutLog( string.format( 'Y1DeltaP=%.3f YDeltaA=%.3f', dY1DeltaP, dY1DeltaA), 5) + if abs( dY1DeltaA - dY1DeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'Y1 slide : ' .. EmtLenToString( dY1DeltaP, 3) .. ' -> ' .. EmtLenToString( dY1DeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Tutto bene + return true +end + +--------------------------------------------------------------------- +function VerifyY2Slide( sName1, dVal1, sName2, dVal2) + -- Se movimento trave agganciata con carrello Y2 + if sName1 == 'T' and sName2 == 'Y2' and GetPY2Light() then + local dY2DeltaP = EgtGetAxisPos( 'Y2') - EgtGetAxisPos( 'T') + local dY2DeltaA = tonumber( dVal2) - tonumber( dVal1) + EgtOutLog( string.format( 'Y2VDeltaP=%.3f Y2DeltaA=%.3f', dY2DeltaP, dY2DeltaA), 5) + if abs( dY2DeltaA - dY2DeltaP) > 0.5 then + EMT.ERR = 2 + local sErr = 'Y2 slide : ' .. EmtLenToString( dY2DeltaP, 3) .. ' -> ' .. EmtLenToString( dY2DeltaA, 3) + EmtSetLastError( 1202, sErr) + end + end + -- Tutto bene + return true +end + +--------------------------------------------------------------------- +function VerifyOneChariotSlide( sName1, dVal1, sName2, dVal2) + -- Metto in prima posizione la trave + if sName2 == 'T' then + sName1, sName2 = sName2, sName1 + dVal1, dVal2 = dVal2, dVal1 + end + -- Eseguo verifica + if sName2 == 'Y1' then + return VerifyY1Slide( sName1, dVal1, sName2, dVal2) + elseif sName2 == 'Y2' then + return VerifyY2Slide( sName1, dVal1, sName2, dVal2) + end + return true +end + +--------------------------------------------------------------------- +function VerifyTwoChariotsSlide( sName1, dVal1, sName2, dVal2, sName3, dVal3) + -- Metto in prima posizione la trave + if sName2 == 'T' then + sName1, sName2 = sName2, sName1 + dVal1, dVal2 = dVal2, dVal1 + elseif sName3 == 'T' then + sName1, sName3 = sName3, sName1 + dVal1, dVal3 = dVal3, dVal1 + end + -- Eseguo verifica + if sName2 == 'Y1' then + return VerifyY1Slide( sName1, dVal1, sName2, dVal2) and VerifyY2Slide( sName1, dVal1, sName3, dVal3) + elseif sName2 == 'Y2' then + return VerifyY2Slide( sName1, dVal1, sName2, dVal2) and VerifyY1Slide( sName1, dVal1, sName3, dVal3) + end + return true +end + +--------------------------------------------------------------------- +function VerifyY1Stroke( dY1) + if dY1 < MinY1 then + EmtSetOutstrokeInfo( 'Y1', 'Y1', true, dY1 - MinY1, ' (L1-)') + EMT.ERR = 1 + local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY1 - MinY1, 3) + EgtOutLog( sErr) + return false + elseif dY1 > MaxY1 then + EmtSetOutstrokeInfo( 'Y1', 'Y1', true, dY1 - MaxY1, ' (L1+)') + EMT.ERR = 1 + local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY1 - MaxY1, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyY2Stroke( dY2) + if dY2 < MinY2 then + EmtSetOutstrokeInfo( 'Y2', 'Y2', true, dY2 - MinY2, ' (L1-)') + EMT.ERR = 1 + local sErr = 'Y2 axis outstroke ' .. EgtNumToString( dY2 - MinY2, 3) + EgtOutLog( sErr) + return false + elseif dY2 > MaxY2 then + EmtSetOutstrokeInfo( 'Y2', 'Y2', true, dY2 - MaxY2, ' (L1+)') + EMT.ERR = 1 + local sErr = 'Y1 axis outstroke ' .. EgtNumToString( dY2 - MaxY2, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyY1Y2Stroke( sName, dVal) + if sName == 'Y1' then + return VerifyY1Stroke( dVal) + elseif sName == 'Y2' then + return VerifyY2Stroke( dVal) + else + return nil + end +end + +--------------------------------------------------------------------- +function VerifyV1Stroke( dV1) + if dV1 < MinV1 then + EmtSetOutstrokeInfo( 'V1', 'V1', true, dV1 - MinV1, ' (L1-)') + EMT.ERR = 1 + local sErr = 'V1 axis outstroke ' .. EgtNumToString( dV1 - MinV1, 3) + EgtOutLog( sErr) + return false + elseif dV1 > MaxV1 then + EmtSetOutstrokeInfo( 'V1', 'V1', true, dV1 - MaxV1, ' (L1+)') + EMT.ERR = 1 + local sErr = 'V1 axis outstroke ' .. EgtNumToString( dV1 - MaxV1, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyV2Stroke( dV2) + if dV2 < MinV2 then + EmtSetOutstrokeInfo( 'V2', 'V2', true, dV2 - MinV2, ' (L1-)') + EMT.ERR = 1 + local sErr = 'V2 axis outstroke ' .. EgtNumToString( dV2 - MinV2, 3) + EgtOutLog( sErr) + return false + elseif dV2 > MaxV2 then + EmtSetOutstrokeInfo( 'V2', 'V2', true, dV2 - MaxV2, ' (L1+)') + EMT.ERR = 1 + local sErr = 'V2 axis outstroke ' .. EgtNumToString( dV2 - MaxV2, 3) + EgtOutLog( sErr) + return false + end + return true +end + +--------------------------------------------------------------------- +function VerifyV1V2Stroke( sName, dVal) + if sName == 'V1' then + return VerifyV1Stroke( dVal) + elseif sName == 'V2' then + return VerifyV2Stroke( dVal) + else + return nil + end +end + +--------------------------------------------------------------------- +function GetV1ToClose() + --EgtOutLog( string.format( 'L1m=%.3f L1M=%.3f V2NP=%.3f LB=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1], EMT.V2NEXTPOS, EMT.LB)) + --EgtOutLog( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT or 0)) + return ( EMT.MAXMAX[1] <= EMT.V1NEXTPOS + RollCageMin and EMT.MAXMIN[1] + EMT.LB >= EMT.V1NEXTPOS + RollCageMax) +end + +--------------------------------------------------------------------- +function GetV2ToClose() + --EgtOutLog( string.format( 'L1m=%.3f L1M=%.3f V2NP=%.3f LB=%.3f', EMT.MAXMIN[1], EMT.MAXMAX[1], EMT.V2NEXTPOS, EMT.LB)) + --EgtOutLog( string.format( 'LB=%.3f LT=%.3f', EMT.LB, EMT.LT or 0)) + return ( EMT.MAXMAX[1] <= EMT.V2NEXTPOS - RollCageMax and EMT.MAXMIN[1] + EMT.LB >= EMT.V2NEXTPOS - RollCageMin) +end + +--------------------------------------------------------------------- +function ShowToolInTcPos( sTcPos, bShow) + -- recupero il gruppo dell'utensile + local TcExitId = EgtGetFirstNameInGroup( EgtGetTcPosId( sTcPos or '') or GDB_ID.NULL, 'T1') + if not TcExitId then return end + -- imposto lo stato di visualizzazione + EgtSetStatus( TcExitId, EgtIf( bShow, GDB_ST.ON, GDB_ST.OFF)) +end + +--------------------------------------------------------------------- +function LoadFirstTool( nHSet, sTcPosDef) + if nHSet ~= 1 and nHSet ~= 2 then return end + if GetHeadSetFromTcPos( sTcPosDef) ~= nHSet then return end + local sTool, sHead, sTcPos = FindFirstToolOnHeadSet( nHSet) + if not sTool then + local vTools = EgtGetToolsInCurrSetupPos( sTcPosDef) + if vTools and vTools[1] then + sTool = vTools[1] + sTcPos = sTcPosDef + if nHSet == 1 then + sHead = EgtIf( sTcPos == 'T1', 'H12', 'H11') + else + sHead = 'H21' + end + end + end + if sTool then + EgtLoadTool( sHead, 1, sTool) + ShowToolInTcPos( sTcPos, false) + end + return sTool +end + +--------------------------------------------------------------------- +-- *** ESTIMATION T&L *** +--------------------------------------------------------------------- +local RAPID_X_FEED = 70000 -- mm/min +local RAPID_Y_FEED = 100000 -- mm/min +local RAPID_Z_FEED = 32000 -- mm/min +local RAPID_C_FEED = 15000 -- deg/min +local RAPID_B_FEED = 15000 -- deg/min +local RAPID_MIN_T = 0.1 -- s +local LOAD_T = 2 -- s +local CHAR_ONE_MOVE_T = 1 -- s +local ROTATION_T = 40 -- s +local SPLIT_T = 6 -- s +local UNLOAD_T = 4 -- s +local FALL_T = 2 -- s + +--------------------------------------------------------------------- +function OnEstimStart() + EMT.INCHES = not EgtUiUnitsAreMM() -- unità di misura mm/inches +end + +--------------------------------------------------------------------- +function OnEstimEnd() +end + +--------------------------------------------------------------------- +function OnEstimProgramStart() + -- imposto inizio movimenti da Home + EMT.L1 = EgtGetAxisHomePos( 'T') + EMT.L2 = EgtGetAxisHomePos( 'X1') + EMT.L3 = EgtGetAxisHomePos( 'Z1') + EMT.R1 = EgtGetAxisHomePos( 'C1') + EMT.R2 = EgtGetAxisHomePos( 'B1') + -- aggiorno valori come precedenti + EmtUpdatePrev() + -- totalizzatori tempi e lunghezze + EMT.TOTCUTLEN = 0 + EMT.TOTCUTTIME = 0 + EMT.TOTEXTLEN = 0 + EMT.TOTEXTTIME = 0 + -- variabile per lunghezza taglio utensili + EMT.TOOLCUTLEN = {} + -- intestazioni + EmtTleStart( EMT.INFO) +end + +--------------------------------------------------------------------- +function OnEstimProgramEnd() + -- stampa dei totali delle lavorazioni + EmtTleAddTotal( EmtSecToHMS( EMT.TOTCUTTIME + EMT.TOTEXTTIME), EmtLenToMF( EMT.TOTCUTLEN)) + -- stampa dei totali degli utensili + for i = 1, #EMT.TOOLCUTLEN do + local TCL = EMT.TOOLCUTLEN[i] + EmtTleAddTool( TCL.Name, EmtLenToMF( TCL.Len)) + end + -- completo il file + local _, _, sExt = EgtSplitPath( EMT.FILE) + EmtTleEnd( sExt:sub( 2)) + -- salvo i dati principali nel progetto + EgtSetInfo( EgtGetCurrMachGroup(), 'Ttot', EgtNumToString( EMT.TOTCUTTIME + EMT.TOTEXTTIME, 0)) + EgtSetInfo( EgtGetCurrMachGroup(), 'Ltot', EgtNumToString( EMT.TOTCUTLEN, 0)) +end + +--------------------------------------------------------------------- +function OnEstimDispositionStart() + -- inizio disposizione + EMT.OPEISDISP = true + -- sulla prima fase dichiaro carico barra + if EMT.PHASE == 1 then + EMT.LOAD = true + else + EMT.LOAD = false + end +end + +--------------------------------------------------------------------- +function OnEstimDispositionEnd() + -- Se disposizione inizio o rimanenza + if IsStartOrRestPhase( EMT.PHASE) then + ; + -- se altrimenti disposizione intermedia, eventuale rotazione + elseif IsMidPhase( EMT.PHASE) then + -- recupero le rotazioni delle fasi corrente e precedente + local nRot = GetPhaseRot( EMT.PHASE) + local nPrevRot = GetPhaseRot( EMT.PHASE - 1) + -- verifico se sono diverse + if nRot ~= nPrevRot then + -- imposto stato post-rotazione + EMT.POSTROT = true + end + -- altrimenti disposizione finale, eventuale scarico pezzo lavorato se non ci sono lavorazioni + else + ; + end + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end + -- termine disposizione + EMT.OPEISDISP = false +end + +--------------------------------------------------------------------- +function OnEstimToolSelect() + -- reset indice utensile in tabella lunghezze + EMT.TCLIND = 0 + -- verifico che l'utensile sia definito + if #EMT.TOOL == 0 then return end + -- cerco l'utensile nella tabella + for i = 1, #EMT.TOOLCUTLEN do + if EMT.TOOLCUTLEN[i].Name == EMT.TOOL then + EMT.TCLIND = i + break + end + end + -- se non trovato, lo aggiungo + if EMT.TCLIND == 0 then + table.insert( EMT.TOOLCUTLEN, { Name = EMT.TOOL, Len = 0}) + EMT.TCLIND = #EMT.TOOLCUTLEN + end +end + +--------------------------------------------------------------------- +function OnEstimToolDeselect() +end + +--------------------------------------------------------------------- +function OnEstimMachiningStart() + EMT.MCHNAME = EgtGetOperationName( EMT.MCHID) + EMT.MCHTYPE = EgtGetMachiningParam( MCH_MP.TYPE) + EgtOutLog( 'Mach : ' .. EMT.MCHNAME, 5) + -- reset contatori di lavorazione + EMT.MCHCUTLEN = 0 + EMT.MCHCUTTIME = 0 + EMT.MCHEXTLEN = 0 + EMT.MCHEXTTIME = 0 +end + +--------------------------------------------------------------------- +function OnEstimMachiningEnd() + -- nel caso di foratura devo dimezzare la lunghezza di taglio perchè comprende anche l'uscita + if EMT.MCHTYPE == MCH_MY.DRILLING then + EMT.MCHCUTLEN = EMT.MCHCUTLEN / 2 + end + local sName = EgtGetName( EMT.MCHID) + EmtTleAddMachining( sName, EmtSecToHMS( EMT.MCHCUTTIME + EMT.MCHEXTTIME), EmtLenToMF( EMT.MCHCUTLEN), EMT.TOOL) + -- aggiorno totali e utensili + EMT.TOTCUTLEN = EMT.TOTCUTLEN + EMT.MCHCUTLEN + EMT.TOTCUTTIME = EMT.TOTCUTTIME + EMT.MCHCUTTIME + EMT.TOTEXTLEN = EMT.TOTEXTLEN + EMT.MCHEXTLEN + EMT.TOTEXTTIME = EMT.TOTEXTTIME + EMT.MCHEXTTIME + EMT.TOOLCUTLEN[EMT.TCLIND].Len = EMT.TOOLCUTLEN[EMT.TCLIND].Len + EMT.MCHCUTLEN + -- emetto dati in sospeso + if EMT.TLE_NAME then + EmtTleAddMachining( EMT.TLE_NAME, EmtSecToHMS( EMT.TLE_TIME), ' - ', ' - ') + EMT.TLE_NAME = nil + EMT.TLE_TIME = nil + end +end + +--------------------------------------------------------------------- +function OnEstimPathStart() + EMT.AUXTYPE = nil + EMT.MCHMOVEFIRST = true +end + +--------------------------------------------------------------------- +function OnEstimPathEnd() + EMT.AUXTYPE = nil +end + +--------------------------------------------------------------------- +function OnEstimPathStartAux() + -- se richiesto, preparo il carico barra + if EMT.LOAD then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Loading', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.LOAD = false + end + -- se altrimenti carico dopo rotazione + elseif EMT.POSTROT then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = ROTATION_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Rotation', EmtSecToHMS( dTime), ' - ', ' - ') + EMT.POSTROT = false + end + -- altrimenti, spostamento carrelli + else + if EMT.AUXTOT > 3 and EMT.AUXIND == EMT.AUXTOT then + local dTime = ( EMT.AUXTOT - 3) * CHAR_ONE_MOVE_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EmtTleAddMachining( 'Charriots move', EmtSecToHMS( dTime), ' - ', ' - ') + end + end +end + +--------------------------------------------------------------------- +function OnEstimPathEndAux() + -- verifico tipo di emissione + if EMT.OPEISDISP then + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + else + EMT.AUXTYPE = 'R' + end + end + else + if not EMT.AUXTYPE then + local Cmd = EgtSplitString( EMT.AUX) + if Cmd[1] == '0' and Cmd[2] == 'Split' then + EMT.AUXTYPE = 'S' + elseif Cmd[1] == '0' and Cmd[2] == 'Unloading' then + EMT.AUXTYPE = 'U' + elseif Cmd[1] == '0' and Cmd[2] == 'Fall' then + EMT.AUXTYPE = 'F' + else + EMT.AUXTYPE = 'P' + end + end + end + -- per lo scarico della rimanenza + if EMT.AUXTYPE == 'R' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = LOAD_T + UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Remnant unloading' + EMT.TLE_TIME = dTime + end + -- per lo split + elseif EMT.AUXTYPE == 'S' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = SPLIT_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Splitting' + EMT.TLE_TIME = dTime + end + -- per lo scarico + elseif EMT.AUXTYPE == 'U' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = UNLOAD_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Unloading' + EMT.TLE_TIME = dTime + end + -- per lo scarico a caduta + elseif EMT.AUXTYPE == 'F' then + if EMT.AUXIND == EMT.AUXTOT then + local dTime = FALL_T + EMT.TOTEXTTIME = EMT.TOTEXTTIME + dTime + EMT.TLE_NAME = 'Fall' + EMT.TLE_TIME = dTime + end + -- per la pre-rotazione + elseif EMT.AUXTYPE == 'P' then + ; -- calcolato come parte della rotazione + end +end + +--------------------------------------------------------------------- +function OnEstimRapid() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + local dR1 = 0 + if EMT.R1 and EMT.R1p then dR1 = EMT.R1 - EMT.R1p end + local dR2 = 0 + if EMT.R2 and EMT.R2p then dR2 = EMT.R2 - EMT.R2p end + -- se primo posizionamento della lavorazione il movimento di L1 è già conteggiato in quello dei carrelli + if EMT.MCHMOVEFIRST then + EMT.MCHMOVEFIRST = false + dL1 = 0 + end + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHEXTLEN = EMT.MCHEXTLEN + dLen + -- calcolo tempo + local dTime = RAPID_MIN_T + local dT1 = abs( dL1) / RAPID_X_FEED * 60 + if dT1 > dTime then dTime = dT1 end + local dT2 = abs( dL2) / RAPID_Y_FEED * 60 + if dT2 > dTime then dTime = dT2 end + local dT3 = abs( dL3) / RAPID_Z_FEED * 60 + if dT3 > dTime then dTime = dT3 end + local dT4 = abs( dR1) / RAPID_C_FEED * 60 + if dT4 > dTime then dTime = dT4 end + local dT5 = abs( dR2) / RAPID_B_FEED * 60 + if dT5 > dTime then dTime = dT5 end + EMT.MCHEXTTIME = EMT.MCHEXTTIME + dTime + EgtOutLog( string.format( ' G0 Len=%.0f Rot=%.0f° Time=%.2f', dLen, abs( dR1) + abs( dR2), dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimLinear() + -- dati movimento + local dL1 = EMT.L1 - EMT.L1p + local dL2 = EMT.L2 - EMT.L2p + local dL3 = EMT.L3 - EMT.L3p + -- calcolo lunghezza + local dLen = sqrt( dL1 * dL1 + dL2 * dL2 + dL3 * dL3) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G1 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +function OnEstimArc() + -- dati movimento + local dLxy = EMT.RR * abs( EMT.AC) * pi / 180 + local dLz = abs( ( Point3d( EMT.L1, EMT.L2, EMT.L3) - Point3d( EMT.L1p, EMT.L2p, EMT.L3p)) * Vector3d( EMT.EXTR)) + -- calcolo lunghezza + local dLen = sqrt( dLxy * dLxy + dLz * dLz) + EMT.MCHCUTLEN = EMT.MCHCUTLEN + dLen + -- calcolo tempo + local dTime = dLen / EMT.F * 60 + EMT.MCHCUTTIME = EMT.MCHCUTTIME + dTime + EgtOutLog( string.format( ' G2 Len=%.0f Time=%.2f', dLen, dTime), 5) + -- aggiorno valori come precedenti + EmtUpdatePrev() +end + +--------------------------------------------------------------------- +-- *** GENERAL *** +--------------------------------------------------------------------- +function IsStartPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START') +end + +--------------------------------------------------------------------- +function IsRestPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'REST') +end + +--------------------------------------------------------------------- +function IsStartOrRestPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'START' or sVal == 'REST') +end + +--------------------------------------------------------------------- +function IsMidPhase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'MID') +end + +--------------------------------------------------------------------- +function IsMid2Phase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'MID2') +end + +--------------------------------------------------------------------- +function IsEnd2Phase( nPhase) + local sVal = GetPhaseType( nPhase) + return ( sVal == 'END2') +end + +--------------------------------------------------------------------- +function GetPhaseType( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') or '') +end + +--------------------------------------------------------------------- +function GetPhaseOrd( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ORD', 'i') or 0) +end + +--------------------------------------------------------------------- +function GetPhaseRot( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) +end + +--------------------------------------------------------------------- +function GetParkT() + local dTmp = EgtGetInfo( EMT.DISPID, 'TPOS', 'd') or EgtGetInfo( EMT.DISPID, 'TPARK', 'd') + if dTmp then + return dTmp + else + return LoadT + end +end + +--------------------------------------------------------------------- +function GetHeadSet( sHead) + if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' then + return 1 + elseif sHead == 'H21' then + return 2 + else + return 0 + end +end + +--------------------------------------------------------------------- +function GetHeadSetFromTcPos( sTcPos) + local TCPOS_1A = { 'T1', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8', 'T9', 'T10'} + local TCPOS_1B = { 'T101'} + local TCPOS_1C = { 'T11', 'T12', 'T13', 'T14', 'T15', 'T16', 'T17', 'T18'} + local TCPOS_2 = { 'T20', 'T21', 'T22', 'T23', 'T24', 'T25', 'T26', 'T27', 'T28', 'T29', 'T30'} + for _, sVal in ipairs( TCPOS_1A) do + if sVal == sTcPos then return 1, 1 end + end + for _, sVal in ipairs( TCPOS_1B) do + if sVal == sTcPos then return 1, 2 end + end + for _, sVal in ipairs( TCPOS_1C) do + if sVal == sTcPos then return 1, 3 end + end + for _, sVal in ipairs( TCPOS_2) do + if sVal == sTcPos then return 2, 1 end + end + return 0, 0 +end + +--------------------------------------------------------------------- +function FindFirstToolOnHeadSet( nHSet) + -- salvo stato iniziale + local CurrMachId = EgtGetCurrMachining() + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- cerco lavorazione con utensile su gruppo testa indicato + local sTool, sHead, sTcPos + local OpId = EgtGetFirstActiveOperation() + while OpId do + local nType = EgtGetOperationType( OpId) + if nType ~= MCH_OY.NONE and nType ~= MCH_OY.DISP then + if EgtSetCurrMachining( OpId) then + local sTest = EgtGetMachiningParam( MCH_MP.TOOL) + if EgtTdbSetCurrTool( sTest) then + sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if GetHeadSet( sHead) == nHSet then + sTool = sTest + sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + break + end + end + end + end + OpId = EgtGetNextActiveOperation( OpId) + end + -- ripristino stato iniziale + EgtSetCurrMachining( CurrMachId or GDB_ID.NULL) + EgtTdbSetCurrTool( CurrTool or '') + -- restituisco risultato + return sTool, sHead, sTcPos +end + +--------------------------------------------------------------------- +function GetToolTcPos( sTool) + -- salvo stato iniziale + local CurrTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- recupero la posizione di cambio utensile dell'utensile indicato + local sTcPos + if EgtTdbSetCurrTool( sTool) then + sTcPos = EgtTdbGetCurrToolParam( MCH_TP.TCPOS) + end + -- ripristino stato iniziale + EgtTdbSetCurrTool( CurrTool or '') + -- restituisco risultato + return sTcPos +end + +--------------------------------------------------------------------- +function GetCurrChainSawingVirtualAxis() + -- recupero il valore dell'asse virtuale bloccato A + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) or 'A=0' + local dPosA = tonumber( sVal:sub( 3)) or 0 + return dPosA +end + +--------------------------------------------------------------------- +function GetNextChainSawingVirtualAxis( MchId) + -- recupero la lavorazione successiva + local NextMchId + if MchId then + NextMchId = EgtGetNextActiveOperation( MchId) + else + NextMchId = EgtGetFirstActiveOperation() + end + while NextMchId and EgtGetOperationType( NextMchId) == MCH_OY.DISP do + NextMchId = EgtGetNextActiveOperation( NextMchId) + end + -- verifico sia un taglio con sega a catena + if EgtGetOperationType( NextMchId) ~= MCH_OY.MORTISING then + return nil + end + -- la imposto come lavorazione corrente + EgtSetCurrMachining( NextMchId) + -- recupero il valore dell'asse virtuale bloccato A + local dPosA = GetCurrChainSawingVirtualAxis() + -- ripristino la lavorazione corrente + if MchId then + EgtSetCurrMachining( MchId) + end + return dPosA +end + +--------------------------------------------------------------------- +function GetStartMachiningXaxis( nMchId) + -- Recupero quota X (nostro -L2) + local nClEntId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nMchId, 'CL') or GDB_ID.NULL, 'P1') or GDB_ID.NULL) + local vAxes = EmtGetAxesPos( nClEntId or GDB_ID.NULL) + if vAxes and #vAxes >= 2 then + return -vAxes[2] + else + return nil + end +end + +--------------------------------------------------------------------- +function RollerParkingNeeded( sHead, dAng1p, dAng2p, dAng1, dAng2) + if sHead == 'H11' or sHead == 'H12' or sHead == 'H13' then + return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1 % 180.0) > 1)) + elseif sHead == 'H21' then + return ( abs( dAng1 - dAng1p) > 1 or ( abs( dAng2 - dAng2p) > 1 and abs( dAng1 % 180.0) > 1)) + end +end + +--------------------------------------------------------------------- +function GetCmdAxMove( Cmd, sAx) + if #Cmd >= 3 and Cmd[2] == sAx then + return tonumber( Cmd[3]) + elseif #Cmd >= 5 and Cmd[4] == sAx then + return tonumber( Cmd[5]) + elseif #Cmd >= 7 and Cmd[6] == sAx then + return tonumber( Cmd[7]) + end +end + +--------------------------------------------------------------------- +-- *** END GENERAL *** diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.mlse b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.mlse new file mode 100644 index 0000000..85c89db --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.mlse @@ -0,0 +1,2510 @@ +-- Special Operations macchina Essetre-PF1250 by EgalTech s.r.l. 2021/10/03 +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +-- Carico i dati globali +local sBaseDir = EgtGetSourceDir() +local BD = dofile( sBaseDir .. 'Beam\\BeamData.lua') + +EgtOutLog ( '** Essetre-PF1250 '..PP_VER..' **', 1) + + +---------------------- OnSpecialMoveZup ----------------------------- +--------------------------------------------------------------------- +function OnSpecialMoveZup() + + --EgtOutLog( 'OnSpecialMoveZup : ' .. EMC.HEAD .. '.' .. tostring( EMC.EXIT)) + + -- Inizializzazioni + EMC.ERR = 0 + EMC.MODIF = false + + -- recupero Z1 home + local dZmax = EgtGetAxisHomePos( 'Z1') + + --EgtOutLog( string.format( 'Zhome=%.3f L3=%.3f R2=%.3f Flag=%i', dZmax, EMC.L3, EMC.R2, EMC.FLAG)) + + -- se fresa su testa1 + if EMC.HEAD == 'H11' then + local Z_EXTRA = 250 + -- se inclinata oltre 90 gradi + if abs( EMC.R2) > 89.9 then + -- se troppo in alto + if EMC.L3 > dZmax - 30 then + -- sistemo asse rotante + EMC.R2 = EgtIf( ( EMC.R2 > 0), 90, -90) + -- ricalcolo versore utensile + EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2) + -- porto alla giusta quota + EMC.L3 = dZmax + -- dichiaro modificato + EMC.MODIF = true + end + -- se inclinata oltre i 60 gradi + elseif abs( EMC.R2) > 60 then + local dZref = dZmax + Z_EXTRA * ( 90 - abs( EMC.R2)) / 30 + -- se troppo in basso + if EMC.L3 < dZref - 0.1 then + if ( EMC.FLAG == 2 or EMC.FLAG == 3) and EMC.FLAG2 == 1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + -- se troppo alto + elseif EMC.L3 > dZref + 0.1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + -- altrimenti inclinata meno di 60 gradi + else + local dZref = dZmax + Z_EXTRA + -- se troppo in basso + if EMC.L3 < dZref - 0.1 then + if ( EMC.FLAG == 2 or EMC.FLAG == 3) and EMC.FLAG2 == 1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + -- se troppo alto + elseif EMC.L3 > dZref + 0.1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + end + -- se lama su testa1 + elseif EMC.HEAD == 'H12' then + local Z_EXTRA = 160 + -- se inclinata oltre 90 gradi + if abs( EMC.R2) > 89.9 then + -- se troppo in alto + if EMC.L3 > dZmax - 100 then + -- sistemo asse rotante + EMC.R2 = EgtIf( ( EMC.R2 > 0), 90, -90) + -- ricalcolo versore utensile + EMC.TDIR = EgtGetCalcToolDirFromAngles( EMC.R1, EMC.R2) + -- porto alla giusta quota + EMC.L3 = dZmax + -- dichiaro modificato + EMC.MODIF = true + end + -- se inclinata oltre i 60 gradi + elseif abs( EMC.R2) > 60 then + local dZref = dZmax + Z_EXTRA * ( 90 - abs( EMC.R2)) / 30 + -- se troppo in basso + if EMC.L3 < dZref - 0.1 then + --if ( EMC.FLAG == 2 or EMC.FLAG == 3) and EMC.FLAG2 == 1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + --end + -- se troppo alto + elseif EMC.L3 > dZref + 0.1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + -- altrimenti inclinata meno di 60 gradi + else + local dZref = dZmax + Z_EXTRA + -- se troppo in basso + if EMC.L3 < dZref - 0.1 then + --if ( EMC.FLAG == 2 or EMC.FLAG == 3) and EMC.FLAG2 == 1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + --end + -- se troppo alto + elseif EMC.L3 > dZref + 0.1 then + -- porto alla giusta quota + EMC.L3 = dZref + -- dichiaro modificato + EMC.MODIF = true + end + end + end +end + + +---------- OnSpecialApplyDisposition & OnPostApplyMachining --------- +----------------------- Costanti ------------------------------------ +local DELTA_SIC = 1 +local MinJoin = BD.MIN_JOIN_S +local MinOther = abs( MinY1) + abs( MaxY2) + MinJoin +local SIC_V = 50 -- sicurezza da testa +local MIN_FRONT_ENG_V = 161 -- ingombro asse Z con cremagliera a destra +local MIN_BACK_ENG_V = 115 -- ingombro asse Z a sinistra +local AGG_V = MinDeltaYV -- ingombro rulli pressori + sicurezza +local MaxLenSmT = 1500 -- massima lunghezza pezzo scaricato con nastri verdi + +----------------------- Variabili ----------------------------------- +local Test = false +local SPLIT + +--------------------------------------------------------------------- +local function PrepareClGroup( nParentId) + + local nClId = EgtGetFirstNameInGroup( nParentId, 'CL') + -- se non c'è, lo aggiungo + if not nClId then + nClId = EgtGroup( EMC.DISPID) + if not nClId then + return nil + end + EgtSetName( nClId, 'CL') + -- altrimenti lo svuoto + else + EgtEmptyGroup( nClId) + end + + return nClId +end + +--------------------------------------------------------------------- +local function IsStartOrRestPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'START' or sVal == 'REST') +end + +--------------------------------------------------------------------- +local function IsMidPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'MID') +end + +--------------------------------------------------------------------- +local function IsEndPhase( nPhase) + local sVal = EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'TYPE') + return ( sVal == 'END') +end + +--------------------------------------------------------------------- +local function GetNextStartOrRestPhase( nPhase) + local nNextPhase = nPhase + 1 + while nNextPhase <= EgtGetPhaseCount() do + if IsStartOrRestPhase( nNextPhase) then + break ; + end + nNextPhase = nNextPhase + 1 + end + return nNextPhase +end + +--------------------------------------------------------------------- +function GetPhaseRot( nPhase) + return ( EgtGetInfo( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL, 'ROT', 'i') or 0) +end + +--------------------------------------------------------------------- +local function IsLastMachiningBeforeRotation( nMchId) + -- se ultima fase, ritorno risultato negativo + if EMC.PHASE == EgtGetPhaseCount() then + return false + end + -- recupero la successiva operazione attiva + local nNextOperId = EgtGetNextActiveOperation( nMchId) + -- se non esiste o non è una disposizione, ritorno risultato negativo + if not nNextOperId or EgtGetOperationType( nNextOperId) ~= MCH_OY.DISP then + return false + end + -- recupero le rotazioni della fase corrente e della prossima fase + local nRot = GetPhaseRot( EMC.PHASE) + local nNextRot = GetPhaseRot( EMC.PHASE + 1) + -- ritorno se sono diverse + return ( nRot ~= nNextRot) +end + +--------------------------------------------------------------------- +local function IsFirstMachiningAfterRotation( nMchId) + -- se prima fase, ritorno risultato negativo + if EMC.PHASE == 1 then + return false + end + -- recupero la precedente operazione attiva + local nPrevOperId = EgtGetPrevActiveOperation( nMchId) + -- se non esiste o non è una disposizione, ritorno risultato negativo + if not nPrevOperId or EgtGetOperationType( nPrevOperId) ~= MCH_OY.DISP then + return false + end + -- recupero le rotazioni della fase corrente e della fase precedente + local nRot = GetPhaseRot( EMC.PHASE) + local nPrevRot = GetPhaseRot( EMC.PHASE - 1) + -- ritorno se sono diverse + return ( nRot ~= nPrevRot) +end + +--------------------------------------------------------------------- +local function UpdateMinJoin() + MinJoin = BD.GetMinJoin( EMC.SB, EMC.HB, EMC.LB) + MinOther = abs( MinY1) + abs( MaxY2) + MinJoin +end + +--------------------------------------------------------------------- +local function GetCUTID() + -- recupero CUTID del pezzo in lavoro + local nOrd = GetPhaseOrd( EMC.PHASE) + local nPartRawId + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nOrd then + nPartRawId = nRawId + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + local CutID = EgtGetInfo( EgtGetFirstPartInRawPart( nPartRawId or GDB_ID.NULL) or GDB_ID.NULL, 'CUTID', 'i') or 0 + return CutID +end + +--------------------------------------------------------------------- +local function GetNextRawInOrd( nCurrRawId) + local nCurrOrd = EgtGetInfo( nCurrRawId, 'ORD', 'i') + if not nCurrOrd then return end + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nRawOrd = EgtGetInfo( nRawId, 'ORD', 'i') + if nRawOrd == nCurrOrd + 1 then + return nRawId + end + nRawId = EgtGetNextRawPart( nRawId) + end +end + +----------------------------------------------------------------------- +local function EnsureZmax( bCloseV, vCmd) + -- posizionamento sicuro teste e rulli + table.insert( vCmd, { 4, EgtIf( bCloseV, 1, 0)}) + if EMC.MCHID then + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + if not sNotes:find( 'StartZmax=2', 1, true) then + sNotes = EgtAdjustNotes( sNotes, 'StartZmax=', '2') + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + EgtSetInfo( EgtGetCurrMachGroup(), 'RECALC', '1') + end + end + return true +end + +----------------------------------------------------------------------- +local function EnsureZmaxAtEnd( vCmd) + -- posizionamento sicuro teste e rulli + table.insert( vCmd, { 4, 0}) +end + +----------------------------------------------------------------------- +local function EmitComment( vCmd, sOut) + EgtOutLog( ' ' .. sOut) + if Test then + table.insert( vCmd, { 0, sOut}) + end +end + +--------------------------------------------------------------------- +function OnSpecialApplyDisposition() + + EgtOutLog( ' *** Fase : ' .. EgtNumToString( EMC.PHASE, 0) .. ' ***') + + -- Inizializzo codice di errore + EMC.ERR = 0 + + -- Campi obbligatori ma non usati + EMC.HEAD = "H14" + EMC.EXIT = 1 + EMC.TCPOS = "" + EMC.SHIFTS = 0 + EMC.SBH = false + + -- Se disposizione da saltare non devo fare alcunché + if EgtExistsInfo( EMC.DISPID, 'SKIP') then return end + + -- Assegno flag di pezzo separato dal resto del grezzo + SPLIT = IsEndPhase( EMC.PHASE) + + -- Recupero il tipo dell'operazione successiva + local nNextOpeType = EgtGetOperationType( EgtGetNextActiveOperation( EMC.DISPID) or GDB_ID.NULL) + + -- Se ci sono lavorazioni successive non devo fare alcunché + if nNextOpeType ~= MCH_OY.NONE and nNextOpeType ~= MCH_OY.DISP then return end + + -- Imposto gruppo e path di movimento + local nClId = PrepareClGroup( EMC.DISPID) + if not nClId then + EMC.ERR = 3 + EMC.MSG = ' Error : creation CL group failed' + return + end + local nPathId = EgtGroup( nClId) + if not nPathId then + EMC.ERR = 6 + EMC.MSG = ' Error : creation path in CL group failed' + return + end + EgtSetName( nPathId, 'Empty') + EMC.PATHID = nPathId + EMC.SHIFTS = -1 + + -- Se la lavorazione successiva è ancora una disposizione, devo scaricare il pezzo + if nNextOpeType == MCH_OY.DISP and SPLIT then + -- aggiornamento posizioni + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') + EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') + EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1 + EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2 + EMC.CNT = SpecGetCNT( EMC.DISPID) + -- Determinazione delle dimensioni del grezzo in lavoro + local b3Raw = BBox3d() + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) and not EgtVerifyRawPartPhase( nRawId, EMC.PHASE + 1) then + b3Raw = EgtGetRawPartBBox( nRawId) + break + end + nRawId = EgtGetNextRawPart( nRawId) + end + EMC.LB = b3Raw:getDimX() + -- Eseguo scarico + local vCmd = SpecCalcUnload() + SpecOutputCmds( vCmd, true) + return + end + + -- Verifico ci sia un solo grezzo nella fase corrente + local nRawCount = 0 + local nCurrRawId = GDB_ID.NULL + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + nRawCount = nRawCount + 1 + nCurrRawId = nRawId + end + nRawId = EgtGetNextRawPart( nRawId) + end + if nRawCount > 1 then + EMC.ERR = 10 + EMC.MSG = ' Error : too many Raw Parts in current Phase' + return + end + + -- Determinazione delle sue dimensioni + local b3Raw = EgtGetRawPartBBox( nCurrRawId) + if b3Raw:isEmpty() then + EMC.ERR = 11 + EMC.MSG = ' Error : null Raw Part' + return + end + EMC.LB = b3Raw:getDimX() + EMC.SB = b3Raw:getDimY() + EMC.HB = b3Raw:getDimZ() + + -- Aggiorno limiti di presa + UpdateMinJoin() + + -- Assegno sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = 0 + EMC.HCING = 0 + EMC.TCING = 0 + + -- Devo scaricare il grezzo rimasto (deve essere unico) + -- Posizione trave + local dPosT + + -- Se fase 1 eseguo carico con carrello Y + local vCmd = {} + if EMC.PHASE == 1 then + dPosT = LoadT + vCmd = SpecCalcLoad( dPosT, 0, 0) + -- se altrimenti fase successiva alla prima di tipo inizio o rimanenza + elseif IsStartOrRestPhase( EMC.PHASE) then + -- recupero posizione trave e quota di aggancio carrello + dPosT = EgtGetInfo( EMC.DISPID, 'TPOS', 'd') + local dPosY1 = EgtGetInfo( EMC.DISPID, 'Y1POS', 'd') + if not dPosY1 then + EMC.ERR = 14 + EMC.MSG = ' Error : Y1 non clamped (start or rest)' + return + end + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dPosY1 - dPosT, 0}) + -- recupero posizione rulli + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + -- recupero contatore pinza 1 + EMC.CNT = SpecGetCNT( EMC.DISPID) + -- altrimenti fase successiva pari + else + EMC.Y2DELTA = EgtGetInfo( EMC.DISPID, 'Y2POS', 'd') + EMC.V1POS = EgtGetInfo( EMC.DISPID, 'V1POS', 'd') + EMC.V2POS = EgtGetInfo( EMC.DISPID, 'V2POS', 'd') + -- recupero contatore pinza 1 + EMC.CNT = SpecGetCNT( EMC.DISPID) + end + -- Se fase inizio o rimanenza, eseguo scambio per avere solo pinza V + local vCmd2 = {} + if IsStartOrRestPhase( EMC.PHASE) then + EMC.TPOS = dPosT + SpecSetCarrPosFromCmds( vCmd) + local dDistFront = EMC.LB - MinJoin + 10 * GEO.EPS_SMALL + local dDistBack = 0 + local dY2DeltaMinUL = EMC.LB + MinY2 - EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) + vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, -EMC.V2POS, EMC.V1POS, nil, dY2DeltaMinUL) + if vCmd and #vCmd > 1 and vCmd2 and #vCmd2 > 1 and SpecTestSomeMoveInCmds( vCmd2) then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + end + -- eseguo scarico + SpecSetCarrPosFromCmds( vCmd2) + local vCmd3 = SpecCalcUnload() + -- unisco ed emetto i comandi + vCmd = EgtJoinTables( vCmd, vCmd2) + vCmd = EgtJoinTables( vCmd, vCmd3) + SpecOutputCmds( vCmd, true) +end + +--------------------------------------------------------------------- +function OnPostApplyMachining() + + EgtOutLog( ' Lavorazione : ' .. EgtGetName( EMC.MCHID) .. ' (' .. tostring( EMC.MCHID) .. ')') + + -- Inizializzo codice di errore + EMC.ERR = 0 + + -- Recupero la posizione della trave e dei carrelli al termine della precedente operazione + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.MCHID) + -- se precedente operazione non esiste, errore + if not nPrevOpeId then + EMC.ERR = 1 + EMC.MSG = ' Error : previous Disposition not found' + return + -- se precedente operazione è disposizione + elseif EgtGetOperationType( nPrevOpeId) == MCH_OY.DISP then + if EMC.PHASE == 1 or ( IsMidPhase( EMC.PHASE) and IsFirstMachiningAfterRotation( EMC.MCHID)) then + -- posizioni home + EMC.TPOS = nil + EMC.Y1DELTA = nil + EMC.Y2DELTA = nil + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + EMC.CNT = nil + elseif IsStartOrRestPhase( EMC.PHASE) then + -- carico le posizioni + local dPosT = EgtGetInfo( nPrevOpeId, 'TPOS', 'd') + local dPosY = EgtGetInfo( nPrevOpeId, 'Y1POS', 'd') + EMC.TPOS = dPosT + EMC.Y1DELTA = dPosY - dPosT + EMC.Y2DELTA = nil + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + EMC.CNT = SpecGetCNT( EMC.MCHID) + else + -- aggiornamento posizioni (da lavorazione precedente a disposizione) + local nPrev2OpeId = EgtGetPrevActiveOperation( nPrevOpeId) + if not nPrev2OpeId then + EMC.ERR = 1 + EMC.MSG = ' Error : previous Disposition not found' + return + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrev2OpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') + EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') + EMC.V1POS = EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1 + EMC.V2POS = EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2 + EMC.CNT = SpecGetCNT( EMC.MCHID) + end + -- altrimenti precedente operazione è lavorazione + else + -- aggiornamento posizioni + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + local nLastEntId = EgtGetLastInGroup( nLastPathId) + local bAtZMax = ( EgtGetClEntMove( nLastEntId) == 0 and EgtGetClEntFlag( nLastEntId) == 3) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + EMC.Y1DELTA = EgtGetInfo( nLastPathId, 'Y1DELTA', 'd') + EMC.Y2DELTA = EgtGetInfo( nLastPathId, 'Y2DELTA', 'd') + EMC.V1POS = EgtIf( bAtZMax, ParkV1, EgtGetInfo( nLastPathId, 'V1POS', 'd') or ParkV1) + EMC.V2POS = EgtIf( bAtZMax, ParkV2, EgtGetInfo( nLastPathId, 'V2POS', 'd') or ParkV2) + EMC.CNT = SpecGetCNT( EMC.MCHID) + end + + -- Verifico se ultima lavorazione della fase + local nNextOpeId = EgtGetNextActiveOperation( EMC.MCHID) + local bMchLast = ( not nNextOpeId or EgtGetOperationPhase( nNextOpeId) ~= EMC.PHASE) + + -- Verifico se ultima lavorazione prima di una rotazione + local bPreRotMch = IsLastMachiningBeforeRotation( EMC.MCHID) and not IsEndPhase( EMC.PHASE) + + -- Verifico flag di separazione e fase di scarico + local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + local bPreSplit = ( false and sNotes:find( 'Presplit', 1, true) ~= nil) + local bSplitting = ( sNotes:find( 'Split', 1, true) ~= nil) + local bPreCut = ( sNotes:find( 'Precut', 1, true) ~= nil) + local bCutting = ( sNotes:find( 'Cut', 1, true) ~= nil) + local bUnload = IsEndPhase( EMC.PHASE) + + -- Agisco sui diversi percorsi della lavorazione + local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( EMC.MCHID, 'CL') or GDB_ID.NULL) + while nPathId do + -- assegno id percorso da elaborare + EMC.PATHID = nPathId + -- recupero id del successivo + nPathId = EgtGetNext( nPathId) + -- verifico se ultimo percorso di ultima lavorazione della fase + local bLast = ( bMchLast and ( not nPathId)) + -- se ultimo, elimino ritorno in home + if bLast then EgtRemoveOperationHome( EMC.MCHID) end + -- salvo lo stato dei carrelli + local OriTPos = EMC.TPOS + local OriY1Delta = EMC.Y1DELTA + local OriY2Delta = EMC.Y2DELTA + local OriV1Pos = EMC.V1POS + local OriV2Pos = EMC.V2POS + local OriCnt = EMC.CNT + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) + -- se separazione, verifico il risultato + if bSplitting then + -- recupero CUTID del pezzo in lavoro + local CutID = GetCUTID() + -- in caso di errore mancato pinzaggio uscita riprovo dopo aver disabilitato le lavorazioni finali + if EMC.ERR == 18 then + -- segnalazione warning + EMC.ERR = -101 + EMC.MSG = 'Warning : skipped final processes (WRN=101,CUTID='..tostring( CutID)..')' + -- ripristino lo stato originale dei carrelli + EMC.TPOS = OriTPos + EMC.Y1DELTA = OriY1Delta + EMC.Y2DELTA = OriY2Delta + EMC.V1POS = OriV1Pos + EMC.V2POS = OriV2Pos + EMC.CNT = OriCnt + -- eseguo le elaborazioni + SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bLast and bUnload, bLast and bPreRotMch) + -- pinzaggio ancora impossibile, pezzo a caduta + if EMC.ERR == 18 then + -- segnalazione warning + EMC.ERR = -102 + EMC.MSG = 'Warning : skipped final processes and unload by fall (WRN=102,CUTID='..tostring( CutID)..')' + end + -- scarico standard + elseif EMC.ERR == 0 then + -- segnalazione warning + EMC.ERR = -100 + EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' + end + -- se taglio del residuo finale, scarico standard + elseif bCutting then + -- recupero CUTID del pezzo in lavoro + local CutID = GetCUTID() + -- se non ci sono errori, segnalazione warning + if EMC.ERR == 0 then + EMC.ERR = -100 + EMC.MSG = 'Warning : standard unload (WRN=100,CUTID='..tostring( CutID)..')' + end + end + if EMC.ERR > 0 then return end + -- determino la posizione finale della trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + end + +end + +--------------------------------------------------------------------- +function SpecApplyPath( bPreSplit, bSplitting, bPreCut, bCutting, bUnload, bPreRotMch) + + -- Verifico se lavorazione pareti + local bWall = ( EgtGetInfo( EgtGetCurrMachGroup() or GDB_ID.NULL, 'Wall', 'd') == 1) + + -- Assegno flag di pezzo separato dal resto del grezzo + SPLIT = IsEndPhase( EMC.PHASE) + + -- Determinazione delle dimensioni totali dei grezzi e del grezzo in lavoro + local b3Tot = BBox3d() + local b3Raw = BBox3d() + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + local nCurrRawId = GDB_ID.NULL + while nRawId do + if EgtVerifyRawPartPhase( nRawId, EMC.PHASE) then + local b3Tmp = EgtGetRawPartBBox( nRawId) + b3Tot:Add( b3Tmp) + if EgtGetPartInRawPartCount( nRawId) > 0 and not EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + b3Raw = b3Tmp + nCurrRawId = nRawId + end + end + nRawId = EgtGetNextRawPart( nRawId) + end + if b3Tot:isEmpty() then + EMC.ERR = 11 + EMC.MSG = ' Error : null Raw Parts' + return + end + EMC.LB = EgtIf( SPLIT, b3Raw:getDimX(), b3Tot:getDimX()) + EMC.SB = b3Tot:getDimY() + EMC.HB = b3Tot:getDimZ() + EMC.LT = b3Raw:getDimX() + + -- Aggiorno limiti di presa + UpdateMinJoin() + + -- Recupero sovramateriale di testa e ingombro tagli di testa e di coda + EMC.HOVM = EgtGetInfo( nCurrRawId, 'HOVM', 'd') or 0 + EMC.HCING = EgtGetInfo( nCurrRawId, 'HCING', 'd') or 0 + EMC.TCING = EgtGetInfo( nCurrRawId, 'TCING', 'd') or 0 + -- Recupero ingombro dei tagli di testa del prossimo pezzo (se esiste) + EMC.NEXT_HCING = 0 + local nNextRawId = GetNextRawInOrd( nCurrRawId) + if nNextRawId then + EMC.NEXT_HCING = EgtGetInfo( nNextRawId, 'HCING', 'd') or 0 + end + + -- Calcolo dell'ingombro della lavorazione + local dDistFront, dDistBack, dRollFront, dRollBack = SpecialCalcMachiningEncumbrance( EMC.MCHID, bPreCut) + if not dDistFront then return end + if bPreSplit or bSplitting then + local dDistF, dDistB, dRollF, dRollB = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + dDistBack = dDistBack + elseif bPreCut or bCutting then + local dDistF, dDistB, dRollF, dRollB = SpecialCalcPhaseEncumbrance( EMC.PHASE + 1) + dDistFront = min( dDistFront, dDistF) + dDistBack = min( dDistBack, dDistB) + end + + -- Verifico lunghezza pezzo + if not SPLIT and not VerifyPartLength() then + return + end + + -- Calcolo quali carrelli sono necessari + local nChar + if bPreSplit or bSplitting then + nChar = 2 + elseif bPreCut or bCutting then + nChar = 3 + end + local dY1DeltaMaxSP + if nChar == 2 then + dY1DeltaMaxSP = MaxY1 - LoadT + EMC.LT + end + local dY2DeltaMinUL + if ( nChar == 2 or nChar == 3) and not bWall then + dY2DeltaMinUL = EMC.LT + MinY2 - EgtIf( EMC.LT < MaxLenSmT, UnloadSmT, UnloadT) + end + + -- Se inizio o appena dopo rotazione, eseguo il carico + if not EMC.TPOS then + local dPosT = LoadT + if IsFirstMachiningAfterRotation( EMC.MCHID) then dPosT = dPosT + TurnerOffs end + local vCmd = SpecCalcLoad( dPosT, dDistFront, max( dDistBack, MinJoin, EMC.LB - ( MaxY1 - MinY1) + 6)) + local vCmd2 = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar) + if bSplitting and EMC.ERR == 18 then + table.insert( vCmd, { 22, dRollBack, -dRollFront}) + end + if vCmd2 and #vCmd2 > 1 and SpecTestSomeMoveInCmds( vCmd2) then + table.insert( vCmd, { 0, 'CARR_MOVE'}) + end + EgtJoinTables( vCmd, vCmd2) + SpecOutputCmds( vCmd) + + -- Se altrimenti non eseguito SPLIT, eseguo calcoli per carrelli + elseif not SPLIT then + local vCmd = SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar) + -- Se non ci sono spostamenti, confermo i parametri di aggancio e di posizione roller + if SpecTestOnlyRemarkInCmds( vCmd) then + table.insert( vCmd, { 21, EgtIf( EMC.Y1DELTA, EMC.Y1DELTA, 0), EgtIf( EMC.Y2DELTA, EMC.Y2DELTA, 0)}) + table.insert( vCmd, { 22, dRollBack, -dRollFront}) + end + SpecOutputCmds( vCmd) + + -- Altrimenti, non muovo i carrelli rispetto alla trave ma impongo la posizione dei rulli + else + local vCmd = {} + table.insert( vCmd, { 21, EgtIf( EMC.Y1DELTA, EMC.Y1DELTA, 0), EgtIf( EMC.Y2DELTA, EMC.Y2DELTA, 0)}) + table.insert( vCmd, { 22, dRollBack, -dRollFront}) + SpecOutputCmds( vCmd) + end + + -- Se taglio di separazione + local vCmd = {} + if bSplitting then + -- rimuovo eventuale vecchia info di Skip + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) or GDB_ID.NULL + EgtRemoveInfo( NextDispId, 'SKIP') + -- verifico se separazione con caduta + if not EMC.Y2DELTA then + EgtOutLog( ' Warning SPLITTING -> separazione con caduta pezzo') + SpecOutputCNT() + if IsEndPhase( EMC.PHASE + 1) then + EgtSetInfo( NextDispId, 'SKIP', '1') + local NextOpeId = EgtGetNextOperation( NextDispId) + while NextOpeId and EgtGetOperationPhase( NextOpeId) == EMC.PHASE + 1 do + EgtSetOperationMode( NextOpeId, false) + NextOpeId = EgtGetNextOperation( NextOpeId) + end + end + -- rimane impostato l'errore 18 + -- verifico che la barra sia agganciata ad entrambi i carrelli + elseif not EMC.Y1DELTA or not EMC.Y2DELTA then + EMC.ERR = 19 + EMC.MSG = ' Error SPLIT : Y1 or Y2 not clamped' + return false + end + -- eseguo la separazione + local dMaxLenLeft = EMC.LT - dDistFront - AGG_V - dRollFront + EgtOutLog( 'MaxLenLeft=' .. EgtNumToString( dMaxLenLeft, 1)) + vCmd = SpecCalcSplit( b3Raw:getDimX(), dMaxLenLeft) + end + -- Se taglio finale di grezzo a perdere + if bCutting then + -- salvo distanza carrello Y2 da inizio grezzo rimasto nella disposizione della prossima fase + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if NextDispId then + EgtSetInfo( NextDispId, 'Y2POS', EMC.Y2DELTA) + EgtSetInfo( NextDispId, 'V1POS', EMC.V1POS) + EgtSetInfo( NextDispId, 'V2POS', EMC.V2POS) + end + end + + -- Se previsto scarico, lo eseguo + if bUnload then + EMC.LB = b3Raw:getDimX() + local vCmdTmp = SpecCalcUnload() + vCmd = EgtJoinTables( vCmd, vCmdTmp) + end + + -- Se ritorno al carico per rotazione + if bPreRotMch then + local vCmdTmp = SpecCalcPreRot() + vCmd = EgtJoinTables( vCmd, vCmdTmp) + end + + -- Emetto eventuali comandi di separazione e/o scarico + if #vCmd > 0 then + SpecOutputCmds( vCmd, true) + end + +end --SpecApplyPath( bLast) + +--------------------------------------------------------------------- +function SpecialCalcMachiningEncumbrance( nMchId, bPreCut) + -- gruppi della lavorazione + local nClId = EgtGetFirstNameInGroup( nMchId, 'CL') + local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) + if not nPathId then + EMC.ERR = 12 + EMC.MSG = ' Error : CL group path not found' + return + end + -- recupero ptMin ptMax della lavorazione + local ptMin = EgtGetInfo( nClId, 'MMIN', 'p') + local ptMax = EgtGetInfo( nClId, 'MMAX', 'p') + if not ptMin or not ptMax then + EMC.ERR = 13 + EMC.MSG = ' Error : machining Min or Max not found' + return + end + -- se pre-taglio, aggiorno ptMax con quello del taglio finale + if bPreCut then + local ptFinMax = GetFinalCutPmax( nMchId) + if ptFinMax then + ptMax = ptFinMax + end + end + -- Recupero testa + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + -- Recupero valore assi macchina + local nSecId = EgtGetNext( EgtGetFirstInGroup( nPathId)) + local vAxes = EmtGetAxesPos( nSecId) + if not vAxes or #vAxes < 5 or ( sHead == 'H13' and #vAxes < 6) then + EMC.ERR = 15 + EMC.MSG = ' Error : machine axes values not found' + return + end + -- Calcolo dell'ingombro della testa rispetto allo Zero Macchina + local b3Enc + if sHead ~= 'H21' then + EgtSetAxisPos( 'C1', vAxes[4]) + EgtSetAxisPos( 'B1', vAxes[5]) + if sHead == 'H13' then + EgtSetAxisPos( 'A', vAxes[6]) + end + b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C1'), GDB_BB.ONLY_VISIBLE) + else + EgtSetAxisPos( 'C2', vAxes[4]) + EgtSetAxisPos( 'B2', vAxes[5]) + b3Enc = EgtGetBBoxGlob( EgtGetAxisId( 'C2'), GDB_BB.ONLY_VISIBLE) + end + local dRollFront = max( b3Enc:getMax():getX(), MIN_FRONT_ENG_V) + SIC_V + local dRollBack = max( -b3Enc:getMin():getX(), MIN_BACK_ENG_V) + SIC_V + EgtOutLog( ' RollFront = ' .. EgtNumToString( dRollFront, 1) .. ' RollBack = ' .. EgtNumToString( dRollBack, 1), 3) + -- Calcolo della posizione della Punta Utensile rispetto allo Zero Macchina + local ptTip + ptTip = EgtGetCalcTipFromPositions( 0, 0, 0, vAxes[4], vAxes[5], vAxes[6] or 0, false) + EgtOutLog( ' ToolTip = ' .. tostring( ptTip), 5) + -- Calcolo dell'ingombro della testa rispetto alla Punta Utensile + local dHeadFront = dRollFront + AGG_V - ptTip:getX() + local dHeadBack = dRollBack + AGG_V + ptTip:getX() + EgtOutLog( ' HeadFront = ' .. EgtNumToString( dHeadFront, 1) .. ' HeadBack = ' .. EgtNumToString( dHeadBack, 1), 5) + -- Distanze limiti della pinza di destra da testa trave e della pinza di sinistra da coda trave + local dDistFront = - ptMax:getX() - LoadT - dHeadFront + local dDistBack = ptMin:getX() + LoadT + EMC.LB - dHeadBack + EgtOutLog( ' DistFront = ' .. EgtNumToString( dDistFront, 1) .. ' DistBack = ' .. EgtNumToString( dDistBack, 1), 3) + return dDistFront, dDistBack, dRollFront, dRollBack +end + +--------------------------------------------------------------------- +function SpecialCalcPhaseEncumbrance( nPhase) + -- Deve essere la fase finale di lavorazione di un pezzo (già staccato dal resto della trave) + local dDistFront = EMC.LB + local dDistBack = EMC.LB + local dRollFront = 0 + local dRollBack = 0 + -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine + local nOrigMchId = EgtGetCurrMachining() + local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + local sOrigHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + -- Ciclo sulle lavorazioni + local nMchId = EgtGetNextActiveOperation( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL) + while nMchId and EgtGetOperationPhase( nMchId) == nPhase do + -- imposto lavorazione e utensile correnti + EgtSetCurrMachining( nMchId) + local sTool = EgtGetMachiningParam( MCH_MP.TOOL) + EgtTdbSetCurrTool( sTool) + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + EgtSetCalcTool( sTool, sHead, 1) + -- calcolo ingombri + local dDistF, dDistB, dRollF, dRollB = SpecialCalcMachiningEncumbrance( nMchId) + if dDistF and dDistB then + dDistFront = min( dDistFront, dDistF) + dDistBack = min( dDistBack, dDistB) + dRollFront = max( dRollFront, dRollF) + dRollBack = max( dRollBack, dRollB) + end + nMchId = EgtGetNextActiveOperation( nMchId) + end + -- Ripristino lavorazione e utensile correnti + if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end + if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end + if sOrigTool and sOrigHead then EgtSetCalcTool( sOrigTool, sOrigHead, 1) end + -- Restituisco gli ingombri trovati + return dDistFront, dDistBack, dRollFront, dRollBack +end + +--------------------------------------------------------------------- +function GetFinalCutPmax( nMchId) + local nFinalCutId + local nId = EgtGetNextActiveOperation( nMchId) + while nId and EgtGetOperationPhase( nId) == EMC.PHASE do + nFinalCutId = nId + nId = EgtGetNextActiveOperation( nId) + end + if not nFinalCutId then return end + local nCLId = EgtGetFirstNameInGroup( nFinalCutId, 'CL') + if not nCLId then return end + return EgtGetInfo( nCLId, 'MMAX', 'p') +end + +--------------------------------------------------------------------- +function VerifyPartLength() + + -- Verifico lunghezza pezzo + if EMC.LB < MinJoin + MinOther + AggLoad + EMC.HCING + EMC.HOVM then + EMC.ERR = 17 + EMC.MSG = ' Error CLAMP : part too short' + return false + end + + return true +end + +--------------------------------------------------------------------- +function SpecCalcLoad( dPosT, dDistFront, dDistBack) + --[L] + local dNewY1min = max( EMC.LB - dDistBack, MinOther + AggLoad + EMC.HCING + EMC.HOVM) + local dNewY1max = min( ( MaxY1 - MinY1) - 5, EMC.LB - MinJoin) + if dNewY1min > dNewY1max then return nil end + local dNewY1Delta = dNewY1max + local dNewY2Delta = nil + local dNewY1 = dPosT + dNewY1Delta + local vCmd = {} + EgtOutLog( ' *[L]') + -- [L-1] + if dNewY1 + TurnerOffs - MaxY1 > 0 then + dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs) + EgtOutLog( ' *[L1]') + end --[L-2] + if EMC.LB - dNewY1Delta < MinJoin then + dNewY1Delta = min( EMC.LB - MinJoin, MaxY1 - dPosT - TurnerOffs) + EgtOutLog( ' *[L2]') + end + -- Commento + table.insert( vCmd, { 0, 'Loading'}) + -- posizionamento sicuro teste e rulli + EnsureZmax( false, vCmd) + -- Apro entrambe le morse + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 12, 0}) + -- Sposto il carrello Y per il carico + table.insert( vCmd, { 2, 'Y1', dPosT + dNewY1Delta, 'Y2', ParkY2}) + -- Chiudo morsa Y + table.insert( vCmd, { 11, 1}) + -- Sposto il carrello Y con la testa trave al parcheggio V1 + table.insert( vCmd, { 2, 'T', ParkV1, 'Y1', ParkV1 + dNewY1Delta}) + -- confermo i nuovi parametri di aggancio + table.insert( vCmd, { 21, dNewY1Delta, 0}) + -- Inizializzo contatore globale + EMC.CNT = 1 + SpecOutputCNT() + -- Assegno stato corrente + EMC.TPOS = ParkV1 + EMC.Y1DELTA = dNewY1Delta + EMC.Y2DELTA = nil + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + -- Restituisco i comandi + return vCmd +end -- SpecAdjustLoad [L] + +--------------------------------------------------------------------- +function SpecCalcCarriages( dDistFront, dDistBack, dRollFront, dRollBack, dY1DeltaMaxSP, dY2DeltaMinUL, nChar) + + local MinFrontJoin = MinJoin + EMC.HCING + EMC.HOVM + local MyMinOther = MinOther + EgtIf( EMC.CNT == 1, AggLoad, 0) + + local sMaxSplit = '' + if dY1DeltaMaxSP then sMaxSplit = '/'..EgtNumToString( dY1DeltaMaxSP, 1)..'(MaxSplit)' end + local sMinUnload = '' + if dY2DeltaMinUL then sMinUnload = '/'..EgtNumToString( dY2DeltaMinUL, 1)..'(MinUnload)' end + EgtOutLog( ' Dist/Min : Back=' .. EgtNumToString( dDistBack, 1) .. '/' .. EgtNumToString( MinJoin, 1) .. sMaxSplit .. + ' Front=' .. EgtNumToString( dDistFront, 1) .. '/' .. EgtNumToString( MinFrontJoin, 1) .. sMinUnload, 3) + + -- [A] se non richiesto solo carrello Y2 e posso mettere solo carrello Y1 + --if nChar ~= 3 and dDistBack > MinJoin - GEO.EPS_SMALL and dDistFront < MinFrontJoin then + if nChar ~= 2 and nChar ~= 3 and dDistBack > MinJoin - GEO.EPS_SMALL then + + local WorkTab = {} + WorkTab.dTPosI = EMC.TPOS + WorkTab.dY1DeltaI = EMC.Y1DELTA + WorkTab.dY2DeltaI = EMC.Y2DELTA + WorkTab.dV1PosI = EMC.V1POS + WorkTab.bV1CloseI = false + WorkTab.dV2PosI = EMC.V2POS + WorkTab.bV2CloseI = false + + WorkTab.dTPosF = nil + WorkTab.dY1DeltaMinF = max( EMC.LB - dDistBack, MyMinOther + EMC.HCING + EMC.HOVM) + WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMinF + ( MaxY1 - MinY1) - ( EMC.LB - dDistFront - dDistBack), EMC.LB - MinJoin) + WorkTab.dY2DeltaMinF = nil + WorkTab.dY2DeltaMaxF = nil + WorkTab.dV1PosF = dRollBack + WorkTab.bV1CloseF = false + WorkTab.dV2PosF = -dRollFront + WorkTab.bV2CloseF = false + + -- aggiuntivo per non avere problemi con pezzi a caduta + if WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 4 * BD.CHAR_EXTRA_DIST + 100 * GEO.EPS_SMALL then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + 4 * BD.CHAR_EXTRA_DIST + elseif WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 2 * BD.CHAR_EXTRA_DIST + 100 * GEO.EPS_SMALL then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + 2 * BD.CHAR_EXTRA_DIST + elseif WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > BD.CHAR_EXTRA_DIST + 100 * GEO.EPS_SMALL then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + BD.CHAR_EXTRA_DIST + end + + -- verifico validità intervallo ammesso per Y1 + if WorkTab.dY1DeltaMinF > WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y1 impossible' + return {} + end + + return SpecAdjustCarriages( WorkTab) + + -- [B] se richiesti entrambi e posso metterli + elseif nChar == 2 and + dDistBack > MinJoin - GEO.EPS_SMALL and + dDistFront > MinFrontJoin - GEO.EPS_SMALL then + + local WorkTab = {} + WorkTab.dTPosI = EMC.TPOS + WorkTab.dY1DeltaI = EMC.Y1DELTA + WorkTab.dY2DeltaI = EMC.Y2DELTA + WorkTab.dV1PosI = EMC.V1POS + WorkTab.bV1CloseI = false + WorkTab.dV2PosI = EMC.V2POS + WorkTab.bV2CloseI = false + + WorkTab.dTPosF = nil + WorkTab.dY1DeltaMinF = max( EMC.LB - dDistBack, MyMinOther + EMC.HCING + EMC.HOVM, EMC.LT + MyMinOther + EMC.NEXT_HCING) + WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMinF + ( MaxY1 - MinY1) - ( EMC.LB - dDistFront - dDistBack), EMC.LB - MinJoin) + WorkTab.dY2DeltaMaxF = min( dDistFront, EMC.LB - MyMinOther - EMC.TCING) + WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMaxF - ( MaxY2 - MinY2) + ( EMC.LB - dDistFront - dDistBack), MinJoin + EMC.HCING + EMC.HOVM) + if dY1DeltaMaxSP then WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMaxF, dY1DeltaMaxSP) end + if dY2DeltaMinUL then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMinF, dY2DeltaMinUL) end + WorkTab.dV1PosF = dRollBack + WorkTab.bV1CloseF = false + WorkTab.dV2PosF = -dRollFront + WorkTab.bV2CloseF = false + + -- aggiuntivo per minimizzare scambi carrelli + if WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 4 * BD.CHAR_EXTRA_DIST + 100 * GEO.EPS_SMALL then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + 4 * BD.CHAR_EXTRA_DIST + elseif WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > 2 * BD.CHAR_EXTRA_DIST + 100 * GEO.EPS_SMALL then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + 2 * BD.CHAR_EXTRA_DIST + elseif WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF > BD.CHAR_EXTRA_DIST + 100 * GEO.EPS_SMALL then + WorkTab.dY1DeltaMinF = WorkTab.dY1DeltaMinF + BD.CHAR_EXTRA_DIST + end + + -- verifico validità intervallo ammesso per Y1 + if WorkTab.dY1DeltaMinF > WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y1 impossible' + return {} + end + + -- verifico validità intervallo ammesso per Y2 + if WorkTab.dY2DeltaMinF > WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y2 impossible' + return {} + end + + return SpecAdjustCarriages( WorkTab) + + -- [C] se non richiesti entrambi e posso mettere carrello Y2 + elseif dDistFront > MinFrontJoin - GEO.EPS_SMALL then + + local WorkTab = {} + WorkTab.dTPosI = EMC.TPOS + WorkTab.dY1DeltaI = EMC.Y1DELTA + WorkTab.dY2DeltaI = EMC.Y2DELTA + WorkTab.dV1PosI = EMC.V1POS + WorkTab.bV1CloseI = false + WorkTab.dV2PosI = EMC.V2POS + WorkTab.bV2CloseI = false + + WorkTab.dTPosF = nil + WorkTab.dY1DeltaMinF = nil + WorkTab.dY1DeltaMaxF = nil + WorkTab.dY2DeltaMaxF = min( dDistFront, EMC.LB - MyMinOther - EMC.TCING) + WorkTab.dY2DeltaMinF = max( EMC.LB - dDistBack - AGG_V - dRollBack + MinY2, MinJoin + EMC.HCING + EMC.HOVM) + if dY2DeltaMinUL then WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMinF, dY2DeltaMinUL) end + WorkTab.dV1PosF = dRollBack + WorkTab.bV1CloseF = false + WorkTab.dV2PosF = -dRollFront + WorkTab.bV2CloseF = false + + -- verifico validità intervallo ammesso per Y2 + if WorkTab.dY2DeltaMinF > WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP Y2 impossible' + return {} + end + + return SpecAdjustCarriages( WorkTab) + + -- altrimenti errore + else + if EgtGetDebugLevel() < 3 then + EgtOutLog( ' DistFront=' .. EgtNumToString( dDistFront) .. ' DistBack=' .. EgtNumToString( dDistBack) .. + ' MinJoin=' .. EgtNumToString( MinJoin) .. ' MinFrontJoin=' .. EgtNumToString( MinFrontJoin)) + end + EMC.ERR = 18 + EMC.MSG = ' Error : CLAMP impossible' + return {} + end +end + +--------------------------------------------------------------------- +function SpecCalcSplit( dLenRaw, dMaxLenLeft) + local vCmd = {} + local bSplit = ( EMC.Y2DELTA ~= nil) + local ParkT = EgtIf( bSplit and dMaxLenLeft > ParkV1 - 50, LoadT, ParkV1) + table.insert( vCmd, { 0, EgtIf( bSplit, 'Split', 'Fall')}) + if not bSplit then EnsureZmaxAtEnd( vCmd) end + -- determino i grezzi da agganciare al carrello Y (sono quelli presenti nella fase successiva dispari) + local nNextOddPhase = GetNextStartOrRestPhase( EMC.PHASE) + local nRawId = EgtGetFirstRawPart() + while nRawId do + if EgtVerifyRawPartPhase( nRawId, nNextOddPhase) then + table.insert( vCmd, { 31, nRawId, 'Y1'}) + end + nRawId = EgtGetNextRawPart( nRawId) + end + -- riporto il carrello Y al carico con il resto della trave + local dLDelta = EMC.Y1DELTA - dLenRaw + table.insert( vCmd, { 1, 'Y1', ParkT + dLDelta}) + table.insert( vCmd, { 21, 0, EMC.Y2DELTA or 0}) + -- imposto subito Y non più attaccato alla trave in lavoro + EMC.Y1DELTA = nil + -- salvo posizione carrello Y in disposizione del pezzo dopo split + local PostDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if PostDispId then + if not bSplit then + EgtSetInfo( PostDispId, 'TPOS', ParkT) + else + EgtRemoveInfo( PostDispId, 'TPOS') + EgtSetInfo( PostDispId, 'TPARK', ParkT) + end + EgtSetInfo( PostDispId, 'Y1POS', ParkT + dLDelta) + end + -- salvo posizione grezzo rimasto e posizione carrello Y nella disposizione iniziale del pezzo succ (prossima fase dispari) + local NextDispId = EgtGetPhaseDisposition( nNextOddPhase) + if NextDispId then + EgtSetInfo( NextDispId, 'TPOS', ParkT) + EgtSetInfo( NextDispId, 'Y1POS', ParkT + dLDelta) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcUnload() + local vCmdPre = {} + EgtOutLog( ' *[U]') + if not EMC.Y1DELTA and not EMC.Y2DELTA then + EMC.ERR = 21 + EMC.MSG = ' Error : Y1 and Y2 not clamped for unloading' + return {} + end + local dY2DeltaMinUL = EMC.LB + MinY2 - EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) + -- Se pinza Y1 chiusa o Y2 troppo a destra, devo effettuare uno scambio + if EMC.Y1DELTA or EMC.Y2DELTA < dY2DeltaMinUL then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + if not nLastEntId then + local nPrevOpeId = EgtGetPrevActiveOperation( EMC.DISPID) + local nPathId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL')) + nLastEntId = EgtGetLastInGroup( nPathId) + end + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + -- imposto quote aggancio per avere solo pinza V + local dDistFront = EMC.LB - MinJoin - EMC.HOVM + 10 * GEO.EPS_SMALL + local dDistBack = 0 + -- imposto rulli aperti (in ogni caso pezzo sicuramente grande) + EMC.V1POS = ParkV1 + EMC.V2POS = ParkV2 + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack, 0, 0, nil, dY2DeltaMinUL) + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' *[U1]') + end + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Unloading'}) + -- posizionamento sicuro teste e rulli (non serve ?) + --table.insert( vCmd, { 4, 0}) + -- Se pinza Y chiusa, la apro + if EMC.Y1DELTA then + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + end + -- Sposto il pezzo in posizione di scarico + local dFinT = EgtIf( EMC.LB < MaxLenSmT, UnloadSmT, UnloadT) - EMC.LB + local dFinY2 = dFinT + EMC.Y2DELTA + table.insert( vCmd, { 2, 'T', dFinT, 'Y2', dFinY2}) + EgtOutLog( ' Y2PosF=' .. EgtNumToString( dFinY2)) + -- apro la morsa + table.insert( vCmd, { 12, 0}) + -- riporto il carrello in home + table.insert( vCmd, { 1, 'Y2', ParkY2}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +function SpecCalcPreRot() + local vCmdPre = {} + EgtOutLog( ' *[PR]') + -- Se pinza Y2 chiusa , devo effettuare uno scambio + if EMC.Y2DELTA then + -- determino posizione testa trave + local nLastEntId = EgtGetLastInGroup( EMC.PATHID) + local vAxes = EmtGetAxesPos( nLastEntId) + if #vAxes > 0 then EMC.TPOS = vAxes[1] end + -- imposto quote aggancio per avere solo pinza Y + local dDistFront = 0 + local dDistBack = EMC.LB - MinOther - EMC.HOVM + 10 * GEO.EPS_SMALL + -- effettuo scambio + vCmdPre = SpecCalcCarriages( dDistFront, dDistBack, 0, 0) + -- recupero nuova posizione carrelli + SpecSetCarrPosFromCmds( vCmdPre) + EgtOutLog( ' [PR1]') + end + -- porto il pezzo alla zona di rotazione con il carro Y1 + local vCmd = {} + -- Commento + table.insert( vCmd, { 0, 'Pre Rotation'}) + -- posizionamento sicuro teste e rulli + EnsureZmax( true, vCmd) + -- Se pinza V chiusa, la apro + if EMC.Y2DELTA then + table.insert( vCmd, { 12, 0}) + end + -- riporto la trave al carico + local RotT = LoadT + TurnerOffs + table.insert( vCmd, { 2, 'Y1', RotT + EMC.Y1DELTA, 'T', RotT}) + -- apro la morsa + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + -- riporto il carrello in home + table.insert( vCmd, { 1, 'Y1', ParkY1}) + + -- eventuale unione tabelle + if #vCmdPre > 0 then + vCmd = EgtJoinTables( vCmdPre, vCmd) + end + + return vCmd +end + +--------------------------------------------------------------------- +local function ChangedTool( nMchId) + local bChanged = false + -- Salvo lavorazione e utensile correnti, per ripristinarli alla fine + local nOrigMchId = EgtGetCurrMachining() + local sOrigTool = EgtTdbGetCurrToolParam( MCH_TP.NAME) + -- Recupero l'utensile della lavorazione precedente + local nPrevMchId = EgtGetPrevActiveOperation( nMchId or GDB_ID.NULL) + if nPrevMchId and EgtGetOperationType( nPrevMchId) ~= MCH_OY.DISP then + EgtSetCurrMachining( nPrevMchId) + local sTool = EgtGetMachiningParam( MCH_MP.TOOL) + bChanged = ( sTool ~= sOrigTool) + end + -- Ripristino lavorazione e utensile correnti + if nOrigMchId then EgtSetCurrMachining( nOrigMchId) end + if sOrigTool then EgtTdbSetCurrTool( sOrigTool) end + return bChanged +end + +-------------------------------------------------------------------------------------------------------- +-- **CHIAMATA DELLE FUNZIONI Spec** +-------------------------------------------------------------------------------------------------------- +function SpecAdjustCarriages( WorkTab) + + --EgtOutLog( ' --->>> CNT=' .. EgtIf( EMC.CNT, '1', '_')) + + -- Aggiorno la posizione dei rulli per eventuale cambio utensile + if ChangedTool( EMC.MCHID) then + WorkTab.dV1PosI = ParkV1 + WorkTab.dV2PosI = ParkV2 + end + -- Verifico se compattare i rulli + local bCloseV = false + if WorkTab.dY1DeltaI then + if WorkTab.dY1DeltaI <= MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V + EMC.HCING + EMC.HOVM + EgtIf( EMC.CNT == 1, AggLoad, 0) then + bCloseV = true + end + end + if WorkTab.dY2DeltaI then + if EMC.LB - WorkTab.dY2DeltaI <= MinJoin + WorkTab.dV1PosI - WorkTab.dV2PosI + 2 * AGG_V then + bCloseV = true + end + end + WorkTab.bCloseV = bCloseV + + -- |POSIZIONO Y1| **[A]** + if WorkTab.dY1DeltaMinF and ( not WorkTab.dY2DeltaMinF) then + -- [A1]/[A2] continuazione da morsa Y1 ( Y1 -> Y1 ) scambio Y2 (Y2 -> Y1) + if ( WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI)) or ( WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI)) then + WorkTab.bY1Parked = not WorkTab.dY1DeltaI + WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) + WorkTab.bY2Parked = not WorkTab.dY2DeltaI + WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) + return SpecAdjustCarrA( WorkTab) + else + EgtOutLog( ' Error CLAMP NULL-> Y1 impossibile') + error( 'Error CLAMP NULL-> Y1 impossibile') + end + + -- |POSIZIONO Y1Y2| **[B]** + elseif WorkTab.dY1DeltaMinF and WorkTab.dY2DeltaMinF then + -- [B1] passo da carrello Y1 a entrambi + if WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI) then + WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) + return SpecAdjustCarrB1( WorkTab) + -- [B2] passo da carrello Y2 a entrambi + elseif WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI) then + WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) + return SpecAdjustCarrB2(WorkTab) + -- [B3] rimango con due carrelli ( per ora accetto solo il caso in cui le posizioni sono già valide) + elseif WorkTab.dY1DeltaI > WorkTab.dY1DeltaMinF - 10 * GEO.EPS_SMALL and WorkTab.dY1DeltaI < WorkTab.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and + WorkTab.dY2DeltaI > WorkTab.dY2DeltaMinF - 10 * GEO.EPS_SMALL and WorkTab.dY2DeltaI < WorkTab.dY2DeltaMaxF + 10 * GEO.EPS_SMALL then + EgtOutLog( '*[B3]') + return {} + else + EgtOutLog( ' Error CLAMP NULL-> Y1+Y2 impossibile') + error( 'Error CLAMP NULL-> Y1+Y2 impossibile') + end + + -- |POSIZIONO Y2| **[C]** + elseif not WorkTab.dY1DeltaMinF and WorkTab.dY2DeltaMinF then + -- [C1]/[C2] continuazione da morsa Y2 ( Y2 -> Y2 ) sacmbio Y1 (Y1 -> Y2) + if ( WorkTab.dY1DeltaI and ( not WorkTab.dY2DeltaI)) or ( WorkTab.dY2DeltaI and (not WorkTab.dY1DeltaI)) then + WorkTab.bY1Parked = not WorkTab.dY1DeltaI + WorkTab.dY1DeltaI = WorkTab.dY1DeltaI or ( ParkY1 - WorkTab.dTPosI) + WorkTab.bY2Parked = not WorkTab.dY2DeltaI + WorkTab.dY2DeltaI = WorkTab.dY2DeltaI or ( ParkY2 - WorkTab.dTPosI) + return SpecAdjustCarrC( WorkTab) + else + EgtOutLog( ' Error CLAMP NULL-> Y2 impossibile') + error( 'Error CLAMP NULL-> Y2 impossibile') + end + end + +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y1 (aperta) e Y2 (chiusa) in **accentramento** +local function PosForCent1FY1( dY1a, dY2a, dTa, dExtraY1, dCorsaY1c, dCorsaY2Tc) + local dY2Delta = dY2a - dTa + local dDispl = dCorsaY1c - dExtraY1 + if dDispl / 2 <= dCorsaY2Tc then + if dDispl / 2 <= dCorsaY1c then + dY1a = dY1a - dDispl / 2 + dY2a = dY2a + dDispl / 2 + else + dY1a = dY1a - dCorsaY1c + dY2a = dY2a + dDispl - dCorsaY1c + end + else + dY2a = dY2a + dCorsaY2Tc + dY1a = dY1a - (dDispl - dCorsaY2Tc) + end + dTa = dY2a - dY2Delta + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y2 (aperta) e Y1 (chiusa) in **accentramento** +local function PosForCent1FY2( dY1a, dY2a, dTa, dExtraY2, dCorsaY1Tc, dCorsaY2c) + local dY1Delta = dY1a - dTa + local dDispl = dCorsaY2c + dExtraY2 + if dDispl / 2 <= dCorsaY1Tc then + if dDispl / 2 <= dCorsaY2c then + dY1a = dY1a - dDispl / 2 + dY2a = dY2a + dDispl / 2 + else + dY2a = dY2a + dCorsaY2c + dY1a = dY1a - min( dDispl - dCorsaY2c, dCorsaY1Tc) + end + else + dY1a = dY1a - dCorsaY1Tc + dY2a = dY2a + min( dDispl - dCorsaY1Tc, dCorsaY2c) + end + dTa = dY1a - dY1Delta + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y1 (aperta) e Y2 (chiusa) in **allontanamento** +local function PosForEnl1FY1( dY1a, dY2a, dTa, dExtra, dCorsaY1e, dCorsaY2Te) + local dDispl = MaxY1 - dY1a + dExtra + -- eseguo il posizionamento di Y1 allontanando Y1 e (Y2+T) + if dDispl/2 <= dCorsaY2Te then + if dDispl/2 <= dCorsaY1e then + dY1a = dY1a + dDispl / 2 + dY2a = dY2a - dDispl / 2 + dTa = dTa - dDispl / 2 + else + dY1a = dY1a + dCorsaY1e + dY2a = dY2a - (dDispl - dCorsaY1e) + dTa = dTa - (dDispl - dCorsaY1e) + end + else + dY2a = dY2a - dCorsaY2Te + dTa = dTa - dCorsaY2Te + dY1a = dY1a + (dDispl - dCorsaY2Te) + end + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +-- calcolo lo spostamento di Y2 (aperta) e Y1 (chiusa) in **allontanamento** +local function PosForEnl1FY2( dY1a, dY2a, dTa, dExtra, dCorsaY1Te, dCorsaY2e) + local dDispl = dY2a - MinY2 - dExtra + -- eseguo il posizionamento di Y2 allontanando (Y1+T) e Y2 + if dDispl/2 <= dCorsaY1Te then + if dDispl/2 <= dCorsaY2e then + dY1a = dY1a + dDispl / 2 + dTa = dTa + dDispl / 2 + dY2a = dY2a - dDispl / 2 + else + dY2a = dY2a - dCorsaY2e + dY1a = dY1a + (dDispl - dCorsaY2e) + dTa = dTa + (dDispl - dCorsaY2e) + end + else + dY1a = dY1a + dCorsaY1Te + dTa = dTa + dCorsaY1Te + dY2a = dY2a - (dDispl - dCorsaY1Te) + end + return dY1a, dY2a, dTa +end + +----------------------------------------------------------------------- +local function MaxDispl( TabI, vCmd, sType) + local dY1a, dY2a + local dTa = TabI.dTPosI + -- **[M1]** = allontanamento dei trascinatori con Y1 in presa + if sType == 'M1' then + EmitComment( vCmd, '[M1]') + -- ev' chiudo Y1, apro Y2 + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- allontano (Y1+T) e (Y2) + dY1a = MaxY1 + dY2a = MinY2 + dTa = ( MaxY1 - TabI.dY1PosI) + dTa + -- **[M2]** = allontanamento dei trascinatori con Y2 in presa + elseif sType == 'M2' then + EmitComment( vCmd, '[M2]') + -- ev' chiudo Y2, apro Y1 + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + -- allontano (Y2+T) e (Y1) + dY1a = MaxY1 + dY2a = MinY2 + dTa = ( MinY2 - TabI.dY2PosI) + dTa + -- **[M3]** = accentramento dei trascinatori con Y1 in presa + elseif sType == 'M3' then + EmitComment( vCmd, '[M3]') + -- ev' chiudo Y1, apro Y2 + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + -- accentro (Y1+T) e (Y2) + dY1a = TabI.MyMinY1V1 + dY2a = TabI.MaxY2V2 + dTa = ( TabI.MyMinY1V1 - TabI.dY1PosI) + dTa + -- **[M4]** = accentramento dei trascinatori con Y2 in presa + elseif sType == 'M4' then + EmitComment( vCmd, '[M4]') + -- ev' chiudo Y2, apro Y1 + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + -- accentro (Y2+T) e (Y1) + dY1a = TabI.MyMinY1V1 + dY2a = TabI.MaxY2V2 + dTa = ( TabI.MaxY2V2 - TabI.dY2PosI) + dTa + end + -- + table.insert( vCmd, { 3, 'Y1', dY1a, 'Y2', dY2a, 'T', dTa}) + TabI.dY1PosI = dY1a + TabI.dY2PosI = dY2a + TabI.dTPosI = dTa +end -- MaxDisplForRiXw + +----------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y1** +------------------------------------------------------------------------------------------------------------------ +local function PosY1FromY2A( TabI, vCmd) + EmitComment( vCmd, '[PosY1FromY2A]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY1New = (TabI.dTPosI + t.dY1NewDelta) - MaxY1 --se > 0, la posizione non è raggiunginile + -- corse disponibili in allontanamento (enlargement) dalle posizioni attuali per Y1 e (Y2+T) + t.dCorsaY1eI = MaxY1 - TabI.dY1PosI + t.dCorsaY2TeI= TabI.dY2PosI - MinY2 + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y1 già entro l'intervallo : non si deve muovere + t.dY1DeltaI = TabI.dY1PosI-TabI.dTPosI + if t.dY1DeltaI < TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY1DeltaI > TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y1(0)] ') + --return t.dY1DeltaI + -- **[ri]** = posY1New non raggiungibile direttamente -> muovo fino a fine corsa + elseif t.dExtraY1New > t.dCorsaY2TeI then + EmitComment( vCmd, '[Y1A-ri]') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M2') + --t.bXW = true + else + -- **[rp]** = raggiungo il punto medio Y1New dell'intervallo + EmitComment( vCmd, '[Y1A-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- **1:** calcolo pos. di allontanamento per (Y1) e (Y2+T) (da posizioni iniziali) + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForEnl1FY1( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY1New, t.dCorsaY1eI, t.dCorsaY2TeI) + -- aggiornamento posizioni e dY1Delta dopo + -- chiusura di Y1, apertura e parcheggio di Y2 a fine funzione + -- ev' chiudo Y2 e apro Y1 ed eseguo allontanamento + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + t.dY1DeltaA = TabI.dY1PosI - TabI.dTPosI + -- chiusura di Y1, ev' apertura e parcheggio di Y2 : in funzioni chiamanti + return t.dY1DeltaA +end -- PosY1FromY2A + +-------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y2** +-------------------------------------------------------------------------------------------------------- +local function PosY2FromY1A( TabI, vCmd) + EmitComment( vCmd, '[PosY2FromY1A]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY2New = ( TabI.dTPosI + t.dY2NewDelta) - MinY2 --se < 0, la posizione non è raggiunginile + -- corse disponibili in allontanamento (enlargement) dalle posizioni attuali per (Y1+T) e Y2 + t.dCorsaY1Te = MaxY1 - TabI.dY1PosI + t.dCorsaY2e = TabI.dY2PosI - MinY2 + -- + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y2 già entro l'intervallo : non si deve muovere + t.dY2DeltaI = TabI.dY2PosI- TabI.dTPosI + if t.dY2DeltaI < TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY2DeltaI > TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y2(0)] ') + -- **[ri]** = posY2New non raggiungibile direttamente -> muovo fino a fine corsa + elseif -t.dExtraY2New > t.dCorsaY1Te then + EmitComment( vCmd, '[Y2A-ri]' ) + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M1') + else + -- **[rp]** = raggiungo il punto medio Y2New dell'intervallo + EmitComment( vCmd, '[Y2A-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- **1:** calcolo pos. di allontanamento per (Y1+T) e (Y2) (da posizioni iniziali) + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForEnl1FY2( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY2New, t.dCorsaY1Te, t.dCorsaY2e) + -- chiudo Y1 e apro Y2 ed eseguo allontanamento (finale) + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + t.dY2DeltaA = TabI.dY2PosI - TabI.dTPosI + -- chiusura di Y2, ev' apertura e parcheggio di Y1 : in funzioni chiamanti + return t.dY2DeltaA +end -- PosY2FromY1A + +------------------------------------------------------------------------------------------------------------ +-- **ACCENTRAMENTO di Y1** +------------------------------------------------------------------------------------------------------------ +local function PosY1FromY2B( TabI, vCmd) + EmitComment( vCmd, '[PosY1FromY2B]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY1New = (TabI.dTPosI + t.dY1NewDelta) - TabI.MyMinY1V1 -- se < 0, la posizione non è raggiunginile + -- corse in accentramento disponibili per Y1 e (Y2+T) dalle posizioni iniziali + t.dCorsaY1cI = TabI.dY1PosI - TabI.MyMinY1V1 + t.dCorsaY2TcI = TabI.MaxY2V2 - TabI.dY2PosI + -- + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y1 già entro l'intervallo : non si deve muovere + t.dY1DeltaI = TabI.dY1PosI-TabI.dTPosI + if t.dY1DeltaI < TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY1DeltaI > TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y1(0)] ') + -- **[ri]** = posY1New non raggiungibile direttamente -> muovo fino a fine corsa + elseif -t.dExtraY1New > t.dCorsaY2TcI then + EmitComment( vCmd, '[Y1B-ri]') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M4') + else + -- **[rp]** = raggiungo il punto medio Y1New dell'intervallo + EmitComment( vCmd, '[Y1B-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y2DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- **1: calcolo accentramento di (Y1) e (Y2+T)** + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForCent1FY1( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY1New, t.dCorsaY1cI, t.dCorsaY2TcI) + -- posizionamento efettivo e aggiornamento di vCmd e dY1Delta dopo + -- ch. di Y1 e ap. e parcheggio di Y2 a fine funzione chiamante + -- chiudo Y2 e apro Y1 ed eseguo accentramento (finale) + table.insert( vCmd, { 12, 1}) + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + t.dY1DeltaA = TabI.dY1PosI - TabI.dTPosI + -- chiusura di Y1, ev' apertura e parcheggio di Y2 : in funzioni chiamanti + return t.dY1DeltaA +end -- PosY1FromY2B + +-------------------------------------------------------------------------------------------------------- +-- **ACCENTRAMENTO di Y2** +-------------------------------------------------------------------------------------------------------- +local function PosY2FromY1B( TabI, vCmd) + EmitComment( vCmd, '[PosY2FromY1B]') + local t = {} + -- **calcolo i delta dai dati iniziali** + t.dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 + -- valuto gli estremi degli intervalli, con riferimento alle posizioni attuali + t.dExtraY2New = (TabI.dTPosI + t.dY2NewDelta) - TabI.MaxY2V2 -- se > 0 la posizione non è raggiunginile + -- corse in accentramento disponibili per (Y1+T) e (Y2) dalle posizioni iniziali + t.dCorsaY1TcI = TabI.dY1PosI - TabI.MyMinY1V1 + t.dCorsaY2cI = TabI.MaxY2V2 - TabI.dY2PosI + -- |RICONOSCO I CASI| + -- **[(0)]** morsa Y2 già entro l'intervallo : non si deve muovere + t.dY2DeltaI = TabI.dY2PosI-TabI.dTPosI + if t.dY2DeltaI < TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL and t.dY2DeltaI > TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then + EmitComment( vCmd, '[Y2(0)] ') + -- **[ri]** = posY2New non raggiungibile direttamente -> muovo fino a fine corsa + elseif t.dExtraY2New > t.dCorsaY1TcI then + EmitComment( vCmd, '[Y2B-ri]' ) + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- questo movimento serve solo a gestire (in modo complesso) il caso [ri] + MaxDispl( TabI, vCmd, 'M3') + else + -- **[rp]** = raggiungo il punto medio Y2New dell'intervallo + EmitComment( vCmd, '[Y2B-rp] ') + if not SpecTestSomeMoveInCmds( vCmd) and not EMC.Y1DELTA then + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + -- Y1 chiuso, Y2 aperto + -- **1: calcolo accentramento di (Y1+T) e (Y2)** + TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI = PosForCent1FY2( TabI.dY1PosI, TabI.dY2PosI, TabI.dTPosI, t.dExtraY2New, t.dCorsaY1TcI, t.dCorsaY2cI) + -- ev' chiudo Y1 e apro Y2 ed eseguo movimento accentramento + table.insert( vCmd, { 11, 1}) + table.insert( vCmd, { 12, 0}) + table.insert( vCmd, { 3, 'Y1', TabI.dY1PosI, 'Y2', TabI.dY2PosI, 'T', TabI.dTPosI}) + end + t.dY2DeltaA = TabI.dY2PosI - TabI.dTPosI + -- chiusura di Y2, apertura e parcheggio di Y1 : in funzioni chiamanti + return t.dY2DeltaA +end -- PosY2FromY1B + +-------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y1 per pos. di Y2 o Y2+Y1** - chiamata da [B2] e [C] +-------------------------------------------------------------------------------------------------------- +local function PosY1Y2A( TabI, vCmd) + EmitComment( vCmd, '[PosY1Y2A]') + -- |RICONOSCO I CASI| + repeat + local dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF)/2 + local bXW = true + -- se intervallo per Y1 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 <=> ( -ExtraI1MaxF < Corsa Y2Tc) + -- e Y2 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 1| in **allontanamento** + PosY1FromY2A( TabI, vCmd) + -- |POSIZIONO MORSA 2| + if (TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- in **allontanamento** + PosY2FromY1A( TabI, vCmd) + else + -- in **accentramento** + PosY2FromY1B( TabI, vCmd) + end + bXW = false + else + -- |POSIZIONO MORSA 2| e poi MORSA 1 + -- in **allontanamento** + if (TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- se intervallo per Y2 raggiungibile in una sola fase + if - (( TabI.dTPosI + TabI.dY2DeltaMaxF) - MinY2) < MaxY1 - TabI.dY1PosI then + PosY2FromY1A( TabI, vCmd) + PosY1FromY2A( TabI, vCmd) + bXW = false + end + else + -- in **accentramento** + -- sempre se intervallo per Y2 raggiungibile in una sola fase + if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 then + PosY2FromY1B( TabI, vCmd) + PosY1FromY2A( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione negativa ( casi **[xw]**) + EmitComment( vCmd, '[Y1A-xw]') + if TabI.dY1PosI ~= TabI.MyMinY1V1 then + -- accentramento morse, trascinamento trave con Y1 + MaxDispl( TabI, vCmd, 'M3') + else + -- allontanamento morse, trascinamento trave con Y2 + MaxDispl( TabI, vCmd, 'M2') + end + end + until ( not bXW) + -- chiusura/parcheggio dei trascinatori in funzioni chiamanti + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY1Y2A + +-------------------------------------------------------------------------------------------------------- +-- **ACCENTRAMENTO di Y1 per pos. di Y2 o Y2+Y1** - chiamata da [B2] e [C] +-------------------------------------------------------------------------------------------------------- +local function PosY1Y2B( TabI, vCmd) + EmitComment( vCmd, '[PosY1Y2B]') + -- |RICONOSCO I CASI| + local nCnt = 0 + repeat + local dY2NewDelta = ( TabI.dY2DeltaMaxF + TabI.dY2DeltaMinF) / 2 + local bXW = true + -- se intervallo per Y1 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 <=> ( -ExtraI1MaxF < Corsa Y2Tc) + -- e Y2 è in posizione per aggancio su T + if -(( TabI.dTPosI + TabI.dY1DeltaMaxF) - TabI.MyMinY1V1) < TabI.MaxY2V2 - TabI.dY2PosI and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 1| in **accentramento** + PosY1FromY2B( TabI, vCmd) + -- |POSIZIONO MORSA 2| + local dY2DeltaI = TabI.dY2PosI - TabI.dTPosI + -- Se il trascinatore 2 non è già nell'intervallo richiesto + if dY2DeltaI > TabI.dY2DeltaMaxF + 10 * GEO.EPS_SMALL or dY2DeltaI < TabI.dY2DeltaMinF - 10 * GEO.EPS_SMALL then + if ( TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- in **allontanamento** + PosY2FromY1A( TabI, vCmd) + else + -- in **accentramento** + PosY2FromY1B( TabI, vCmd) + end + end + bXW = false + -- se posso posizionare 'direttamente' Y2 all'interno dell'intervallo I2 (casi [rp] o [ri]) + else + -- |POSIZIONO MORSA 2| e poi MORSA 1 + -- in **allontanamento** + if ( TabI.dTPosI + dY2NewDelta) < TabI.dY2PosI then + -- se intervallo per Y2 è raggiungibile in una sola fase e Y1 è in posizione per aggancio su T + if -(( TabI.dTPosI + TabI.dY2DeltaMaxF) - MinY2) < MaxY1 - TabI.dY1PosI and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + PosY2FromY1A( TabI, vCmd) + PosY1FromY2B( TabI, vCmd) + bXW = false + end + -- in **accentramento** + else + -- sempre se intervallo per Y2 è raggiungibile in una sola fase e Y1 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 and + TabI.dY1PosI <= TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + PosY2FromY1B( TabI, vCmd) + PosY1FromY2B( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione positiva (casi **[xw]** ) + -- se Y1 non è a f.c. e se Y1 può afferrare la trave + EmitComment( vCmd, '[Y1B-xw]') + if TabI.dY1PosI ~= MaxY1 and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + -- allontanamento morse, trascinamento trave con Y1 + MaxDispl( TabI, vCmd, 'M1') + else + -- accentramento morse, trascinamento trave con Y2 + MaxDispl( TabI, vCmd, 'M4') + end + end + nCnt = nCnt + 1 + if nCnt > 5 then return end + until ( not bXW) + -- chiusura/parcheggio dei trascinatori in funzioni chiamanti + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY1Y2B + +-------------------------------------------------------------------------------------------------------- +-- **ALLONTANAMENTO di Y2 per pos. di Y1 o Y1+Y2** - chiamata da [A] e [B1] +-------------------------------------------------------------------------------------------------------- +local function PosY2Y1A( TabI, vCmd) + EmitComment( vCmd, '[PosY2Y1A]') + -- |RICONOSCO I CASI| + repeat + local dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF)/2 + local bXW = true + -- se intervallo per Y2 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y2 all'interno dell'intervallo <=> ( -ExtraI2MaxF < Corsa Y1Te and) + -- e Y1 è in posizione per aggancio su T + if MinY2 - ( TabI.dTPosI + TabI.dY2DeltaMaxF) < MaxY1 - TabI.dY1PosI and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 2| in **allontanamento** + PosY2FromY1A( TabI, vCmd) + -- |POSIZIONO MORSA 1| + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- in **allontanamento** + PosY1FromY2A( TabI, vCmd) + else + -- in **accentramento** + PosY1FromY2B( TabI, vCmd) + end + bXW = false + else + -- |POSIZIONO MORSA 1| e poi MORSA 2 + -- caso di allontanamento + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- se l'intervallo per Y1 è raggiungibile in una sola fase + if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 then + PosY1FromY2A( TabI, vCmd) + PosY2FromY1A( TabI, vCmd) + bXW = false + end + -- in **accentramento** + else + -- sempre se l'intervallo per Y1 è raggiungibile in una sola fase + if TabI.MyMinY1V1 - ( TabI.dTPosI + TabI.dY1DeltaMaxF) < TabI.MaxY2V2 - TabI.dY2PosI then + PosY1FromY2B( TabI, vCmd) + PosY2FromY1A( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione positiva (casi **[xw]**) + EmitComment( vCmd, '[Y2A-xw]') + -- accentramento morse, trascinamento trave con Y2 + if TabI.dY2PosI ~= TabI.MaxY2V2 then + MaxDispl( TabI, vCmd, 'M4') + -- allontanamento morse, trascinamento trave con Y1 + else + MaxDispl( TabI, vCmd, 'M1') + end + end + + until ( not bXW) + -- chiusura/parcheggio dei trascinatori in funzioni chiamanti + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY2Y1A + +-------------------------------------------------------------------------------------------------------- +-- **ACCENTRAMENTO di Y2 per pos. di Y1 o Y1+Y2** - chiamata da [A] e [B1] +-------------------------------------------------------------------------------------------------------- +local function PosY2Y1B( TabI, vCmd) + EmitComment( vCmd, '[PosY2Y1B]') + -- |RICONOSCO I CASI| + local nCnt = 0 + repeat + local dY1NewDelta = ( TabI.dY1DeltaMaxF + TabI.dY1DeltaMinF) / 2 + local bXW = true + -- se intervallo per Y2 raggiungibile in una sola fase + -- ossia se posso posizionare 'direttamente' Y2 all'interno dell'intervallo I2 <=> (-ExtraI2MinF < Corsa Y1Tc) + -- e Y1 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY2DeltaMinF) - TabI.MaxY2V2 < TabI.dY1PosI - TabI.MyMinY1V1 and + TabI.dY1PosI < TabI.dTPosI + EMC.LB - MinJoin - EgtIf( SPLIT, EMC.TCING, 0) + 10 * GEO.EPS_SMALL then + -- |POSIZIONO MORSA 2| in **accentramento** + PosY2FromY1B( TabI, vCmd) + -- |POSIZIONO MORSA 1| + local dY1DeltaI = TabI.dY1PosI - TabI.dTPosI + -- Se il trascinatore 1 non è già nell'intervallo richiesto + if dY1DeltaI > TabI.dY1DeltaMaxF + 10 * GEO.EPS_SMALL or dY1DeltaI < TabI.dY1DeltaMinF - 10 * GEO.EPS_SMALL then + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- in **allontanamento** + PosY1FromY2A( TabI, vCmd) + else + -- in **accentramento** + PosY1FromY2B( TabI, vCmd) + end + end + bXW = false + -- se posso posizionare 'direttamente' Y1 all'interno dell'intervallo I1 (casi [rp] o [ri]) + else + -- |POSIZIONO MORSA 1| e poi MORSA 2 + -- in **allontanamento** + if ( TabI.dTPosI + dY1NewDelta) > TabI.dY1PosI then + -- se intervallo per Y1 è raggiungibile in una sola fase e Y2 è in posizione per aggancio su T + if ( TabI.dTPosI + TabI.dY1DeltaMinF) - MaxY1 < TabI.dY2PosI - MinY2 and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + PosY1FromY2A( TabI, vCmd) + PosY2FromY1B( TabI, vCmd) + bXW = false + end + -- in **accentramento** + else + -- se (-ExtraI1MaxF < Corsa Y2Tc) e (Y2 è in posizione per aggancio su T) + if TabI.MyMinY1V1 - ( TabI.dTPosI + TabI.dY1DeltaMaxF) < TabI.MaxY2V2 - TabI.dY2PosI and + TabI.dY2PosI >= TabI.dTPosI + MinJoin + EMC.HCING + EMC.HOVM - 10 * GEO.EPS_SMALL then + PosY1FromY2B( TabI, vCmd) + PosY2FromY1B( TabI, vCmd) + bXW = false + end + end + end + if bXW then + -- Massimo trascinamento della trave in direzione negativa (casi x[w]) + EmitComment( vCmd, '[Y2B-xw]') + -- se Y2 non è a f.c. e se Y2 può afferrare la trave + if TabI.dY2PosI > MinY2 and + TabI.dY2PosI > TabI.dTPosI + MinJoin + EMC.HOVM + EMC.HCING - 10 * GEO.EPS_SMALL then + -- allontanamento morse, trascinamento trave con Y2 + MaxDispl( TabI, vCmd, 'M2') + else + -- accentramento morse, trascinamento trave con Y1 + MaxDispl( TabI, vCmd, 'M3') + end + end + nCnt = nCnt + 1 + if nCnt > 5 then return end + until ( not bXW) + -- la chiusura delle morse è fatta sopra + local dY1Delta = TabI.dY1PosI - TabI.dTPosI + local dY2Delta = TabI.dY2PosI - TabI.dTPosI + return dY1Delta, dY2Delta +end -- PosY2Y1FromY1B + +--------------------------------------------------------------------- +-- **[A] Posizionamento trascinatore Y1 da (Y1 o Y2) <=> Y1/Y2 -> Y1** +--------------------------------------------------------------------- +function SpecAdjustCarrA( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y1/Y2 -> Y1'}) + EmitComment( vCmd, '*[A]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + -- recupero le posizioni correnti + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY1DeltaF + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + EgtOutLog( ' Y1DeltaI=' .. EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI=' .. EgtNumToString( WorkTab.dY2DeltaI)) + EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF)) + + -- [A(1)] - Se il trascinatore Y1 non è nell'intervallo valido, devo posizionarlo + if WorkTab.dY1DeltaI < WorkTab.dY1DeltaMinF - GEO.EPS_SMALL or WorkTab.dY1DeltaI > WorkTab.dY1DeltaMaxF + GEO.EPS_SMALL then + EmitComment( vCmd, '*[A(1)]') + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + -- eseguo eventuale posizionamento sicuro di teste e rulli + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + -- ------------------------------------------ + -- |DEFINISCO INTERVALLO 2| + -- ------------------------------------------ + WorkTab.dY2DeltaMaxF = WorkTab.dY1DeltaMinF - ( MyMinY1V1 - MaxY2V2) + ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF) + WorkTab.dY2DeltaMinF = WorkTab.dY1DeltaMaxF - ( MaxY1 - MinY2) - ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF) + -- se Y2 deve allontanarsi assegno il primo punto valido (altrimenti mantengo tutto l'intervallo valido) + if WorkTab.dY2DeltaI > WorkTab.dY2DeltaMaxF then + WorkTab.dY2DeltaMinF = max( WorkTab.dY2DeltaMaxF - ( WorkTab.dY1DeltaMaxF - WorkTab.dY1DeltaMinF), MinJoin + EMC.HCING + EMC.HOVM) + end + -- se la trave è più 'corta' dell'intervallo per Y2 aggiorno l'intervallo (potrei essere comunque in un punto valido) + if WorkTab.dY2DeltaMinF < MinJoin + EMC.HCING + EMC.HOVM then + WorkTab.dY2DeltaMinF = MinJoin + EMC.HCING + EMC.HOVM + -- se Y2 deve accentrarsi + if WorkTab.dY2DeltaI < WorkTab.dY2DeltaMinF then + WorkTab.dY2DeltaMaxF = 2 * ( MinJoin + EMC.HCING + EMC.HOVM) + end + end + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 + local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 + -------------------------------------------- + -- |RICONOSCO I CASI| + -------------------------------------------- + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } + if WorkTab.dY1DeltaI > dY1NewDelta then + --[A(1)B] **ACCENTRAMENTO** (dall'origine) del trascinatore Y1 + EmitComment( vCmd, '[A-Y1B]') + dY1DeltaF = PosY1Y2B( TabValI, vCmd) + else + --[A(1)A] **ALLONTANAMENTO** (dall'origine) del trascinatore Y1 + EmitComment( vCmd, '[AY1A]') + dY1DeltaF = PosY1Y2A( TabValI, vCmd) + end + -- chiudo Y1 + table.insert( vCmd, { 11, 1}) + -- dichiaro Y2 da parcheggiare + WorkTab.bY2Parked = false + + -- [A(0)] - Se Y1 è già nell'intervallo valido, si lascia dove è + else + EmitComment( vCmd, '*[A(0)]') + if not WorkTab.bY2Parked then + -- dichiaro posizione di Y2 e T + table.insert( vCmd, { 2, 'T', WorkTab.dTPosI, 'Y2', dY2PosI}) + end + if WorkTab.bY1Parked then + -- chiudo Y1 + table.insert( vCmd, { 11, 1}) + end + dY1DeltaF = WorkTab.dY1DeltaI + end + + if not WorkTab.bY2Parked then + -- apro e parcheggio Y2 + table.insert( vCmd, { 12, 0}) + table.insert( vCmd, { 1, 'Y2', ParkY2}) + end + + -- aggiorno e segnalo la posizione finale Y1Delta + table.insert( vCmd, { 21, dY1DeltaF, 0}) + EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF)) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end +-- SpecAdjustCarrAA + +-------------------------------------------------------------------- +-- **[B1] da trascinatore Y1 a entrambi <=> Y1 -> Y1+Y2** +-------------------------------------------------------------------- +function SpecAdjustCarrB1( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y1 -> Y1+Y2'}) + EmitComment( vCmd, '*[B1]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + + -- recupero le posizioni correnti + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY1DeltaF, dY2DeltaF + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 + local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 + -- + EgtOutLog( ' Y1DeltaI='..EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI='..EgtNumToString( WorkTab.dY2DeltaI)) + EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF)) + EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF)) + + -- Il controllo che i trascinatori non siano già nell'intervallo valido è svolto nelle funzioni a valle + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + + -- ----------------------------------------- + -- |RICONOSCO I CASI| + -- ------------------------------------------ + -- definisco la tabella delle posizioni iniziali + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } + -- [B1-Y2A] **ALLONTANAMENTO** del trascinatore **Y2** e (eventuale) posizionamento di Y1 + if WorkTab.dY2DeltaI > dY2NewDelta then + EmitComment( vCmd, '[B1-Y2A]') + dY1DeltaF, dY2DeltaF = PosY2Y1A( TabValI, vCmd) + else + -- [B1-Y2B] **ACCENTRAMENTO** del trascinatore **Y2** e (eventuale) posizionamento di Y1 + EmitComment( vCmd, '[B1-Y2B] ') + dY1DeltaF, dY2DeltaF = PosY2Y1B( TabValI, vCmd) + end + -- ----------------------------------------- + -- |CHIUSURA MORSE| + -- ------------------------------------------ + if not SpecTestSomeMoveInCmds( vCmd) then + table.insert( vCmd, { 3, 'Y1', dY1PosI, 'Y2', dY2PosI, 'T', WorkTab.dTPosI}) + end + table.insert( vCmd, { 11, 1}) -- chiudo Y1 + table.insert( vCmd, { 12, 1}) -- Chiudo Y2 + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dY1DeltaF, dY2DeltaF}) + EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF) .. ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF)) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end +-- SpecAdjustCarrB1 + +--------------------------------------------------------------------- +-- **[B2] da trascinatore Y2 a entrambi <=> Y2 -> Y1+Y2** +-------------------------------------------------------------------- +function SpecAdjustCarrB2( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y2 -> Y1+Y2'}) + EmitComment( vCmd, '*[B2]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + + -- definisco le posizioni **Iniziali** (= recupero le posizioni correnti) + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY2DeltaF, dY1DeltaF + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = ( WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF) / 2 + local dY2NewDelta = ( WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF) / 2 + -- + EgtOutLog( ' Y1DeltaI='..EgtNumToString( WorkTab.dY1DeltaI)..' Y2DeltaI='..EgtNumToString( WorkTab.dY2DeltaI) ) + EgtOutLog( ' Y1DeltaMinF=' .. EgtNumToString( WorkTab.dY1DeltaMinF)..' Y1DeltaMaxF=' .. EgtNumToString( WorkTab.dY1DeltaMaxF)) + EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF)) + + -- Il controllo che i trascinatori non siano già nell'intervallo valido è svolto nelle funzioni a valle + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + -- eseguo eventuale posizionamento sicuro di teste e rulli + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + + -- ----------------------------------------- + -- |RICONOSCO I CASI| + -- ------------------------------------------ + -- definisco la tabella delle posizioni iniziali + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF } + -- [B2-Y1A] **ALLONTANAMENTO** del trascinatore **Y1** e (eventuale) posizionamento di Y2 + if WorkTab.dY1DeltaI < dY1NewDelta then + EmitComment( vCmd, '[B2-Y1A]') + dY1DeltaF, dY2DeltaF = PosY1Y2A( TabValI, vCmd) + else + -- [B2-Y1B] **ACCENTRAMENTO** del trascinatore **Y1** e (eventuale) posizionamento di Y2 + EmitComment( vCmd, '[B2-Y1B]') + dY1DeltaF, dY2DeltaF = PosY1Y2B( TabValI, vCmd) + end + + -- ----------------------------------------- + -- |CHIUSURA MORSE| + -- ------------------------------------------ + if not SpecTestSomeMoveInCmds( vCmd) then + table.insert( vCmd, { 3, 'Y1', dY1PosI, 'Y2', dY2PosI, 'T', WorkTab.dTPosI}) + end + table.insert( vCmd, { 11, 1}) -- chiudo Y1 + table.insert( vCmd, { 12, 1}) -- Chiudo Y2 + -- imposto i nuovi parametri di aggancio + table.insert( vCmd, { 21, dY1DeltaF, dY2DeltaF}) + EgtOutLog( ' Y1DeltaF=' .. EgtNumToString( dY1DeltaF) .. ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF)) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end +-- SpecAdjustCarrB2 + +--------------------------------------------------------------------- +-- **[C] ex[C1]/[C2] Posizionamento trascinatore Y2 da (Y1 o Y2) <=> Y1/Y2 -> Y2** +--------------------------------------------------------------------- +function SpecAdjustCarrC( WorkTab) + -- Elenco comandi + local vCmd = {} + table.insert( vCmd, { 0, 'Y1/Y2 -> Y2'}) + EmitComment( vCmd, '*[C]') + + local MinY1V1 = max( WorkTab.dV1PosI + AGG_V, MinY1) + local MaxY2V2 = min( WorkTab.dV2PosI - AGG_V, MaxY2) + local MyTCING = EgtIf( SPLIT, EMC.TCING, 0) + -- se primo scambio + local MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1V1 + AggLoad, MinY1V1) + -- recupero le posizioni correnti + local dY1PosI = WorkTab.dTPosI + WorkTab.dY1DeltaI + local dY2PosI = WorkTab.dTPosI + WorkTab.dY2DeltaI + local dY2DeltaF + -- + EgtOutLog( ' Y1DeltaI=' .. EgtNumToString( WorkTab.dY1DeltaI) .. ' Y2DeltaI=' .. EgtNumToString( WorkTab.dY2DeltaI)) + EgtOutLog( ' Y2DeltaMinF=' .. EgtNumToString( WorkTab.dY2DeltaMinF)..' Y2DeltaMaxF=' .. EgtNumToString( WorkTab.dY2DeltaMaxF)) + + -- [C(1)] - Se il trascinatore Y2 non è nell'intervallo valido, devo posizionarlo + if WorkTab.dY2DeltaI < WorkTab.dY2DeltaMinF - GEO.EPS_SMALL or WorkTab.dY2DeltaI > WorkTab.dY2DeltaMaxF + GEO.EPS_SMALL then + EmitComment( vCmd, '*[C(1)]') + -- ----------------------------------------- + -- |VERIFICO POSIZIONE RULLI| + -- ------------------------------------------ + -- eseguo eventuale posizionamento sicuro di teste e rulli + if WorkTab.bCloseV then + EnsureZmax( true, vCmd) + MyMinY1V1 = EgtIf( EMC.CNT == 1, MinY1 + AggLoad, MinY1) + MaxY2V2 = MaxY2 + end + -- ------------------------------------------ + -- |DEFINISCO INTERVALLO 1| + -- ------------------------------------------ + WorkTab.dY1DeltaMaxF = WorkTab.dY2DeltaMinF + (MaxY1 - MinY2) + (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF) + WorkTab.dY1DeltaMinF = WorkTab.dY2DeltaMaxF + (MyMinY1V1 - MaxY2V2) - (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF) + -- se Y1 deve allontanarsi assegno il primo punto valido (altrimenti lascio l'intervallo) + if WorkTab.dY1DeltaI < WorkTab.dY1DeltaMinF then + WorkTab.dY1DeltaMaxF = min( WorkTab.dY1DeltaMinF + (WorkTab.dY2DeltaMaxF - WorkTab.dY2DeltaMinF), EMC.LB - MinJoin - MyTCING) + end + -- se la trave è più 'corta' dell'intervallo per Y1 aggiorno l'intervallo (potrei essere comunque in un punto valido) + if WorkTab.dY1DeltaMaxF > EMC.LB - ( MinJoin + MyTCING) then + WorkTab.dY1DeltaMaxF = EMC.LB - ( MinJoin + MyTCING) + -- se Y1 deve accentrarsi + if WorkTab.dY1DeltaI > WorkTab.dY1DeltaMaxF then + WorkTab.dY1DeltaMinF = EMC.LB - 2 *( MinJoin + MyTCING) + end + end + -- posizioni obiettivo dei carrelli al centro dei rispettivi intervalli di validità + local dY1NewDelta = (WorkTab.dY1DeltaMinF + WorkTab.dY1DeltaMaxF)/2 + local dY2NewDelta = (WorkTab.dY2DeltaMinF + WorkTab.dY2DeltaMaxF)/2 + + -- ------------------------------------------ + -- |RICONOSCO I CASI| + -- ------------------------------------------ + TabValI = {dY1PosI=dY1PosI, dY2PosI=dY2PosI, dTPosI=WorkTab.dTPosI, MyMinY1V1=MyMinY1V1, MaxY2V2=MaxY2V2, dY1DeltaMaxF=WorkTab.dY1DeltaMaxF, + dY1DeltaMinF=WorkTab.dY1DeltaMinF, dY2DeltaMaxF=WorkTab.dY2DeltaMaxF, dY2DeltaMinF=WorkTab.dY2DeltaMinF} + if WorkTab.dY2DeltaI < dY2NewDelta then + -- [C-Y2B] **ACCENTRAMENTO** (dall'origine) del trascinatore Y2 + EmitComment( vCmd, '[C-Y2B]') + _, dY2DeltaF = PosY2Y1B( TabValI, vCmd) + else + -- [C-Y2A] **ALLONTANAMENTO** (dall'origine) del trascinatore Y2 + EmitComment( vCmd, '[C-Y2A]') + _, dY2DeltaF = PosY2Y1A( TabValI, vCmd) + end + -- chiudo Y2 + table.insert( vCmd, { 12, 1}) + -- dichiaro Y1 da parcheggiare + WorkTab.bY1Parked = false + + -- [C(0)] - Se Y2 è già nell'intervallo valido, si lascia dove è + else + EmitComment( vCmd, '*[C(0)]') + if not WorkTab.bY1Parked then + -- dichiaro posizione di Y1 e T + table.insert( vCmd, { 2, 'T', WorkTab.dTPosI, 'Y1', dY1PosI}) + end + if WorkTab.bY2Parked then + -- chiudo Y2 + table.insert( vCmd, { 12, 1}) + end + dY2DeltaF = WorkTab.dY2DeltaI + end + + if not WorkTab.bY1Parked then + -- apro e parcheggio Y1 + table.insert( vCmd, { 11, 0}) + EMC.CNT = nil + table.insert( vCmd, { 1, 'Y1', ParkY1}) + end + + -- aggiorno e segnalo la posizione finale Y2Delta + table.insert( vCmd, { 21, 0, dY2DeltaF}) + EgtOutLog( ' Y2DeltaF=' .. EgtNumToString( dY2DeltaF)) + -- segnalo la posizione dei rulli + table.insert( vCmd, { 22, WorkTab.dV1PosF, WorkTab.dV2PosF}) + + SpecOutputCNT() + return vCmd +end -- SpecAdjustCarrC2 + +--------------------------------------------------------------------- +function SpecOutputCNT() + if EMC.CNT == 1 then + EgtSetInfo( EMC.PATHID, 'CNT', 1) + else + EgtRemoveInfo( EMC.PATHID, 'CNT') + end +end + +--------------------------------------------------------------------- +function SpecGetCNT( CurrOpeId) + while CurrOpeId do + local nPrevOpeId = EgtGetPrevActiveOperation( CurrOpeId) + if not nPrevOpeId then + return nil + end + local nLastPathId = EgtGetLastInGroup( EgtGetFirstNameInGroup( nPrevOpeId, 'CL') or GDB_ID.NULL) + if nLastPathId then + return EgtGetInfo( nLastPathId, 'CNT', 'i') + end + CurrOpeId = nPrevOpeId + end + return nil +end + +--------------------------------------------------------------------- +function SpecOutputCmds( vCmd, bEnd) + local sRoot = EgtIf( not bEnd, 'AS', 'AE') + -- Registro il numero di comandi + if #vCmd > 0 then + EgtSetInfo( EMC.PATHID, sRoot..'#', #vCmd) + else + EgtRemoveInfo( EMC.PATHID, sRoot..'#') + end + -- Registro i comandi + for i = 1, #vCmd do + local Cmd = vCmd[i] + local sKey = sRoot .. tostring( i) + -- commento + if Cmd[1] == 0 then + local sInfo = '0,'..Cmd[2] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 1 asse + elseif Cmd[1] == 1 then + local sInfo = '1,'..Cmd[2]..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 2 assi + elseif Cmd[1] == 2 then + local sInfo = '2,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- movimento di 3 assi + elseif Cmd[1] == 3 then + local sInfo = '3,'..Cmd[2]..','..EgtNumToString( Cmd[3],3)..','..Cmd[4]..','..EgtNumToString( Cmd[5],3)..','.. + Cmd[6]..','..EgtNumToString( Cmd[7],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- posizione sicura per movimento carrelli + elseif Cmd[1] == 4 then + local sInfo = '4,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- apertura/chiusura morsa Y + elseif Cmd[1] == 11 then + local sInfo = '11,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- apertura/chiusura morsa V + elseif Cmd[1] == 12 then + local sInfo = '12,'..EgtNumToString( Cmd[2],0) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- impostazione nuovo stato dei carrelli + elseif Cmd[1] == 21 then + local sInfo = '21,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = nil + elseif Cmd[3] > 0 then + EMC.Y1DELTA = nil + EMC.Y2DELTA = Cmd[3] + end + -- impostazione nuova posizione dei rulli + elseif Cmd[1] == 22 then + local sInfo = '22,'..EgtNumToString( Cmd[2],3)..','..EgtNumToString( Cmd[3],3) + EgtSetInfo( EMC.PATHID, sKey, sInfo) + EMC.V1POS = Cmd[2] + EMC.V2POS = Cmd[3] + -- aggancio grezzo a carrello + elseif Cmd[1] == 31 then + local sInfo = '31,'..EgtNumToString( Cmd[2],0)..','..Cmd[3] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + -- segnalazione errore + elseif Cmd[1] == 99 then + local sInfo = '99,' .. Cmd[2] .. ',' .. Cmd[3] + EgtSetInfo( EMC.PATHID, sKey, sInfo) + end + end + + -- Salvo i nuovi delta dei carrelli + if EMC.Y1DELTA then + EgtSetInfo( EMC.PATHID, 'Y1DELTA', EMC.Y1DELTA) + else + EgtRemoveInfo( EMC.PATHID, 'Y1DELTA') + end + if EMC.Y2DELTA then + EgtSetInfo( EMC.PATHID, 'Y2DELTA', EMC.Y2DELTA) + else + EgtRemoveInfo( EMC.PATHID, 'Y2DELTA') + end + + --Salvo le nuove posizioni dei rulli + EgtSetInfo( EMC.PATHID, 'V1POS', EMC.V1POS) + EgtSetInfo( EMC.PATHID, 'V2POS', EMC.V2POS) + -- Se comandi finali + if bEnd then + -- Se operazione successiva è disposizione, salvo anche lì le posizioni dei rulli + local NextDispId = EgtGetPhaseDisposition( EMC.PHASE + 1) + if NextDispId and NextDispId == EgtGetNextActiveOperation( EMC.DISPID or EMC.MCHID) then + EgtSetInfo( NextDispId, 'V1POS', EMC.V1POS) + EgtSetInfo( NextDispId, 'V2POS', EMC.V2POS) + end + end + +end + +--------------------------------------------------------------------- +function SpecSetCarrPosFromCmds( vCmd) + -- recupero nuova posizione carrelli + for i = 1, #vCmd do + local Cmd = vCmd[i] + if Cmd[1] == 21 then + if Cmd[2] > 0 and Cmd[3] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = Cmd[3] + elseif Cmd[2] > 0 then + EMC.Y1DELTA = Cmd[2] + EMC.Y2DELTA = nil + elseif Cmd[3] > 0 then + EMC.Y1DELTA = nil + EMC.Y2DELTA = Cmd[3] + end + elseif Cmd[1] == 22 then + EMC.V1POS = Cmd[2] + EMC.V2POS = Cmd[3] + end + end +end + +--------------------------------------------------------------------- +function SpecTestOnlyRemarkInCmds( vCmd) + if not vCmd then return true end + -- verifico se nella lista dei comandi ci sono solo commenti + for i = 1, #vCmd do + if vCmd[i][1] ~= 0 then + return false + end + end + return true +end + +--------------------------------------------------------------------- +function SpecTestSomeMoveInCmds( vCmd) + if not vCmd then return false end + -- verifico se nella lista dei comandi c'è almeno un movimento + for i = 1, #vCmd do + if vCmd[i][1] == 1 or vCmd[i][1] == 2 or vCmd[i][1] == 3 then + return true + end + end + return false +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.nge new file mode 100644 index 0000000..e509b63 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250rl.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250rl.ini new file mode 100644 index 0000000..3c22471 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250rl.ini @@ -0,0 +1,64 @@ +; Commento per evitare BOM con UTF-8 +[General] +Material=Beam + +[Tools] +Drillbit=1 +Sawblade=1 +Mill=1 +Mortise=1 +Chisel=0 +DrillMaker=MakeWoodDrill.lua +SawbladeMaker=MakeSawblade.lua +MillMaker=MakeWoodCylMill.lua +MortiseMaker=MakeMortise.lua +ChiselMaker=MakeChisel.lua +Active=1 + +[ToolHolder] +H11.1=Standard.nge +H11.1:MILL_NOTIP=MillNoTip.nge +H12.1=Saw.nge +H13.1=ChainSaw.nge +H21.1=Standard.nge +H21.1:MILL_NOTIP=MillNoTip.nge +H21.1:SAW_FLAT=SawH2.nge + +[Machinings] +Drilling=1 +Sawing=1 +Milling=1 +Pocketing=1 +Mortising=1 +Chiseling=0 +SawRoughing=0 +SawFinishing=0 + +[Machining] +InitScript=InitMach.lua +ExitScript=ExitMach.lua + +[Disposition] +;InitScript=InitDisp.lua + +[Heads] +; 5 axis head +H11=6608 +; 5 axis saw +H12=6615 +; Chainsaw +H13=6616 +; Second 5 axis head +H21=6620 + +[SetUp] +Default=Standard + +[Estimations] +Enable=1 +WinPlace=0,514,138,628,810 + +[VMill] +Enable=1 +Save=0 + diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250rl.mlde b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250rl.mlde new file mode 100644 index 0000000..a87d483 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Essetre-PF1250rl.mlde @@ -0,0 +1,858 @@ +-- Descrizione macchina Essetre-PF1250rl by EgalTech s.r.l. 2021/10/04 +-- 2021/08/03 ver 2.3h1 Prima versione. +-- 2021/09/14 ver 2.3i9 Estesa gestione sega a catena. +-- 2021/09/16 ver 2.3i10 Correzione per apertura paratie per Zmax appena dopo split. +-- 2021/09/21 ver 2.3i11 Correzione gestione ultima lavorazione di pareti. Gestione AggLoad. +-- Correzione movimento pezzi rimanenti allo split. Aggiunta gestione Uso Trieste (UT- in info MATERIAL del pezzo). +-- 2021/09/26 ver 2.3i18 Riportate tutte le modifiche da PF1250 e aggiunta gestione secondo TC per testa sopra. +-- 2021/10/03 ver 2.3j1 Ripristinata risalita lama a Z sicura se troppo bassa indipendentemente da Flag e Flag2 (mlse). +-- 2021/10/04 ver 2.3j2 Aggiunto controllo Z1 minima per abilitare durante la lavorazione il cambio di H2. + +-- Intestazioni +require( 'EmtGenerator') +EgtEnableDebug( false) + +PP_VER = '2.3j3' + +-- Parametri macchina +NumericalControl = 'TPA' -- NUM o TPA +MinMchY1 = 335 +MaxMchY1 = 5790.0 +ParkMchY1 = 970.0 +MinMchY2 = -5775.0 +MaxMchY2 = -324 +ParkMchY2 = -955.0 +MinV1 = 5.0 +MaxV1 = 640.0 +ParkV1 = 609.0 +MinV2 = -635.0 +MaxV2 = -5.0 +ParkV2 = -609.0 +MinDeltaYV = 317 + 0.1 +MinY1 = MinV1 + MinDeltaYV +MaxY1 = MaxMchY1 +MaxY2 = MaxV2 - MinDeltaYV +MinY2 = MinMchY2 +ParkY1 = ParkV1 + MinDeltaYV +ParkY2 = ParkV2 - MinDeltaYV +LoadT = 2172.8 +UnloadT = -2400 +UnloadSmT = UnloadT - 300 +MaxHoOpen = 1300 +MaxVeOpen = 420 +RollCageMin = 120 +RollCageMax = 250 +MillOffs = 170.0 +SawOffsX = 111.0 +SawOffsY = 0 +SawOffsZ = -150.25 +SawC1Offs = 0 +SawB1Offs = 0 +ChSawLen = 90.0 +Mill2Offs = 170.0 +SawC2Offs = 0 +SawB2Offs = 0 +MinX1 = 0 +MaxX1 = 3300 +MinZ1 = -1550 +MaxZ1 = -100 +MinC1 = -275 +MaxC1 = 275 +MinB1 = -127 +MaxB1 = 127 +MinB1b = -119 +MaxB1b = 119 +ParkX1 = 250 +ParkTc2X1 = 3100 +ParkZ1 = -535 +ParkC1 = -90 +ParkB1 = -90 +ParkCSawX1 = 1500 +ParkCSawZ1 = -100 +ParkCSaw0Z1 = -400 +ParkCSawC1 = -90 +ParkCSaw0C1 = 0 +ParkCSawB1 = 0 +MinZ1ToChangeH2 = -1400 +MinX2 = -2760 +MaxX2 = 0 +MinZ2 = 0 +MaxZ2 = 795 +MinC2 = -275 +MaxC2 = 275 +MinB2 = -127 +MaxB2 = 127 +ParkX2 = -100 +ParkZ2 = 0 +ParkC2 = -90 +ParkB2 = -90 +TurnerOffs = 120.0 +AggLoad = 50 +DeltaTabY = 1200.0 +DeltaTabZ = -1137.5 + MillOffs -- per TPA : -1128.0 + MillOffs -- per NUM : -958.0 +DeltaRulliTraveZ = -903 +DimTabY = 1400 +DimTabX = 24000 +Delta2TabY = -2235.9 +Delta2TabZ = 395.2 - Mill2Offs -- per TPA : 378.0 - Mill2Offs -- per NUM : 208.0 +Head2X = 0 +Head2Y = DeltaTabY - Delta2TabY +Head2Z = DeltaTabZ - Delta2TabZ +DefTcPos1 = 'T1' +DefTcPos2 = 'T20' +CoeffVM = 0.5 +Tc2Active = true + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Beam', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-PF1250rl.data" +local sData = EgtGetSourceDir().."\\Beam\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Offsets then + --NumericalControl = EgtIf( Machine.Offsets.TIPO_CN == 0, 'NUM', 'TPA') + if Machine.Offsets.X1_POS then MinX1 = -Machine.Offsets.X1_POS end + if Machine.Offsets.X1_NEG then MaxX1 = -Machine.Offsets.X1_NEG end + if Machine.Offsets.Z1_NEG then MinZ1 = Machine.Offsets.Z1_NEG end + if Machine.Offsets.Z1_POS then MaxZ1 = min( MaxZ1, Machine.Offsets.Z1_POS) end + if Machine.Offsets.PARK_Z1 then ParkZ1 = Machine.Offsets.PARK_Z1 end + if Machine.Offsets.C1_NEG then MinC1 = Machine.Offsets.C1_NEG end + if Machine.Offsets.C1_POS then MaxC1 = Machine.Offsets.C1_POS end + if Machine.Offsets.B1_NEG then MinB1 = Machine.Offsets.B1_NEG end + if Machine.Offsets.B1_POS then MaxB1 = Machine.Offsets.B1_POS end + if Machine.Offsets.B1_NEG1 then MinB1b = Machine.Offsets.B1_NEG1 end + if Machine.Offsets.B1_POS1 then MaxB1b = Machine.Offsets.B1_POS1 end + if Machine.Offsets.X2_NEG then MinX2 = Machine.Offsets.X2_NEG end + if Machine.Offsets.X2_POS then MaxX2 = Machine.Offsets.X2_POS end + if Machine.Offsets.Z2_POS then MinZ2 = -Machine.Offsets.Z2_POS end + if Machine.Offsets.Z2_NEG then MaxZ2 = -Machine.Offsets.Z2_NEG end + if Machine.Offsets.PARK_Z2 then ParkZ2 = -Machine.Offsets.PARK_Z2 end + if Machine.Offsets.C2_NEG then MinC2 = Machine.Offsets.C2_NEG end + if Machine.Offsets.C2_POS then MaxC2 = Machine.Offsets.C2_POS end + if Machine.Offsets.B2_NEG then MinB2 = Machine.Offsets.B2_NEG end + if Machine.Offsets.B2_POS then MaxB2 = Machine.Offsets.B2_POS end + if Machine.Offsets.MIN_Y1 then MinMchY1 = Machine.Offsets.MIN_Y1 end + if Machine.Offsets.MAX_Y1 then MaxMchY1 = Machine.Offsets.MAX_Y1 end + if Machine.Offsets.PARK_Y1 then ParkMchY1 = Machine.Offsets.PARK_Y1 end + if Machine.Offsets.MIN_V1 then MinV1 = Machine.Offsets.MIN_V1 end + if Machine.Offsets.MAX_V1 then MaxV1 = Machine.Offsets.MAX_V1 end + if Machine.Offsets.MIN_Y2 then MinMchY2 = Machine.Offsets.MIN_Y2 end + if Machine.Offsets.MAX_Y2 then MaxMchY2 = Machine.Offsets.MAX_Y2 end + if Machine.Offsets.PARK_Y2 then ParkMchY2 = Machine.Offsets.PARK_Y2 end + if Machine.Offsets.MIN_V2 then MinV2 = Machine.Offsets.MIN_V2 end + if Machine.Offsets.MAX_V2 then MaxV2 = Machine.Offsets.MAX_V2 end + if Machine.Offsets.DIST_FTZERO then LoadT = Machine.Offsets.DIST_FTZERO end + if Machine.Offsets.DELTA_CARICZERO then TurnerOffs = Machine.Offsets.DELTA_CARICZERO end + if Machine.Offsets.MIN_DELTAVY then MinDeltaYV = Machine.Offsets.MIN_DELTAVY + 0.1 end + if Machine.Offsets.DIST_UNLOAD then UnloadT = Machine.Offsets.DIST_UNLOAD end + if Machine.Offsets.PIVOT_T1 then MillOffs = Machine.Offsets.PIVOT_T1 end + if Machine.Offsets.PIVOT_T2 then Mill2Offs = Machine.Offsets.PIVOT_T2 end + if Machine.Offsets.OFFSETCLAMAT1 then SawC1Offs= Machine.Offsets.OFFSETCLAMAT1 end + if Machine.Offsets.OFFSETBLAMAT1 then SawB1Offs= Machine.Offsets.OFFSETBLAMAT1 end + if Machine.Offsets.OFFSETCLAMAT2 then SawC2Offs= Machine.Offsets.OFFSETCLAMAT2 end + if Machine.Offsets.OFFSETBLAMAT2 then SawB2Offs= Machine.Offsets.OFFSETBLAMAT2 end + if Machine.Offsets.OFFSETXT1 then DeltaTabY = -Machine.Offsets.OFFSETXT1 end + if Machine.Offsets.OFFSETZT1 then DeltaTabZ = Machine.Offsets.OFFSETZT1 + MillOffs end + if Machine.Offsets.OFFSETXT2 then Delta2TabY = Machine.Offsets.OFFSETXT2 end + if Machine.Offsets.OFFSETZT2 then Delta2TabZ = -Machine.Offsets.OFFSETZT2 - MillOffs end + if Machine.Offsets.OFFSETZSOTTOTRAVE then DeltaRulliTraveZ = -abs( Machine.Offsets.OFFSETZSOTTOTRAVE) end + -- aggiustamenti + MinY1 = MinV1 + MinDeltaYV + MaxY1 = MaxMchY1 + ParkV1 = MaxV1 + ParkY1 = ParkV1 + MinDeltaYV + MinY2 = MinMchY2 + MaxY2 = MaxV2 - MinDeltaYV + ParkV2 = MinV2 + ParkY2 = ParkV2 - MinDeltaYV + UnloadSmT = UnloadT - 300 + Head2Y = DeltaTabY - Delta2TabY + Head2Z = DeltaTabZ - Delta2TabZ + ParkCSawZ1 = min( ParkCSawZ1, MaxZ1) + end + end +end + +EmtGeneral { + File='Essetre-PF1250.nge', + Offset = Vector3d(0.0,1360.0,-2130.0), + AxisMaxAdjust = 300, + ExitMaxAdjust = 300, + AngDeltaMinForHome = 80, + Special = 'Essetre-PF1250.mlse', + Processor = 'Essetre-PF1250.mlpe'} +local sBaseAux = {'BASE/SOLID', 'BASE/CONVOYER', 'BASE/COLLISION', 'BASE/TC1', 'BASE/TCR', 'BASE/TC3'} +if Tc2Active then table.insert( sBaseAux, 5, 'BASE/TC2') end +local BaseId = EmtBase { + Name = 'Base', + Geo = 'BASE/GEO', + Aux = sBaseAux} +local X1Id = EmtAxis { + Name = 'X1', + Parent = 'Base', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(207.0,-300.0,104.0), + Stroke = {MinX1, MaxX1}, + Home = ParkX1, + Invert = true, + Geo = 'X1_AXIS/GEO', + Aux = 'X1_AXIS/SOLID'} +-- *** Testa 1 *** +EmtAxis { + Name = 'Z1', + Parent = 'X1', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(0.0,-140.1,113.0), + Stroke = {MinZ1, MaxZ1}, + Home = ParkZ1, + Geo = 'Z1_AXIS/GEO', + Aux = {'Z1_AXIS/SOLID', 'Z1_AXIS/COLLISION'}} +EmtAxis { + Name = 'C1', + Parent = 'Z1', + Token = 'C', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d(0.0,0.0,503.0), + Stroke = {MinC1, MaxC1}, + Home = ParkC1, + Geo = 'C1_AXIS/GEO', + Aux = {'C1_AXIS/SOLID', 'C1_AXIS/COLLISION'}} +EmtAxis { + Name = 'B1', + Parent = 'C1', + Token = 'B', + Type = MCH_AT.ROTARY, + Dir = X_AX(), + Pos = Point3d(-108.4,0.0,MillOffs), + Stroke = {MinB1, MaxB1}, + Home = ParkB1, + Geo = 'B1_AXIS/GEO', + Aux = {'B1_AXIS/SOLID', 'B1_AXIS/COLLISION'}} +-- Frese +local H11Id = EmtHead { + Name = 'H11', + Parent = 'B1', + HSet = 'H11', + Type = MCH_HT.STD, + Pos = Point3d(0,0,0), + TDir = Z_AX(), + ADir = -Y_AX(), + Rot1W = 0.2, + Rot2Stroke = { MinB1, MaxB1}, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H11_HEAD/GEO'} +EgtSetInfo( H11Id, 'ZEXTRA', '250,60') +-- Lama +local H12Id = EmtHead { + Name = 'H12', + Parent = 'B1', + HSet = 'H11', + Type = MCH_HT.STD, + Pos = Point3d(SawOffsX,SawOffsY,SawOffsZ), + TDir = Z_AX(), + ADir = -X_AX(), + Rot1W = 0.5, + Rot2Stroke = { MinB1b, MaxB1b}, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H12_HEAD/GEO'} +EgtSetInfo( H12Id, 'ZEXTRA', '160,60') +EgtSetInfo( H12Id, 'ZMAXONROT', '1,190') +-- Sega a catena +EmtAxis { + Name = 'A', + Parent = 'B1', + Token = '**', + Type = MCH_AT.ROTARY, + Dir = Z_AX(), + Pos = Point3d( 0, 0, 0), + Stroke = { 0, 270}, + Home = 0, + Geo = 'A_AXIS/GEO'} +local H13Id = EmtHead { + Name = 'H13', + Parent = 'A', + HSet = 'H11', + Type = MCH_HT.STD, + Pos = Point3d(0,0,-ChSawLen), + TDir = -X_AX(), + ADir = Z_AX(), + Rot1W = 0.2, + Rot2Stroke = { -90.1, 90.1}, + SolCh = MCH_SCC.ADIR_NEAR, + OthColl = {'B1/SOLID', 'C1/SOLID'}, + Geo = 'H13_HEAD/GEO'} +EgtSetInfo( H13Id, 'ZEXTRA', '200') +EgtSetInfo( H13Id, 'ZSAFEDELTA', '60') +EgtSetInfo( H13Id, 'ZMAXONROT', '1,80') +-- Dummy +EmtHead { + Name = 'H14', + Parent = 'B1', + HSet = 'H14', + Type = MCH_HT.STD, + Pos = Point3d(0,0,0), + TDir = Z_AX(), + ADir = X_AX(), + Rot1W = 0.2, + Geo = 'H14_HEAD/GEO'} +-- *** Testa 2 *** +local Z2Id = EmtAxis { + Name = 'Z2', + Parent = 'Base', + Token = 'Z', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(291.0,-140.1,-2056.3), + Stroke = {MinZ2, MaxZ2}, + Home = ParkZ2, + Invert = true, + Geo = 'Z2_AXIS/GEO', + Aux = {'Z2_AXIS/SOLID', 'Z2_AXIS/COLLISION'}} +local X2Id = EmtAxis { + Name = 'X2', + Parent = 'Z2', + Token = 'X', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(115.8,3065.9,-1738.0), + Stroke = {MinX2, MaxX2}, + Home = ParkX2, + Geo = 'X2_AXIS/GEO', + Aux = {'X2_AXIS/SOLID', 'X2_AXIS/COLLISION'}} +local C2Id = EmtAxis { + Name = 'C2', + Parent = 'X2', + Token = 'C', + Type = MCH_AT.ROTARY, + Dir = -Z_AX(), + Pos = Point3d( Head2X, Head2Y, Head2Z-485), + Stroke = {MinC2, MaxC2}, + Home = ParkC2, + Geo = 'C2_AXIS/GEO', + Aux = {'C2_AXIS/SOLID', 'C2_AXIS/COLLISION'}} +local B2Id = EmtAxis { + Name = 'B2', + Parent = 'C2', + Token = 'B', + Type = MCH_AT.ROTARY, + Dir = X_AX(), + Pos = Point3d( Head2X, Head2Y, Head2Z-Mill2Offs), + Stroke = {MinB2, MaxB2}, + Home = ParkB2, + Geo = 'B2_AXIS/GEO', + Aux = {'B2_AXIS/SOLID', 'B2_AXIS/COLLISION'}} +local vtMoveZ2 = Vector3d( 0, 0, Head2Z + 1181.0) +EgtMove( EgtGetFirstNameInGroup( Z2Id, 'SOLID'), vtMoveZ2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Z2Id, 'COLLISION'), vtMoveZ2, GDB_RT.GLOB) +local vtMoveX2 = Vector3d( 0, Head2Y - 3435.9, Head2Z + 1181.0) +EgtMove( EgtGetFirstNameInGroup( X2Id, 'SOLID'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X2Id, 'COLLISION'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( C2Id, 'SOLID'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( C2Id, 'COLLISION'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( B2Id, 'SOLID'), vtMoveX2, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( B2Id, 'COLLISION'), vtMoveX2, GDB_RT.GLOB) +-- Frese +local H21Id = EmtHead { + Name = 'H21', + Parent = 'B2', + HSet = 'H21', + Type = MCH_HT.STD, + Pos = Point3d( Head2X, Head2Y, Head2Z), + TDir = -Z_AX(), + Rot1W = 0.2, + Rot2Stroke = { MinB2, MaxB2}, + OthColl = {'B2/SOLID', 'C2/SOLID'}, + Geo = 'H21_HEAD/GEO'} +EgtSetInfo( H21Id, 'ABOVE', '0') +EgtSetInfo( H21Id, 'ZHOMEDOWN', '1') +-- *** Carrelli *** +-- Morse +local Y1Id = EmtAxis { + Name = 'Y1', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(-865.7,2626.8,-866.0), + Stroke = { MinY1, MaxY1}, + Home = ParkY1, + Geo = 'Y1_AXIS/GEO', + Aux = 'Y1_AXIS/SOLID'} +local PY1Id = EmtAxis { + Name = 'PY1', + Parent = 'Y1', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(-469.6,2367.5,-751.6), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PY1_AXIS/GEO', + Aux = 'PY1_AXIS/SOLID'} +local Y2Id = EmtAxis { + Name = 'Y2', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(865.7,2626.8,-866.0), + Stroke = { MinY2, MaxY2}, + Home = ParkY2, + Geo = 'Y2_AXIS/GEO', + Aux = 'Y2_AXIS/SOLID'} +local PY2Id = EmtAxis { + Name = 'PY2', + Parent = 'Y2', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(469.6,2367.5,-751.6), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PY2_AXIS/GEO', + Aux = 'PY2_AXIS/SOLID'} +-- Rulli +local V1Id = EmtAxis { + Name = 'V1', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(-875.5,1072.0,-1509.1), + Stroke = { MinV1, MaxV1}, + Home = ParkV1, + Geo = 'V1_AXIS/GEO', + Aux = {'V1_AXIS/SOLID', 'V1_AXIS/COLLISION'}} +local PV1Id = EmtAxis { + Name = 'PV1', + Parent = 'V1', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(-194.0,2364.7,-879.1), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PV1_AXIS/GEO', + Aux = 'PV1_AXIS/SOLID'} +local QV1Id = EmtAxis { + Name = 'QV1', + Parent = 'V1', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(-287.0,2481.0,-943.0), + Stroke = {0, MaxVeOpen}, + Home = MaxVeOpen, + Geo = 'QV1_AXIS/GEO', + Aux = 'QV1_AXIS/SOLID'} +local V2Id = EmtAxis { + Name = 'V2', + Parent = 'Base', + Type = MCH_AT.LINEAR, + Dir = -X_AX(), + Pos = Point3d(875.5,1072.0,-1509.1), + Stroke = { MinV2, MaxV2}, + Home = ParkV2, + Geo = 'V2_AXIS/GEO', + Aux = {'V2_AXIS/SOLID', 'V2_AXIS/COLLISION'}} +local PV2Id = EmtAxis { + Name = 'PV2', + Parent = 'V2', + Type = MCH_AT.LINEAR, + Dir = Y_AX(), + Pos = Point3d(194.0,2364.7,-879.1), + Stroke = {0, MaxHoOpen}, + Home = MaxHoOpen, + Geo = 'PV2_AXIS/GEO', + Aux = 'PV2_AXIS/SOLID'} +local QV2Id = EmtAxis { + Name = 'QV2', + Parent = 'V2', + Type = MCH_AT.LINEAR, + Dir = Z_AX(), + Pos = Point3d(287.0,2481.0,-943.0), + Stroke = {0, MaxVeOpen}, + Home = MaxVeOpen, + Geo = 'QV2_AXIS/GEO', + Aux = 'QV2_AXIS/SOLID'} +-- *** Tavola *** +EmtAxis { + Name = 'T', + Parent = 'Base', + --Token = '**', + Type = MCH_AT.LINEAR, + Dir = - X_AX(), + Pos = Point3d(0.0,2450.0,-958.0), + Stroke = {-20000, 20000}, + Home = LoadT, + Geo = 'T_AXIS/GEO'} +EmtTable { + Name = 'Tab', + Parent = 'T', + Type = MCH_TT.FLAT, + Ref1 = Point3d( - DimTabX, DeltaTabY, DeltaTabZ), + Geo = 'TABLE/GEO', + Aux = 'TABLE/SOLID'} +-- *** ToolChanger *** +local ptTc1 = Point3d( 150, -151, -221 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) +local vtDt1 = Vector3d( 0, 0, - 102.5) +EmtTcPos { + Name = 'T1', + Parent = 'Base', + Pos = ptTc1 + Vector3d( SawOffsX, SawOffsZ, 0), + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T1'} +EmtTcPos { + Name = 'T3', + Parent = 'Base', + Pos = ptTc1 + 2 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T3'} +EmtTcPos { + Name = 'T4', + Parent = 'Base', + Pos = ptTc1 + 3 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T4'} +EmtTcPos { + Name = 'T5', + Parent = 'Base', + Pos = ptTc1 + 4 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T5'} +EmtTcPos { + Name = 'T6', + Parent = 'Base', + Pos = ptTc1 + 5 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T6'} +EmtTcPos { + Name = 'T7', + Parent = 'Base', + Pos = ptTc1 + 6 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T7'} +EmtTcPos { + Name = 'T8', + Parent = 'Base', + Pos = ptTc1 + 7 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T8'} +EmtTcPos { + Name = 'T9', + Parent = 'Base', + Pos = ptTc1 + 8 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T9'} +EmtTcPos { + Name = 'T10', + Parent = 'Base', + Pos = ptTc1 + 9 * vtDt1, + TDir = Y_AX(), + ADir = -X_AX(), + Geo = 'BASE/T10'} +if Tc2Active then + local ptTc2 = Point3d( 150, 3617, -118.5 + ( DeltaTabZ - DeltaRulliTraveZ + 55)) + local vtDt2 = Vector3d( 0, 0, - 102.5) + EmtTcPos { + Name = 'T11', + Parent = 'Base', + Pos = ptTc2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T11'} + EmtTcPos { + Name = 'T12', + Parent = 'Base', + Pos = ptTc2 + 1 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T12'} + EmtTcPos { + Name = 'T13', + Parent = 'Base', + Pos = ptTc2 + 2 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T13'} + EmtTcPos { + Name = 'T14', + Parent = 'Base', + Pos = ptTc2 + 3 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T14'} + EmtTcPos { + Name = 'T15', + Parent = 'Base', + Pos = ptTc2 + 4 * vtDt2, + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T15'} +end +local ptTc3 = Point3d( 480, 529, -200.8) +EmtTcPos { + Name = 'T101', + Parent = 'Base', + Pos = ptTc3, + TDir = -X_AX(), + ADir = Z_AX(), + Geo = 'BASE/T101'} +local ptTcR = Point3d( -0.5, 3815, -1571.2) +EmtTcPos { + Name = 'T20', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -30, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T20'} +EmtTcPos { + Name = 'T21', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -60, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T21'} +EmtTcPos { + Name = 'T22', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -90, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T22'} +EmtTcPos { + Name = 'T23', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -120, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T23'} +EmtTcPos { + Name = 'T24', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -150, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T24'} +EmtTcPos { + Name = 'T25', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -180, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T25'} +EmtTcPos { + Name = 'T26', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -210, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T26'} +EmtTcPos { + Name = 'T27', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -240, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T27'} +EmtTcPos { + Name = 'T28', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -270, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T28'} +EmtTcPos { + Name = 'T29', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -300, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T29'} +EmtTcPos { + Name = 'T30', + Parent = 'Base', + Pos = ptTcR + VectorFromSpherical( 324.3, -330, 0), + TDir = -Y_AX(), + ADir = X_AX(), + Geo = 'BASE/T30'} + +-- Aggiusto posizioni geometriche +local vtMovB = Vector3d( 0, 0, ( DeltaTabZ - DeltaRulliTraveZ + 55)) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SOLID'), vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'COLLISION'), vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'SIGN') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC1') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC1S') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC2') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC3') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'MTC') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'TC3') or GDB_ID.NULL, vtMovB, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( X1Id, 'SOLID'), vtMovB, GDB_RT.GLOB) +local vtMove = Vector3d( 0, ( DeltaTabY - 1200.0), ( DeltaTabZ + 958.0)) +EgtMove( EgtGetFirstNameInGroup( BaseId, 'CONVOYER'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Y1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PY1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( Y2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PY2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( V1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PV1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( QV1Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( V2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( PV2Id, 'SOLID'), vtMove, GDB_RT.GLOB) +EgtMove( EgtGetFirstNameInGroup( QV2Id, 'SOLID'), vtMove, GDB_RT.GLOB) + +-- Assegno identificativi alle spie delle morse +PY1LightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( Y1Id, 'SOLID') or GDB_ID.NULL, 'Light') +PY2LightId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( Y2Id, 'SOLID') or GDB_ID.NULL, 'Light') + +--------------------------------------------------------------------- +-- Funzioni richiamate per modificare i dati macchina in casi particolari +--function OnSetTable() +--end + +--------------------------------------------------------------------- +function OnSetHead() + -- se testa H11 (fresa) + if EMC.HEAD == 'H11' then + if GetTcForTopHeadTool( EMC.TCPOS) ~= 2 then + EmtModifyAxisHome( 'X1', ParkX1) + else + EmtModifyAxisHome( 'X1', ParkTc2X1) + end + EmtModifyAxisHome( 'Z1', ParkZ1) + EmtModifyAxisHome( 'C1', ParkC1) + EmtModifyAxisHome( 'B1', ParkB1) + -- se testa H12 (lama) + elseif EMC.HEAD == 'H12' then + EmtModifyAxisHome( 'X1', ParkX1) + EmtModifyAxisHome( 'Z1', ParkZ1) + EmtModifyAxisHome( 'C1', ParkC1) + EmtModifyAxisHome( 'B1', ParkB1) + -- se testa H13 (sega a catena) + elseif EMC.HEAD == 'H13' then + -- recupero valore asse A bloccato + local sVal = EgtGetMachiningParam( MCH_MP.BLOCKEDAXIS) + CSawPosA = tonumber( sVal:sub( 3) or '') + EmtModifyAxisHome( 'X1', ParkCSawX1) + EmtModifyAxisHome( 'Z1', GetChainSawZHomeFromVirtualAxis( CSawPosA)) + EmtModifyAxisHome( 'C1', GetChainSawCHomeFromVirtualAxis( CSawPosA)) + EmtModifyAxisHome( 'B1', ParkCSawB1) + end +end + +--------------------------------------------------------------------- +-- Funzione che riconosce TC per utensili testa sopra +function GetTcForTopHeadTool( sTcPos) + if sTcPos == 'T1' or sTcPos == 'T3' or sTcPos == 'T4' or sTcPos == 'T5' or + sTcPos == 'T6' or sTcPos == 'T7' or sTcPos == 'T8' or sTcPos == 'T9' or sTcPos == 'T10' then + return 1 + elseif sTcPos == 'T11' or sTcPos == 'T12' or sTcPos == 'T13' or sTcPos == 'T14' or sTcPos == 'T15' then + return 2 + else + return 0 + end +end + +--------------------------------------------------------------------- +-- Funzione che riconosce testa per sega a catena +function HeadIsChainSaw( sHead) + return ( sHead == 'H13' or sHead == 'H15') +end + +--------------------------------------------------------------------- +-- Funzione che calcola la posizione Home di Z per la sega a catena dal valore dell'asse virtuale +function GetChainSawZHomeFromVirtualAxis( dPosA) + -- se A=0 -> T101 -> HomeZ = -400 + if abs( dPosA) < 0.1 then + return ParkCSaw0Z1 + -- altrimenti A=-90 -> T102 o A=90 -> T104 -> HomeZ = -100 + else + return ParkCSawZ1 + end +end + +--------------------------------------------------------------------- +-- Funzione che calcola l'angolo Home di C per la sega a catena dal valore dell'asse virtuale +--------------------------------------------------------------------- +function GetChainSawCHomeFromVirtualAxis( dPosA) + -- se A=0 -> T101 -> HomeC = 0 + if abs( dPosA) < 0.1 then + return ParkCSaw0C1 + -- altrimenti A=90 -> T104 -> HomeC = -90 + else + return ParkCSawC1 + end +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello Y1 +function SetPY1Light( bClosed) + if not PY1LightId then return end + EgtSetColor( PY1LightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PY1LightId, 'On', '1') + else + EgtRemoveInfo( PY1LightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello Y1 +function GetPY1Light() + if not PY1LightId then return false end + return ( EgtGetInfo( PY1LightId, 'On') == '1') +end + +--------------------------------------------------------------------- +-- Funzione per impostare spia stato morsa carrello Y2 +function SetPY2Light( bClosed) + if not PY2LightId then return end + EgtSetColor( PY2LightId, EgtIf( bClosed, 'RED', 'LIME')) + if bClosed then + EgtSetInfo( PY2LightId, 'On', '1') + else + EgtRemoveInfo( PY2LightId, 'On') + end +end + +--------------------------------------------------------------------- +-- Funzione per leggere lo stato della morsa carrello Y2 +function GetPY2Light() + if not PY2LightId then return false end + return ( EgtGetInfo( PY2LightId, 'On') == '1') +end + + +--------------------------------------------------------------------- +-- Funzione per resettare tutte le attivazioni della macchina +function OnResetMachine() + EmtUnlinkAllRawPartsFromGroups() + EmtUnlinkAllFixturesFromGroups() + SetPY1Light( false) + SetPY2Light( false) + -- nascondo Vmill + local nRawId = EgtGetFirstRawPart() + while nRawId do + local nVmId = EgtGetFirstNameInGroup( nRawId, 'VMill') + local nId = EgtGetFirstInGroup( nRawId) + while nId do + EgtSetStatus( nId, EgtIf( nId ~= nVmId, GDB_ST.ON, GDB_ST.OFF)) + nId = EgtGetNext( nId) + end + nRawId = EgtGetNextRawPart( nRawId) + end + EgtSetStatus( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'VMill') or GDB_ID.NULL, GDB_ST.OFF) +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Machinings/Machinings.data b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Machinings/Machinings.data new file mode 100644 index 0000000..c12a055 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Machinings/Machinings.data differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Machinings/Machinings.data.bak b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Machinings/Machinings.data.bak new file mode 100644 index 0000000..b4deb10 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Machinings/Machinings.data.bak differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Scripts/ExitMach.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Scripts/ExitMach.lua new file mode 100644 index 0000000..18f86ad --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Scripts/ExitMach.lua @@ -0,0 +1,36 @@ +-- 2018/11/21 17:30:00 +-- Machining Exit for Essetre-FAST machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Uscita da Lavorazioni *** + +-- Nascondo il pezzo così marcato e le geometrie aggiunte, visualizzo il Box +local function ProcessPart( PartId) + -- visualizzo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.ON) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice (già chiusi tutti i gruppi di lavoro) +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +EgtZoom( SCE_ZM.ALL, false) + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Scripts/InitMach.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Scripts/InitMach.lua new file mode 100644 index 0000000..6ac761b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Scripts/InitMach.lua @@ -0,0 +1,44 @@ +-- 2018/11/21 16:30:00 +-- Machining Init for Essetre-FAST machine + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-------------------------------------------------------------------------------- +-- *** Ingresso in Lavorazioni *** + +-- Rendo visibile il pezzo e le geometrie aggiunte, nascondo il Box +local function ProcessPart( PartId) + -- nascondo il Box + EgtSetStatus( EgtGetFirstNameInGroup( PartId, 'Box') or GDB_ID.NULL, GDB_ST.OFF) +end + +-- Disabilito segnalazione modifica progetto +local bEnMod = EgtGetEnableModified() +EgtDisableModified() + +-- Processo i pezzi nella radice +local PartId = EgtGetFirstPart() +while PartId do + ProcessPart( PartId) + PartId = EgtGetNextPart( PartId) +end + +-- Processo i pezzi già nei gruppi di lavoro (quando appena lanciata Process) +local GhostId = EgtGetFirstGhostPart() +while GhostId do + local PartId = EgtGetInfo( GhostId, GDB_SI.SOURCE, 'i') + if PartId then + ProcessPart( PartId) + end + GhostId = EgtGetNextGhostPart( GhostId) +end + +-- Ripristino segnalazione modifica progetto +if bEnMod then + EgtEnableModified() +end + +MACH.ERR = 0 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Scripts/SetUp.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Scripts/SetUp.lua new file mode 100644 index 0000000..6cdd4b5 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Scripts/SetUp.lua @@ -0,0 +1,240 @@ +-- 2020/12/10 +-- Gestione attrezzaggio per Essetre-PF1250 + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Tavola di passaggio valori +local STU = {} +STU.TUUID = "" +STU.TCPOS = "" +STU.HEAD = "" +STU.GROUP = "" +STU.POS = "" +STU.EXIT = 0 +STU.INDEX = 0 +STU.HEAD1 = "" +STU.HEAD2 = "" +STU.ISVALID = false +STU.ERR = 0 +_G.STU = STU + +local INVALIDPOS = "" +local POS = "Pos" + +-- Geom Set +local GS = {} + +-- Configurazione posizioni (con o senza TC2) +local PositionTable = {} +local bTc2Active = EgtGetFirstNameInGroup( EgtGetBaseId( 'Base'), 'TC2') +if bTc2Active then + PositionTable = {{Pos = "Pos1", TcPos = "T1", Head = "H12", Group = "G1"}, + {Pos = "Pos2", TcPos = "T3", Head = "H11", Group = "G1"}, + {Pos = "Pos3", TcPos = "T4", Head = "H11", Group = "G1"}, + {Pos = "Pos4", TcPos = "T5", Head = "H11", Group = "G1"}, + {Pos = "Pos5", TcPos = "T6", Head = "H11", Group = "G1"}, + {Pos = "Pos6", TcPos = "T7", Head = "H11", Group = "G1"}, + {Pos = "Pos7", TcPos = "T8", Head = "H11", Group = "G1"}, + {Pos = "Pos8", TcPos = "T9", Head = "H11", Group = "G1"}, + {Pos = "Pos9", TcPos = "T10", Head = "H11", Group = "G1"}, + {Pos = "Pos10", TcPos = "T101", Head = "H13", Group = "G2"}, + {Pos = "Pos11", TcPos = "T11", Head = "H11", Group = "G3"}, + {Pos = "Pos12", TcPos = "T12", Head = "H11", Group = "G3"}, + {Pos = "Pos13", TcPos = "T13", Head = "H11", Group = "G3"}, + {Pos = "Pos14", TcPos = "T14", Head = "H11", Group = "G3"}, + {Pos = "Pos15", TcPos = "T15", Head = "H11", Group = "G3"}, + {Pos = "Pos16", TcPos = "T20", Head = "H21", Group = "G4"}, + {Pos = "Pos17", TcPos = "T21", Head = "H21", Group = "G4"}, + {Pos = "Pos18", TcPos = "T22", Head = "H21", Group = "G4"}, + {Pos = "Pos19", TcPos = "T23", Head = "H21", Group = "G4"}, + {Pos = "Pos20", TcPos = "T24", Head = "H21", Group = "G4"}, + {Pos = "Pos21", TcPos = "T25", Head = "H21", Group = "G4"}, + {Pos = "Pos22", TcPos = "T26", Head = "H21", Group = "G4"}, + {Pos = "Pos23", TcPos = "T27", Head = "H21", Group = "G4"}, + {Pos = "Pos24", TcPos = "T28", Head = "H21", Group = "G4"}, + {Pos = "Pos25", TcPos = "T29", Head = "H21", Group = "G4"}, + {Pos = "Pos26", TcPos = "T30", Head = "H21", Group = "G4"}} +else + PositionTable = {{Pos = "Pos1", TcPos = "T1", Head = "H12", Group = "G1"}, + {Pos = "Pos2", TcPos = "T3", Head = "H11", Group = "G1"}, + {Pos = "Pos3", TcPos = "T4", Head = "H11", Group = "G1"}, + {Pos = "Pos4", TcPos = "T5", Head = "H11", Group = "G1"}, + {Pos = "Pos5", TcPos = "T6", Head = "H11", Group = "G1"}, + {Pos = "Pos6", TcPos = "T7", Head = "H11", Group = "G1"}, + {Pos = "Pos7", TcPos = "T8", Head = "H11", Group = "G1"}, + {Pos = "Pos8", TcPos = "T9", Head = "H11", Group = "G1"}, + {Pos = "Pos9", TcPos = "T10", Head = "H11", Group = "G1"}, + {Pos = "Pos10", TcPos = "T101", Head = "H13", Group = "G2"}, + {Pos = "Pos11", TcPos = "T20", Head = "H21", Group = "G3"}, + {Pos = "Pos12", TcPos = "T21", Head = "H21", Group = "G3"}, + {Pos = "Pos13", TcPos = "T22", Head = "H21", Group = "G3"}, + {Pos = "Pos14", TcPos = "T23", Head = "H21", Group = "G3"}, + {Pos = "Pos15", TcPos = "T24", Head = "H21", Group = "G3"}, + {Pos = "Pos16", TcPos = "T25", Head = "H21", Group = "G3"}, + {Pos = "Pos17", TcPos = "T26", Head = "H21", Group = "G3"}, + {Pos = "Pos18", TcPos = "T27", Head = "H21", Group = "G3"}, + {Pos = "Pos19", TcPos = "T28", Head = "H21", Group = "G3"}, + {Pos = "Pos20", TcPos = "T29", Head = "H21", Group = "G3"}, + {Pos = "Pos21", TcPos = "T30", Head = "H21", Group = "G3"}} +end + +local UsePositionHead = true + +local function IsInGeomSet( ToolHead, PosHead) + for GsIndex = 1, #GS do + local bToolHead = false + local bPosHead = false + for HIndex = 1, #GS[GsIndex] do + if GS[GsIndex][HIndex] == ToolHead then + bToolHead = true + elseif GS[GsIndex][HIndex] == PosHead then + bPosHead = true + end + if bToolHead and bPosHead then + return true + end + end + if bToolHead and bPosHead then + return true + end + end + return false +end + +function STU.IsCompatibleHeads() + STU.ISVALID = false + if IsInGeomSet(STU.HEAD1, STU.HEAD2) then + STU.ISVALID = true + else + STU.ISVALID = false + end +end + +function STU.GetValidHeadExitForPos() + -- se TUUID non valido restituisco errore + local ToolName = EgtTdbGetToolFromUUID( STU.TUUID) + if ToolName == nill then + STU.ERR = 1 + return + end + EgtTdbSetCurrTool( ToolName) + local CurrToolHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + STU.EXIT = EgtTdbGetCurrToolParam( MCH_TP.EXIT) + -- recupero testa predefinita per la posizione corrente + local CurrPosHead + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + CurrPosHead = PositionTable[i].Head + break + end + end + -- verifico se la testa è quella della posizione predefinita + if CurrPosHead == CurrToolHead then + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + -- verifico se la testa è compatibile con quella della posizione predefinita + elseif IsInGeomSet( CurrToolHead, CurrPosHead) then + if UsePositionHead then + STU.HEAD = CurrPosHead + STU.ERR = 0 + return + else + STU.HEAD = CurrToolHead + STU.ERR = 0 + return + end + -- la testa non è compatibile con quella della posizione predefinita + else + STU.HEAD = INVALIDPOS + STU.ERR = 0 + return + end +end + +function STU.IsValidTcPosFromHead() + STU.ISVALID = false + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + if PositionTable[i].Head == STU.HEAD then + STU.ISVALID = true + STU.ERR = 0 + return + elseif IsInGeomSet(PositionTable[i].Head, STU.HEAD) then + STU.ISVALID = true + STU.ERR = 0 + return + end + STU.ISVALID = false + STU.ERR = 0 + return + end + end +end + +function STU.GetTcPosHeadGroupFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.HEAD = PositionTable[i].Head + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.HEAD = INVALIDPOS + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetPosFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.POS = PositionTable[i].Pos + STU.ERR = 0 + return + end + end + STU.POS = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetGroupFromTcPos() + for i = 1, #PositionTable do + if PositionTable[i].TcPos == STU.TCPOS then + STU.GROUP = PositionTable[i].Group + STU.ERR = 0 + return + end + end + STU.GROUP = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetHeadFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.HEAD = PositionTable[i].Head + STU.ERR = 0 + return + end + end + STU.HEAD = INVALIDPOS + STU.ERR = 1 +end + +function STU.GetTcPosFromPos() + for i = 1, #PositionTable do + if PositionTable[i].Pos == (POS .. tostring(STU.INDEX)) then + STU.TCPOS = PositionTable[i].TcPos + STU.ERR = 0 + return + end + end + STU.TCPOS = INVALIDPOS + STU.ERR = 1 +end diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/SetUp/SetupImage.qqq.PNG b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/SetUp/SetupImage.qqq.PNG new file mode 100644 index 0000000..a8d5b53 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/SetUp/SetupImage.qqq.PNG differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/SetUp/Standard.stu b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/SetUp/Standard.stu new file mode 100644 index 0000000..f781082 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/SetUp/Standard.stu @@ -0,0 +1,28 @@ +; Commento per evitare BOM con UTF-8 +[General] +Pos1=T1;H12;1/6CB00A83-DDCD-49E6-A301-E1A0482615CA/Lama550_H1 +Pos2=T3;H11;1/E7F6A2BB-1F66-48B9-9561-496231C33403/FresaDT60_H1 +Pos3=T4;H11;1/6EBB8C90-3B4A-498D-B971-1D1EBE6BE77F/Fresa20x50_H1 +Pos4=T5;H11;1/8B729108-7A53-4D8E-8394-379BA211C597/Fresa25x130_H1 +Pos5=T6;H11;1/6578321A-C13D-4D64-9DEC-D5DC5DE93A6A/PuntaD18 CORTA_H1_1 +Pos6=T7;H11;1/0147ED47-EB5D-44D6-9CE2-5282B484B5BD/Smusso45x40_H1 +Pos7=T8 +Pos8=T9 +Pos9=T10;H11;1/73EA9F19-5634-447D-8A23-8EEC777983E6/Fresa200x60_H1 +Pos10=T101;H13;1/49CCF5AC-6566-4B11-BC2D-A758D1167896/ChainSaw_1 +Pos11=T11 +Pos12=T12 +Pos13=T13 +Pos14=T14 +Pos15=T15 +Pos16=T20;H21;1/80F536B5-E4A6-4B60-8BF4-0EF2D0B7FC0E/Lama450_H2 +Pos17=T21 +Pos18=T22;H21;1/D9955E46-78B5-4134-A2FA-89963DD13F69/Fresa 8 x60_H2 +Pos19=T23;H21;1/4238B8C9-9CB5-4FCC-B44C-192E390F4C24/Fresa10x55_H2_1 +Pos20=T24 +Pos21=T25;H21;1/877C9B3A-9078-42B6-808D-5ED5CF5C505B/Fresa20x50_H2 +Pos22=T26;H21;1/CF0294F8-2783-40D5-9197-DC83F744549B/Smusso45x40_H2 +Pos23=T27;H21;1/B83BAE62-B8B5-45DC-AD00-E03ED19B49BE/FresaDT60_H2 +Pos24=T28;H21;1/0A54F32E-C48D-45DB-8502-953CA94FD7A0/Fresa25x130_H2 +Pos25=T29 +Pos26=T30 diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/ChainSaw.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/ChainSaw.nge new file mode 100644 index 0000000..d29af27 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/ChainSaw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/MillNoTip.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/MillNoTip.nge new file mode 100644 index 0000000..5b2fe8a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/MillNoTip.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/Saw.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/Saw.nge new file mode 100644 index 0000000..5d6b54b Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/Saw.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/SawH2.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/SawH2.nge new file mode 100644 index 0000000..ad8bd11 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/SawH2.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/Standard.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/Standard.nge new file mode 100644 index 0000000..23ee6c6 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/THolders/Standard.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge new file mode 100644 index 0000000..57df73a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/0147ED47-EB5D-44D6-9CE2-5282B484B5BD.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge new file mode 100644 index 0000000..6ff54d9 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/0A54F32E-C48D-45DB-8502-953CA94FD7A0.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/4238B8C9-9CB5-4FCC-B44C-192E390F4C24.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/4238B8C9-9CB5-4FCC-B44C-192E390F4C24.nge new file mode 100644 index 0000000..3fe6e8f Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/4238B8C9-9CB5-4FCC-B44C-192E390F4C24.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/49CCF5AC-6566-4B11-BC2D-A758D1167896.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/49CCF5AC-6566-4B11-BC2D-A758D1167896.nge new file mode 100644 index 0000000..0612fc8 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/49CCF5AC-6566-4B11-BC2D-A758D1167896.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/6578321A-C13D-4D64-9DEC-D5DC5DE93A6A.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/6578321A-C13D-4D64-9DEC-D5DC5DE93A6A.nge new file mode 100644 index 0000000..033d1fe Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/6578321A-C13D-4D64-9DEC-D5DC5DE93A6A.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge new file mode 100644 index 0000000..fc5c99f Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/6CB00A83-DDCD-49E6-A301-E1A0482615CA.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/6EBB8C90-3B4A-498D-B971-1D1EBE6BE77F.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/6EBB8C90-3B4A-498D-B971-1D1EBE6BE77F.nge new file mode 100644 index 0000000..2989800 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/6EBB8C90-3B4A-498D-B971-1D1EBE6BE77F.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/73EA9F19-5634-447D-8A23-8EEC777983E6.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/73EA9F19-5634-447D-8A23-8EEC777983E6.nge new file mode 100644 index 0000000..c0af9a4 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/73EA9F19-5634-447D-8A23-8EEC777983E6.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/80F536B5-E4A6-4B60-8BF4-0EF2D0B7FC0E.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/80F536B5-E4A6-4B60-8BF4-0EF2D0B7FC0E.nge new file mode 100644 index 0000000..8160d13 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/80F536B5-E4A6-4B60-8BF4-0EF2D0B7FC0E.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge new file mode 100644 index 0000000..37ec4fb Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/877C9B3A-9078-42B6-808D-5ED5CF5C505B.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/8B729108-7A53-4D8E-8394-379BA211C597.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/8B729108-7A53-4D8E-8394-379BA211C597.nge new file mode 100644 index 0000000..9b5dc0d Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/8B729108-7A53-4D8E-8394-379BA211C597.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/9253DA3D-4740-4537-B376-E034D20130A7.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/9253DA3D-4740-4537-B376-E034D20130A7.nge new file mode 100644 index 0000000..b01ff9a Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/9253DA3D-4740-4537-B376-E034D20130A7.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/982D1B6F-6F27-45B4-B365-B693CBD1E1C1.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/982D1B6F-6F27-45B4-B365-B693CBD1E1C1.nge new file mode 100644 index 0000000..cde44ea Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/982D1B6F-6F27-45B4-B365-B693CBD1E1C1.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge new file mode 100644 index 0000000..bf6f9fc Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/A6CFDA65-DABB-441E-990A-776B5C24C2E4.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/B0B27EB8-6F64-46F8-8CD2-82F6FCE56E18.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/B0B27EB8-6F64-46F8-8CD2-82F6FCE56E18.nge new file mode 100644 index 0000000..a4fa1cf Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/B0B27EB8-6F64-46F8-8CD2-82F6FCE56E18.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/B83BAE62-B8B5-45DC-AD00-E03ED19B49BE.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/B83BAE62-B8B5-45DC-AD00-E03ED19B49BE.nge new file mode 100644 index 0000000..12d1ff0 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/B83BAE62-B8B5-45DC-AD00-E03ED19B49BE.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/CF0294F8-2783-40D5-9197-DC83F744549B.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/CF0294F8-2783-40D5-9197-DC83F744549B.nge new file mode 100644 index 0000000..9ea8a94 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/CF0294F8-2783-40D5-9197-DC83F744549B.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge new file mode 100644 index 0000000..330752d Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/D077C810-A58B-41DE-A3F5-D2187EBB1B67.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/D9955E46-78B5-4134-A2FA-89963DD13F69.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/D9955E46-78B5-4134-A2FA-89963DD13F69.nge new file mode 100644 index 0000000..cd14c81 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/D9955E46-78B5-4134-A2FA-89963DD13F69.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge new file mode 100644 index 0000000..42eb1b2 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/E7F6A2BB-1F66-48B9-9561-496231C33403.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/Tools.data b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/Tools.data new file mode 100644 index 0000000..8f9d266 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/Tools.data differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/Tools.data.bak b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/Tools.data.bak new file mode 100644 index 0000000..f29749d Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/Tools.data.bak differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/penna.nge b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/penna.nge new file mode 100644 index 0000000..ccfc123 Binary files /dev/null and b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Tools/penna.nge differ diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/CutData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/CutData.lua new file mode 100644 index 0000000..7d3c486 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/CutData.lua @@ -0,0 +1,10 @@ +-- CutData.lua by Egaltech s.r.l. 02/03/2021 18:18:17 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local CutData = { + { On = true, Name = 'Sawing550', Type = 'Standard'} +} + +--------------------------------------------------------------------- +return CutData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/DrillData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/DrillData.lua new file mode 100644 index 0000000..f490cce --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/DrillData.lua @@ -0,0 +1,11 @@ +-- DrillData.lua by Egaltech s.r.l. 02/03/2021 18:18:05 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local DrillData = { + { On = true, Name = 'DrillD20_H1', Type = 'Drill'}, + { On = true, Name = 'DrillPock25x130_H1', Type = 'Pocket'} +} + +--------------------------------------------------------------------- +return DrillData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/MachiningTypes.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/MachiningTypes.ini new file mode 100644 index 0000000..414615b --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/MachiningTypes.ini @@ -0,0 +1,23 @@ +[Cut] +1=Standard + +[Drill] +1=Drill +2=Pocket + +[Milling] +1=FreeContour +2=Side +3=SideGroove +4=DtMortise +5=Mark +6=Text +7=CleanCorner60 +8=CleanCorner30 + +[Pocketing] +1=Pocket +2=OpenPocket + +[Sawing] +1=Sawing diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/MillingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/MillingData.lua new file mode 100644 index 0000000..7981b31 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/MillingData.lua @@ -0,0 +1,10 @@ +-- MillingData.lua by Egaltech s.r.l. 02/03/2021 19:11:10 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local MillingData = { + { On = true, Name = 'FreeWall25x130_H1_1', Type = 'FreeContour'} +} + +--------------------------------------------------------------------- +return MillingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/PocketingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/PocketingData.lua new file mode 100644 index 0000000..1c0d982 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/PocketingData.lua @@ -0,0 +1,12 @@ +-- PocketingData.lua by Egaltech s.r.l. 02/03/2021 18:19:34 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local PocketingData = { + { On = true, Name = 'DrillPock25x130_H1', Type = 'Pocket'}, + { On = true, Name = 'DrillPock20x50_H1', Type = 'Pocket'}, + { On = true, Name = 'Svuot200x60_H1', Type = 'OpenPocket'} +} + +--------------------------------------------------------------------- +return PocketingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/SawingData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/SawingData.lua new file mode 100644 index 0000000..7ef7340 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/SawingData.lua @@ -0,0 +1,10 @@ +-- SawingData.lua by Egaltech s.r.l. 18/02/2021 18:55:40 +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local SawingData = { + { On = true, Name = 'TaglioCatena', Type = 'Sawing'} +} + +--------------------------------------------------------------------- +return SawingData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/Ts3Data.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/Ts3Data.lua new file mode 100644 index 0000000..0d5c528 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/Ts3Data.lua @@ -0,0 +1,118 @@ +-- C:\TechnoEssetre7\EgtData\Essetre-PF1250.data + +local Offsets = { + X1_NEG=-3450.0, + X1_POS=0.0, + PARK_X1=250.0, + Z1_NEG=-1550.0, + Z1_POS=0.0, + PARK_Z1=-535.0, + PARK_SAWZ1=-150.0, + B1_NEG=-127.0, + B1_NEG1=-119.0, + B1_POS=127.0, + B1_POS1=119.0, + PARK_B1=-90.0, + PARK_SAWB1=0.0, + C1_NEG=-275.0, + C1_POS=275.0, + PARK_C1=-90.0, + PARK_SAWC1=-90.0, + X2_NEG=-2760.0, + X2_POS=0.0, + PARK_X2=-70.0, + PIVOT_T1=170.0, + Z2_NEG=-795.0, + Z2_POS=0.0, + PARK_Z2=-10.0, + B2_NEG=-127.0, + B2_NEG1=-119.0, + B2_POS=127.0, + B2_POS1=119.0, + PARK_B2=-90.0, + C2_NEG=-275.0, + C2_POS=275.0, + PARK_C2=-90.0, + MIN_Y1=317.0, + MAX_Y1=5772.0, + PARK_Y1=952.0, + MIN_V1=5.0, + MAX_V1=635.0, + PIVOT_T2=170.0, + X1P_NEG=30.0, + X1P_POS=1330.0, + DIST_FTZERO=2167.6, + DELTA_CARICZERO=120.0, + X2P_NEG=35.0, + X2P_POS=1330.0, + Z2P_NEG=30.0, + Z2P_POS=350.0, + X3P_NEG=35.0, + X3P_POS=1330.0, + Z3P_NEG=30.0, + Z3P_POS=350.0, + MIN_V2=-635.0, + MAX_V2=-5.0, + X4P_NEG=30.0, + X4P_POS=1330.0, + MIN_Y2=-5772.0, + MAX_Y2=-321.0, + PARK_Y2=-952.0, + MIN_DELTAVY=317, + DIST_UNLOAD=-2400, + OFFSETBLAMAT1=0, + OFFSETCLAMAT1=0, + OFFSETBLAMAT2=0, + OFFSETCLAMAT2=0, + OFFSETXT1=-2466.7, + OFFSETZT1=-1140.6, + OFFSETXT2=-967.3, + OFFSETZT2=-394.3, + Zzz=1 +} + +local Trave = { + XMIN=30, + XMAX=1251, + ZMIN=30, + ZMAX=300, + Zzz=1 +} + +local User = { + NESTING_MATERIAL=1, + NESTING_TYPEEXTERNALOP=1, + NESTING_FROM_BTL=0, + SAFETY_DISTANCE_ZSAVE=30, + OPTIMIZATIONS_ENABLE_SLICES_F5=1, + OPTIMIZATIONS_ENABLE_SLICES_F6=1, + OPTIMIZATIONS_LENGTH_SLICES=100, + L056_ACTIVE_AS=1, + L055_ADD_P13=0, + L055_ACTIVE_AS=1, + L050_ADDDEPTH=3, + L060_PEN_F2=2, + L060_PEN_F1=2, + L138_TOLLERANZA=0, + L037_TOOL_WIDTH=0, + L032_LENGTH_MIN_DIV=0, + T055_ACTIVE_AS=1, + L040_ADD_P11=0, + L040_ADD_P11_PASS=3, + L040_OFFSET_P1=0, + L040_TYPEDRILLING=0, + L012_LIM=0, + L012_LENGTH_MIN_DIV=950, + L010_LIM=3, + L010_LENGTH_MIN_DIV=1000, + L020_DIAM_HOLE=12, + L030_AUM_DIM=0, + L030_LENGTH_MIN_DIV=0, + T010_ALTCATENA=361, + T010_OFFSETPIANOCATENA=20, + L036_LENGTH_MIN_DIV=900, + Zzz=1 +} + +local Machine = { Offsets=Offsets, Trave=Trave, User=User} +return Machine diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/WallData.lua b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/WallData.lua new file mode 100644 index 0000000..465b1b1 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/WallData.lua @@ -0,0 +1,62 @@ +-- WallData.lua by Egaltech s.r.l. 2021/03/08 +-- Raccolta dati generali per Pareti + +EgtOutLog( ' WALL-WallData started', 1) + +-- Tabella per definizione modulo +local WallData = { + MIN_LENGTH = 4000, -- lunghezza minima del grezzo + MIN_WIDTH = 100, -- larghezza minima del grezzo + MIN_HEIGHT = 10, -- altezza minima del grezzo + MAX_LENGTH = 14000, -- lunghezza massima del grezzo + MAX_WIDTH = 1250, -- larghezza massima del grezzo + MAX_HEIGHT = 300, -- altezza massima del grezzo + STD_RAW_LENGTH = 10000, -- lunghezza standard del grezzo + STD_RAW_WIDTH = 1250, -- larghezza standard del grezzo + OVM_HEAD = 60, -- sovramateriale testa + OVM_MID = 50, -- sovramateriale intermedio + COLL_SIC = 5, -- distanza di sicurezza per collisioni + CUT_SIC = 20, -- distanza di sicurezza per tagli + CUT_EXTRA = 0, -- affondamento extra standard per tagli di lama e fresature + CUT_EXTRA_MIN = 0, -- affondamento extra ridotto per tagli di lama e fresature + NZ_MINA = 0.5, -- componente limite in Z normale di una faccia (-30deg) + NZ_MINB = -0.4, -- componente limite in Z normale di un insieme di facce (-23deg) + DRILL_TOL = 0.5, -- tolleranza tra diametro foro e diametro punta + DRILL_VZ_MIN = 0.5, -- componente limite in Z del versore di un foro + DRILL_VX_MAX = 0.866, -- componente limite in X del versore di un foro sulle facce laterali + DRILL_OVERLAP = 5, -- sovrapposizione tra due mezze forature + MILL_OVERLAP = 5, -- sovrapposizione tra due mezze fresature + RAWCOL = { 255, 160, 32, 30}, -- colore del grezzo + ORIG_CORNER = 'BR', -- angolo tavola per origine di battuta (BR (default), TR, BL, TL) + MAX_CLEAN_CRN30 = 120, -- massimo spessore per pulitura angolo con fresa 30deg + MIN_DIM_ALLOW_CLEAN = 200, -- apertura minima per lavorazione pulitura spigolo + MILL_MAX_DEPTH_AS_MAT = true, -- massimo affondamento frese uguale ad altezza tagliente (max materiale) + CUT_MAX_LENGTH = 3000, -- massima lunghezza di un taglio + BEAM_MACHINE = true -- lavorazione pareti su macchina travi (PF...) +} + +-- Aggiornamento con dati da TechnoEssetre7 +local sTs3Data = EgtGetStringFromIni( 'Wall', 'DATA_DIR', "C:\\TechnoEssetre7\\EgtData", EgtGetIniFile()).."\\Essetre-PF1250.data" +local sData = EgtGetSourceDir().."\\Ts3Data.lua" +if EgtExistsFile( sTs3Data) then + EgtCopyFile( sTs3Data, sData) + local sTs3DataOld = sTs3Data..'.old' + EgtEraseFile( sTs3DataOld) + EgtRenameFile( sTs3Data, sTs3DataOld) +end +if EgtExistsFile( sData) then + local Machine = dofile( sData) + if Machine then + if Machine.Trave then + WallData.MIN_LENGTH = Machine.Trave.YMIN or WallData.MIN_LENGTH + WallData.MIN_WIDTH = Machine.Trave.XMIN or WallData.MIN_WIDTH + WallData.MIN_HEIGHT = Machine.Trave.ZMIN or WallData.MIN_HEIGHT + WallData.MAX_LENGTH = Machine.Trave.YMAX or WallData.MAX_LENGTH + WallData.MAX_WIDTH = Machine.Trave.XMAX or WallData.MAX_WIDTH + WallData.MAX_HEIGHT = Machine.Trave.ZMAX or WallData.MAX_HEIGHT + end + end +end + +--------------------------------------------------------------------- +return WallData diff --git a/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/WallTableTemplate.ini b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/WallTableTemplate.ini new file mode 100644 index 0000000..ccb02c1 --- /dev/null +++ b/ProgramData/EgtCAM5/Machines/Essetre-PF1250rl/Wall/WallTableTemplate.ini @@ -0,0 +1,9 @@ +-- %TABLE_NAME%.lua by Egaltech s.r.l. %DATE_TIME% +-- Gestione dati lavorazioni per Travi + +-- Tabella per definizione modulo +local %TABLE_NAME% = { +} + +--------------------------------------------------------------------- +return %TABLE_NAME% diff --git a/ProgramData/EgtCAM5/Resources/Custom1.png b/ProgramData/EgtCAM5/Resources/Custom1.png new file mode 100644 index 0000000..28d70c2 Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom1.png differ diff --git a/ProgramData/EgtCAM5/Resources/Custom10.png b/ProgramData/EgtCAM5/Resources/Custom10.png new file mode 100644 index 0000000..ca39384 Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom10.png differ diff --git a/ProgramData/EgtCAM5/Resources/Custom11.png b/ProgramData/EgtCAM5/Resources/Custom11.png new file mode 100644 index 0000000..92cb4fb Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom11.png differ diff --git a/ProgramData/EgtCAM5/Resources/Custom2.png b/ProgramData/EgtCAM5/Resources/Custom2.png new file mode 100644 index 0000000..4a79dce Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom2.png differ diff --git a/ProgramData/EgtCAM5/Resources/Custom3.png b/ProgramData/EgtCAM5/Resources/Custom3.png new file mode 100644 index 0000000..bc5d894 Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom3.png differ diff --git a/ProgramData/EgtCAM5/Resources/Custom4.png b/ProgramData/EgtCAM5/Resources/Custom4.png new file mode 100644 index 0000000..606bbf1 Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom4.png differ diff --git a/ProgramData/EgtCAM5/Resources/Custom5.png b/ProgramData/EgtCAM5/Resources/Custom5.png new file mode 100644 index 0000000..77fccf5 Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom5.png differ diff --git a/ProgramData/EgtCAM5/Resources/Custom6.png b/ProgramData/EgtCAM5/Resources/Custom6.png new file mode 100644 index 0000000..50ceaef Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom6.png differ diff --git a/ProgramData/EgtCAM5/Resources/Custom7.png b/ProgramData/EgtCAM5/Resources/Custom7.png new file mode 100644 index 0000000..f420f73 Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom7.png differ diff --git a/ProgramData/EgtCAM5/Resources/Custom8.png b/ProgramData/EgtCAM5/Resources/Custom8.png new file mode 100644 index 0000000..ab89564 Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom8.png differ diff --git a/ProgramData/EgtCAM5/Resources/Custom9.png b/ProgramData/EgtCAM5/Resources/Custom9.png new file mode 100644 index 0000000..6470226 Binary files /dev/null and b/ProgramData/EgtCAM5/Resources/Custom9.png differ diff --git a/ProgramData/EgtCAM5/Temp/EgtCAM5Log1 00.txt b/ProgramData/EgtCAM5/Temp/EgtCAM5Log1 00.txt new file mode 100644 index 0000000..2515d11 --- /dev/null +++ b/ProgramData/EgtCAM5/Temp/EgtCAM5Log1 00.txt @@ -0,0 +1,821 @@ +2019/12/09 15:04:54 Init +User DESKTOP-933NOPU\carlo (1) +EgtCAM5R32.exe ver. 2.1j1 +EgtUILib.dll ver. 2.1j1 +EgtInterfaceR32.dll ver. 2.1j1 +EgtExecutorR32.dll ver. 2.1j1 +EgtGeneralR32.dll ver. 2.1h1 +EgtNumKernelR32.dll ver. 2.1h1 +EgtGeomKernelR32.dll ver. 2.1j1 +EgtGraphicsR32.dll ver. 2.1i2 +EgtExchangeR32.dll ver. 2.1i4 +EgtMachKernelR32.dll ver. 2.1i3 +Key 000335 (28620) +OS Ms Windows 10.0 (Build 18362) +CPU Intel(R) Core(TM)2 Duo CPU T9400 @ 2.53GHz - 2 threads - MMX+SSE+SSE2 +Memory 4083 MB (virtual 6008 MB) +UserObj Managers : +EXePicture +EGkDefault +EXePhoto +EMkAxis +EMkDrilling +EMkDisposition +EMkCamData +EMkChiseling +EMkExit +EMkGenMachining +EMkMilling +EMkPocketing +EMkMortising +EMkSawFinishing +EMkSawing +EMkSawRoughing +EMkHead +EMkSurfFinishing +EMkTable +EMkWaterJetting +Lua 5.3 interpreter started +Require Library = EgtBase +EgtBase started +EgtConst started +EgtVector3d started +EgtPoint3d started +EgtFrame3d started +EgtBBox3d started +EgtColor3d started +KeyOptions : True 83 +Context 1 started +OpenGL 3.3.0 (Nw) NVIDIA Corporation Quadro FX 1700M/PCIe/SSE2 +GLSL 3.30 NVIDIA via Cg compiler +PixFmt 7 ICD BUFF2 RGBA32 Z24 +MachMgr started (C:\EgtData\Machines) +Exec File = C:\ProgramData\Egaltech\EgtCAM5\Beam\Rotate.lua +Release Mode +Exec File = C:\ProgramData\Egaltech\EgtCAM5\Beam\Rotate.lua +Release Mode +Exec File = C:\ProgramData\Egaltech\EgtCAM5\Beam\Process.lua +Release Mode +Lua 5.3 machine interpreter started (Essetre-FAST) +EgtBase started +EgtConst started +EgtVector3d started +EgtPoint3d started +EgtFrame3d started +EgtBBox3d started +EgtColor3d started +LuaLoadMachine : C:\EgtData\Machines\Essetre-FAST\Essetre-FAST.Mlde +EmtGenerator started +Release Mode +LuaEmtGeneral : Essetre-FAST.nge, Essetre-FAST.mlse, Essetre-FAST.mlpe +Debug Mode (32bit) +** Essetre-FAST 2.1l1 ** +Release Mode +LuaEmtBase : Base +LuaEmtAxis : X +LuaEmtAxis : Z +LuaEmtAxis : C +LuaEmtAxis : B + Move = (0.000444,0,0.35) +LuaEmtStdHead : H1 +LuaEmtStdHead : H2 + Exit T1 move = (0.000053,0.000234,0.480015) +LuaEmtAxis : A +LuaEmtStdHead : H3 + Exit T1 move = (0.000007,0,1.000002) +LuaEmtStdHead : H4 +LuaEmtAxis : Y +LuaEmtAxis : PY +LuaEmtAxis : V +LuaEmtAxis : PV +LuaEmtAxis : T +LuaEmtTable : Tab + Move = (0,-22.97,-15.0007) +*** Beam Process Start *** + FAST-BeamData started + MachiningLib started + BeamLib started + DiceCut started + FacesBySaw started + ProcessSplit started + ProcessSplit started + ProcessCut started + ProcessDoubleCut started + ProcessLongCut started + ProcessLongDoubleCut started + ProcessRidgeLap started + ProcessLapJoint started + ProcessChamfer started + ProcessDrill started + ProcessTenon started + ProcessMortise started + ProcessTenon started + ProcessDtMortise started + ProcessMark started + ProcessText started + ProcessSimpleScarf started + ProcessStepJoint started + ProcessStepJointNotch started + ProcessProfFront started + ProcessProfConcave started + ProcessProfConvex started + ProcessProfCamb started + ProcessProfHead started + ProcessRoundArch started + ProcessFreeContour started + ProcessDecor started + BeamExec started +Travi selezionate : 509-6x12 HIP RAFTER +Travi ordinate : 509-6x12 HIP RAFTER +Ltot : 6314.7 Lagg : 10 +Lraw : 6500 Lovm : 10 +ToolsMgr Init : C:\EgtData\Machines\Essetre-FAST\Tools\Tools.data +ReloadTools : FileVer = 1002 CurrVer = 1002 +PartSez=139.7x292.1 +Phase=1 Raw=4877 Part=1 + RawBox=((-7784.3, 750.49, -845.038),(-1454.2, 890.19, -552.938)) + Proc=4881 Grp=1 Prc=340 TC= 0/0 Flg= 1 Down=F Head=T Tail=F Fcse=0,0 Diam=0.00 Fct= 1 Box=((-1464.2, 750.49, -845.038),(-1464.2, 890.19, -552.938)) + Proc= 18 Grp=2 Prc= 10 TC= 0/0 Flg= 1 Down=F Head=T Tail=F Fcse=0,0 Diam=0.00 Fct= 1 Box=((-1864.36, 750.49, -647.2369),(-1464.2, 890.19, -552.938)) + Proc= 15 Grp=2 Prc= 10 TC= 0/0 Flg= 1 Down=F Head=T Tail=F Fcse=0,0 Diam=0.00 Fct= 1 Box=((-1582.5765, 750.49, -845.038),(-1464.2, 865.7105, -552.938)) + Proc= 17 Grp=2 Prc= 10 TC= 0/0 Flg= 1 Down=F Head=T Tail=F Fcse=0,0 Diam=0.00 Fct= 1 Box=((-1582.58, 774.9661, -845.038),(-1464.2, 890.19, -552.938)) + Proc= 19 Grp=4 Prc= 20 TC= 0/0 Flg= 1 Down=F Head=F Tail=F Fcse=0,0 Diam=0.00 Fct= 3 Box=((-2697.8289, 750.49, -635.588),(-2327.6818, 890.19, -552.938)) + Proc= 20 Grp=4 Prc= 30 TC= 0/0 Flg= 1 Down=F Head=F Tail=F Fcse=0,0 Diam=0.00 Fct= 3 Box=((-6119.7742, 750.49, -651.5964),(-5798.8638, 890.19, -552.938)) + Proc= 16 Grp=0 Prc= 12 TC= 0/0 Flg= 1 Down=F Head=F Tail=F Fcse=0,0 Diam=0.00 Fct= 2 Box=((-7778.9, 750.49, -845.038),(-1464.2, 890.19, -829.0146)) + Proc=4882 Grp=2 Prc=350 TC= 0/0 Flg= 1 Down=F Head=F Tail=T Fcse=0,0 Diam=0.00 Fct= 1 Box=((-7778.9, 750.49, -845.038),(-7778.9, 890.19, -552.938)) + Proc= 21 Grp=3 Prc= 20 TC= 0/0 Flg= 1 Down=F Head=F Tail=T Fcse=0,0 Diam=0.00 Fct= 2 Box=((-7778.9, 750.49, -634.958),(-7474.2012, 890.19, -552.938)) + Proc= 22 Grp=1 Prc= 10 TC= 0/0 Flg= 1 Down=F Head=F Tail=T Fcse=0,0 Diam=0.00 Fct= 1 Box=((-7778.9, 750.49, -845.038),(-7570.3158, 890.19, -552.938)) +MachiningsMgr Init : C:\EgtData\Machines\Essetre-FAST\Machinings\Machinings.data +ReloadMachinings : FileVer = 1008 CurrVer = 1008 +Vref=(0, 1, 0) V1=(0, 1, 0) V2=(0, 1, 0) +LiFaceNorm=(0, 1, 0) +LeadIn Dist=164.7 +LiFaceNorm2=(0, 1, 0) +LeadIn Dist2=1164.7 +LoFaceNorm=(0, 1, 0) +LeadOut Dist=164.7 +LoFaceNorm2=(0, 1, 0) +LeadOut Dist2=1164.7 +vtN=(1, 0, 0) vtRef=(0, 1, 0) vtOut=(0, 1, 0) vtAux=(0, 1, 0) +MaxDepth=200.0 CutH=139.7 CutV=411.1 +Vref=(0, 1, 0) V1=(0, 1, 0) V2=(0, 1, 0) +LiFaceNorm=(0, 1, 0) +LeadIn Dist=164.7 +LiFaceNorm2=(0, 1, 0) +LeadIn Dist2=1164.7 +LoFaceNorm=(0, 1, 0) +LeadOut Dist=164.7 +LoFaceNorm2=(0, 1, 0) +LeadOut Dist2=1164.7 +vtN=(0.22937, 0, 0.973339) vtRef=(0, 1, 0) vtOut=(0, 1, 0) vtAux=(0, 1, 0) +MaxDepth=200.0 CutH=165.2 CutV=296.0 +Vref=(0.688255, -0.707107, -0.162189) V1=(0.69749, -0.716595, 0) V2=(0.69749, -0.716595, 0) +LiFaceNorm=(0, -1, 0) +LeadIn Dist=112.276 +LiFaceNorm2=(1, 0, 0) +LeadIn Dist2=131.842 +LoFaceNorm=(0, -1, 0) +LeadOut Dist=64.265 +LoFaceNorm2=(1, 0, 0) +LeadOut Dist2=83.831 +vtN=(0.716595, 0.69749, 0) vtRef=(0.688255, -0.707107, -0.162189) vtOut=(0.688255, -0.707107, -0.162189) vtAux=(0.69749, -0.716595, 0) +Vref=(0.716595, 0.69749, 0) V1=(0.716595, 0.69749, 0) V2=(0.716595, 0.69749, 0) +LiFaceNorm=(1, 0, 0) +LeadIn Dist=128.176 +LiFaceNorm2=(0, 1, 0) +LeadIn Dist2=150.504 +LoFaceNorm=(1, 0, 0) +LeadOut Dist=81.445 +LoFaceNorm2=(0, 1, 0) +LeadOut Dist2=199.83 +vtN=(0.688255, -0.707107, -0.162189) vtRef=(0.716595, 0.69749, 0) vtOut=(0.716595, 0.69749, 0) vtAux=(0.716595, 0.69749, 0) +Vref=(0.688255, 0.707107, -0.162189) V1=(0.716595, 0.69749, 0) V2=(0.716595, 0.69749, 0) +LiFaceNorm=(1, 0, 0) +LeadIn Dist=222.637 +LiFaceNorm2=(0, 1, 0) +LeadIn Dist2=228.964 +LoFaceNorm=(1, 0, 0) +LeadOut Dist=126.58 +LoFaceNorm2=(0, 1, 0) +LeadOut Dist2=228.964 +vtN=(0.688255, -0.707107, -0.162189) vtRef=(0.688255, 0.707107, -0.162189) vtOut=(0.688255, 0.707107, -0.162189) vtAux=(0.716595, 0.69749, 0) +MaxDepth=200.0 CutH=165.2 CutV=296.0 +Vref=(0.688255, 0.707107, -0.162189) V1=(0.69749, 0.716595, 0) V2=(0.69749, 0.716595, 0) +LiFaceNorm=(0, 1, 0) +LeadIn Dist=112.279 +LiFaceNorm2=(1, 0, 0) +LeadIn Dist2=131.845 +LoFaceNorm=(0, 1, 0) +LeadOut Dist=64.268 +LoFaceNorm2=(1, 0, 0) +LeadOut Dist2=83.834 +vtN=(0.716595, -0.69749, 0) vtRef=(0.688255, 0.707107, -0.162189) vtOut=(0.688255, 0.707107, -0.162189) vtAux=(0.69749, 0.716595, 0) +Vref=(0.716595, -0.69749, 0) V1=(0.716595, -0.69749, 0) V2=(0.716595, -0.69749, 0) +LiFaceNorm=(1, 0, 0) +LeadIn Dist=128.179 +LiFaceNorm2=(0, -1, 0) +LeadIn Dist2=150.501 +LoFaceNorm=(1, 0, 0) +LeadOut Dist=81.448 +LoFaceNorm2=(0, -1, 0) +LeadOut Dist2=199.828 +vtN=(0.688255, 0.707107, -0.162189) vtRef=(0.716595, -0.69749, 0) vtOut=(0.716595, -0.69749, 0) vtAux=(0.716595, -0.69749, 0) +Vref=(0.688255, -0.707107, -0.162189) V1=(0.716595, -0.69749, 0) V2=(0.716595, -0.69749, 0) +LiFaceNorm=(1, 0, 0) +LeadIn Dist=222.642 +LiFaceNorm2=(0, -1, 0) +LeadIn Dist2=228.964 +LoFaceNorm=(1, 0, 0) +LeadOut Dist=126.585 +LoFaceNorm2=(0, -1, 0) +LeadOut Dist2=228.964 +vtN=(0.688255, 0.707107, -0.162189) vtRef=(0.688255, -0.707107, -0.162189) vtOut=(0.688255, -0.707107, -0.162189) vtAux=(0.716595, -0.69749, 0) +Warning on LinearMove : Min Feed +Vref=(0, 1, 0) V1=(0, 1, 0) V2=(0, 1, 0) +LiFaceNorm=(0, 1, 0) +LeadIn Dist=164.7 +LiFaceNorm2=(0, 1, 0) +LeadIn Dist2=1164.7 +LoFaceNorm=(0, 1, 0) +LeadOut Dist=164.7 +LoFaceNorm2=(0, 1, 0) +LeadOut Dist2=1164.7 +vtN=(-1, 0, 0) vtRef=(0, 1, 0) vtOut=(0, 1, 0) vtAux=(0, 1, 0) +Vref=(0.229382, 0.000005, 0.973337) V1=(0.229377, 0, 0.973338) V2=(0.229377, 0, 0.973338) +LiFaceNorm=(0, 0, 1) +LeadIn Dist=73.989 +LiFaceNorm2=(0, 0, 1) +LeadIn Dist2=1101.382 +LoFaceNorm=(0, 0, 1) +LeadOut Dist=41.061 +LoFaceNorm2=(0, 0, 1) +LeadOut Dist2=1068.454 +vtN=(-0.688204, 0.707158, 0.162182) vtRef=(0.229382, 0.000005, 0.973337) vtOut=(0.229382, 0.000005, 0.973337) vtAux=(0.716646, 0.697437, 0) +Vref=(0.229382, 0.000005, 0.973337) V1=(0.229377, 0, 0.973338) V2=(0.229377, 0, 0.973338) +LiFaceNorm=(0, 0, 1) +LeadIn Dist=108.952 +LiFaceNorm2=(0, 0, 1) +LeadIn Dist2=1136.345 +LoFaceNorm=(0, 0, 1) +LeadOut Dist=76.024 +LoFaceNorm2=(0, 0, 1) +LeadOut Dist2=1103.417 +vtN=(-0.688204, 0.707158, 0.162182) vtRef=(0.229382, 0.000005, 0.973337) vtOut=(0.229382, 0.000005, 0.973337) vtAux=(0.716646, 0.697437, 0) +Vref=(-0.688204, 0.707158, 0.162182) V1=(-0.973337, 0, 0.229382) V2=(0, 1, -0.000005) +LiFaceNorm=(0, 1, 0) +LeadIn Dist=107.853 +LiFaceNorm2=(0, 1, 0) +LeadIn Dist2=1107.853 +LoFaceNorm=(0, 1, 0) +LeadOut Dist=247.553 +LoFaceNorm2=(0, 1, 0) +LeadOut Dist2=1247.553 +vtN=(0.229382, 0.000005, 0.973337) vtRef=(-0.688204, 0.707158, 0.162182) vtOut=(-0.688204, 0.707158, 0.162182) vtAux=(-0.000022, 1, 0) +Vref=(-0.688204, 0.707158, 0.162182) V1=(-0.973337, 0, 0.229382) V2=(0.688302, 0.707055, -0.162213) +LiFaceNorm=(-1, 0, 0) +LeadIn Dist=407.166 +LiFaceNorm2=(0, 0, 1) +LeadIn Dist2=532.648 +LoFaceNorm=(-1, 0, 0) +LeadOut Dist=267.446 +LoFaceNorm2=(0, 0, 1) +LeadOut Dist2=392.925 +vtN=(0.229382, 0.000005, 0.973337) vtRef=(-0.688204, 0.707158, 0.162182) vtOut=(-0.688204, 0.707158, 0.162182) vtAux=(-0.000022, 1, 0) +MaxDepth=200.0 CutH=246.9 CutV=296.0 +Vref=(-0.688255, 0.707107, 0.162189) V1=(-0.69749, 0.716595, 0) V2=(-0.69749, 0.716595, 0) +LiFaceNorm=(0, 1, 0) +LeadIn Dist=104.034 +LiFaceNorm2=(-1, 0, 0) +LeadIn Dist2=164.591 +LoFaceNorm=(0, 1, 0) +LeadOut Dist=152.045 +LoFaceNorm2=(-1, 0, 0) +LeadOut Dist2=212.602 +vtN=(-0.716595, -0.69749, 0) vtRef=(-0.688255, 0.707107, 0.162189) vtOut=(-0.688255, 0.707107, 0.162189) vtAux=(-0.69749, 0.716595, 0) +Vref=(-0.716595, -0.69749, 0) V1=(-0.716595, -0.69749, 0) V2=(-0.716595, -0.69749, 0) +LiFaceNorm=(0, -1, 0) +LeadIn Dist=158.972 +LiFaceNorm2=(-1, 0, 0) +LeadIn Dist2=160.052 +LoFaceNorm=(0, -1, 0) +LeadOut Dist=109.645 +LoFaceNorm2=(-1, 0, 0) +LeadOut Dist2=206.783 +vtN=(-0.688255, 0.707107, 0.162189) vtRef=(-0.716595, -0.69749, 0) vtOut=(-0.716595, -0.69749, 0) vtAux=(-0.716595, -0.69749, 0) +Vref=(-0.688255, -0.707107, 0.162189) V1=(-0.716595, -0.69749, 0) V2=(-0.716595, -0.69749, 0) +LiFaceNorm=(0, -1, 0) +LeadIn Dist=228.964 +LiFaceNorm2=(-1, 0, 0) +LeadIn Dist2=246.045 +LoFaceNorm=(0, -1, 0) +LeadOut Dist=228.964 +LoFaceNorm2=(-1, 0, 0) +LeadOut Dist2=342.102 +vtN=(-0.688255, 0.707107, 0.162189) vtRef=(-0.688255, -0.707107, 0.162189) vtOut=(-0.688255, -0.707107, 0.162189) vtAux=(-0.716595, -0.69749, 0) + *** Fase : 1 *** + Lavorazione : Cut_StartCut_1 + Tdir=(1, 0, 0) Zup=-730 + DistFront=10 DistBack=6490.01 HeadFront=450 HeadBack=90 + *[L] + Dist/Min : Back=5863.5/238.2 Front=-440/366.5 + *[A1] = Y -> Y + YDeltaI=636.53 TPosI=1454.2 + YDeltaF=636.53 NewYDelta =636.53 + [A1Yns] + YDeltaA =636.53 + Lavorazione : Cut_4_1 + Tdir=(0.22937, 0, 0.973339) Zup=-69.821 + DistFront=10 DistBack=6089.85 HeadFront=342.002 HeadBack=342.002 + Dist/Min : Back=5747.8/238.2 Front=-332/366.5 + *[A1] = Y -> Y + YDeltaI=636.53 TPosI=238.08 + YDeltaF=752.162 NewYDelta =871.237 + [A1Ys-r] + YDeltaA =871.237 + Lavorazione : Cut_AddCut_15_1 + Tdir=(0.716595, 0.69749, 0) Zup=-778.673 + DistFront=-215.669 DistBack=6637.367 HeadFront=350 HeadBack=249.247 + Dist/Min : Back=5913.5/238.2 Front=-565.7/366.5 + *[A1] = Y -> Y + YDeltaI=871.237 TPosI=-353.258 + YDeltaF=586.53 NewYDelta =705.605 + [A1Ys-xs1] + YDeltaA =705.605 + Lavorazione : Cut_AddCut_15_2 + Tdir=(0.688255, -0.707107, -0.162189) Zup=-722.056 + DistFront=-237.712 DistBack=6645.872 HeadFront=350 HeadBack=257.641 + Dist/Min : Back=5913.5/238.2 Front=-587.7/366.5 + *[A1] = Y -> Y + YDeltaI=705.605 TPosI=393.441 + YDeltaF=586.53 NewYDelta =705.605 + [A1Yns] + YDeltaA =705.605 + Lavorazione : Cut_AddCut_15_3 + Tdir=(0.688255, -0.707107, -0.162189) Zup=-770.729 + DistFront=-237.71 DistBack=6578.179 HeadFront=350 HeadBack=257.641 + Dist/Min : Back=5913.5/238.2 Front=-587.7/366.5 + *[A1] = Y -> Y + YDeltaI=705.605 TPosI=408.455 + YDeltaF=586.53 NewYDelta =705.605 + [A1Yns] + YDeltaA =705.605 + Lavorazione : Cut_AddCut_17_1 + Tdir=(0.716595, -0.69749, 0) Zup=-778.673 + DistFront=-215.669 DistBack=6637.365 HeadFront=350 HeadBack=249.247 + Dist/Min : Back=5913.5/238.2 Front=-565.7/366.5 + *[A1] = Y -> Y + YDeltaI=705.605 TPosI=408.452 + YDeltaF=586.53 NewYDelta =705.605 + [A1Yns] + YDeltaA =705.605 + Lavorazione : Cut_AddCut_17_2 + Tdir=(0.688255, 0.707107, -0.162189) Zup=-722.056 + DistFront=-237.712 DistBack=6645.87 HeadFront=350 HeadBack=257.641 + Dist/Min : Back=5913.5/238.2 Front=-587.7/366.5 + *[A1] = Y -> Y + YDeltaI=705.605 TPosI=393.441 + YDeltaF=586.53 NewYDelta =705.605 + [A1Yns] + YDeltaA =705.605 + Lavorazione : Cut_AddCut_17_3 + Tdir=(0.688255, 0.707107, -0.162189) Zup=-770.729 + DistFront=-237.71 DistBack=6578.175 HeadFront=350 HeadBack=257.641 + Dist/Min : Back=5913.5/238.2 Front=-587.7/366.5 + *[A1] = Y -> Y + YDeltaI=705.605 TPosI=408.455 + YDeltaF=586.53 NewYDelta =705.605 + [A1Yns] + YDeltaA =705.605 + Lavorazione : Pock_8 + Tdir=(0.229416, -0.00004, 0.973329) Zup=77.77 + DistFront=897.184 DistBack=5262.465 HeadFront=441.193 HeadBack=130 + Dist/Min : Back=5132.5/238.2 Front=456/366.5 + *[B1] = Y -> Y+V + YDeltaI=705.605 VDeltaI(Park)=-888.452 TPosI=408.452 + YDeltaF=1367.545 VDeltaF=455.991 + NewYDelta=1608.731 NewVDelta=410.761 + [B1Vs-r] + [B1Ys] + [B1Ys-r] + YDeltaA =1608.731 VDeltaA =410.761 +Warning on LinearMove : Min Feed + Lavorazione : Pock_5 + Tdir=(0.229437, 0.000062, 0.973324) Zup=48.507 + DistFront=4384.445 DistBack=1868.403 HeadFront=421.355 HeadBack=130 + Dist/Min : Back=1738.4/238.2 Front=3963.1/366.5 + *[B2] = Y+V -> Y+V + YDeltaI=1608.731 VDeltaI=410.761 TPosI=-997.499 + YDeltaF=4761.607 VDeltaF=3963.09 + NewYDelta=5031.053 NewVDelta=3693.644 + [B2V] + [B2Vs-xs2] + [B2C] + [B2Cn] + YDeltaA =5031.053 VDeltaA =3693.644 + Lavorazione : L2C_7_1 + Tdir=(0, -0.974683, 0.22359) Zup=-226.15 + DistFront=10 DistBack=5890.01 HeadFront=350 HeadBack=130 + Dist/Min : Back=5760/238.2 Front=-340/366.5 + *[A2] = Y+V -> Y + YDeltaI=5031.053 TPosI=-4497.108 VDeltaI=3693.644 + YDeltaF=740 NewYDelta=859.075 + [A2Ys-xs2] + YDeltaA =859.075 + Lavorazione : L2C_7_2 + Tdir=(0, 0.974683, 0.22359) Zup=-226.15 + DistFront=10 DistBack=5890.01 HeadFront=440 HeadBack=130 + Dist/Min : Back=5760/238.2 Front=-430/366.5 + *[A1] = Y -> Y + YDeltaI=859.075 TPosI=-610 + YDeltaF=740 NewYDelta =859.075 + [A1Yns] + YDeltaA =859.075 + Lavorazione : L2C_7_3 + Tdir=(0, -0.974683, 0.22359) Zup=-226.15 + DistFront=610 DistBack=5037.56 HeadFront=350 HeadBack=130 + Dist/Min : Back=4907.6/238.2 Front=260/366.5 + *[A1] = Y -> Y + YDeltaI=859.075 TPosI=-10 + YDeltaF=1592.45 NewYDelta =1711.525 + [A1Ys-r] + YDeltaA =1711.525 + Lavorazione : L2C_7_4 + Tdir=(0, 0.974683, 0.22359) Zup=-226.15 + DistFront=610 DistBack=5037.56 HeadFront=440 HeadBack=130 + Dist/Min : Back=4907.6/238.2 Front=170/366.5 + *[A1] = Y -> Y + YDeltaI=1711.525 TPosI=-1462.45 + YDeltaF=1592.45 NewYDelta =1711.525 + [A1Yns] + YDeltaA =1711.525 + Lavorazione : L2C_7_5 + Tdir=(0, -0.974683, 0.22359) Zup=-226.15 + DistFront=1462.45 DistBack=4185.11 HeadFront=350 HeadBack=130 + Dist/Min : Back=4055.1/238.2 Front=1112.5/366.5 + *[B1] = Y -> Y+V + YDeltaI=1711.525 VDeltaI(Park)=130 TPosI=-610 + YDeltaF=2444.9 VDeltaF=1112.45 + NewYDelta=2580.862 NewVDelta=976.487 + [B1Vs-xs1] + [B1Ys] + [B1Ys-r] + YDeltaA =2580.862 VDeltaA =976.487 + Lavorazione : L2C_7_6 + Tdir=(0, 0.974683, 0.22359) Zup=-226.15 + DistFront=1462.45 DistBack=4185.11 HeadFront=440 HeadBack=130 + Dist/Min : Back=4055.1/238.2 Front=1022.5/366.5 + *[B2] = Y+V -> Y+V + YDeltaI=2580.863 VDeltaI=976.487 TPosI=-2314.9 + YDeltaF=2444.9 VDeltaF=1022.45 + NewYDelta=2580.863 NewVDelta=976.487 + [B2V] + [B2Vns] + [B2Y] + [B2Yns] + [B2C] + [B2Cn] + YDeltaA =2580.863 VDeltaA =976.487 + Lavorazione : L2C_7_7 + Tdir=(0, -0.974683, 0.22359) Zup=-226.15 + DistFront=2314.9 DistBack=3332.66 HeadFront=350 HeadBack=130 + Dist/Min : Back=3202.7/238.2 Front=1964.9/366.5 + *[B2] = Y+V -> Y+V + YDeltaI=2580.863 VDeltaI=976.487 TPosI=-1462.45 + YDeltaF=3297.35 VDeltaF=1964.9 + NewYDelta=3433.313 NewVDelta=1828.937 + [B2V] + [B2Vs-xs1] + [B2C] + [B2CYs] + [B2CYs-r] + YDeltaA =3433.313 VDeltaA =1828.937 + Lavorazione : L2C_7_8 + Tdir=(0, 0.974683, 0.22359) Zup=-226.15 + DistFront=2314.9 DistBack=3332.66 HeadFront=440 HeadBack=130 + Dist/Min : Back=3202.7/238.2 Front=1874.9/366.5 + *[B2] = Y+V -> Y+V + YDeltaI=3433.313 VDeltaI=1828.938 TPosI=-3167.35 + YDeltaF=3297.35 VDeltaF=1874.9 + NewYDelta=3433.313 NewVDelta=1828.938 + [B2V] + [B2Vns] + [B2Y] + [B2Yns] + [B2C] + [B2Cn] + YDeltaA =3433.313 VDeltaA =1828.938 + Lavorazione : L2C_7_9 + Tdir=(0, -0.974683, 0.22359) Zup=-226.15 + DistFront=3167.35 DistBack=2480.21 HeadFront=350 HeadBack=130 + Dist/Min : Back=2350.2/238.2 Front=2817.4/366.5 + *[B2] = Y+V -> Y+V + YDeltaI=3433.313 VDeltaI=1828.938 TPosI=-2314.9 + YDeltaF=4149.8 VDeltaF=2817.35 + NewYDelta=4285.762 NewVDelta=2681.388 + [B2V] + [B2Vs-xs1] + [B2C] + [B2CYs] + [B2CYs-r] + YDeltaA =4285.762 VDeltaA =2681.388 + Lavorazione : L2C_7_10 + Tdir=(0, 0.974683, 0.22359) Zup=-226.15 + DistFront=3167.35 DistBack=2480.21 HeadFront=440 HeadBack=130 + Dist/Min : Back=2350.2/238.2 Front=2727.4/366.5 + *[B2] = Y+V -> Y+V + YDeltaI=4285.762 VDeltaI=2681.387 TPosI=-4019.8 + YDeltaF=4149.8 VDeltaF=2727.35 + NewYDelta=4285.762 NewVDelta=2681.387 + [B2V] + [B2Vns] + [B2Y] + [B2Yns] + [B2C] + [B2Cn] + YDeltaA =4285.762 VDeltaA =2681.387 + Lavorazione : L2C_7_11 + Tdir=(0, -0.974683, 0.22359) Zup=-226.15 + DistFront=4019.8 DistBack=1627.76 HeadFront=350 HeadBack=130 + Dist/Min : Back=1497.8/238.2 Front=3669.8/366.5 + *[B2] = Y+V -> Y+V + YDeltaI=4285.762 VDeltaI=2681.387 TPosI=-3167.35 + YDeltaF=5002.25 VDeltaF=3669.8 + NewYDelta=5138.212 NewVDelta=3533.838 + [B2V] + [B2Vs-xs1] + [B2C] + [B2CYs] + [B2CYs-r] + YDeltaA =5138.212 VDeltaA =3533.838 + Lavorazione : L2C_7_12 + Tdir=(0, 0.974683, 0.22359) Zup=-226.15 + DistFront=4019.8 DistBack=1627.76 HeadFront=440 HeadBack=130 + Dist/Min : Back=1497.8/238.2 Front=3579.8/366.5 + *[B2] = Y+V -> Y+V + YDeltaI=5138.212 VDeltaI=3533.838 TPosI=-4872.25 + YDeltaF=5002.25 VDeltaF=3579.8 + NewYDelta=5138.212 NewVDelta=3533.838 + [B2V] + [B2Vns] + [B2Y] + [B2Yns] + [B2C] + [B2Cn] + YDeltaA =5138.212 VDeltaA =3533.838 + Lavorazione : L2C_7_13 + Tdir=(0, -0.974683, 0.22359) Zup=-226.15 + DistFront=4872.25 DistBack=775.31 HeadFront=350 HeadBack=130 + Dist/Min : Back=645.3/238.2 Front=4522.3/366.5 + *[B2] = Y+V -> Y+V + YDeltaI=5138.212 VDeltaI=3533.838 TPosI=-4019.8 + YDeltaF=5854.7 VDeltaF=4522.25 + NewYDelta=5953.993 NewVDelta=4386.288 + [B2V] + [B2Vs-xs1] + [B2C] + [B2CYs] + [B2CYs-r] + YDeltaA =5953.993 VDeltaA =4386.288 + Lavorazione : L2C_7_14 + Tdir=(0, 0.974683, 0.22359) Zup=-226.15 + DistFront=4872.25 DistBack=775.31 HeadFront=440 HeadBack=130 + Dist/Min : Back=645.3/238.2 Front=4432.3/366.5 + *[B2] = Y+V -> Y+V + YDeltaI=5953.993 VDeltaI=4386.288 TPosI=-5724.7 + YDeltaF=5854.7 VDeltaF=4432.25 + NewYDelta=5953.993 NewVDelta=4386.288 + [B2V] + [B2Vns] + [B2Y] + [B2Yns] + [B2C] + [B2Cn] + YDeltaA =5953.993 VDeltaA =4386.288 + Lavorazione : L2C_7_15 + Tdir=(0, -0.974683, 0.22359) Zup=-226.15 + DistFront=5724.7 DistBack=175.31 HeadFront=350 HeadBack=130 + Dist/Min : Back=45.3/238.2 Front=5374.7/366.5 + *[C2] = Y+V -> V + YDeltaI=5953.993 VDeltaI=4386.288 VDeltaF=5374.7 + NewVDelta=5255.625 + [C2Vs-xs1] + VDeltaA =5255.625 + Lavorazione : L2C_7_16 + Tdir=(0, 0.974683, 0.22359) Zup=-226.15 + DistFront=5724.7 DistBack=175.31 HeadFront=440 HeadBack=130 + Dist/Min : Back=45.3/238.2 Front=5284.7/366.5 + *[C3] = V -> V + VDeltaI=5255.625 TPosI=-6324.7 + VDeltaF=5284.7 NewVDelta =5255.625 + [C3Vns] + VDeltaA =5255.625 + Lavorazione : Cut_EndCut_1 + Tdir=(-1, 0, 0) Zup=-730 + DistFront=6324.7 DistBack=175.31 HeadFront=90 HeadBack=450 + Tdir=(-0.688204, 0.707158, 0.162182) Zup=-185.945 + DistFront=6097.946 DistBack=249.097 HeadFront=257.655 HeadBack=350 + Tdir=(-0.688204, 0.707158, 0.162182) Zup=-219.976 + DistFront=5945.524 DistBack=393.5 HeadFront=257.655 HeadBack=350 + Tdir=(0.229382, 0.000005, 0.973337) Zup=25.136 + DistFront=6390.194 DistBack=-26.171 HeadFront=342.001 HeadBack=342.001 + Tdir=(0.229382, 0.000005, 0.973337) Zup=-8.894 + DistFront=6245.791 DistBack=-142.091 HeadFront=342.001 HeadBack=342.001 + Tdir=(-0.716595, -0.69749, 0) Zup=-681.327 + DistFront=6411.128 DistBack=-17.168 HeadFront=249.247 HeadBack=350 + Tdir=(-0.688255, 0.707107, 0.162189) Zup=-722.056 + DistFront=6419.633 DistBack=-67.029 HeadFront=257.641 HeadBack=350 + Tdir=(-0.688255, 0.707107, 0.162189) Zup=-673.383 + DistFront=6322.661 DistBack=-55.56 HeadFront=257.641 HeadBack=350 + Dist/Min : Back=0/238.2 Front=5687.9/366.5 + *[C3] = V -> V + VDeltaI=5255.625 TPosI=-5724.7 + VDeltaF=5687.869 NewVDelta =5568.794 + [C3Vs] + [C3Vs-xn] + VDeltaA =5463.276 + *** Fase : 2 *** + Lavorazione : Cut_AddCut_21_1 + Tdir=(-0.688204, 0.707158, 0.162182) Zup=-185.945 + DistFront=6097.946 DistBack=79.197 HeadFront=257.655 HeadBack=350 + Lavorazione : Cut_AddCut_21_2 + Tdir=(-0.688204, 0.707158, 0.162182) Zup=-219.976 + DistFront=5945.524 DistBack=223.6 HeadFront=257.655 HeadBack=350 + Lavorazione : Cut_AddCut_21_3 + Tdir=(0.229382, 0.000005, 0.973337) Zup=25.136 + DistFront=6390.194 DistBack=-196.071 HeadFront=342.001 HeadBack=342.001 + Lavorazione : Cut_AddCut_21_4 + Tdir=(0.229382, 0.000005, 0.973337) Zup=-8.894 + DistFront=6245.791 DistBack=-311.991 HeadFront=342.001 HeadBack=342.001 + Lavorazione : Cut_AddCut_22_1 + Tdir=(-0.716595, -0.69749, 0) Zup=-681.327 + DistFront=6411.128 DistBack=-187.068 HeadFront=249.247 HeadBack=350 + Lavorazione : Cut_AddCut_22_2 + Tdir=(-0.688255, 0.707107, 0.162189) Zup=-722.056 + DistFront=6419.633 DistBack=-236.929 HeadFront=257.641 HeadBack=350 + Lavorazione : Cut_AddCut_22_3 + Tdir=(-0.688255, 0.707107, 0.162189) Zup=-673.383 + DistFront=6322.661 DistBack=-225.46 HeadFront=257.641 HeadBack=350 + *[U] +Exec File = C:\EgtData\Machines\Essetre-FAST\Scripts\InitMach.lua +Release Mode +Disposition postapply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Pocketing apply skipped : status already ok +Pocketing apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Disposition postapply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +OnSimulPathEnd C:\EgtData\Machines\Essetre-FAST\Essetre-FAST.mlpe:451: attempt to call a nil value (global 'EgtVolZmapGetPartBBoxGlob') +Exec File = C:\EgtData\Machines\Essetre-FAST\Scripts\ExitMach.lua +Release Mode +Lua machine interpreter closed (Essetre-FAST) +Exec File = C:\EgtData\Machines\Essetre-FAST\Scripts\InitMach.lua +Release Mode +Lua 5.3 machine interpreter started (Essetre-FAST) +EgtBase started +EgtConst started +EgtVector3d started +EgtPoint3d started +EgtFrame3d started +EgtBBox3d started +EgtColor3d started +LuaLoadMachine : C:\EgtData\Machines\Essetre-FAST\Essetre-FAST.Mlde +EmtGenerator started +Release Mode +LuaEmtGeneral : Essetre-FAST.nge, Essetre-FAST.mlse, Essetre-FAST.mlpe +Debug Mode (32bit) +** Essetre-FAST 2.1l1 ** +Release Mode +LuaEmtBase : Base +LuaEmtAxis : X +LuaEmtAxis : Z +LuaEmtAxis : C +LuaEmtAxis : B + Move = (0.000444,0,0.35) +LuaEmtStdHead : H1 +LuaEmtStdHead : H2 + Exit T1 move = (0.000053,0.000234,0.480015) +LuaEmtAxis : A +LuaEmtStdHead : H3 + Exit T1 move = (0.000007,0,1.000002) +LuaEmtStdHead : H4 +LuaEmtAxis : Y +LuaEmtAxis : PY +LuaEmtAxis : V +LuaEmtAxis : PV +LuaEmtAxis : T +LuaEmtTable : Tab + Move = (0,-22.97,-15.0007) +ToolsMgr Init : C:\EgtData\Machines\Essetre-FAST\Tools\Tools.data +ReloadTools : FileVer = 1002 CurrVer = 1002 +MachiningsMgr Init : C:\EgtData\Machines\Essetre-FAST\Machinings\Machinings.data +ReloadMachinings : FileVer = 1008 CurrVer = 1008 +Disposition postapply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Pocketing apply skipped : status already ok +Pocketing apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Disposition postapply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Exec File = C:\EgtData\Machines\Essetre-FAST\Scripts\ExitMach.lua +Release Mode +Exec File = C:\EgtData\Machines\Essetre-FAST\Scripts\InitMach.lua +Release Mode +Disposition postapply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Pocketing apply skipped : status already ok +Pocketing apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Disposition postapply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +Milling apply skipped : status already ok +OnSimulPathEnd C:\EgtData\Machines\Essetre-FAST\Essetre-FAST.mlpe:451: attempt to call a nil value (global 'EgtVolZmapGetPartBBoxGlob') +Lua machine interpreter closed (Essetre-FAST) +All Contexts deleted (1) +Lua interpreter closed +2019/12/09 15:12:51 Exit diff --git a/ProgramData/EgtCAM5/Temp/EgtCAM5Log1.tua b/ProgramData/EgtCAM5/Temp/EgtCAM5Log1.tua new file mode 100644 index 0000000..a5e8b01 --- /dev/null +++ b/ProgramData/EgtCAM5/Temp/EgtCAM5Log1.tua @@ -0,0 +1,7 @@ +-- 2022/05/19 14:03:25 EgtCommandLog +EgtSetObjFilterForSelect(true,true,true,true,true) -- Ok=1 +EgtNewFile() -- Ok=1 +EgtGroup(GDB_ID.ROOT) -- Id=1 +EgtGroup(1) -- Id=2 +EgtSetCurrPartLayer(1,2) -- Ok=1 +EgtOpenFile('C:\\ProgramData\\EgalTech\\EgtBeamWall\\Projs\\0001\\5.bwe') -- Ok=1 diff --git a/ProgramData/EgtCAM5/Temp/EgtCAM5Log1.tua.bak b/ProgramData/EgtCAM5/Temp/EgtCAM5Log1.tua.bak new file mode 100644 index 0000000..c7ed943 --- /dev/null +++ b/ProgramData/EgtCAM5/Temp/EgtCAM5Log1.tua.bak @@ -0,0 +1,6 @@ +-- 2022/05/19 12:05:34 EgtCommandLog +EgtSetObjFilterForSelect(true,true,true,true,true) -- Ok=1 +EgtNewFile() -- Ok=1 +EgtGroup(GDB_ID.ROOT) -- Id=1 +EgtGroup(1) -- Id=2 +EgtSetCurrPartLayer(1,2) -- Ok=1 diff --git a/ProgramData/EgtCAM5/Temp/EgtCAM5Log1.txt b/ProgramData/EgtCAM5/Temp/EgtCAM5Log1.txt new file mode 100644 index 0000000..bac8406 --- /dev/null +++ b/ProgramData/EgtCAM5/Temp/EgtCAM5Log1.txt @@ -0,0 +1,58 @@ +2022/05/19 14:03:17 Init +User DESKTOP-933NOPU\carlo Inst1 Ulv1 Dbg3 +EgtCAM5R32.exe ver. 2.4d3 +EgtUILib.dll ver. 2.4d2 +EgtInterfaceR32.dll ver. 2.4d2 +EgtExecutorR32.dll ver. 2.4d2 +EgtGeneralR32.dll ver. 2.4d1 +EgtNumKernelR32.dll ver. 2.4b1 +EgtGeomKernelR32.dll ver. 2.4c2 +EgtGraphicsR32.dll ver. 2.4c1 +EgtExchangeR32.dll ver. 2.4d3 +EgtMachKernelR32.dll ver. 2.4d2 +Warning on Key (ENS/OPT) +Key 000335 (28620) +OS Ms Windows 10.0 (Build 19043) +CPU Intel(R) Core(TM)2 Duo CPU T9400 @ 2.53GHz - 2 threads - MMX+SSE+SSE2 +Memory 4083 MB (virtual 7831 MB) +UserObj Managers : +EXePicture +EGkDefault +EXePhoto +EMkAxis +EMkDrilling +EMkDisposition +EMkCamData +EMkChiseling +EMkExit +EMkGenMachining +EMkMilling +EMkPocketing +EMkMortising +EMkSawFinishing +EMkSawing +EMkSawRoughing +EMkHead +EMkSurfFinishing +EMkTable +EMkTcPos +EMkWaterJetting +Lua 5.3 interpreter started +Require Library = EgtBase +EgtBase started +EgtConst started +EgtVector3d started +EgtPoint3d started +EgtFrame3d started +EgtBBox3d started +EgtColor3d started +KeyOptions : True 595 +Context 1 started +OpenGL 3.3.0 (Nw) NVIDIA Corporation Quadro FX 1700M/PCIe/SSE2 +GLSL 3.30 NVIDIA via Cg compiler +PixFmt 7 ICD BUFF2 RGBA32 Z24 +MachMgr started (C:\EgtData\Machines) +BeamMgr started +All Contexts deleted (1) +Lua interpreter closed +2022/05/19 14:03:54 Exit diff --git a/ProgramData/EgtCAM5/Temp/EgtCAM5Log2.tua b/ProgramData/EgtCAM5/Temp/EgtCAM5Log2.tua new file mode 100644 index 0000000..630d29f --- /dev/null +++ b/ProgramData/EgtCAM5/Temp/EgtCAM5Log2.tua @@ -0,0 +1,7 @@ +-- 2022/05/04 13:33:46 EgtCommandLog +EgtSetObjFilterForSelect(true,true,true,true,true) -- Ok=1 +EgtNewFile() -- Ok=1 +EgtGroup(GDB_ID.ROOT) -- Id=1 +EgtGroup(1) -- Id=2 +EgtSetCurrPartLayer(1,2) -- Ok=1 +EgtOpenFile('E:\\EGALWARE\\ProgramData\\BeamWall\\CasaMosca0001.nge') -- Ok=1 diff --git a/ProgramData/EgtCAM5/Temp/EgtCAM5Log2.tua.bak b/ProgramData/EgtCAM5/Temp/EgtCAM5Log2.tua.bak new file mode 100644 index 0000000..3cd2082 --- /dev/null +++ b/ProgramData/EgtCAM5/Temp/EgtCAM5Log2.tua.bak @@ -0,0 +1,6 @@ +-- 2021/10/18 15:06:29 EgtCommandLog +EgtSetObjFilterForSelect(true,true,true,true,true) -- Ok=1 +EgtNewFile() -- Ok=1 +EgtGroup(GDB_ID.ROOT) -- Id=1 +EgtGroup(1) -- Id=2 +EgtSetCurrPartLayer(1,2) -- Ok=1 diff --git a/ProgramData/EgtCAM5/Temp/EgtCAM5Log2.txt b/ProgramData/EgtCAM5/Temp/EgtCAM5Log2.txt new file mode 100644 index 0000000..602dd13 --- /dev/null +++ b/ProgramData/EgtCAM5/Temp/EgtCAM5Log2.txt @@ -0,0 +1,58 @@ +2022/05/04 13:33:44 Init +User DESKTOP-933NOPU\carlo Inst2 Ulv1 Dbg3 +EgtCAM5R32.exe ver. 2.4d3 +EgtUILib.dll ver. 2.4d2 +EgtInterfaceR32.dll ver. 2.4d2 +EgtExecutorR32.dll ver. 2.4d2 +EgtGeneralR32.dll ver. 2.4d1 +EgtNumKernelR32.dll ver. 2.4b1 +EgtGeomKernelR32.dll ver. 2.4c2 +EgtGraphicsR32.dll ver. 2.4c1 +EgtExchangeR32.dll ver. 2.4d3 +EgtMachKernelR32.dll ver. 2.4d2 +Warning on Key (ENS/OPT) +Key 000335 (28620) +OS Ms Windows 10.0 (Build 19043) +CPU Intel(R) Core(TM)2 Duo CPU T9400 @ 2.53GHz - 2 threads - MMX+SSE+SSE2 +Memory 4083 MB (virtual 6899 MB) +UserObj Managers : +EXePicture +EGkDefault +EXePhoto +EMkAxis +EMkDrilling +EMkDisposition +EMkCamData +EMkChiseling +EMkExit +EMkGenMachining +EMkMilling +EMkPocketing +EMkMortising +EMkSawFinishing +EMkSawing +EMkSawRoughing +EMkHead +EMkSurfFinishing +EMkTable +EMkTcPos +EMkWaterJetting +Lua 5.3 interpreter started +Require Library = EgtBase +EgtBase started +EgtConst started +EgtVector3d started +EgtPoint3d started +EgtFrame3d started +EgtBBox3d started +EgtColor3d started +KeyOptions : True 595 +Context 1 started +OpenGL 3.3.0 (Nw) NVIDIA Corporation Quadro FX 1700M/PCIe/SSE2 +GLSL 3.30 NVIDIA via Cg compiler +PixFmt 7 ICD BUFF2 RGBA32 Z24 +MachMgr started (C:\EgtData\Machines) +BeamMgr started +All Contexts deleted (1) +Lua interpreter closed +2022/05/04 14:28:33 Exit diff --git a/ProgramData/EgtCAM5/ToolMakers/MakeChisel.lua b/ProgramData/EgtCAM5/ToolMakers/MakeChisel.lua new file mode 100644 index 0000000..5046aaa --- /dev/null +++ b/ProgramData/EgtCAM5/ToolMakers/MakeChisel.lua @@ -0,0 +1,125 @@ +-- 2019/09/23 11:30:00 +-- Creazione di uno scalpello per legno + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +require( "EgtDimension") + +-- Dati utensile : dichiarazione e valori standard +local TOOL = {} +TOOL.TOOLHOLDER = '' +TOOL.TOTLEN = 110 +TOOL.LEN = 80 +TOOL.DIAM = 20 +TOOL.MAXMAT = 40 +TOOL.ERR = 0 +_G.TOOL = TOOL + +-------------------------------------------------------------------------------- +function CreateTool() + + TOOL.ERR = 999 + + -- Parametri utensile + local sFilePath = TOOL.TOOLHOLDER + local dWDHeight = TOOL.TOTLEN + local dWDCylHeight = TOOL.LEN + local dWDDiameter = TOOL.DIAM + local dMaxMat = TOOL.MAXMAT + local dCutterHeight = dMaxMat + + -- Cancello tutto + EgtNewFile() + + -- Se richiesto inserisco porta utensile + local dToolHolderHeight = 0 + local dToolHolderDiameter = 0 + if sFilePath and sFilePath ~= "" then + -- eseguo inserimento + if not EgtInsertFile( sFilePath) then + TOOL.ERR = 1 + return + end + -- recupero altezza portautensile + local P = EgtGetFirstInGroup( GDB_ID.ROOT) + dToolHolderHeight = tonumber( EgtGetInfo( P, "H")) or 0 + dToolHolderDiameter = tonumber( EgtGetInfo (P, "D")) or 0 + -- Altrimenti creo pezzo e layer opportuni + else + -- Creo pezzo e layer + local P = EgtGroup( GDB_ID.ROOT) + local L = EgtGroup( P) + -- altezza portautensile rimane nulla + end + + -- Layer + local Part = EgtGetFirstGroupInGroup( GDB_ID.ROOT) + local WDLayer = EgtGetFirstInGroup( Part) + EgtSetName( WDLayer, 'SOLID') + local QuoteLayer = EgtGroup( Part) + EgtSetName( QuoteLayer, 'AUX') + EgtSetColor( QuoteLayer, BLACK()) + if EgtGetBackground then + local colTop, colBot = EgtGetBackground() + if colTop and colBot then + local nInt = colTop:getRed() + colTop:getGreen() + colTop:getBlue() + colBot:getRed() + colBot:getGreen() + colBot:getBlue() + if nInt < 769 then + EgtSetColor( QuoteLayer, WHITE()) + end + end + end + + -- verifico altezza parte non tagliente + local dNoCutHeight = dWDCylHeight - dMaxMat + if dNoCutHeight < dToolHolderHeight then + TOOL.ERR = 12 + return + end + + -- Pseudo raggio + local dRad = 0.5 * dWDDiameter + + -- Creazione parte non tagliente + if dNoCutHeight > 0.1 then + local dRadP = dRad + 0.5 + local NoCutRect = EgtRectangle2P( WDLayer, { -dRadP, -dRadP, 0}, { dRadP, dRadP, 0}, GDB_RT.GRID) + local NoCutSurf = EgtSurfTmByRegionExtrusion( WDLayer, NoCutRect, {0,0,dNoCutHeight}, 0.05, GDB_RT.GRID) + EgtRotate( NoCutSurf, ORIG(), X_AX(), 90, GDB_RT.GRID) + EgtSetColor( NoCutSurf, LGRAY()) + EgtErase( NoCutRect) + end + + -- Creazione parte tagliente + local CutRect1 = EgtRectangle2P( WDLayer, { -dRad, -dRad, 0}, { dRad, dRad, 0}, GDB_RT.GRID) + local dRadM = dRad - 0.5 + local CutRect2 = EgtRectangle2P( WDLayer, { -dRadM, -dRadM, 0}, { dRadM, dRadM, 0}, GDB_RT.GRID) + local dH = dWDCylHeight - dNoCutHeight + local CutSurf = EgtSurfTmByRegionExtrusion( WDLayer, {CutRect1, CutRect2}, { 0, 0, dH}, 0.05, GDB_RT.GRID) + EgtMove( CutSurf, Vector3d( 0, 0, dNoCutHeight), GDB_RT.GRID) + EgtRotate( CutSurf, ORIG(), X_AX(), 90, GDB_RT.GRID) + EgtSetColor( CutSurf, RED()) + EgtErase( {CutRect1, CutRect2}) + + -- Quotatura + local ptP2 = Point3d( dRad, - dWDCylHeight, 0) + local ptP4 = Point3d( - dRad, - dWDCylHeight, 0) + local dLenghtArrow = 0.05 * dWDHeight + local dDistQuoteX = 10 + local dDistQuoteY = max( dToolHolderDiameter, dWDDiameter) / 2 + 10 + local dTextSize = min( 15, max( 0.1 * dWDDiameter, 0.1 * dWDHeight)) + local dTextDist = 5 + local sLenTxt = EgtNumToString( EgtToUiUnits( dWDCylHeight), 3) + CreateLinearDimensionOnY( QuoteLayer, ORIG(), ptP4, sLenTxt, dTextSize, dDistQuoteY, + dLenghtArrow, dTextDist, false, 'LEN', GDB_RT.GRID) + local sDiamTxt = EgtNumToString( EgtToUiUnits( dWDDiameter), 3) + CreateLinearDimensionOnX( QuoteLayer, ptP2, ptP4, sDiamTxt, dTextSize, dDistQuoteX, + dLenghtArrow, dTextDist, false, 'DIAM', GDB_RT.GRID) + + TOOL.ERR = 0 + +end + +_G.CreateTool = CreateTool diff --git a/ProgramData/EgtCAM5/ToolMakers/MakeCylMill.lua b/ProgramData/EgtCAM5/ToolMakers/MakeCylMill.lua new file mode 100644 index 0000000..1595cbc --- /dev/null +++ b/ProgramData/EgtCAM5/ToolMakers/MakeCylMill.lua @@ -0,0 +1,141 @@ +-- 2019/09/23 09:30:00 +-- Creazione di fresa cilindrica + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +require("EgtDimension") + +-- Dati utensile : dichiarazione e valori standard +local TOOL = {} +TOOL.TOOLHOLDER = '' +TOOL.LEN = 80 +TOOL.DIAM = 20 +TOOL.MAXMAT = 40 +TOOL.ERR = 0 +_G.TOOL = TOOL + +-- Creazione utensile cilindrico +function CreateTool() + + TOOL.ERR = 999 + + -- Parametri utensile + local nType = TOOL.TYPE + local sFilePath = TOOL.TOOLHOLDER + local dMillHeight = TOOL.LEN + local dMillDiameter = TOOL.DIAM + local dCutterHeight = TOOL.MAXMAT + + -- progetto vuoto + EgtNewFile() + + local dToolHolderHeight = 0 + local dStemDiam = 40 + + -- Se richiesto inserisco porta utensile + if sFilePath and sFilePath ~= "" then + -- eseguo inserimento + if not EgtInsertFile(sFilePath) then + TOOL.ERR = 1 + return + end + -- recupero altezza portautensile e diametro gambo + local P = EgtGetFirstInGroup( GDB_ID.ROOT) + dToolHolderHeight = tonumber( EgtGetInfo( P, "H") or '0') + dStemDiam = tonumber( EgtGetInfo( P, "D_STEM") or '40') + -- Altrimenti creo pezzo e layer opportuni + else + -- Creo pezzo e layer + local P = EgtGroup(GDB_ID.ROOT) + local L = EgtGroup(P) + -- altezza portautensile rimane nulla + end + + -- Controllo lunghezza utensile + if dMillHeight - dToolHolderHeight - dCutterHeight < 0 then + TOOL.ERR = 12 + return + end + + -- Calcolo dimensione quote + local dMaxLinDim + if dMillHeight > dMillDiameter then + dMaxLinDim = dMillHeight + else + dMaxLinDim = dMillDiameter + end + local dLenghtArrow = 0.05 * dMaxLinDim + local dDistQuote = 20 + local dTextSize = 15 + local dTextDist = 5 + + -- Layer + local Part = EgtGetFirstGroupInGroup(GDB_ID.ROOT) + local MillLayer = (EgtGetFirstInGroup(Part)) + EgtSetName(MillLayer,'SOLID') + local QuoteLayer = EgtGroup(Part) + EgtSetName(QuoteLayer,'AUX') + EgtSetColor(QuoteLayer,BLACK()) + if EgtGetBackground then + local colTop, colBot = EgtGetBackground() + if colTop and colBot then + local nInt = colTop:getRed() + colTop:getGreen() + colTop:getBlue() + colBot:getRed() + colBot:getGreen() + colBot:getBlue() + if nInt < 769 then + EgtSetColor( QuoteLayer, WHITE()) + end + end + end + + -- Disegno utensile + local dTopDiam = min( dStemDiam, dMillDiameter) + local ptP1 = Point3d( dTopDiam/2, - dToolHolderHeight, 0) + local ptP2 = Point3d( dMillDiameter/2, -(dMillHeight - dCutterHeight), 0) + + if dMillHeight - dToolHolderHeight - dCutterHeight > 0.1 then + + local NoCutterLine = EgtLine(MillLayer, ptP1, ptP2, GDB_RT.GRID) + + local NoCutterHeight = dMillHeight - dToolHolderHeight - dCutterHeight + + local NoCutterSurf = EgtSurfTmByRevolve(MillLayer, NoCutterLine, Point3d(0,0,0), Vector3d(0,-1,0), false, 0.05, GDB_RT.GRID) + EgtSetColor(NoCutterSurf, LGRAY()) + EgtErase(NoCutterLine) + else + ptP2 = Point3d( ptP1) + end + + local ptP3 = Point3d(dMillDiameter/2, -dMillHeight, 0) + local CutterLine = EgtLine(MillLayer, ptP2, ptP3, GDB_RT.GRID) + + local sLenTxt = EgtNumToString(EgtToUiUnits(dMillHeight),3) + CreateLinearDimensionOnY(QuoteLayer, Point3d(0,0,0), ptP3, sLenTxt, dTextSize, 2.5 * dDistQuote, dLenghtArrow, dTextDist, true, 'LEN', GDB_RT.GRID) + + local ptP2M = Point3d( ptP2) + ptP2M:mirror(ORIG(),X_AX()) + local ptP3M = Point3d( ptP3) + ptP3M:mirror(ORIG(),X_AX()) + local sMaxMatTxt = EgtNumToString(EgtToUiUnits(dCutterHeight),3) + CreateLinearDimensionOnY(QuoteLayer, ptP2M, ptP3M, sMaxMatTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, false, 'MAXMAT', GDB_RT.GRID) + + local ptP4 = Point3d(0, -dMillHeight, 0) + local TipLine = EgtLine(MillLayer, ptP3, ptP4, GDB_RT.GRID) + + local ptP5 = Point3d(-dMillDiameter/2,-dMillHeight, 0) + + local sDiamTxt = EgtNumToString(EgtToUiUnits(dMillDiameter),3) + CreateLinearDimensionOnX(QuoteLayer, ptP3, ptP5, sDiamTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, false, 'DIAM', GDB_RT.GRID) + + CutterLine = EgtCurveCompo(MillLayer,{CutterLine, TipLine}) + + local CutterSurf = EgtSurfTmByRevolve(MillLayer, CutterLine, Point3d(0,0,0), Vector3d(0,-1,0), false, 0.05, GDB_RT.GRID) + + EgtSetColor(CutterSurf,ORANGE()) + + EgtErase(CutterLine) + + TOOL.ERR = 0 +end +_G.CreateTool = CreateTool diff --git a/ProgramData/EgtCAM5/ToolMakers/MakeDrill.lua b/ProgramData/EgtCAM5/ToolMakers/MakeDrill.lua new file mode 100644 index 0000000..659ab25 --- /dev/null +++ b/ProgramData/EgtCAM5/ToolMakers/MakeDrill.lua @@ -0,0 +1,283 @@ +-- 2019/09/23 18:30:00 +-- Creazione di un foretto + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +require("EgtDimension") + +-- Dati utensile : dichiarazione e valori standard +local TOOL = {} +TOOL.TOOLHOLDER = '' +TOOL.LEN = 80 +TOOL.DIAM = 20 +TOOL.MAXMAT = 40 +TOOL.ERR = 0 +_G.TOOL = TOOL + +function CreateTool() + + TOOL.ERR = 999 + + -- Parametri utensile + local sFilePath = TOOL.TOOLHOLDER + local dDrillHeight = TOOL.LEN + local dDrillDiameter = TOOL.DIAM + local dMaxMat = TOOL.MAXMAT + local dCutterHeight = dMaxMat + local bDrillType = true + + -- progetto vuoto + EgtNewFile() + + local dToolHolderHeight = 0 + + -- Se richiesto inserisco porta utensile + if sFilePath and sFilePath ~= "" then + -- eseguo inserimento + if not EgtInsertFile(sFilePath) then + TOOL.ERR = 1 + return + end + -- recupero altezza portautensile + local P = EgtGetFirstInGroup(GDB_ID.ROOT) + dToolHolderHeight = tonumber(EgtGetInfo(P,"H")) + -- Altrimenti creo pezzo e layer opportuni + else + -- Creo pezzo e layer + local P = EgtGroup(GDB_ID.ROOT) + local L = EgtGroup(P) + -- altezza portautensile rimane nulla + end + + -- Calcolo dimensione quote + local dMaxLinDim + if dDrillHeight > dDrillDiameter + GEO.EPS_SMALL then + dMaxLinDim = dDrillHeight + else + dMaxLinDim = dDrillDiameter + end + local dLenghtArrow = 0.05 * dMaxLinDim + local dDistQuote = 20 + local dTextSize = 15 + local dTextDist = 5 + + -- Layer + local Part = EgtGetFirstGroupInGroup(GDB_ID.ROOT) + local DrillLayer = (EgtGetFirstInGroup(Part)) + EgtSetName(DrillLayer,'SOLID') + local QuoteLayer = EgtGroup(Part) + EgtSetName(QuoteLayer,'AUX') + EgtSetColor(QuoteLayer,BLACK()) + if EgtGetBackground then + local colTop, colBot = EgtGetBackground() + if colTop and colBot then + local nInt = colTop:getRed() + colTop:getGreen() + colTop:getBlue() + colBot:getRed() + colBot:getGreen() + colBot:getBlue() + if nInt < 769 then + EgtSetColor( QuoteLayer, WHITE()) + end + end + end + + -- Se foretto periferico + if bDrillType then + + local dDrillInnerHeight = dMaxMat + 5 + local dSpessore = min( 3, dDrillDiameter / 4) + local dDrillInnerDiameter = dDrillDiameter - 2 * dSpessore + local dNoCutterHeight = dDrillHeight - dToolHolderHeight - dCutterHeight + local dInnNoCutterHeight = dDrillInnerHeight - dCutterHeight + + if dDrillHeight - dToolHolderHeight < dDrillInnerHeight - GEO.EPS_SMALL then + TOOL.ERR = 12 + return + end + + if dDrillDiameter < 1 then + TOOL.ERR = 19 + return + end + + if dNoCutterHeight > 0.1 then + + local ptP1 = Point3d(dDrillDiameter/2, - dToolHolderHeight, 0) + local ptP2 = Point3d(dDrillDiameter/2, - (dNoCutterHeight + dToolHolderHeight), 0) + local ptP3 = Point3d(dDrillInnerDiameter/2, - (dNoCutterHeight + dToolHolderHeight), 0) + local ptP4 = Point3d(dDrillInnerDiameter/2, - dDrillHeight + dDrillInnerHeight, 0) + local ptP5 = Point3d(0, - dDrillHeight + dDrillInnerHeight, 0) + + local NoCutLineExt = EgtLine(DrillLayer, ptP1, ptP2, GDB_RT.GRID) + + local NoCutterSurfExt = EgtSurfTmByRevolve(DrillLayer, NoCutLineExt, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) + + EgtSetColor(NoCutterSurfExt, LGRAY()) + EgtErase(NoCutLineExt) + + if dInnNoCutterHeight > 0.1 then + + local NoCutIn = EgtLine(DrillLayer, ptP3, ptP4, GDB_RT.GRID) + local CeilingLine = EgtLine(DrillLayer, ptP4, ptP5, GDB_RT.GRID) + + local NoCutCurve = EgtCurveCompo(DrillLayer,{NoCutIn,CeilingLine}) + local NoCutterSurfInn = EgtSurfTmByRevolve(DrillLayer, NoCutCurve, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) + + EgtSetColor(NoCutterSurfInn, LGRAY()) + EgtErase(NoCutCurve) + + else + + local NewCeilLine = EgtLine(DrillLayer, ptP3, ptP5, GDB_RT.GRID) + + local NewCeiling = EgtSurfTmByRevolve(DrillLayer, NewCeilLine, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) + + EgtSetColor(NewCeiling, LGRAY()) + EgtErase(NewCeilLine) + + end + + local ptP6 = Point3d(dDrillDiameter/2, - dDrillHeight, 0) + local ptP7 = Point3d(dDrillInnerDiameter/2, -dDrillHeight, 0) + + local sLenTxt = EgtNumToString(EgtToUiUnits(dDrillHeight),3) + CreateLinearDimensionOnY(QuoteLayer, Point3d(40,0,0), ptP6, sLenTxt, dTextSize, 2*dDistQuote, dLenghtArrow, dTextDist, true, 'LEN', GDB_RT.GRID) + + local ptP8 = Point3d(-dDrillDiameter/2, -dDrillHeight, 0) + + local sDiamTxt = EgtNumToString(EgtToUiUnits(dDrillDiameter),3) + CreateLinearDimensionOnX(QuoteLayer, ptP8, ptP6, sDiamTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, false, 'DIAM', GDB_RT.GRID) + + local ptP6M = Point3d( ptP6) + ptP6M:mirror(ORIG(),X_AX()) + local ptP2M = Point3d( ptP2) + ptP2M:mirror(ORIG(),X_AX()) + local sMaxMatTxt = EgtNumToString(EgtToUiUnits(dMaxMat),3) + CreateLinearDimensionOnY(QuoteLayer, ptP2M, ptP6M, sMaxMatTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, false, 'MAXMAT', GDB_RT.GRID) + + local CutLineExt = EgtLine(DrillLayer, ptP2, ptP6, GDB_RT.GRID) + local CutLineBot = EgtLine(DrillLayer, ptP6, ptP7, GDB_RT.GRID) + local CutLineInn = EgtLine(DrillLayer, ptP7, ptP3, GDB_RT.GRID) + + local CutLin = EgtCurveCompo(DrillLayer,{CutLineExt,CutLineBot,CutLineInn}) + + local CutterSurf = EgtSurfTmByRevolve(DrillLayer, CutLin, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) + + EgtSetColor(CutterSurf, ORANGE()) + EgtErase(CutLin) + + else + + local ptP1 = Point3d(dDrillDiameter/2, - dToolHolderHeight, 0) + local ptP2 = Point3d(dDrillDiameter/2, - dDrillHeight, 0) + local ptP3 = Point3d(dDrillInnerDiameter/2, - dDrillHeight, 0) + local ptP4 = Point3d(dDrillInnerDiameter/2, - dToolHolderHeight, 0) + local ptP5 = Point3d(0, - dToolHolderHeight, 0) + local ptP6 = Point3d(-dDrillDiameter/2, - dDrillHeight, 0) + + local sLenTxt = EgtNumToString(EgtToUiUnits(dDrillHeight),3) + CreateLinearDimensionOnY(QuoteLayer, ORIG(), ptP2, sLenTxt, dTextSize, 2*dDistQuote, dLenghtArrow, dTextDist, true, 'LEN', GDB_RT.GRID) + + local sDiamTxt = EgtNumToString(EgtToUiUnits(dDrillDiameter),3) + CreateLinearDimensionOnX(QuoteLayer, ptP2, ptP6, sDiamTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, false, 'DIAM', GDB_RT.GRID) + + local ptP1M = Point3d( ptP1) + ptP1M:mirror(ORIG(),X_AX()) + local ptP2M = Point3d( ptP2) + ptP2M:mirror(ORIG(),X_AX()) + local sMaxMatTxt = EgtNumToString(EgtToUiUnits(dMaxMat),3) + CreateLinearDimensionOnY(QuoteLayer, ptP1M, ptP2M, sMaxMatTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, false, 'MAXMAT', GDB_RT.GRID) + + local Ext = EgtLine(DrillLayer, ptP1, ptP2, GDB_RT.GRID) + local Bot = EgtLine(DrillLayer, ptP2, ptP3, GDB_RT.GRID) + local Inn = EgtLine(DrillLayer, ptP3, ptP4, GDB_RT.GRID) + + local CutCurve = EgtCurveCompo(DrillLayer,{Ext,Bot,Inn}) + + local CutSurf = EgtSurfTmByRevolve(DrillLayer, CutCurve, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) + + EgtSetColor(CutSurf, ORANGE()) + + EgtErase(CutCurve) + + local Cei = EgtLine(DrillLayer, ptP4, ptP5, GDB_RT.GRID) + + local CeiSurf = EgtSurfTmByRevolve(DrillLayer, Cei, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) + + EgtSetColor(CeiSurf, LGRAY()) + + EgtErase(Cei) + + end + + else + + local dNoCutterHeight = dDrillHeight - dToolHolderHeight - dCutterHeight + + if dNoCutterHeight < - GEO.EPS_SMALL then + TOOL.ERR = 12 + return + end + + if dNoCutterHeight > 0.1 then + + local ptP1 = Point3d(dDrillDiameter/2, - dToolHolderHeight, 0) + local ptP2 = Point3d(dDrillDiameter/2, - (dNoCutterHeight + dToolHolderHeight), 0) + local ptP3 = Point3d(dDrillDiameter/2, - dDrillHeight, 0) + local ptP4 = Point3d(0, - dDrillHeight, 0) + local ptP5 = Point3d(-dDrillDiameter/2, -dDrillHeight, 0) + + local sLenTxt = EgtNumToString(EgtToUiUnits(dDrillHeight),3) + CreateLinearDimensionOnY(QuoteLayer, ORIG(), ptP3, sLenTxt, dTextSize, 2*dDistQuote, dLenghtArrow, dTextDist, true, 'LEN', GDB_RT.GRID) + + local sDiamTxt = EgtNumToString(EgtToUiUnits(dDrillDiameter),3) + CreateLinearDimensionOnX(QuoteLayer, ptP5, ptP3, sDiamTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, false, 'DIAM', GDB_RT.GRID) + + local NoCutterLine = EgtLine(DrillLayer, ptP1, ptP2, GDB_RT.GRID) + local CutterLine = EgtLine(DrillLayer, ptP2, ptP3, GDB_RT.GRID) + local TipLine = EgtLine(DrillLayer, ptP3, ptP4, GDB_RT.GRID) + + local NoCutterSurf = EgtSurfTmByRevolve(DrillLayer, NoCutterLine, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) + + EgtSetColor(NoCutterSurf, LGRAY()) + EgtErase(NoCutterLine) + + local CutLin = EgtCurveCompo(DrillLayer,{CutterLine,TipLine}) + + local CutterSurf = EgtSurfTmByRevolve(DrillLayer, CutLin, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) + + EgtSetColor(CutterSurf, ORANGE()) + EgtErase(CutLin) + + else + + local ptP1 = Point3d(dDrillDiameter/2, - dToolHolderHeight, 0) + local ptP2 = Point3d(dDrillDiameter/2, - dDrillHeight, 0) + local ptP3 = Point3d(0, - dDrillHeight, 0) + + local sLenTxt = EgtNumToString(EgtToUiUnits(dDrillHeight),3) + CreateLinearDimensionOnY(QuoteLayer,ORIG(), ptP2, sLenTxt, dTextSize, 2*dDistQuote, dLenghtArrow, dTextDist, true, 'LEN', GDB_RT.GRID) + + local ptP4 = Point3d(-dDrillDiameter/2, -dDrillHeight, 0) + + local sDiamTxt = EgtNumToString(EgtToUiUnits(dDrillDiameter),3) + CreateLinearDimensionOnX(QuoteLayer, ptP2, ptP4, sDiamTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, false, 'DIAM', GDB_RT.GRID) + + local Curve1 = EgtLine(DrillLayer, ptP1, ptP2, GDB_RT.GRID) + local Curve2 = EgtLine(DrillLayer, ptP2, ptP3, GDB_RT.GRID) + + local CutCurve = EgtCurveCompo(DrillLayer, {Curve1, Curve2}) + + local CutSurf = EgtSurfTmByRevolve(DrillLayer, CutCurve, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) + + EgtSetColor(CutSurf, ORANGE()) + + EgtErase(CutCurve) + + end + + end + + TOOL.ERR = 0 +end +_G.CreateTool = CreateTool diff --git a/ProgramData/EgtCAM5/ToolMakers/MakeMortise.lua b/ProgramData/EgtCAM5/ToolMakers/MakeMortise.lua new file mode 100644 index 0000000..7d5c08c --- /dev/null +++ b/ProgramData/EgtCAM5/ToolMakers/MakeMortise.lua @@ -0,0 +1,146 @@ +-- 2021/04/06 09:30:00 +-- Creazione di una sega a catena per legno +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +require( "EgtDimension") + +-- Dati utensile : dichiarazione e valori standard +local TOOL = {} +TOOL.TOOLHOLDER = '' +TOOL.SPEED = nil +TOOL.LEN = 400 +TOOL.DIAM = 100 +TOOL.THICK = 10 +TOOL.CORNRAD = 50 +TOOL.DIST = 90 +TOOL.MAXMAT = 300 +TOOL.ERR = 0 +_G.TOOL = TOOL + +-------------------------------------------------------------------------------- +function CreateTool() + + TOOL.ERR = 999 + + -- Parametri utensile + local sFilePath = TOOL.TOOLHOLDER + local dHeight = TOOL.LEN + local dDiameter = TOOL.DIAM + local dThick = TOOL.THICK + local dCornR = TOOL.CORNRAD + local dDist = TOOL.DIST + local dMaxMat = TOOL.MAXMAT + local dSpeed = TOOL.SPEED + + -- Cancello tutto + EgtNewFile() + + -- Se richiesto inserisco porta utensile + local dToolHolderHeight = 0 + local dToolHolderDiameter = 0 + if sFilePath and sFilePath ~= "" then + -- eseguo inserimento + if not EgtInsertFile( sFilePath) then + TOOL.ERR = 1 + return + end + -- recupero dimensioniuportautensile + local Pz = EgtGetFirstInGroup( GDB_ID.ROOT) + dToolHolderHeight = EgtGetInfo( Pz, "H", 'd') or 0 + dToolHolderDiameter = EgtGetInfo( Pz, "D", 'd') or 0 + -- eventuale visualizzazione senso di rotazione + local Ly = EgtGetFirstInGroup( Pz or GDB_ID.NULL) + local RotId = EgtGetFirstNameInGroup( Ly or GDB_ID.NULL, 'Rot') + if RotId then + if dSpeed and abs( dSpeed) > 1 then + -- se rotazione opposta, devo invertire + if dSpeed < 0 then + EgtMirror( RotId, ORIG(), X_AX(), GDB_RT.GLOB) + end + else + EgtSetStatus( RotId, GDB_ST.OFF) + end + end + -- Altrimenti creo pezzo e layer opportuni + else + -- Creo pezzo e layer + local Pz = EgtGroup( GDB_ID.ROOT) + local Ly = EgtGroup( Pz) + -- altezza portautensile rimane nulla + end + + -- Layer + local Part = EgtGetFirstGroupInGroup( GDB_ID.ROOT) + local Layer = EgtGetFirstInGroup( Part) + EgtSetName( Layer, 'SOLID') + local QuoteLayer = EgtGroup( Part) + EgtSetName( QuoteLayer, 'AUX') + EgtSetColor( QuoteLayer, BLACK()) + if EgtGetBackground then + local colTop, colBot = EgtGetBackground() + if colTop and colBot then + local nInt = colTop:getRed() + colTop:getGreen() + colTop:getBlue() + colBot:getRed() + colBot:getGreen() + colBot:getBlue() + if nInt < 769 then + EgtSetColor( QuoteLayer, WHITE()) + end + end + end + + -- verifico altezza parte non tagliente + local dNoCutHeight = dHeight - dMaxMat + if dNoCutHeight < dToolHolderHeight then + TOOL.ERR = 12 + return + end + + -- Pseudo raggio + local dRad = 0.5 * dDiameter + + -- Creazione parte non tagliente + if dNoCutHeight > 0.1 then + local NoCutRect = EgtRectangle2P( Layer, { -dRad, -dNoCutHeight, 0}, { dRad, 0, 0}, GDB_RT.GRID) + local NoCutSurf = EgtSurfTmByRegionExtrusion( Layer, NoCutRect, { 0, 0, dThick}, 0.05, GDB_RT.GRID) + EgtSetColor( NoCutSurf, LGRAY()) + EgtErase( NoCutRect) + end + + -- Creazione parte tagliente + local Pts = {{-dRad, -dNoCutHeight, 0, 0}, + {-dRad, -dHeight+dCornR, 0, 0.41421356}, + {-dRad+dCornR, -dHeight, 0, 0}, + {dRad-dCornR, -dHeight, 0, 0.41421356}, + {dRad, -dHeight+dCornR, 0, 0}, + {dRad, -dNoCutHeight, 0, 0}} + local CutShape = EgtCurveCompoFromPointBulges( Layer, Pts) + EgtCloseCurveCompo( CutShape) + local CutSurf = EgtSurfTmByRegionExtrusion( Layer, CutShape, { 0, 0, dThick}, 0.05, GDB_RT.GRID) + EgtSetColor( CutSurf, Color3d( 224, 0, 0)) + EgtErase( CutShape) + + -- Quotatura + local ptP2 = Point3d( dRad, - dHeight, 0) + local ptP4 = Point3d( - dRad, - dHeight, 0) + local dLenghtArrow = 0.05 * dHeight + local dDistQuoteX = 40 + local dDistQuoteY = max( dToolHolderDiameter, dDiameter) / 2 + 10 + local dTextSize = min( 15, max( 0.1 * dDiameter, 0.1 * dHeight)) + local dTextDist = 5 + local sLenTxt = EgtNumToString( EgtToUiUnits( dHeight), 3) + CreateLinearDimensionOnY( QuoteLayer, ORIG(), ptP4, sLenTxt, dTextSize, dDistQuoteY, + dLenghtArrow, dTextDist, false, 'LEN', GDB_RT.GRID) + local sDiamTxt = EgtNumToString( EgtToUiUnits( dDiameter), 3) + CreateLinearDimensionOnX( QuoteLayer, ptP2, ptP4, sDiamTxt, dTextSize, dDistQuoteX, + dLenghtArrow, dTextDist, false, 'DIAM', GDB_RT.GRID) + if dDist > 1 then + local ptP5 = Point3d( -150, 50, 0) + local sDistTxt = 'D=' .. EgtNumToString( EgtToUiUnits( dDist), 3) + EgtText( QuoteLayer, ptP5, sDistTxt, dTextSize, GDB_RT.GRID) + end + + TOOL.ERR = 0 +end + +_G.CreateTool = CreateTool diff --git a/ProgramData/EgtCAM5/ToolMakers/MakeSawBlade.lua b/ProgramData/EgtCAM5/ToolMakers/MakeSawBlade.lua new file mode 100644 index 0000000..31935a2 --- /dev/null +++ b/ProgramData/EgtCAM5/ToolMakers/MakeSawBlade.lua @@ -0,0 +1,215 @@ +-- 2021/03/14 10:30:00 +-- Creazione di una lama +-- 2021/03/14 Aggiunta gestione parte mobile del porta-utensile (ThMobile). + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +require("EgtDimension") + +-- Dati utensile : dichiarazione e valori standard +local TOOL = {} +TOOL.TOOLHOLDER = '' +TOOL.SPEED = nil +TOOL.LEN = 80 +TOOL.DIAM = 400 +TOOL.CORE = 4 +TOOL.THICK = 5 +TOOL.CORNRAD = 0 +TOOL.MAXMAT = 40 +TOOL.ERR = 0 +_G.TOOL = TOOL + +function CreateTool() + + TOOL.ERR = 999 + + -- Parametri utensile + local sFilePath = TOOL.TOOLHOLDER + local dSawHeight = TOOL.LEN + local dSawRad = TOOL.DIAM / 2 + local dSawCornRad = TOOL.CORNRAD + local bCornRad = ( dSawCornRad > GEO.EPS_SMALL) + local dBodyThickness = TOOL.CORE + local dToothThickness = TOOL.THICK + local dToothRadLen = min( 20, dSawRad / 2) + local dToothOffs = ( dToothThickness - dBodyThickness) / 2 + -- Parametri portautensile + local dThHeight = 0 + local dThTotHeight = 0 + -- Rotazione + local dSpeed = TOOL.SPEED + + -- Progetto vuoto + EgtNewFile() + local Pz = GDB_ID.NULL + + -- Se richiesto inserisco porta utensile + if sFilePath and sFilePath ~= "" then + -- eseguo inserimento + if not EgtInsertFile( sFilePath) then + TOOL.ERR = 1 + return + end + -- recupero altezza portautensile + Pz = EgtGetFirstInGroup( GDB_ID.ROOT) + dThHeight = EgtGetInfo( Pz, "H", 'd') or 0 + -- recupero ingombro portautensile + local b3Th = EgtGetBBoxGlob( Pz, GDB_BB.STANDARD) + if b3Th then + dThTotHeight = abs( b3Th:getMin():getY()) + end + -- eventuale visualizzazione senso di rotazione + local Ly = EgtGetFirstInGroup( Pz or GDB_ID.NULL) + local RotId = EgtGetFirstNameInGroup( Ly or GDB_ID.NULL, 'Rot') + if RotId then + if dSpeed and abs( dSpeed) > 1 then + -- se rotazione opposta, devo invertire + if dSpeed < 0 then + EgtMirror( RotId, ORIG(), X_AX(), GDB_RT.GLOB) + end + else + EgtSetStatus( RotId, GDB_ST.OFF) + end + end + -- posizionamento eventuale parte mobile + local ThMobId = EgtGetFirstNameInGroup( Ly or GDB_ID.NULL, 'ThMobile') + if ThMobId then + EgtMove( ThMobId, Vector3d( 0, -dSawHeight, 0)) + end + -- Altrimenti creo pezzo e layer opportuni + else + -- Creo pezzo e layer + Pz = EgtGroup( GDB_ID.ROOT) + EgtGroup( Pz) + -- altezza portautensile rimane nulla + end + + -- Ruoto la lama per ragioni di visualizzazione + EgtRotate( Pz, ORIG(), Z_AX(), 90, GDB_RT.GRID) + + -- Calcolo dimensione quote + local dMaxLinDim + if dSawHeight > 2 * dSawRad + GEO.EPS_SMALL then + dMaxLinDim = dSawHeight + else + dMaxLinDim = 2 * dSawRad + end + local dLenghtArrow = 0.005 * dMaxLinDim + local dDistQuote = 40 + local dTextSize = 15 + local dTextDist = 5 + + -- Layers + local SawLayer = EgtGetFirstGroupInGroup( Pz) + EgtSetName( SawLayer, 'SOLID') + local QuoteLayer = EgtGroup( Pz) + EgtSetName( QuoteLayer, 'AUX') + EgtSetColor( QuoteLayer, BLACK()) + if EgtGetBackground then + local colTop, colBot = EgtGetBackground() + if colTop and colBot then + local nInt = colTop:getRed() + colTop:getGreen() + colTop:getBlue() + colBot:getRed() + colBot:getGreen() + colBot:getBlue() + if nInt < 769 then + EgtSetColor( QuoteLayer, WHITE()) + end + end + end + + -- Controllo se i valori passati degli spessori sono validi (dToothThickness deve essere maggiore di dBodyThickness) + if dToothOffs < - GEO.EPS_SMALL or dBodyThickness < 0.1 then + TOOL.ERR = 2 + return + end + + -- Raggio corner non deve essere superiore a metà spessore + dSawCornRad = min( dSawCornRad, 0.5 * dToothThickness) + + -- Determino l'altezza del gambo e fisso i parametri geometrici diametro gambo e lunghezza radiale dei denti + local dStemHeight = dSawHeight - dThHeight - dToothThickness + dToothOffs + local dStemRad = max( min( dSawRad / 8, 60), 1) + + -- Controllo: se il gambo è di lunghezza negativa errore + if dStemHeight < - GEO.EPS_SMALL then + TOOL.ERR = 3 + return + end + + -- Gambo, se previsto + local vStem = {} + if dStemHeight > 0.1 then + vStem[1] = Point3d( dThHeight, 0, 0) + vStem[2] = Point3d( dThHeight, dStemRad, 0) + vStem[3] = Point3d( dThHeight + dStemHeight, dStemRad, 0) + local StemLine = EgtCurveCompoFromPoints( SawLayer, vStem, GDB_RT.GRID) + local StemSurf = EgtSurfTmByRevolve( SawLayer, StemLine, ORIG(), X_AX(), false, 0.05, GDB_RT.GRID) + EgtSetColor( StemSurf, LGRAY()) + EgtErase( StemLine) + else + dStemHeight = 0 + vStem[3] = Point3d( dThHeight, 0, 0) + end + + -- Corpo + local vBody = {} + vBody[1] = Point3d( vStem[3]) + vBody[2] = Point3d( dThHeight + dStemHeight, dSawRad - dToothRadLen, 0) + vBody[3] = Point3d( dThHeight + dStemHeight + dBodyThickness, dSawRad - dToothRadLen, 0) + vBody[4] = Point3d( dThHeight + dStemHeight + dBodyThickness, 0, 0) + local BodyLineUp = EgtLine( SawLayer, vBody[1], vBody[2], GDB_RT.GRID) + local BodyLineDw = EgtLine( SawLayer, vBody[3], vBody[4], GDB_RT.GRID) + local BodySurfUp = EgtSurfTmByRevolve( SawLayer, BodyLineUp, ORIG(), X_AX(), false, 0.05, GDB_RT.GRID) + local BodySurfDw = EgtSurfTmByRevolve( SawLayer, BodyLineDw, ORIG(), X_AX(), false, 0.05, GDB_RT.GRID) + EgtSetColor( { BodySurfUp, BodySurfDw}, Color3d( 224, 32, 32)) + EgtErase( { BodyLineUp, BodyLineDw}) + + -- Denti + local vTooth = {} + table.insert( vTooth, Point4d( vBody[2], 0)) + table.insert( vTooth, Point4d( dThHeight + dStemHeight - dToothOffs, dSawRad - dToothRadLen, 0, 0)) + local ptLeft = Point3d( dThHeight + dStemHeight - dToothOffs, dSawRad, 0) + if bCornRad then + table.insert( vTooth, Point4d( ptLeft - Y_AX() * dSawCornRad, -0.414213562)) + table.insert( vTooth, Point4d( ptLeft + X_AX() * dSawCornRad, 0)) + else + table.insert( vTooth, Point4d( ptLeft, 0)) + end + local ptRight = Point3d( dSawHeight, dSawRad, 0) + if bCornRad then + table.insert( vTooth, Point4d( ptRight - X_AX() * dSawCornRad, -0.414213562)) + table.insert( vTooth, Point4d( ptRight - Y_AX() * dSawCornRad, 0)) + else + table.insert( vTooth, Point4d( ptRight, 0)) + end + table.insert( vTooth, Point4d( dSawHeight, dSawRad - dToothRadLen, 0, 0)) + table.insert( vTooth, Point4d( vBody[3], 0)) + --local ToothLine = EgtCurveCompoFromPoints( SawLayer, vTooth, GDB_RT.GRID) + local ToothLine = EgtCurveCompoFromPointBulges( SawLayer, vTooth, GDB_RT.GRID) + local ToothSurf = EgtSurfTmByRevolve( SawLayer, ToothLine, ORIG(), X_AX(), false, 0.05, GDB_RT.GRID) + EgtSetColor( ToothSurf, Color3d( 224, 0, 0)) + EgtErase( ToothLine) + + -- Quotature + -- creo punto diametralmente opposto a ptRight + local ptToothDw = Point3d( dSawHeight, -dSawRad, 0) + local dDistAdd = max( dThTotHeight - dSawHeight, 0) + local sLenTxt = EgtNumToString( EgtToUiUnits( dSawHeight), 3) + CreateLinearDimensionOnX( QuoteLayer, ORIG(), ptToothDw, sLenTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, false, "LEN", GDB_RT.GRID) + local sThickTxt = EgtNumToString( EgtToUiUnits( dToothThickness), 3) + CreateLinearDimensionOnX( QuoteLayer, ptLeft, ptRight, sThickTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, true, "THICK", GDB_RT.GRID) + local sDiamTxt = EgtNumToString( EgtToUiUnits( 2 * dSawRad), 3) + CreateLinearDimensionOnY( QuoteLayer, ptRight, ptToothDw, sDiamTxt, dTextSize, dDistQuote + dDistAdd, dLenghtArrow, dTextDist, true, "DIAM", GDB_RT.GRID) + if bCornRad then + local sCradTxt = EgtNumToString( EgtToUiUnits( dSawCornRad), 3) + local ptC = ptToothDw + Vector3d( -dSawCornRad, dSawCornRad, 0) + local ptOn = ptC + VectorFromPolar( dSawCornRad + 0.05 * dDistQuote, -45) + local ptText = ptOn + VectorFromPolar( 0.5 * dDistQuote, -45) + CreateRadialDimension( QuoteLayer, ptText, ptOn, sCradTxt, dTextSize, dDistQuote + dDistAdd, dLenghtArrow, dTextDist, nil, "CRAD", GDB_RT.GRID) + end + + TOOL.ERR = 0 + +end +_G.CreateTool = CreateTool diff --git a/ProgramData/EgtCAM5/ToolMakers/MakeWoodCylMill.lua b/ProgramData/EgtCAM5/ToolMakers/MakeWoodCylMill.lua new file mode 100644 index 0000000..fe0b011 --- /dev/null +++ b/ProgramData/EgtCAM5/ToolMakers/MakeWoodCylMill.lua @@ -0,0 +1,695 @@ +-- 2021/11/14 11:00:00 +-- Creazione di fresa cilindrica per legno +-- 2019/03/26 DS Tolleranza creazione superficie portata a 0.01. +-- 2020/05/15 DS Correzione creazione layer per utensile senza portautensile. +-- 2021/05/22 DS Cancellazione eventuale layer aux di portautensile +-- 2021/11/14 DS Aggiunta gestione eventuale secondo ingombro portautensile. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +require( "EgtDimension") + +-- Dati utensile : dichiarazione e valori standard +local TOOL = {} +TOOL.TOOLHOLDER = '' +TOOL.SPEED = nil +TOOL.LEN = 80 +TOOL.TOTLEN = 80 +TOOL.DIAM = 20 +TOOL.TOTDIAM = 20 +TOOL.CORNRAD = 0 +TOOL.SIDEANG = 0 +TOOL.HEIGHT = 30 +TOOL.MAXMAT = 40 +TOOL.ERR = 0 +_G.TOOL = TOOL + +-- Creazione utensile cilindrico +function CreateTool() + + TOOL.ERR = 999 + + -- Parametri utensile + local sFilePath = TOOL.TOOLHOLDER + local dMillHeight = TOOL.LEN + local dTotMillHeight = TOOL.TOTLEN + local dMillDiameter = TOOL.DIAM + local dTotMillDiameter = TOOL.TOTDIAM + local dRadFillet = TOOL.CORNRAD + local dProfileHeight = TOOL.HEIGHT + local dSideAng = TOOL.SIDEANG + local dCutterHeight = TOOL.MAXMAT + local dSpeed = TOOL.SPEED + + -- correzione diametro utensile prossimo allo 0 + if dMillDiameter <= GEO.EPS_SMALL then + dMillDiameter = 0 + end + + -- progetto vuoto + EgtNewFile() + + local dToolHolderHeight = 0 + local dToolHolderDiameter = 0 + local dToolHolderStemDiam = 0 + if not dRadFillet then dRadFillet = 0 end + + -- Se richiesto inserisco porta utensile + if sFilePath and sFilePath ~= "" then + -- eseguo inserimento + if not EgtInsertFile(sFilePath) then + TOOL.ERR = 1 + return + end + -- recupero dimensioni portautensile + local Pz = EgtGetFirstInGroup( GDB_ID.ROOT) + dToolHolderHeight = EgtGetInfo( Pz, "H", 'd') or 0 + dToolHolderDiameter = EgtGetInfo( Pz, "D", 'd') or 0 + dToolHolderStemDiam = EgtGetInfo( Pz, "D_STEM", 'd') or 0 + -- eventuale gestione secondo ingombro + local dThH2 = EgtGetInfo( Pz, "H2", 'd') + local dThD2 = EgtGetInfo( Pz, "D2", 'd') + if dThH2 and dThD2 and dTotMillDiameter <= dThD2 then + EgtSetInfo( Pz, "H", dThH2) + EgtSetInfo( Pz, "D", dThD2) + EgtSetInfo( Pz, "H2", dToolHolderHeight) + EgtSetInfo( Pz, "D2", dToolHolderDiameter) + dToolHolderHeight = dThH2 + dToolHolderDiameter = dThD2 + end + -- rimuovo eventuale nome e layer ausiliario + EgtSetName( Pz, '') + local ThAuxId = EgtGetFirstNameInGroup( Pz, 'TH_AUX') + if ThAuxId then + EgtErase( ThAuxId) + end + -- eventuale visualizzazione senso di rotazione + local Ly = EgtGetFirstInGroup( Pz or GDB_ID.NULL) + local RotId = EgtGetFirstNameInGroup( Ly or GDB_ID.NULL, 'Rot') + if RotId then + if dSpeed and abs( dSpeed) > 1 then + -- se rotazione opposta, devo invertire + if dSpeed < 0 then + EgtMirror( RotId, ORIG(), X_AX(), GDB_RT.GLOB) + end + else + EgtSetStatus( RotId, GDB_ST.OFF) + end + end + -- Altrimenti creo pezzo e layer opportuni + else + -- Creo pezzo e layer + local Pz = EgtGroup( GDB_ID.ROOT) + local Ly = EgtGroup( Pz) + -- altezza portautensile rimane nulla + end + + local dLenRef = dMillHeight + local nProfH = 0 + if dProfileHeight and dProfileHeight ~= 0 then + if dSideAng and dSideAng ~= 0 then + if dProfileHeight > 0 then + dLenRef = dLenRef + dProfileHeight + nProfH = 1 + else + nProfH = -1 + end + -- se lunghezza totale ( senza raccordo) è maggiore della lunghezza utensile aggiorno la lunghezza tagliente + if dTotMillHeight > dLenRef and dRadFillet <= 0 then + dCutterHeight = dCutterHeight - ( dTotMillHeight - dLenRef) + end + end + end + + -- variabile quotatura tagliente + local dQuoteCutter = dCutterHeight + -- Controllo lunghezza utensile + local dCutterRef = dCutterHeight + if nProfH ~= 0 then + if abs(dProfileHeight) > dCutterHeight then + dCutterRef = abs(dProfileHeight) + end + end + + if dLenRef - dToolHolderHeight - dCutterRef < 0 then + TOOL.ERR = 12 + return + end + + -- Layer + local Part = EgtGetFirstGroupInGroup( GDB_ID.ROOT) + local MillLayer = EgtGetFirstInGroup( Part) + EgtSetName( MillLayer, 'SOLID') + local QuoteLayer = EgtGroup(Part) + EgtSetName( QuoteLayer, 'AUX') + EgtSetColor( QuoteLayer, BLACK()) + if EgtGetBackground then + local colTop, colBot = EgtGetBackground() + if colTop and colBot then + local nInt = colTop:getRed() + colTop:getGreen() + colTop:getBlue() + colBot:getRed() + colBot:getGreen() + colBot:getBlue() + if nInt < 769 then + EgtSetColor( QuoteLayer, WHITE()) + end + end + end + + -- Disegno utensile + local dXP0, dYP0, dXP1, dYP1, dXP2, dYP2, dXP3, dYP3, dXP4, dYP4, dXP5, dYP5, dXP6, dYP6 + local dAddRad, dAddRefRad, dAddCutRad + local ptP0, ptP1, ptP2, ptP3, ptP4, ptP5, ptP6, ptLen, ptLenC, ptLenT + local dMyTotMillDiameter + local dMyOrigDiam = dMillDiameter + local bNoTipLine = false + local dLenExtra = dTotMillHeight - dLenRef + + if dSideAng and dSideAng ~= 0 then -- ae è conico + + -- se non ho altezza profilo do errore + if nProfH == 0 then + TOOL.ERR = 13 -- 6131 + return + end + + -- se angolo conicità errato do errore + if dSideAng >= 90 then + TOOL.ERR = 14 -- 6132 + return + elseif dSideAng <= -90 then + TOOL.ERR = 15 -- 6133 + return + end + + -- dato che la lunghezza utensile può essere espressa nella parte alta, controllo con la lunghezza totale + if dLenRef > dTotMillHeight then + TOOL.ERR = 22 -- 6134 + return + end + + dAddRad = dProfileHeight * tan(abs(dSideAng)) -- può essere positivo o negativo + dAddRefRad = dCutterRef * tan(abs(dSideAng)) -- è positivo + dAddCutRad = dCutterHeight * tan(abs(dSideAng)) -- è positivo + + local dMinDiam = 2 * ( dRadFillet / tan( (90 + dSideAng)/2)) + + if dSideAng > 0 then -- utensile a punta + if dAddRad < 0 then -- lunghezza definita sulla punta + if dMillDiameter == 0 then -- se diametro 0 gli assegno il diametro minimo + dMillDiameter = dMinDiam + bNoTipLine = true + elseif dMillDiameter < dMinDiam then -- se raccordo troppo grande do errore + TOOL.ERR = 16 -- 6135 + return + end + -- se altezza profilo minore o uguale della parte occupata dal raccordo do errore + if dRadFillet > 0 and abs( dProfileHeight) <= ( ( dMinDiam / 2) * cos( dSideAng)) then + TOOL.ERR = 17 -- 6136 + return + elseif dRadFillet > 0 and abs( dCutterHeight) <= ( ( dMinDiam / 2) * cos( dSideAng)) then + TOOL.ERR = 17 -- 6136 + return + end + -- se il diametro calcolato in alto supera il diametro max do errore + dMyTotMillDiameter = ( dMillDiameter - ( 2 * dAddRad)) -- per le quotature + if dMyTotMillDiameter > dTotMillDiameter then + TOOL.ERR = 18 -- 6137 + return + end + + -- se non ho raccordo e la differenza tra lungtot e lunghezza profilo generano parte inclinata che collassa do errore + if dMinDiam <= 0 and ( dLenExtra * tan(abs(dSideAng)))*2 > dMillDiameter then + TOOL.ERR = 19 -- 6138 + return + end + else -- altrimenti lunghezza definita nella parte alta del profilo + if ( dMillDiameter - (2*dAddRad)) < 0 then -- se in punta il diametro collassa + TOOL.ERR = 19 -- 6138 + return + elseif ( dMillDiameter - (2*dAddRad)) == dMinDiam then -- se la tip line va a 0 + bNoTipLine = true + -- se raccordo troppo grande do errore + elseif ( dMillDiameter - (2*dAddRad)) < dMinDiam then + TOOL.ERR = 16 -- 6135 + return + end + -- se altezza profilo minore o uguale della parte occupata dal raccordo do errore + if dRadFillet > 0 and abs( dProfileHeight) <= ( ( dMinDiam / 2) * cos( dSideAng)) then + TOOL.ERR = 17 -- 6136 + return + elseif dRadFillet > 0 and abs( dCutterHeight) <= ( ( dMinDiam / 2) * cos( dSideAng)) then + TOOL.ERR = 17 -- 6136 + return + end + dMyTotMillDiameter = dMillDiameter -- per le quotature + + -- se non ho raccordo e la differenza tra lungtot e lunghezza profilo generano parte inclinata che collassa do errore + if dMinDiam <= 0 and (( dLenExtra + dProfileHeight) * tan(abs(dSideAng)))*2 > dMillDiameter then + TOOL.ERR = 19 -- 6138 + return + end + end + else -- altrimenti a coda di rontine + if dAddRad < 0 then -- lunghezza definita sulla punta + if ( dMillDiameter - ( 2 * dRadFillet)) < 0 then -- se raccordo troppo grande do errore + TOOL.ERR = 16 -- 6135 + return + elseif ( dMillDiameter - ( 2 * dRadFillet)) < 0.001 then -- se raccordo arriva a 0 + bNoTipLine = true + end + -- se altezza profilo minore o uguale della parte occupata dal raccordo do errore + if dRadFillet > 0 and abs(dProfileHeight) <= ( ( dMinDiam / 2) * cos(abs(dSideAng))) then + TOOL.ERR = 17 -- 6136 + return + -- se altezza tagliente minore o uguale della parte occupata dal raccordo do errore + elseif dRadFillet > 0 and dCutterHeight <= ( ( dMinDiam / 2) * cos(abs(dSideAng))) then + TOOL.ERR = 17 -- 6136 + return + -- se il diametro in alto si annulla do errore + elseif ( dMillDiameter + ( 2 * ( dAddRad - dRadFillet)) + dMinDiam) <= 0 then + TOOL.ERR = 20 -- 6139 + return + end + dMyTotMillDiameter = dMillDiameter - dMinDiam + ( 2 * ( ( ( dTotMillHeight - dLenRef) * tan(abs(dSideAng))) + dRadFillet)) -- per le quotature + + -- se non ho raccordo e la differenza tra lungtot e lunghezza profilo generano parte inclinata che supera maxdiam do errore + if dMinDiam <= 0 and ((( dLenExtra * tan(abs(dSideAng)))*2) + dMillDiameter) > dTotMillDiameter then + TOOL.ERR = 18 -- 6137 + return + end + else -- altrimenti lunghezza definita nella parte alta del profilo + -- se il diametro effettivo supera il diametro massimo do errore + dMyTotMillDiameter = ( dMillDiameter - dMinDiam + ( 2 * ( ( ( dTotMillHeight - dLenRef) * tan(abs(dSideAng))) + dAddRad + dRadFillet))) -- per le quotature + if dMyTotMillDiameter > dTotMillDiameter then + TOOL.ERR = 18 -- 6137 + return + elseif ( dMillDiameter - dMinDiam + ( 2 * dAddRad)) < 0 then -- se raccordo troppo grande do errore + TOOL.ERR = 16 -- 6135 + return + elseif ( dMillDiameter - dMinDiam + ( 2 * dAddRad)) < 0.001 then -- se il raccordo arriva a 0 + bNoTipLine = true + end + -- se altezza profilo minore o uguale della parte occupata dal raccordo do errore + if dRadFillet > 0 and abs(dProfileHeight) <= ( ( dMinDiam / 2) * cos(abs(dSideAng))) then + TOOL.ERR = 17 -- 6136 + return + end + -- se altezza tagliente minore o uguale della parte occupata dal raccordo do errore + if dRadFillet > 0 and abs(dCutterHeight) <= ( ( dMinDiam / 2) * cos(abs(dSideAng))) then + TOOL.ERR = 17 -- 6136 + return + end + + -- se non ho raccordo e la differenza tra lungtot e lunghezza profilo generano parte inclinata che collassa do errore + if dMinDiam <= 0 and (((( dLenExtra + dProfileHeight) * tan(abs(dSideAng)))*2) + dMillDiameter) > dTotMillDiameter then + TOOL.ERR = 18 -- 6137 + return + end + end + end + + -- calcolo punti per gambo utensile + dYP0 = - dToolHolderHeight + + dYP1 = dYP0 + if dSideAng > 0 then -- utensile a punta + dXP1 = ( dMillDiameter / 2) - dAddRad + else + dXP1 = ( dMillDiameter / 2) - dRadFillet + ( dMinDiam / 2) + dAddRad + end + if dAddRad > 0 then -- se profilo definito in alto + dXP1 = ( dMillDiameter / 2) + end + -- calcolo punti per gambo utensile + if dToolHolderStemDiam > 0 and ( dToolHolderStemDiam / 2) < dXP1 then + dXP0 = dToolHolderStemDiam / 2 + elseif dToolHolderDiameter > 0 and (( dToolHolderDiameter - 5)/2) < dXP1 then + dXP0 = ( dToolHolderDiameter - 5) / 2 + else + dXP0 = dXP1 + end + dXP2 = dXP1 + dXP1 = dXP0 + dYP2 = - dLenRef + dCutterRef + + -- se tagliente minore dell'altezza profilo + if dCutterHeight < dCutterRef then + if dSideAng > 0 then -- utensile a punta + dXP3 = dXP2 - ( dAddRefRad - dAddCutRad) + else -- altrimenti a coda di rondine + dXP3 = dXP2 + ( dAddRefRad - dAddCutRad) + end + dYP3 = - dLenRef + dCutterHeight + end + + if dSideAng > 0 then -- utensile a punta + dXP4 = dXP2 - abs( dAddRad) + else -- altrimenti a coda di rondine + dXP4 = dXP2 + abs( dAddRad) + end + + -- completo i punti comuni per entrambe i casi + dYP4 = - dLenRef + if dRadFillet > 0 then + dXP5 = 0 + dYP5 = - dLenRef + else + dXP5 = dXP4 - ( dLenExtra * tan(dSideAng)) + dYP5 = - dTotMillHeight + dXP6 = 0 + dYP6 = - dTotMillHeight + end + + -- costruisco le linee + local NoCutter + local NoCutterLine + local NoCutterLine2 + local NoCutterLine3 + local NoCutterSurf + local tNoCutter = {} + ptP0 = Point3d( dXP0, dYP0, 0) + ptP1 = Point3d( dXP1, dYP1, 0) + + if ( dYP1 - dYP2) > 0.01 then + ptP1 = Point3d( dXP1, dYP2, 0) + NoCutterLine = EgtLine(MillLayer, ptP0, ptP1, GDB_RT.GRID) + if NoCutterLine then + table.insert( tNoCutter, NoCutterLine) + end + ptP2 = Point3d( dXP2, dYP2, 0) + else + ptP2 = Point3d( dXP2, dYP1, 0) + end + + if abs( dXP1 - dXP2) > 0.01 then + NoCutterLine2 = EgtLine(MillLayer, ptP1, ptP2, GDB_RT.GRID) + if NoCutterLine2 then + table.insert( tNoCutter, NoCutterLine2) + end + end + + if dYP3 and ( dYP2 - dYP3) > 0.01 then + ptP3 = Point3d( dXP3, dYP3, 0) + ptLenC = ptP3 + NoCutterLine3 = EgtLine(MillLayer, ptP2, ptP3, GDB_RT.GRID) + if NoCutterLine3 then + table.insert( tNoCutter, NoCutterLine3) + end + else + ptLenC = ptP2 + end + + -- disegno la superfice non tagliente + if #tNoCutter > 0 then + NoCutter = EgtCurveCompo( MillLayer, tNoCutter, true) + NoCutterSurf = EgtSurfTmByRevolve( MillLayer, NoCutter, Point3d(0,0,0), Vector3d(0,-1,0), false, 0.01, GDB_RT.GRID) + EgtSetColor( NoCutterSurf, LGRAY()) + EgtErase( NoCutter) + end + + -- geometria parte tagliente + local CutterLine + local CutterLine0 + local CutterLine1 + local CutterLine2 + local CutterLine3 + local CutterArc + local CutterSurf + local tCutter = {} + + -- se altezza profilo minore del tagliente + if abs(dProfileHeight) < dCutterRef then + dXP3 = dXP2 + dYP3 = - dLenRef + abs(dProfileHeight) + ptP3 = Point3d( dXP3, dYP3, 0) + CutterLine0 = EgtLine( MillLayer, ptP2, ptP3, GDB_RT.GRID) + if CutterLine0 then + table.insert( tCutter, CutterLine0) + end + elseif abs(dProfileHeight) == dCutterHeight then -- se uguale al tagliente + ptP3 = ptP2 + end + + -- costruisco le linee + ptP4 = Point3d( dXP4, dYP4, 0) + ptP5 = Point3d( dXP5, dYP5, 0) + if dCutterHeight < 0 then + CutterLine1 = EgtLine( MillLayer, ptP3, ptP5, GDB_RT.GRID) + ptP4 = ptP5 + else + CutterLine1 = EgtLine( MillLayer, ptP3, ptP4, GDB_RT.GRID) + end + if CutterLine1 then + table.insert( tCutter, CutterLine1) + end + + -- se utensile a punta e non ho raccordo e non devo disegnare la tip line, non faccio la linea + if dSideAng > 0 and dRadFillet <= 0 and bNoTipLine then + ptP4 = ptP5 + -- se non ho raccordo e devo disegnare tip line + elseif dRadFillet <= 0 and not bNoTipLine then + if dCutterHeight >= 0 then + CutterLine2 = EgtLine( MillLayer, ptP4, ptP5, GDB_RT.GRID) + end + ptP6 = Point3d( dXP6, dYP6, 0) + CutterLine3 = EgtLine( MillLayer, ptP5, ptP6, GDB_RT.GRID) + else + CutterLine2 = EgtLine( MillLayer, ptP4, ptP5, GDB_RT.GRID) + end + + if dRadFillet > 0 then + CutterArc = EgtCurveFillet( MillLayer, CutterLine1, ptP3, CutterLine2, ptP5, dRadFillet, true, GDB_RT.GRID) + if CutterArc then + table.insert( tCutter, CutterArc) + end + if bNoTipLine then + EgtErase( CutterLine2) + CutterLine2 = nil + end + end + + if CutterLine2 then + table.insert( tCutter, CutterLine2) + end + + if CutterLine3 then + table.insert( tCutter, CutterLine3) + end + + -- in caso di lunghezza definita sulla punta + if dAddRad < 0 then + if dSideAng < 0 then -- se utensile a coda di rondine + ptLen = Point3d( (dMillDiameter/2), dYP4, 0) + else -- utensile a punta + if dMyOrigDiam == 0 then + ptLen = Point3d( 0, dYP4, 0) + else + ptLen = ptP4 + end + end + else -- lunghezza profilo nella parte alta + if abs(dProfileHeight) < dCutterRef then + ptLen = Point3d( dXP2, dYP3, 0) + else + ptLen = Point3d( dXP2, dYP2, 0) + end + end + ptLenT = ptP4 + + -- disegno la superfice tagliente + if #tCutter > 0 then + CutterLine = EgtCurveCompo( MillLayer,tCutter, true) + CutterSurf = EgtSurfTmByRevolve( MillLayer, CutterLine, Point3d(0,0,0), Vector3d(0,-1,0), false, 0.01, GDB_RT.GRID) + EgtSetColor( CutterSurf, Color3d( 224, 0, 0)) + EgtErase( CutterLine) + end + + else -- altrimenti cilindrico + + if dRadFillet == ( dMillDiameter/2) then + bNoTipLine = true + -- se raccordo troppo grande do errore + elseif dRadFillet > ( dMillDiameter/2) then + TOOL.ERR = 16 -- 6135 + return + elseif dRadFillet > dCutterHeight then + TOOL.ERR = 21 -- 6140 + return + end + + dMyTotMillDiameter = dMillDiameter -- per le quotature + + -- calcolo punti per gambo utensile + if dToolHolderStemDiam > 0 and dToolHolderStemDiam < dMillDiameter then + dXP0 = dToolHolderStemDiam / 2 + elseif dToolHolderDiameter > 0 and ( dToolHolderDiameter - 5) < dMillDiameter then + dXP0 = ( dToolHolderDiameter - 5) / 2 + else + dXP0 = dMillDiameter/2 + end + dYP0 = - dToolHolderHeight + + dXP1 = dXP0 + dYP1 = dYP0 + dXP2 = dMillDiameter/2 + dYP2 = - dLenRef + dCutterHeight + dXP3 = dXP2 + dYP3 = - dLenRef + dXP4 = 0 + dYP4 = dYP3 + + -- costruisco le linee + local NoCutter + local NoCutterLine + local NoCutterLine2 + local NoCutterSurf + local tNoCutter = {} + ptP0 = Point3d( dXP0, dYP0, 0) + ptP1 = Point3d( dXP1, dYP1, 0) + + if ( dYP1 - dYP2) > 0.01 then + ptP1 = Point3d( dXP1, dYP2, 0) + NoCutterLine = EgtLine(MillLayer, ptP0, ptP1, GDB_RT.GRID) + if NoCutterLine then + table.insert( tNoCutter, NoCutterLine) + end + ptP2 = Point3d( dXP2, dYP2, 0) + else + ptP2 = Point3d( dXP2, dYP1, 0) + end + + if abs( dXP1 - dXP2) > 0.01 then + NoCutterLine2 = EgtLine(MillLayer, ptP1, ptP2, GDB_RT.GRID) + if NoCutterLine2 then + table.insert( tNoCutter, NoCutterLine2) + end + end + + -- disegno la superfice non tagliente + if #tNoCutter > 0 then + NoCutter = EgtCurveCompo( MillLayer, tNoCutter, true) + NoCutterSurf = EgtSurfTmByRevolve( MillLayer, NoCutter, Point3d(0,0,0), Vector3d(0,-1,0), false, 0.01, GDB_RT.GRID) + EgtSetColor( NoCutterSurf, LGRAY()) + EgtErase( NoCutter) + end + + -- geometria parte tagliente + local CutterLine + local CutterLine1 + local CutterLine2 + local CutterArc + local CutterSurf + local tCutter = {} + + -- costruisco le linee + ptP3 = Point3d( dXP3, dYP3, 0) + ptLen = ptP3 + ptP4 = Point3d( dXP4, dYP4, 0) + ptLenC = ptP2 + ptLenT = ptP3 + + CutterLine1 = EgtLine( MillLayer, ptP2, ptP3, GDB_RT.GRID) + if CutterLine1 then + table.insert( tCutter, CutterLine1) + end + CutterLine2 = EgtLine( MillLayer, ptP3, ptP4, GDB_RT.GRID) + + if dRadFillet > 0 then + CutterArc = EgtCurveFillet( MillLayer, CutterLine1, ptP2, CutterLine2, ptP4, dRadFillet, true, GDB_RT.GRID) + if CutterArc then + table.insert( tCutter, CutterArc) + end + if bNoTipLine then + EgtErase( CutterLine2) + CutterLine2 = nil + end + end + + if CutterLine2 then + table.insert( tCutter, CutterLine2) + end + + -- disegno la superfice tagliente + if #tCutter > 0 then + CutterLine = EgtCurveCompo( MillLayer,tCutter, true) + CutterSurf = EgtSurfTmByRevolve( MillLayer, CutterLine, Point3d(0,0,0), Vector3d(0,-1,0), false, 0.01, GDB_RT.GRID) + EgtSetColor( CutterSurf, Color3d( 224, 0, 0)) + EgtErase( CutterLine) + end + end + + -- Calcolo dimensione quote + local dMaxLinDim + if dLenRef > dMyTotMillDiameter then + dMaxLinDim = dMillHeight + else + dMaxLinDim = dMyTotMillDiameter + end + local dLenghtArrow = 0.05 * dMaxLinDim + local dDistQuote = 20 + if dAddRad and dAddRad > 0 then -- se utensile definito nella parte alta + dDistQuote = dDistQuote + abs(dProfileHeight) + end + if dTotMillHeight > dLenRef and dRadFillet <= 0 then -- se ho in aggiunta la lunghezza totale utensile + dDistQuote = dDistQuote + ( dTotMillHeight - dLenRef) + end + local dDistQuoteY = max( dToolHolderDiameter, dMyTotMillDiameter) / 2 + 10 + local dTextSize = min( 13, max( 0.1 * dMyTotMillDiameter, 0.1 * dLenRef)) + local dTextDist = 5 + + -- quotatura lunghezza utensile + local sLenTxt = EgtNumToString( EgtToUiUnits( dMillHeight),3) + CreateLinearDimensionOnY( QuoteLayer, Point3d(0,0,0), ptLen, sLenTxt, dTextSize, dDistQuoteY, dLenghtArrow, dTextDist, true, 'LEN', GDB_RT.GRID) + + -- quotatura altezza tagliente + local ptP2M = ptLenC + ptP2M:mirror(ORIG(),X_AX()) + local ptP3M = ptLenT + ptP3M:mirror(ORIG(),X_AX()) + + -- calcolo extralunghezza + if dAddRad and dAddRad ~= 0 and -- se utensile inclinato + dTotMillHeight > dLenRef and -- se ho in aggiunta la lunghezza totale utensile + dRadFillet <= 0 then -- se non c'è raccordo utensile + local ptP5M = Point3d( ptP3M:getX(), -dTotMillHeight, 0) + local sMaxLenTxt = EgtNumToString(EgtToUiUnits( dCutterHeight + dTotMillHeight - dLenRef),3) + CreateLinearDimensionOnY( QuoteLayer, ptP2M, ptP5M, sMaxLenTxt, dTextSize, dDistQuoteY, dLenghtArrow, dTextDist, false, 'MAXEXTRA', GDB_RT.GRID) + else + local sMaxMatTxt = EgtNumToString(EgtToUiUnits( dCutterHeight),3) + CreateLinearDimensionOnY( QuoteLayer, ptP2M, ptP3M, sMaxMatTxt, dTextSize, dDistQuoteY, dLenghtArrow, dTextDist, false, 'MAXMAT', GDB_RT.GRID) + end + + -- quotatura diametro + local ptP4M = Point3d( ptLen) + ptP4M:mirror( ORIG(), X_AX()) + local sDiamTxt = EgtNumToString( EgtToUiUnits( dMyOrigDiam), 3) + CreateLinearDimensionOnX( QuoteLayer, ptLen, ptP4M, sDiamTxt, dTextSize, dDistQuote, dLenghtArrow, dTextDist, false, 'DIAM', GDB_RT.GRID) + + -- quotatuta diametro e lunghezza ingombro solo per utensile a coda di rondine + if dAddRad and dAddRad ~= 0 and dSideAng < 0 and -- se utensile a coda di rondine + dRadFillet <= 0 then -- se non c'è raccordo utensile + + -- se diametri differenti inserisco la quota + if abs( dMyTotMillDiameter - dMillDiameter) > 0.001 then + local ptP6M = Point3d( dMyTotMillDiameter / 2, -dTotMillHeight, 0) + local ptP7M = Point3d( -dMyTotMillDiameter / 2, -dTotMillHeight, 0) + local dDistQuote2 = abs(( ptLen:getY() - dDistQuote) - ptP7M:getY()) + dTextSize * 2.1 + local sDiamTotTxt = EgtNumToString(EgtToUiUnits( dMyTotMillDiameter),3) + CreateLinearDimensionOnX( QuoteLayer, ptP6M, ptP7M, sDiamTotTxt, dTextSize, dDistQuote2, dLenghtArrow, dTextDist, false, 'MAXDIAM', GDB_RT.GRID, ORANGE()) + end + + -- se lunghezze differenti inserisco la seconda quota + if abs( dTotMillHeight - dMillHeight) > 0.001 then + local b3Solid = EgtGetBBoxGlob( Part, GDB_BB.STANDARD) + local pMax = b3Solid:getMax() + local ptP8M = Point3d( dMyTotMillDiameter / 2, -dTotMillHeight, 0) + local sLenTotTxt = EgtNumToString( EgtToUiUnits( dTotMillHeight),3) + local dDistQuoteY2 = pMax:getX() - ptP8M:getX() + dTextSize / 2 + CreateLinearDimensionOnY( QuoteLayer, Point3d(0,0,0), ptP8M, sLenTotTxt, dTextSize, dDistQuoteY2, dLenghtArrow, dTextDist, true, 'LENTOT', GDB_RT.GRID, ORANGE()) + end + end + + TOOL.ERR = 0 +end +_G.CreateTool = CreateTool diff --git a/ProgramData/EgtCAM5/ToolMakers/MakeWoodDrill.lua b/ProgramData/EgtCAM5/ToolMakers/MakeWoodDrill.lua new file mode 100644 index 0000000..03f48e0 --- /dev/null +++ b/ProgramData/EgtCAM5/ToolMakers/MakeWoodDrill.lua @@ -0,0 +1,142 @@ +-- 2019/09/23 18:30:00 +-- Creazione di una punta a forare per legno + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +require( "EgtDimension") + +-- Dati utensile : dichiarazione e valori standard +local TOOL = {} +TOOL.TOOLHOLDER = '' +TOOL.TOTLEN = 110 +TOOL.LEN = 80 +TOOL.DIAM = 20 +TOOL.MAXMAT = 40 +TOOL.ERR = 0 +_G.TOOL = TOOL + + +function CreateTool() + + TOOL.ERR = 999 + + -- Parametri utensile + local sFilePath = TOOL.TOOLHOLDER + local dWDHeight = TOOL.TOTLEN + local dWDCylHeight = TOOL.LEN + local dWDDiameter = TOOL.DIAM + local dMaxMat = TOOL.MAXMAT + local dCutterHeight = dMaxMat + local bWDType = true + -- Parametri portautensile + local dThHeight = 0 + local dThDiam = 0 + + -- Progetto vuoto + EgtNewFile() + local Pz = GDB_ID.NULL + + -- Se richiesto inserisco porta utensile + if sFilePath and sFilePath ~= "" then + -- eseguo inserimento + if not EgtInsertFile(sFilePath) then + TOOL.ERR = 1 + return + end + -- recupero altezza portautensile + Pz = EgtGetFirstInGroup(GDB_ID.ROOT) + dThHeight = EgtGetInfo( Pz, "H", "d") or 0 + dThDiam = EgtGetInfo( Pz, "D", "d") or 0 + -- Altrimenti creo pezzo e layer opportuni + else + -- Creo pezzo e layer + Pz = EgtGroup(GDB_ID.ROOT) + EgtGroup( Pz) + -- altezza portautensile rimane nulla + end + + -- Layer + Pz = EgtGetFirstGroupInGroup(GDB_ID.ROOT) + local WDLayer = EgtGetFirstInGroup( Pz) + EgtSetName( WDLayer, 'SOLID') + local QuoteLayer = EgtGroup( Pz) + EgtSetName( QuoteLayer, 'AUX') + EgtSetColor( QuoteLayer, BLACK()) + if EgtGetBackground then + local colTop, colBot = EgtGetBackground() + if colTop and colBot then + local nInt = colTop:getRed() + colTop:getGreen() + colTop:getBlue() + colBot:getRed() + colBot:getGreen() + colBot:getBlue() + if nInt < 769 then + EgtSetColor( QuoteLayer, WHITE()) + end + end + end + + local dWDTipHeight = dWDHeight - dWDCylHeight + + if dWDTipHeight < 0 then + TOOL.ERR = 2 + return + end + + local dNoCutHeight = dWDCylHeight - dMaxMat + + if dNoCutHeight < dThHeight then + TOOL.ERR = 12 + return + end + + + local ptP1 = Point3d( 0.5 * dWDDiameter, 0, 0) + local ptP2 = Point3d( 0.5 * dWDDiameter, - dWDCylHeight, 0) + local ptP3 = Point3d( 0, - dWDHeight, 0) + local ptP4 = Point3d( - 0.5 * dWDDiameter, - dWDCylHeight, 0) + + if dNoCutHeight > 0.1 then + + local ptPM = Point3d( 0.5 * dWDDiameter, - dNoCutHeight, 0) + + local NoCutLine = EgtLine( WDLayer, ptP1, ptPM, GDB_RT.GRID) + local NoCutSurf = EgtSurfTmByRevolve( WDLayer, NoCutLine, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) + + EgtSetColor( NoCutSurf, LGRAY()) + EgtErase( NoCutLine) + + ptP1 = ptPM + + end + + local CutStemLine = EgtLine( WDLayer, ptP1, ptP2, GDB_RT.GRID) or GDB_ID.NULL + local TipLine = EgtLine( WDLayer, ptP2, ptP3, GDB_RT.GRID) or GDB_ID.NULL + + local CutLine = EgtCurveCompo( WDLayer, { CutStemLine, TipLine}) or GDB_ID.NULL + + local CutSurf = EgtSurfTmByRevolve( WDLayer, CutLine, ORIG(), -Y_AX(), false, 0.05, GDB_RT.GRID) or GDB_ID.NULL + + EgtSetColor( CutSurf, Color3d( 224, 0, 0)) + EgtErase( CutLine) + + local dLenVertArrow = 0.05 * dWDHeight + local dLenHorArrow = 0.4 * dWDDiameter + local dDistQuoteX = dWDTipHeight + dLenHorArrow + 10 + local dDistQuoteY = max( dThDiam, dWDDiameter) / 2 + 10 + local dTextSize = min( 15, max( 0.1 * dWDDiameter, 0.1 * dWDHeight)) + local dTextDist = 5 + + local sLenTxt = EgtNumToString( EgtToUiUnits( dWDCylHeight),3) + CreateLinearDimensionOnY( QuoteLayer, ORIG(), ptP4, sLenTxt, dTextSize, dDistQuoteY, dLenVertArrow, dTextDist, false, 'LEN', GDB_RT.GRID) + + local sLenTotTxt = EgtNumToString( EgtToUiUnits( dWDHeight),3) + CreateLinearDimensionOnY( QuoteLayer, ORIG(), ptP3, sLenTotTxt, dTextSize, dDistQuoteY, dLenVertArrow, dTextDist, true, 'TOTLEN', GDB_RT.GRID) + + local sDiamTxt = EgtNumToString( EgtToUiUnits( dWDDiameter),3) + CreateLinearDimensionOnX( QuoteLayer, ptP2, ptP4, sDiamTxt, dTextSize, dDistQuoteX, dLenHorArrow, dTextDist, false, 'DIAM', GDB_RT.GRID) + + TOOL.ERR = 0 + +end + +_G.CreateTool = CreateTool diff --git a/ProgramData/EgtCAM5/ToolMakers/ToolAdjust.lua b/ProgramData/EgtCAM5/ToolMakers/ToolAdjust.lua new file mode 100644 index 0000000..9b26255 --- /dev/null +++ b/ProgramData/EgtCAM5/ToolMakers/ToolAdjust.lua @@ -0,0 +1,103 @@ +-- 2019/02/07 09:30:00 +-- Gestione di lunghezza e diametro utensile variabili +-- (tramite spostameno delle parti identificate con Info 'mobile' = 1 +-- Ver.2.1b1 2019/02/13 + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +require("EgtDimension") + +-- Dati utensile : dichiarazione e valori standard +local TOOL = {} +TOOL.LEN = nil +TOOL.DIAM = nil +TOOL.ERR = 999 +_G.TOOL = TOOL + +function AdjustCustomTool() + + TOOL.ERR = 999 + + local dToolNewL = TOOL.LEN + local dToolNewD = TOOL.DIAM + if not dToolNewL or not dToolNewD then + TOOL.ERR = 1 + return + end + + -- Dati utensile dal disegno + local PartId = EgtGetFirstPart() + local SolidId = EgtGetFirstNameInGroup( PartId, 'SOLID') + local dToolL = EgtGetInfo( SolidId, 'Le') -- lunghezza da disegno utensile + local dToolD = EgtGetInfo( SolidId, 'De') -- diametro da disegno utensile + + -- raccolta delle parti da adattare in base alle nuove quote di input + local MobilePart = {} + local ObjId = EgtGetFirstInGroup( SolidId) + while ObjId do + if EgtExistsInfo( ObjId, 'Mobile') then + table.insert( MobilePart, ObjId) + end + ObjId = EgtGetNext( ObjId) + end + + -- adattamento della lunghezza utensile in base al dato di input + if dToolL and abs ( dToolNewL - dToolL) > 10 * GEO.EPS_SMALL then + local dDeltaL = dToolNewL - dToolL + EgtMove( MobilePart, Vector3d( 0, -dDeltaL, 0)) + EgtSetInfo( SolidId, 'Le', dToolNewL) + -- riporto in posizione inizio di Outline + local OutlineId = EgtGetFirstNameInGroup( SolidId, 'Outline') + if OutlineId then + EgtModifyCurveStartPoint( OutlineId, ORIG(), GDB_RT.GLOB) + end + end + + -- adattamento della larghezza utensile in base al dato di input + if dToolD and abs ( dToolNewD - dToolD) > 10 * GEO.EPS_SMALL then + local dRatioD = dToolNewD / dToolD + EgtScale( MobilePart, Frame3d( 0,0,0), dRatioD, 1, dRatioD) + EgtSetInfo( SolidId, 'De', dToolNewD) + end + + -- posizioni per linee di quota + local BBoxSolid = EgtGetBBoxGlob( SolidId, 0) + local dSolidMinY = BBoxSolid:getMin():getY() + local dSolidMaxX = BBoxSolid:getMax():getX() + local ptP1 = Point3d( - 0.5 * dToolNewD, - dToolNewL, 0) + local ptP2 = Point3d( 0.5 * dToolNewD, - dToolNewL, 0) + + -- quotatura + local DimsId = EgtGetFirstNameInGroup( PartId, 'DIMS') + if DimsId then + EgtEmptyGroup( DimsId) + EgtSetStatus( DimsId, GDB_ST.ON) + else + DimsId = EgtGroup( PartId) + EgtSetName( DimsId, 'DIMS') + EgtSetColor( DimsId, BLACK()) + end + + local dDistQuoteD = -( dSolidMinY - ptP1:getY()) + 10 + local dDistQuoteL = dSolidMaxX - ptP2:getX() + 10 + local dTextSize = min( 20, 0.1 * max( dToolNewL, dToolNewD)) + local dLenghtArrow = 0.03 * max( dToolNewL, dToolNewD) + local dTextDist = 3 + + local sDiamTxt = EgtNumToString( EgtToUiUnits( dToolNewD), 3) + CreateLinearDimensionOnX( DimsId, ptP1, ptP2, sDiamTxt, dTextSize, dDistQuoteD, dLenghtArrow, dTextDist, false, 'DIAM', GDB_RT.GRID) + + local sLenTxt = EgtNumToString( EgtToUiUnits( dToolNewL),3) + CreateLinearDimensionOnY( DimsId, ORIG(), ptP2, sLenTxt, dTextSize, dDistQuoteL, dLenghtArrow, dTextDist, true, 'LEN', GDB_RT.GRID) + + local Dims = EgtGetAllInGroup( DimsId) + if Dims then + EgtMove( Dims, Vector3d( 0, 0, BBoxSolid:getMax():getZ()+10)) + end + + TOOL.ERR = 0 +end +_G.AdjustCustomTool = AdjustCustomTool diff --git a/ProgramData/EgtCAM5/Wall/.gitlab-ci.yml b/ProgramData/EgtCAM5/Wall/.gitlab-ci.yml new file mode 100644 index 0000000..17f6c47 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/.gitlab-ci.yml @@ -0,0 +1,85 @@ +variables: + VERS_MAIN: '1.0' + APP_NAME: 'Wall' + NEW_REL: '' + NET_SHARE_R: '\\10.74.82.50\EgtTech' + NET_USER: '10.74.82.50\Server' + NET_SHARE_Z: '\\10.74.82.201\Artifacts' + +#Note compilazione LUA: +# lua53 -o 32\$FileName -s $FileName: -o = output, -s = NON include i debug symbols + +# helper compilazione LUA a 32 bit +.LuaCompile32: &LuaCompile32 + - | + Set-Alias lua53 C:\Tools\Lua32\luac53 + $FileList = Get-ChildItem("*.lua") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + Copy-Item -Path $FileName -Destination 32\$FileName + echo "Copy-Item -Path $FileName -Destination 32\$FileName" + } + $FileList = Get-ChildItem("LuaLibs\*.lua") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + lua53 -o 32\LuaLibs\$FileName LuaLibs\$FileName + echo "lua53 -o 32\LuaLibs\$FileName LuaLibs\$FileName" + } + +# helper compilazione LUA a 64 bit +.LuaCompile64: &LuaCompile64 + - | + Set-Alias lua53 C:\Tools\Lua64\luac53 + $FileList = Get-ChildItem("*.lua") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + Copy-Item -Path $FileName -Destination 64\$FileName + echo "Copy-Item -Path $FileName -Destination 64\$FileName" + } + $FileList = Get-ChildItem("LuaLibs\*.lua") + ForEach ($File in $FileList) { + $FileName = Split-Path $File -leaf + lua53 -o 64\LuaLibs\$FileName LuaLibs\$FileName + echo "lua53 -o 64\LuaLibs\$FileName LuaLibs\$FileName" + } + +# helper copia script verso cartella di rete R:\ delle cartelle 32 e 64 +.ReplicaR: &ReplicaR + - | + net use R: /delete + net use R: $env:NET_SHARE_R /u:$env:NET_USER $RDRIVE_PASSWD + ROBOCOPY /MIR 32 R:\EgtData\$env:APP_NAME\32 + ROBOCOPY /MIR 64 R:\EgtData\$env:APP_NAME\64 + ROBOCOPY /MIR Images R:\EgtData\$env:APP_NAME\32\Images + ROBOCOPY /MIR Images R:\EgtData\$env:APP_NAME\64\Images + SLEEP 2 + net use R: /delete + +# helper copia script verso cartella di rete R:\ delle cartelle 32 e 64 +.ReplicaZ: &ReplicaZ + - | + net use Z: /delete + net use Z: $env:NET_SHARE_Z + ROBOCOPY /MIR 32 Z:\EgtData\$env:APP_NAME\32 + ROBOCOPY /MIR 64 Z:\EgtData\$env:APP_NAME\64 + ROBOCOPY /MIR Images Z:\EgtData\$env:APP_NAME\32\Images + ROBOCOPY /MIR Images Z:\EgtData\$env:APP_NAME\64\Images + SLEEP 2 + net use Z: /delete + +stages: + - build + +LuaCompile:build: + stage: build +# only: +# - main +# - master + tags: + - win + script: + - *LuaCompile32 + - *LuaCompile64 + - *ReplicaR + - *ReplicaZ + \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Wall/32/Images/.placeholder b/ProgramData/EgtCAM5/Wall/32/Images/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/ProgramData/EgtCAM5/Wall/32/LuaLibs/.placeholder b/ProgramData/EgtCAM5/Wall/32/LuaLibs/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/ProgramData/EgtCAM5/Wall/64/Images/.placeholder b/ProgramData/EgtCAM5/Wall/64/Images/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/ProgramData/EgtCAM5/Wall/64/LuaLibs/.placeholder b/ProgramData/EgtCAM5/Wall/64/LuaLibs/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/ProgramData/EgtCAM5/Wall/BatchProcess.lua b/ProgramData/EgtCAM5/Wall/BatchProcess.lua new file mode 100644 index 0000000..616cd84 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/BatchProcess.lua @@ -0,0 +1,657 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2022/02/24 +-- Gestione calcolo batch disposizione e lavorazioni per Pareti +-- 2020/07/24 Nuvola di punti riferita allo Zero Tavola. +-- 2020/10/28 Corretto spostamento pezzi per rotazioni (0 o 180) e inversioni( 0, 90, 180, o 270). +-- 2020/12/03 Ora riconosciute rotazioni di inversione con angoli negativi. +-- 2021/03/05 Aggiunta gestione altri angoli di inversione e rotazione combinati. +-- 2021/03/06 La creazione del file ori si fa solo alla fine se non ci sono stati errori o se edit. +-- 2021/03/08 Aggiunta gestione lavorazione su macchine per travi. +-- 2021/04/09 Corretto spostamento pezzi per rotazioni e inversioni. +-- 2021/07/28 Aggiunta scelta direzione di vista per modifica e simulazione. +-- 2021/10/27 Nel controllo spessore si deve considerare anche PosY. +-- 2022/02/24 Se ricalcolo si aggiorna il setup. In ogni caso si verifica prima di simulazione. + + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--WALL = {} +--WALL.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl' +--WALL.MACHINE = '90480019_MW' +--WALL.FLAG = 5 + +-- 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 == 5 then + sFlag = 'CLOUD' +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 or WALL.FLAG == 5) 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 or WALL.FLAG == 5) 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' +local sPntFile = sDir..sTitle..'.pnt' + +-- 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 .. '\\Wall\\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 + -- 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 + end + + -- Aggiorno eventuali dati ausiliari + UpdateAuxData( sBtmFile) + + -- Recupero informazione se progetto o produzione + local bProj = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PROJECT', 'i') == 1) + + -- Dimensioni del pannello + local dRawL = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PANELLEN', 'd') or 100) + local dRawW = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PANELWIDTH', 'd') or 50) + local dExtraL = 0 + local dExtraW = 0 + if bProj then + if WD.BEAM_MACHINE then + if dRawL < WD.MIN_LENGTH then + dExtraL = WD.MIN_LENGTH - dRawL + dRawL = WD.MIN_LENGTH + elseif dRawL < WD.MAX_LENGTH then + dExtraL = min( WD.MAX_LENGTH - dRawL, 3000) + dRawL = dRawL + dExtraL + end + if dRawW + 10 < WD.MIN_WIDTH then + dExtraW = WD.MIN_WIDTH - dRawW + dRawW = WD.MIN_WIDTH + elseif dRawW < WD.MAX_WIDTH then + dExtraW = min( WD.MAX_WIDTH - dRawW, 10) + dRawW = dRawW + dExtraW + end + else + dExtraW = 10 + dRawW = dRawW + dExtraW + end + end + + -- 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 + min( dExtraL, 1200) + if WD.USE_POSY then + local PosY = EgtGetInfo( vWall[i].Id, 'POSY', 'd') + vWall[i].PosY = max( PosY, 0) + else + vWall[i].PosY = 0 + end + local PosZ = EgtGetInfo( vWall[i].Id, 'POSZ', 'd') + vWall[i].PosZ = PosZ + dExtraW / 2 + 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 then + if 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 + EgtSetInfo( vWall[i].Id, 'ROTATED_DONE', dRotAng) + end + -- inversione + local dInvAng = EgtGetInfo( vWall[i].Id, 'INVERTED', 'd') + if dInvAng then + if abs( dInvAng - 180) > GEO.EPS_ANG_SMALL and abs( dInvAng + 180) > GEO.EPS_ANG_SMALL then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vWall[i].Id, ptInvCen, Z_AX(), dInvAng - 180, GDB_RT.GLOB) + b3Solid:rotate( ptInvCen, Z_AX(), dInvAng - 180) + end + EgtSetInfo( vWall[i].Id, 'INVERTED_DONE', dInvAng) + end + -- correzioni per rotazioni non centrate di produzioni TS3 (quasi sempre multipli di 90 deg) + local sType = EgtGetInfo( vWall[i].Id, 'TYPE', 's') + if not bProj and dRotAng and dInvAng and sType ~= 'LAYER' then + if abs( dInvAng - 0) < GEO.EPS_ANG_SMALL then + if abs( dRotAng - 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + end + elseif abs( dInvAng - 90) < GEO.EPS_ANG_SMALL or abs( dInvAng + 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + if abs( dRotAng - 180) < GEO.EPS_ANG_SMALL or abs( dRotAng + 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL or abs( dRotAng + 90) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + end + elseif abs( dInvAng - 180) < GEO.EPS_ANG_SMALL or abs( dInvAng + 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + if abs( dRotAng - 0) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL or abs( dRotAng + 90) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 90) < GEO.EPS_ANG_SMALL or abs( dRotAng + 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + end + elseif abs( dInvAng - 270) < GEO.EPS_ANG_SMALL or abs( dInvAng + 90) < GEO.EPS_ANG_SMALL then + if abs( dRotAng - 0) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + end + end + end + end + + -- Ne verifico le dimensioni + local dRawH = vWall[1].Box:getDimZ() + vWall[1].PosY + local vWallErr = {} + for i = 2, #vWall do + local dDimH = vWall[i].Box:getDimZ() + vWall[i].PosY + 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 or '', '\n', ' ', 10) + sMsg = string.gsub( sMsg or '', '\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) + + -- Se non ci sono errori o modalità modifica, salvo il file originale + if nErrCnt == 0 or WALL.FLAG == 1 then + EgtCopyFile( WALL.FILE, sDir..sTitle..'.ori'..sExt) + end + + -- 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 LayerId = {} + LayerId[1] = EgtGetFirstNameInGroup( nPartId, 'Outline') + LayerId[2] = EgtGetFirstNameInGroup( nPartId, 'Processings') + for nInd = 1, #LayerId do + local nProcId = EgtGetFirstInGroup( LayerId[nInd] 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 + 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 >>>') + EgtImportSetup() + 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 >>>') + -- verifico setup + local bSetUpOk, SetUpErrors = EgtVerifyCurrSetup() + if not bSetUpOk then + local sToolsList = "" + for ToolIndex = 1, #SetUpErrors do + sToolsList = sToolsList .. SetUpErrors[ToolIndex] + if ToolIndex ~= #SetUpErrors then + sToolsList = sToolsList .. ", " + end + end + WriteErrToLogFile( 19, 'Error in setup: tool/s ' .. sToolsList .. ' not found', 0, 0, 0) + return + end + -- lancio simulazione + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.INIT then + WALL.ERR = 19 + WALL.MSG = 'Error starting simulation' + 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 = 'Special 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 >>>') + local sInfo = 'EgtCAM5 - ' + if EgtGetExeVersion then + sInfo = 'EgtCAM5 ver.' .. EgtGetExeVersion() .. ' - ' + end + if not EgtGenerate( '', sInfo .. 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) + +-- Se modalità Cloud, importo la nuvola di punti +if WALL.FLAG == 5 then + EgtOutLog( ' +++ Importing Point Cloud >>>') + -- Creo gruppo Cloud nel gruppo di lavorazione + local nMGrpId = EgtGetCurrMachGroup() + local nCloudId = EgtGetFirstNameInGroup( nMGrpId or GDB_ID.NULL, 'Cloud') + if nCloudId then + EgtEmptyGroup( nCloudId) + else + nCloudId = EgtGroup( nMGrpId) + EgtSetName( nCloudId, 'Cloud') + end + -- Recupero BBox della tavola + local b3Tab = EgtGetTableArea() + if not b3Tab or b3Tab:isEmpty() then + WALL.ERR = 22 + WALL.MSG = 'Machine table not found' + return + end + -- Recupero i punti della nuvola + local hFile = io.open( sPntFile, 'r') + if not hFile then + WALL.ERR = 23 + WALL.MSG = 'Missing point cloud file' + return + end + local vPoints = {} + local sLine = hFile:read( '*l') + while sLine do + local vCoord = EgtSplitString( sLine, ' ') + if vCoord and #vCoord >= 2 then + local dX = tonumber( vCoord[1]) + b3Tab:getMax():getX() + local dY = tonumber( vCoord[2]) + b3Tab:getMin():getY() + local dZ = b3Tab:getMax():getZ() + EgtOutLog( ' X='..EgtNumToString( dX, 3)..' Y='..EgtNumToString( dY, 3), 3) + table.insert( vPoints, { dX, dY, dZ}) + end + sLine = hFile:read( '*l') + end + hFile:close() + -- Inserisco la curva di contorno della nuvola + local nClCrvId = EgtCurveCompoFromPoints( nCloudId, vPoints, GDB_RT.GLOB) + if not nClCrvId then + WALL.ERR = 24 + WALL.MSG = 'Failed to create Point cloud Contour' + return + end + EgtCloseCurveCompo( nClCrvId) + EgtApproxCurve( nClCrvId, GDB_CA.LINES, 1.0) + EgtSetColor( nClCrvId, 'RED') +end + +-- Se modifica o simula, imposto la vista ISO 3d opportuna +if WALL.FLAG == 1 or WALL.FLAG == 2 then + local vView = { SCE_VD.ISO_NW, SCE_VD.ISO_SW, SCE_VD.ISO_NE, SCE_VD.ISO_SE} + local nV = min( max( WD.SIMUL_VIEW_DIR or 2, 1), 4) + EgtSetView( vView[nV], false) +-- se cloud, imposto la vista TOP +elseif WALL.FLAG == 5 then + EgtSetView( SCE_VD.TOP, 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/ProgramData/EgtCAM5/Wall/BatchProcessNew.lua b/ProgramData/EgtCAM5/Wall/BatchProcessNew.lua new file mode 100644 index 0000000..686d463 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/BatchProcessNew.lua @@ -0,0 +1,711 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2022/01/20 +-- Gestione calcolo batch disposizione e lavorazioni per Pareti +-- 2021/01/15 Per nuova interfaccia Egt. +-- 2021/11/10 Aggiunta modifica per gestione modifiche manuali come in Beam. +-- 2022/01/06 Per CUTID/TASKID senza ToProcess si verificano anche eventuali Duplo. +-- 2022/01/17 Eliminata assegnazione Feature ok se non calcolata. +-- 2022/01/20 Si aggiorna il setup anche quando si creano le lavorazioni (MachGroup vecchio...). + + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--WALL = {} +--WALL.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl' +--WALL.MACHINE = 'Essetre-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 == 5 then + sFlag = 'CLOUD' +elseif WALL.FLAG == 6 then + sFlag = 'CREATE_PANEL' +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 BWMessageId( nMsgId, sMsg, params) + if WALL.BW and nMsgId and nMsgId > 0 then + local sFinalMsg = '$$' .. nMsgId + for Index = 1, #params do + sFinalMsg = sFinalMsg .. ',' .. params[Index] + end + return sFinalMsg + else + return string.format( sMsg, table.unpack( params)) + end +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 or WALL.FLAG == 5) 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 or WALL.FLAG == 5) 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 + +-- Funzione di reset gruppo di lavoro in caso di impossibilità di inserire i pezzi +local function ResetMachGroup( vWall) + for i = 1, #vWall do + EgtErase( vWall[i].Id) + end + EgtRemoveMachGroup( EgtGetCurrMachGroup() or GDB_ID.NULL) +end + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Se necessario, impostazione della macchina corrente +local sMachine = WALL.MACHINE +if WALL.FLAG ~= 6 then + EgtResetCurrMachGroup() + 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 +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti +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') + +-- Carico le librerie +_G.package.loaded.WallExec = nil +local WE = require( 'WallExec') +local WL = require( 'WallLib') + +-- Carico i dati globali +local WD = require( 'WallData') + +-- Dati del file +local sDir, sTitle, sExt = EgtSplitPath( WALL.FILE) +local sOriFile = sDir..sTitle..'.ori.bwe' +local sNgeFile = sDir..sTitle..'.bwe' +local sBtmFile = sDir..sTitle..'.btm' +local sPntFile = sDir..sTitle..'.pnt' + +-- In generale va completamente riprocessato +local bToProcess = true +local bToRecalc = false +-- se BTL, barra ed esiste già il corrispondente progetto Nge +if EgtExistsFile( sOriFile) then + bToProcess = false + EgtCopyFile( sOriFile, sNgeFile) + -- se cambiata configurazione macchina da ultima elaborazione, devo aggiornare + if EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\Wall\\TS3Data.lua') == -1 or + EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\Tools\\Tools.data') == -1 or + EgtCompareFilesLastWriteTime( sOriFile, sMachDir .. '\\' .. sMachine ..'.mlde') == -1 then + bToRecalc = true + end +end + +-- Inizializzo contatori errori e avvisi +local nErrCnt = 0 +local nWarnCnt = 0 + +-- Se da elaborare +if bToProcess then + EgtOutLog( ' +++ Processing Parts >>>') + + -- Flag di pannello da creare + local bCreatePanel + -- Dimensioni del pannello ed elenco pareti + local dPanelLen + local dPanelWidth + local vWall = {} + -- flag per Nesting da Btl + local bNestingFromBtl = false + local nRawOutlineId = GDB_ID.NULL + + -- Se necessario, apro il file Bwe + if WALL.FLAG ~= 6 then + if not EgtOpenFile( WALL.FILE) then + WALL.ERR = 13 + WALL.MSG = 'Error opening BWE file : ' .. WALL.FILE + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end + -- faccio copia del file originale + EgtCopyFile( WALL.FILE, sOriFile) + + -- Aggiorno eventuali dati ausiliari + --UpdateAuxData( sBtmFile) + + -- Se già presente un gruppo di lavoro + if EgtGetFirstMachGroup() then + -- Barra già presente + bCreatePanel = false + -- Rendo corrente il gruppo di lavoro + EgtSetCurrMachGroup() + -- 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) + + -- altrimenti devo recuperare i pezzi per creare il pannello + else + -- Pannello da creare + bCreatePanel = true + -- Recupero l'elenco ordinato delle pareti + 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( 'Pareti trovate : ' .. sOut, 1) + end + -- variabile che indica se ci sono fori orizzontali lunghi + local bUseMinRawYForLongDrill = false + -- recupero libreria fori + _G.package.loaded.WProcessDrill = nil + local Drill = require( 'WProcessDrill') + -- 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 wall ' .. vWall[i].Name + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + else + vWall[i].Box = b3Solid + end + -- recupero lista feature e ciclo + local vPartProc = WE.CollectFeatures( vWall[i].Id) + for nInd = 1, #vPartProc do + if Drill.Identify( vPartProc[nInd]) and Drill.UseMinYForLongDrill(vPartProc[nInd]) then + bUseMinRawYForLongDrill = true + end + end + end + -- se parete con fori lunghi orizzontali + local dMinY = 0 + if bUseMinRawYForLongDrill then + -- considero minima larghezza per permettere di farli + dMinY = ( WD.MINRAWY_HOR_DRILL or 2800) + end + -- Assegno dimensioni del pannello + dPanelLen = vWall[1].Box:getDimX() + 20 + dPanelWidth = math.max( vWall[1].Box:getDimY() + 20, dMinY) + -- Assegno posizione prima ed unica parete + vWall[1].PosX = 10 + vWall[1].PosZ = 10 + vWall[1].Rot = 0 + vWall[1].Flip = 0 + end + + -- Altrimenti, opero sul progetto corrente + else + -- Recupero l'identificativo del gruppo di lavoro corrente + local nMGrpId = EgtGetCurrMachGroup() + -- Pannello da creare + bCreatePanel = true + -- leggo se grezzo da nesting btl + bNestingFromBtl = EgtGetInfo( nMGrpId, 'BTLNESTING', 'b') or false + if bNestingFromBtl then + -- recupero superficie + nRawOutlineId = EgtGetInfo( nMGrpId, 'RAWOUTLINEID') or GDB_ID.NULL + if nRawOutlineId ~= GDB_ID.NULL then + local nRawPartId = EgtGetParent( EgtGetParent( nRawOutlineId)) + EgtSetStatus( nRawPartId, GDB_ST.ON) + local b3RawSurf = EgtGetBBoxGlob( nRawPartId, GDB_BB.STANDARD) + EgtSetStatus( nRawPartId, GDB_ST.OFF) + --EgtSurfTmBBox( nRawOutlineId, b3RawSurf, false, GDB_RT.GLOB) + if b3RawSurf then + -- Lunghezza e larghezza del pannello + dPanelLen = b3RawSurf:getDimX() + dPanelWidth = b3RawSurf:getDimY() + end + end + else + -- Lunghezza e larghezza del pannello + dPanelLen = EgtGetInfo( nMGrpId, 'PANELLEN', 'd') + dPanelWidth = EgtGetInfo( nMGrpId, 'PANELWIDTH', 'd') + end + -- Recupero l'elenco ordinato delle pareti da inserire nel pannello + for i = 1, 100 do + local sKey = 'PART'..tostring( i) + local sVal = EgtGetInfo( nMGrpId, sKey) + local vVal = EgtSplitString( sVal or '') + if not vVal or #vVal < 5 then break end + local nPartId = tonumber( vVal[1]) + local dPosX = tonumber( vVal[2]) + local dPosY = tonumber( vVal[3]) + local dRot = tonumber( vVal[4]) + local dFlip = tonumber( vVal[5]) + table.insert( vWall, { Id = nPartId, PosX = dPosX, PosZ = dPosY, Rot = dRot, Flip = dFlip, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + if #vWall == 0 then + WALL.ERR = 14 + WALL.MSG = 'Error : no walls in the project' + WriteErrToLogFile( 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( 'Pareti 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) + return + else + vWall[i].Box = b3Solid + end + end + end + + -- Se devo creare il pannello + if bCreatePanel then + -- 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 + ResetMachGroup( vWall) + WALL.ERR = 16 + WALL.MSG = sOut + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + end + + local dRawL = dPanelLen + local dRawW = dPanelWidth + + -- 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 + ResetMachGroup( vWall) + local sOut = BWMessageId( 1, 'Grezzo (%s x %s x %s) oltre il limite della macchina (%s x %s x %s)', + {EgtNumToString( dRawL, 2), EgtNumToString( dRawW, 2), EgtNumToString( dRawH, 2), + EgtNumToString( WD.MAX_LENGTH, 2), EgtNumToString( WD.MAX_WIDTH, 2), 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 + ResetMachGroup( vWall) + 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, WALL.FLAG == 6, true, nRawOutlineId) + if not bPbOk then + WALL.ERR = 18 + WALL.MSG = sPbErr + WriteErrToLogFile( WALL.ERR, WALL.MSG) + PostErrView( WALL.ERR, WALL.MSG) + return + else + -- Scrivo altezza grezzo nel gruppo di lavoro corrente + local nMGrpId = EgtGetCurrMachGroup() + EgtSetInfo( nMGrpId, 'PANELHEIGHT', dRawH) + end + -- altrimenti sistemo + else + -- recupero il grezzo + local nRawId = EgtGetFirstRawPart() + -- ciclo sui pezzi + local nPartId = EgtGetFirstPartInRawPart( nRawId) + while nPartId do + WL.CreateOrEmptyAddGroup( nPartId) + nPartId = EgtGetNextPartInRawPart( nPartId) + end + end + + -- Se richiesta solo pannello, esco + if WALL.FLAG == 6 then + -- Completamento senza errori e avvisi + if nWarnCnt == 0 then + WALL.ERR = 0 + WALL.MSG = '---' + WriteErrToLogFile( WALL.ERR, WALL.MSG) + end + EgtOutLog( ' +++ BatchProcess completed') + return + end + + -- Imposto Nome file CN + local _, sName, _ = EgtSplitPath( WALL.FILE) + EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + + -- Abilito Vmill + EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + + -- Aggiorno Setup utensili + EgtImportSetup() + + -- Lavoro le features + local bPfOk, Stats = WE.ProcessFeatures() + local sOutput = '' + for i = 1, #Stats do + local sMsg = Stats[i].Msg + sMsg = string.gsub( sMsg or '', '\n', ' ', 10) + sMsg = string.gsub( sMsg or '', '\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) + -- copio come originale (per dichiarare progetto ricalcolato) + EgtCopyFile( sNgeFile, sOriFile) + + -- 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 vDup = EgtDuploList( nPartId) + -- if not vDup or #vDup == 0 then + -- vDup = { nPartId} + -- end + -- for i = 1, #vDup do + -- local nCutId = EgtGetInfo( vDup[i], 'CUTID', 'i') + -- if nCutId then + -- local LayerId = {} + -- LayerId[1] = EgtGetFirstNameInGroup( vDup[i], 'Outline') + -- LayerId[2] = EgtGetFirstNameInGroup( vDup[i], 'Processings') + -- for nInd = 1, #LayerId do + -- local nProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL) + -- while nProcId do + -- local bIsFea = EgtExistsInfo( nProcId, 'GRP') and EgtExistsInfo( nProcId, 'PRC') + -- local nTaskId = EgtGetInfo( nProcId, 'TASKID', 'i') + -- 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 + -- end + -- end + -- nPartId = EgtGetNextPart( nPartId) + --end + -- Aggiorno eventuali dati ausiliari + --UpdateAuxData( sBtmFile) + -- Passo in modalità lavora + EgtSetCurrMachGroup( EgtGetLastMachGroup()) + -- Se necessario eseguo aggiornamento con setup corrente e ricalcolo delle lavorazioni + if bToRecalc then + EgtOutLog( ' +++ Recalculating all dispositions and machinings >>>') + EgtImportSetup() + EgtApplyAllMachinings() + -- Salvo il progetto + EgtSaveFile( sNgeFile) + -- copio come originale (per dichiarare progetto ricalcolato) + EgtCopyFile( sNgeFile, sOriFile) + end +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 >>>') + -- verifico setup + local bSetUpOk, SetUpErrors = EgtVerifyCurrSetup() + if not bSetUpOk then + local sToolsList = "" + for ToolIndex = 1, #SetUpErrors do + sToolsList = sToolsList .. SetUpErrors[ToolIndex] + if ToolIndex ~= #SetUpErrors then + sToolsList = sToolsList .. ", " + end + end + WriteErrToLogFile( 19, 'Error in setup: tool/s ' .. sToolsList .. ' not found', 0, 0, 0) + return + end + -- lancio simulazione + local bSimOk, nErr, sErr = EgtSimulate() + if not bSimOk then + if nErr == MCH_SHE.INIT then + WALL.ERR = 19 + WALL.MSG = 'Error starting simulation' + 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 = 'Special 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 >>>') + local sInfo = 'EgtCAM5 - ' + if EgtGetExeVersion then + sInfo = 'EgtCAM5 ver.' .. EgtGetExeVersion() .. ' - ' + end + if not EgtGenerate( '', sInfo .. 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', 'd') +local sTime = 'Total Time = ' .. EgtNumToString( Ttot, 1) +EgtOutLog( sTime) + +-- Se modalità Cloud, importo la nuvola di punti +if WALL.FLAG == 5 then + EgtOutLog( ' +++ Importing Point Cloud >>>') + -- Creo gruppo Cloud nel gruppo di lavorazione + local nMGrpId = EgtGetCurrMachGroup() + local nCloudId = EgtGetFirstNameInGroup( nMGrpId or GDB_ID.NULL, 'Cloud') + if nCloudId then + EgtEmptyGroup( nCloudId) + else + nCloudId = EgtGroup( nMGrpId) + EgtSetName( nCloudId, 'Cloud') + end + -- Recupero BBox della tavola + local b3Tab = EgtGetTableArea() + if not b3Tab or b3Tab:isEmpty() then + WALL.ERR = 22 + WALL.MSG = 'Machine table not found' + return + end + -- Recupero i punti della nuvola + local hFile = io.open( sPntFile, 'r') + if not hFile then + WALL.ERR = 23 + WALL.MSG = 'Missing point cloud file' + return + end + local vPoints = {} + local sLine = hFile:read( '*l') + while sLine do + local vCoord = EgtSplitString( sLine, ' ') + if vCoord and #vCoord >= 2 then + local dX = tonumber( vCoord[1]) + b3Tab:getMax():getX() + local dY = tonumber( vCoord[2]) + b3Tab:getMin():getY() + local dZ = b3Tab:getMax():getZ() + EgtOutLog( ' X='..EgtNumToString( dX, 3)..' Y='..EgtNumToString( dY, 3), 3) + table.insert( vPoints, { dX, dY, dZ}) + end + sLine = hFile:read( '*l') + end + hFile:close() + -- Inserisco la curva di contorno della nuvola + local nClCrvId = EgtCurveCompoFromPoints( nCloudId, vPoints, GDB_RT.GLOB) + if not nClCrvId then + WALL.ERR = 24 + WALL.MSG = 'Failed to create Point cloud Contour' + return + end + EgtCloseCurveCompo( nClCrvId) + EgtApproxCurve( nClCrvId, GDB_CA.LINES, 1.0) + EgtSetColor( nClCrvId, 'RED') +end + +-- Se modifica o simula, imposto la vista ISO 3d opportuna +if WALL.FLAG == 1 or WALL.FLAG == 2 then + local vView = { SCE_VD.ISO_NW, SCE_VD.ISO_SW, SCE_VD.ISO_NE, SCE_VD.ISO_SE} + local nV = min( max( WD.SIMUL_VIEW_DIR or 2, 1), 4) + EgtSetView( vView[nV], false) +-- se cloud, imposto la vista TOP +elseif WALL.FLAG == 5 then + EgtSetView( SCE_VD.TOP, 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/ProgramData/EgtCAM5/Wall/GetWallData.lua b/ProgramData/EgtCAM5/Wall/GetWallData.lua new file mode 100644 index 0000000..6c62842 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/GetWallData.lua @@ -0,0 +1,48 @@ +-- GetWallData.lua by Egaltech s.r.l. 2021/11/22 +-- Recupero dati da file WallData.lua di macchina + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--GWD = {} +--GWD.MACHINE = 'Essetre-90480019_MW' + +local sLog = 'GetWallData : ' .. GWD.MACHINE +EgtOutLog( sLog) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Wall\\WallData.lua') then + GWD.ERR = 12 + GWD.MSG = 'Error not configured for walls machine : ' .. GWD.MACHINE + WriteErrToLogFile( GWD.ERR, GWD.MSG) + PostErrView( GWD.ERR, GWD.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua') + +-- Carico i dati globali +local WD = require( 'WallData') + +-- Assegno valori di interesse +GWD.SIMUL_VIEW_DIR = WD.SIMUL_VIEW_DIR +GWD.ORIG_CORNER = WD.ORIG_CORNER +GWD.NESTING_CORNER = WD.NESTING_CORNER +GWD.HOR_DRILL_DIAM = WD.HOR_DRILL_DIAM +GWD.MIN_HEIGHT = WD.MIN_HEIGHT +GWD.MAX_HEIGHT = WD.MAX_HEIGHT + +-- Tutto ok +GWD.ERR = 0 + +EgtOutLog( ' +++ GetWallData completed') diff --git a/ProgramData/EgtCAM5/Wall/Images/Overturn.png b/ProgramData/EgtCAM5/Wall/Images/Overturn.png new file mode 100644 index 0000000..9854743 Binary files /dev/null and b/ProgramData/EgtCAM5/Wall/Images/Overturn.png differ diff --git a/ProgramData/EgtCAM5/Wall/Images/Process.png b/ProgramData/EgtCAM5/Wall/Images/Process.png new file mode 100644 index 0000000..e51b0b9 Binary files /dev/null and b/ProgramData/EgtCAM5/Wall/Images/Process.png differ diff --git a/ProgramData/EgtCAM5/Wall/Images/Rotate.png b/ProgramData/EgtCAM5/Wall/Images/Rotate.png new file mode 100644 index 0000000..fc5b749 Binary files /dev/null and b/ProgramData/EgtCAM5/Wall/Images/Rotate.png differ diff --git a/ProgramData/EgtCAM5/Wall/Images/WallMachinings.png b/ProgramData/EgtCAM5/Wall/Images/WallMachinings.png new file mode 100644 index 0000000..e88dd70 Binary files /dev/null and b/ProgramData/EgtCAM5/Wall/Images/WallMachinings.png differ diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WMachiningLib.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WMachiningLib.lua new file mode 100644 index 0000000..efc4d5c --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WMachiningLib.lua @@ -0,0 +1,181 @@ +-- MachiningLib.lua by Egaltech s.r.l. 2022/01/12 +-- Libreria ricerca lavorazioni per Pareti + +-- Tabella per definizione modulo +local WMachiningLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' WMachiningLib 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 Surfacings +if EgtExistsFile( EgtGetCurrMachineDir() .. '\\Wall\\SurfacingData.lua') then + Surfacings = require( 'SurfacingData') +end + +--------------------------------------------------------------------- +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 WMachiningLib.FindCutting( sType, dDepth, nTool_ID) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.On and Cutting.Type == sType and SetCurrMachiningAndTool( Cutting.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or 0 + local dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or 0 + local dSawMaxDepth = EgtTdbGetCurrToolMaxDepth() or 0 + local nMyTool_ID = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'Tool_ID', 'i') + if nMchType == MCH_MY.SAWING and + ( not dDepth or dSawMaxDepth > dDepth - 10 * GEO.EPS_SMALL) and + ( not nTool_ID or nTool_ID == 0 or nTool_ID == nMyTool_ID) then + return Cutting.Name, dSawDiam, dSawThick, dSawMaxDepth + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindMilling( sType, dDepth, sTuuid, nTool_ID, dMaxDiam, dMaxMat, bTipFeed, dMinSideElev) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.On and Milling.Type == sType and SetCurrMachiningAndTool( Milling.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local sMyTuuid = EgtGetMachiningParam( MCH_MP.TUUID) + local dTMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + local dTMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, dTMaxMat, EgtTdbGetCurrToolMaxDepth()) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTDiamTh = EgtTdbGetCurrToolThDiam() or 0 + local dTTipFeed = EgtTdbGetCurrToolParam( MCH_TP.TIPFEED) + local dTMaxDepthOnSide = min( EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or 0, 0.5 * ( dTDiam - dTDiamTh)) + local nMyTool_ID = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'Tool_ID', 'i') + if nMchType == MCH_MY.MILLING and + ( not sTuuid or sTuuid == sMyTuuid) and + ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and + ( not dMaxDiam or dTDiam < dMaxDiam + GEO.EPS_SMALL) and + ( not dMaxMat or dTMaxMat < dMaxMat + GEO.EPS_SMALL) and + ( not bTipFeed or dTTipFeed > 1) and + ( not dMinSideElev or dTMaxDepthOnSide > dMinSideElev - GEO.EPS_SMALL) and + ( not nTool_ID or nTool_ID == 0 or nTool_ID == nMyTool_ID) then + return Milling.Name, dTMaxDepth, dTMaxMat, dTDiam + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindNailing( nType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.On and Milling.Type == 'Nailing' and SetCurrMachiningAndTool( Milling.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local sTName = EgtTdbGetCurrToolParam( MCH_TP.NAME) + if nMchType == MCH_MY.MILLING and + sTName == tostring( nType) then + return Milling.Name + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindPocketing( sType, dMaxDiam, dDepth, nTool_ID) + for i = 1, #Pocketings do + local Pocketing = Pocketings[i] + if Pocketing.On and Pocketing.Type == sType and SetCurrMachiningAndTool( Pocketing.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) + local nMyTool_ID = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'Tool_ID', 'i') + if nMchType == MCH_MY.POCKETING and + ( not dMaxDiam or dTDiam < dMaxDiam + GEO.EPS_SMALL) and + ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and + ( not nTool_ID or nTool_ID == 0 or nTool_ID == nMyTool_ID) then + return Pocketing.Name, dTDiam, dTMaxDepth + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindSawing( sType) + for i = 1, #Sawings do + local Sawing = Sawings[i] + if Sawing.On and Sawing.Type == sType and SetCurrMachiningAndTool( Sawing.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + if nMchType == MCH_MY.MORTISING then + return Sawing.Name + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindDrilling( dDiam, dDepth, sHead, bOnlyPockets) + if bOnlyPockets == nil or not bOnlyPockets then + -- 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 nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + local sMyHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if nMchType == MCH_MY.DRILLING and + dTDiam < dDiam + 10 * GEO.EPS_SMALL and dTDiam > dDiam - WD.DRILL_TOL - 10 * GEO.EPS_SMALL and + ( not dDepth or dTMaxMat > dDepth - GEO.EPS_SMALL) and + (( not sHead and sMyHead ~= 'H5' and sMyHead ~= 'H6') or sHead == sMyHead) then + return Drilling.Name, Drilling.Type, dTMaxMat + end + 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 nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + local dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) + local dTMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) + local sMyHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + if nMchType == MCH_MY.POCKETING and + dTDiam < dDiam - 10 * GEO.EPS_SMALL and + ( not dDepth or dTMaxDepth > dDepth - GEO.EPS_SMALL) and + ( ( not sHead and sMyHead ~= 'H5' and sMyHead ~= 'H6') or sHead == sMyHead) then + return Drilling.Name, Drilling.Type, dTMaxDepth + end + end + end +end + +--------------------------------------------------------------------- +function WMachiningLib.FindSurfacing( sType) + if not Surfacings then return end + for i = 1, #Surfacings do + local Surfacing = Surfacings[i] + if Surfacing.On and Surfacing.Type == sType and SetCurrMachiningAndTool( Surfacing.Name) then + local nMchType = EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) + if nMchType == MCH_MY.SURFFINISHING then + return Surfacing.Name + end + end + end +end + +------------------------------------------------------------------------------------------------------------- +return WMachiningLib diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessCut.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessCut.lua new file mode 100644 index 0000000..3523ea7 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessCut.lua @@ -0,0 +1,74 @@ +-- WProcessCut.lua by Egaltech s.r.l. 2020/11/13 +-- Gestione calcolo taglio di testa o longitudinale per Pareti + +-- Tabella per definizione modulo +local WPC = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') +local FreeContour = require( 'WProcessFreeContour') + +EgtOutLog( ' WProcessCut started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPC.Identify( Proc) + return ( (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) or + (( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 10)) +end + + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPC.Classify( Proc, b3Raw) + -- verifico abbia una sola faccia + if Proc.Fct ~= 1 then return false end + -- controllo la normale + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 then return false end + return true +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPC.FlipClassify( Proc) + -- verifico abbia una sola faccia + if Proc.Fct ~= 1 then return 0, 0 end + -- controllo la normale + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local vtNZ = vtN:getZ() + if vtNZ > - GEO.EPS_SMALL then + nFlip0 = 100 + elseif vtNZ < -0.5 then + nFlip0 = 0 + else + nFlip0 = 50 + end + + if - vtNZ > - GEO.EPS_SMALL then + nFlip1 = 100 + elseif - vtNZ < -0.5 then + nFlip1 = 0 + else + nFlip1 = 50 + end + + --nFlip0 = EgtIf( vtN:getZ() < -0.5, 0, 100) + --nFlip1 = EgtIf( - vtN:getZ() < -0.5, 0, 100) + return nFlip0, nFlip1 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPC.Make( Proc, nRawId, b3Raw) + return FreeContour.Make( Proc, nRawId, b3Raw) +end + +--------------------------------------------------------------------- +return WPC diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessDoubleCut.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessDoubleCut.lua new file mode 100644 index 0000000..74a0bc4 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessDoubleCut.lua @@ -0,0 +1,65 @@ +-- WProcessDoubleCut.lua by Egaltech s.r.l. 2021/04/28 +-- Gestione calcolo doppi tagli di lama per Pareti + +-- Tabella per definizione modulo +local WPDC = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') +local Cut = require( 'WProcessCut') +local LapJoint = require( 'WProcessLapJoint') + +EgtOutLog( ' WProcessDoubleCut started', 1) + +-- Dati +local WD = require( 'WallData') +local ML = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPDC.Identify( Proc) + return ( (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 11) or + ( Proc.Grp == 0 and Proc.Prc == 12)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPDC.Classify( Proc, b3Raw) + -- se una faccia, uso la classificazione dei tagli singoli + if Proc.Fct == 1 then return Cut.Classify( Proc, b3Raw) end + -- se più di due facce non si fa + if Proc.Fct > 2 then return false end + -- dati delle facce + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile da sopra o di fianco + return ( vtN[1]:getZ() >= - 0.01 or vtN[2]:getZ() >= - 0.01) +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPDC.FlipClassify( Proc) + + -- se una faccia, uso la classificazione dei tagli singoli + if Proc.Fct == 1 then return Cut.FlipClassify( Proc) end + -- se due facce, uso la classificazione del lap joint a due facce + if Proc.Fct == 2 then return LapJoint.FlipClassify( Proc) end + -- se più di due facce non si fa + if Proc.Fct > 2 then return 0, 0 end + +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPDC.Make( Proc, nRawId, b3Raw) + -- se singola faccia, passo a quella lavorazione + if Proc.Fct == 1 then return Cut.Make( Proc, nRawId, b3Raw) end + -- altrimenti due facce e passo alla LapJoint + return LapJoint.Make( Proc, nRawId, b3Raw) +end + +--------------------------------------------------------------------- +return WPDC diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessDrill.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessDrill.lua new file mode 100644 index 0000000..79e2295 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessDrill.lua @@ -0,0 +1,544 @@ +-- WProcessDrill.lua by Egaltech s.r.l. 2022/03/08 +-- Gestione calcolo forature per Pareti +-- 2021/08/29 DS Se foratura di fianco setto flag per farla dopo i tagli. +-- 2021/12/04 DS Modifiche per forature speciali lungo Y. +-- 2022/01/12 DS Se con fresatura richiedo che l'utensile possa lavorare di testa. +-- 2022/01/19 DS Forature orizzontali lunghe con nome LhDrill_. +-- 2022/01/20 DS Aggiunta gestione Q01 (flag forzatura solo contornatura). +-- 2022/01/29 DS Corretta gestione ingombro portautensili per fori inclinati da sopra. +-- 2022/02/22 ES Aggiunta gestione prefori. +-- 2022/03/08 DS Vanno accettati fori orizzontali sul bordo anche senza foratori orizzontali speciali. + +-- Tabella per definizione modulo +local WPD = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') + +EgtOutLog( ' WProcessDrill started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +-- Parametri Q +local sContourOnly = 'Q01' -- 0=no, 1=si + + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPD.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 40) +end + +--------------------------------------------------------------------- +-- Recupero dati foro e adattamento se speciale +function WPD.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 WPD.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) + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- se inizia o finisce sulla faccia sopra + if ptCen:getZ() > b3Raw:getMax():getZ() - dDiam / 2 or ( bOpen and ptCen:getZ() - vtExtr:getZ() * dLen > b3Raw:getMax():getZ() - dDiam / 2) then + -- è lavorabile se non troppo inclinato + return ( abs( vtExtr:getZ()) >= WD.DRILL_VZ_MIN) + end + -- se con direzione asse Y e macchina con foratore orizzontale del giusto diametro + if WD.HOR_DRILL_DIAM and abs( dDiam - WD.HOR_DRILL_DIAM) < WD.DRILL_TOL and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then + return true + end + -- se foro orizzontale, verifico sia sul bordo del grezzo + local b3RedRaw = BBox3d( b3Raw) + b3RedRaw:expand( -20) + if ( WD.HOR_DRILL_5AX or WD.HOR_DRILL_5AX == nil) and vtExtr:getZ() > -0.05 and not EnclosesPointXY( b3RedRaw, ptCen) then + return true + end + -- altrimenti non lavorabile + return false +end + +--------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPD.FlipClassify( Proc, b3Part) + -- 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) + -- se foro cieco + if Proc.Fcs == 0 or Proc.Fce == 0 then + -- se normale positiva + local dVtExtrZ = vtExtr:getZ() + -- verifico se è lavorabile da sopra + local nFlip0 = EgtIf( dVtExtrZ >= WD.DRILL_VZ_MIN, 100, 0) + -- verifico se e' lavorabile da flipped: cambio segno al versore + local nFlip1 = EgtIf( -dVtExtrZ >= WD.DRILL_VZ_MIN, 100, 0) + return nFlip0, nFlip1 + end + -- altrimenti + return 0, 0 +end + +--------------------------------------------------------------------- +-- Classificazione della rotazione della feature per nesting +-- return nRot0, nRot90, nRot180, nRot270 +function WPD.RotateClassify( Proc) + + local nRot0 = -1 + local nRot90 = -1 + local nRot180 = -1 + local nRot270 = -1 + -- 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) + -- se foro orizzontale con punta lunga + if dDiam <= WD.HOR_DRILL_DIAM + WD.DRILL_TOL and dDiam >= WD.HOR_DRILL_DIAM - WD.DRILL_TOL and vtExtr:getZ() > -0.1 and vtExtr:getZ() < 0.1 then + -- se orientato perpendicolare ad X + if AreSameOrOppositeVectorApprox( vtExtr, X_AX()) then + nRot0 = 0 + nRot90 = 100 + nRot180 = 0 + nRot270 = 100 + return nRot0, nRot90, nRot180, nRot270 + elseif AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then + nRot0 = 100 + nRot90 = 0 + nRot180 = 100 + nRot270 = 0 + return nRot0, nRot90, nRot180, nRot270 + end + end +end + +--------------------------------------------------------------------- +local function IsHorizLongDrill( Proc) + -- 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 vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + return dDiam <= WD.HOR_DRILL_DIAM + WD.DRILL_TOL and dDiam >= WD.HOR_DRILL_DIAM - WD.DRILL_TOL and vtExtr:getZ() > -0.1 and vtExtr:getZ() < 0.1 +end + +--------------------------------------------------------------------- +function WPD.UseMinYForLongDrill( Proc) + if IsHorizLongDrill( Proc) then + -- 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) + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- se foro lungo orizzontale e piu' lungo della punta o orientato in Y- + if dDiam <= WD.HOR_DRILL_DIAM + WD.DRILL_TOL and dDiam >= WD.HOR_DRILL_DIAM - WD.DRILL_TOL and vtExtr:getZ() > -0.1 and vtExtr:getZ() < 0.1 and + ( (bOpen and dLen > WD.HOR_DRILL_LEN) or ( not bOpen and vtExtr:getY() < 0)) then + return true + end + end + return false +end + +--------------------------------------------------------------------- +-- Verifica se da lavorare in due metà +function WPD.Split( 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 bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- verifico se foro orizzontale in Y da lavorare in due metà + if WD.HOR_DRILL_Y_SPLIT and bOpen and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) and + Proc.Box:getMin():getY() < WD.HOR_DRILL_Y_SPLIT - 10 and Proc.Box:getMax():getY() > WD.HOR_DRILL_Y_SPLIT + 10 then + return true + else + return false + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPD.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 : 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 ptCen = EgtCP( 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.1) + if bToInvert and ( not bOpen or Proc.Flg ~= 1) then + local sErr = 'Error : drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- se foro da fare dall'altra parte forzo inversione + if Proc.Flg == -2 then bToInvert = true end + -- se foro chiuso sulla partenza forzo inversione + if Proc.Fcs == 0 then bToInvert = true end + -- se richiesta inversione, inverto versore di riferimento + if bToInvert then vtExtr = - vtExtr end + -- recupero la lavorazione (foratura/svuotatura) + local sHead + if WD.HOR_DRILL_Y_SPLIT and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) then + local dExtrY = vtExtr:getY() + if not bOpen or abs( Proc.Flg) == 2 then + sHead = EgtIf( dExtrY > 0, 'H5', 'H6') + else + if Proc.Box:getMax():getY() > WD.HOR_DRILL_Y_SPLIT + 10 then + sHead = 'H5' + if vtExtr:getY() < 0 then bToInvert = true end + else + sHead = 'H6' + if vtExtr:getY() > 0 then bToInvert = true end + end + end + end + local sDrilling, nType = WM.FindDrilling( dDiam, dLen, sHead) + if not sDrilling then + sDrilling, nType = WM.FindDrilling( dDiam, nil, sHead) + end + if sHead and not sDrilling then + sDrilling, nType = WM.FindDrilling( dDiam, dLen) + if not sDrilling then + sDrilling, nType = WM.FindDrilling( dDiam) + end + if sDrilling then sHead = '' end + end + local bAngledContourDrill = false + local nAngledContourDrillId = GDB_ID.NULL + local dReduceDepth = 0 + -- se trovata svuotatura, verifico se richiesta invece contornatura + if nType == 'Pocket' then + -- recupero eventuale flag per fare sola contornatura + local nContourOnly = ( EgtGetInfo( Proc.Id, sContourOnly, 'i') or 0) + if nContourOnly == 1 then + -- imposto riduzione profondita' per evitare distacco pezzo interno + dReduceDepth = 5 + -- se inclinato e passante + if abs( vtExtr:getZ()) >= WD.DRILL_VZ_MIN and abs( vtExtr:getZ()) < 0.999 and Proc.Fcs > 0 and Proc.Fce > 0 then + -- gruppo ausiliario per preforo + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + -- ricavo contorno inferiore della superficie + local nAngledCircleId, nAngledCircleCnt = EgtExtractSurfTmLoops( Proc.Id, nAddGrpId) + local dMinZ = 10000 + local nMinCircleId = GDB_ID.NULL + for Circleindex = 1, nAngledCircleCnt do + local b3Circle = EgtGetBBoxGlob( nAngledCircleId + Circleindex -1, GDB_BB.EXACT) + if b3Circle:getMin():getZ() < dMinZ then + nMinCircleId = nAngledCircleId + Circleindex -1 + end + end + -- estrudo + EgtModifyCurveExtrusion( nMinCircleId, vtExtr, GDB_RT.GLOB) + EgtModifyCurveThickness( nMinCircleId, dLen) + bAngledContourDrill = true + nAngledContourDrillId = nMinCircleId + end + sDrilling = WM.FindMilling( 'FreeContour', dLen, nil, nil, nil, nil, true) + if sDrilling then + nType = 'Mill' + sHead = '' + end + end + end + if not sDrilling then + local sErr = 'Error : drilling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- controllo posizione Y inizio foro con testa H6 + if WD.HOR_DRILL_YNEG_MAXMIN and sHead == 'H6' then + if b3Raw:getMin():getY() > WD.HOR_DRILL_YNEG_MAXMIN then + local sErr = 'Error : horizontal hole with Drilling2 starting too far' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dMaxDepth = 20 + local dFreeLen = 20 + local dDiamTh = 35 + local dDiamT = 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 + dFreeLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) - EgtTdbGetCurrToolThLength() - EgtMdbGetGeneralParam( MCH_GP.MAXDEPTHSAFE) + dMaxDepth = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth + else + dFreeLen = EgtTdbGetCurrToolMaxDepth() or dFreeLen + dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxDepth, dFreeLen) + end + dDiamTh = EgtTdbGetCurrToolThDiam() + dDiamT = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dDiamT + end + end + -- calcolo riduzione lunghezza aggiuntiva per inclinazione utensile + if bAngledContourDrill then + local dToolAngleReduce = ( dDiamT / 2) * sqrt( 1 - vtExtr:getZ() * vtExtr:getZ()) / vtExtr:getZ() + dReduceDepth = ( dToolAngleReduce) + ( 5 / vtExtr:getZ()) + end + -- aggiusto massimo affondamento per fori lungo Y con teste speciali + if sHead == 'H5' then + local dMaxY = WD.HOR_DRILL_Y_SPLIT + WD.HOR_DRILL_Y_TABLE / 2 + local dDeltaY = dMaxY - Proc.Box:getMax():getY() + if dDeltaY > 0 then + dMaxDepth = dMaxDepth - dDeltaY + end + elseif sHead == 'H6' then + local dMinY = WD.HOR_DRILL_Y_SPLIT - WD.HOR_DRILL_Y_TABLE / 2 + local dDeltaY = Proc.Box:getMin():getY() - dMinY + if dDeltaY > 0 then + dMaxDepth = dMaxDepth - dDeltaY + end + end + -- se foro faccia sopra, limito il massimo affondamento secondo inclinazione + if ptCen:getZ() > b3Raw:getMax():getZ() - dDiam / 2 then + local SinA = abs( vtExtr:getZ()) + if SinA >= WD.DRILL_VZ_MIN then + local CosA = sqrt( 1 - SinA * SinA) + local dSlantFreeLen = dFreeLen - ( dDiamTh / 2 * CosA / SinA) + dMaxDepth = min( dMaxDepth, dSlantFreeLen) + else + dMaxDepth = 0 + end + end + -- inserisco la lavorazione + local sName = EgtIf( sHead == 'H5' or sHead == 'H6', 'LhDrill_', '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 + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- se foratura di fianco setto la nota per spostarla dopo i tagli di lama + if vtExtr:getZ() < WD.NZ_MINA and not sHead then + EgtSetInfo( nMchId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + if bAngledContourDrill then + EgtSetMachiningGeometry( nAngledContourDrillId) + else + EgtSetMachiningGeometry( {{ AuxId, -1}}) + end + -- eventuale inversione + if nType == 'Drill' then + EgtSetMachiningParam( MCH_MP.INVERT, bToInvert) + else + EgtSetMachiningParam( MCH_MP.TOOLINVERT, bToInvert) + end + -- se fresatura gestisco il lato di lavoro + if bAngledContourDrill then + local nWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if nWorkSide == MCH_MILL_WS.CENTER then + nWorkSide = MCH_MILL_WS.RIGHT + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, nWorkSide == MCH_MILL_WS.LEFT) + elseif nType == 'Mill' then + local frRef = EgtGetGlobFrame( AuxId) + local vtNa, _, dArea = EgtCurveArea( AuxId) + vtNa:toGlob( frRef) + if vtNa:getZ() * dArea > 0 then + EgtSetMachiningParam( MCH_MP.INVERT, true) + else + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + -- per fori lungo Y con teste speciali aggiusto eventuale parte prima del foro ma nel grezzo + if sHead == 'H5' then + local dSafeStart = b3Raw:getMax():getY() - Proc.Box:getMax():getY() + 10 + if dSafeStart > 20 then + EgtSetMachiningParam( MCH_MP.STARTPOS, dSafeStart) + end + elseif sHead == 'H6' then + local dSafeStart = Proc.Box:getMin():getY() - b3Raw:getMin():getY() + 10 + if dSafeStart > 20 then + EgtSetMachiningParam( MCH_MP.STARTPOS, dSafeStart) + end + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- aggiusto l'affondamento + local sMyWarn + local dDepth = dLen - dReduceDepth + if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth + if abs( Proc.Flg) ~= 2 then + sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dLen, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + EgtOutLog( sMyWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + end + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- Note utente + local sUserNotes = '' + -- se foratura o svuotatura, dichiarazione nessuna generazione sfridi per Vmill + if nType == 'Drill' or nType == 'Pocket' then + sUserNotes = 'VMRS=0;' + end + -- 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 + sMyWarn = (sMyWarn or sWarn) + end + end + -- se preforo inclinato impostato, inclinazione oltre limite impostato e foro non orizzontale + if WD.PREDRILL_DIAM and WD.PREDRILL_DIAM > 0 and vtExtr:getZ() < ( WD.PREDRILL_MINANGLE or 0.707) and vtExtr:getZ() > 0.1 then + -- gruppo ausiliario per preforo + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + -- calcolo profondita' foro + local dLen = ( WD.PREDRILL_DIAM / 2) * sqrt( 1 - vtExtr:getZ() * vtExtr:getZ()) / vtExtr:getZ() + -- copio foro originale + local nPreHoleId = EgtCopyGlob( AuxId, nAddGrpId) + EgtModifyArcRadius( nPreHoleId, WD.PREDRILL_DIAM / 2) + EgtModifyCurveThickness( nPreHoleId, -dLen) --dLen = 10 + + -- se da invertire + if bToInvert then + -- lo sposto della lunghezza d'estrusione e ne inverto il versore + local dThickness = EgtCurveThickness( AuxId) + EgtMove( nPreHoleId, abs( dThickness) * vtExtr, GDB_RT.GLOB) + EgtModifyCurveExtrusion( nPreHoleId, vtExtr, GDB_RT.GLOB) + end + -- recupero lavorazione di pocket + local sDrilling = WM.FindDrilling( WD.PREDRILL_DIAM, dLen, nil, true) --dLen = 10 + + if not sDrilling then + local sErr = 'Error : prehole pocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + + -- inserisco la lavorazione + local sName = 'PreDrill_' .. ( 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 + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- setto la nota per spostarla prima della foratura + EgtSetInfo( nMchId, 'MOVE_BEFORE', 1) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nPreHoleId, -1}}) + + -- note utente, dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + 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 + sMyWarn = (sMyWarn or sWarn) + end + end + end + + return true, sMyWarn + +end + +--------------------------------------------------------------------- +return WPD diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessDtMortise.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessDtMortise.lua new file mode 100644 index 0000000..811e74a --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessDtMortise.lua @@ -0,0 +1,220 @@ +-- WProcessDtMortise.lua by Egaltech s.r.l. 2021/04/20 +-- Gestione calcolo mortase a coda di rondine per Pareti + +-- Tabella per definizione modulo +local WPDM= {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') + +EgtOutLog( ' WProcessDtMortise started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +-- settaggi interni ( poi andrà utilizzato parametro ACTIVE_AS proveniente da parametri utente di TechnoEssetre) +local bMakeAntiSplitPath = true +local bMakeAsByArc = true + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPDM.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 55)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPDM.Classify( Proc, b3Raw) + -- recupero i dati della curva di contorno della faccia di fondo + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se la mortasa è lavorabile + return ( vtExtr:getZ() > WD.NZ_MINA) +end + + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPDM.FlipClassify( Proc) + -- recupero i dati della curva di contorno della faccia di fondo + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + -- verifico se la mortasa è lavorabile + nFlip0 = EgtIf( vtExtr:getZ() > WD.NZ_MINA, 100, 0) + nFlip1 = EgtIf( - vtExtr:getZ() > WD.NZ_MINA, 100, 0) + + return nFlip0, nFlip1 + +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPDM.Make( Proc, nRawId, b3Raw) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Missing profile geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + -- verifico che la mortasa non sia orientata verso il basso (-5 deg) o che ci sia una testa da sotto + local bFaceDown = ( vtExtr:getZ() < - 0.1) + if bFaceDown then + local sErr = 'Machining from bottom impossible : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- determino l'altezza della mortasa (0=faccia di fondo) + local rfDtMrt = Frame3d( ptBC, vtExtr) + local b3DtMrt = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, rfDtMrt) + local dAltMort = b3DtMrt:getDimZ() + -- verifico se di tipo pocket + local bPocket = ( EgtGetInfo( Proc.Id, 'P05', 'i') == 1) + if bPocket then bMakeAntiSplitPath = false end + -- recupero il raggio minimo della mortasa + local dMinRad = 1000 + local nSt, nEnd = EgtCurveDomain( AuxId) + for i = nSt, nEnd - 1 do + local dRad = EgtCurveCompoRadius( AuxId, i) + if dRad > 0 and dRad < dMinRad then + dMinRad = dRad + end + end + -- recupero la lavorazione + local sMillType = 'DtMortise' + -- recupero la lavorazione : prima ricerca per sola tipologia + local sMilling = WM.FindMilling( sMillType) + if not sMilling then + local sErr = 'Milling not found in library : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione : seconda ricerca con tipologia e diametro massimo + sMilling = WM.FindMilling( sMillType, nil, nil, nil, 2 * dMinRad) + if not sMilling then + local sErr = 'Radius too small : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile e l'angolo di spoglia + local dToolDiam = 100 + local dMaxMat = 30 + local dSideAng = 0 + local bCW = true + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + dToolDiam = max( dToolDiam, 10) + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- verifico che la profondità non superi il massimo materiale dell'utensile + if dAltMort > dMaxMat + 10 * GEO.EPS_SMALL then + local sErr = 'Error : DtMortise Depth bigger than Tool Cutting edge' + EgtOutLog( sErr) + return false, sErr + end + -- se con tasca, la lavoro + if bPocket then + -- recupero il contorno della tasca (seconda curva ausiliaria) + local sVal = EgtGetInfo( Proc.Id, 'AUXID') + local vsAuxId = EgtSplitString( sVal) + local Aux2Id + if vsAuxId and #vsAuxId >=2 then + Aux2Id = tonumber( vsAuxId[2]) + end + if Aux2Id then Aux2Id = Aux2Id + Proc.Id end + if not Aux2Id or ( EgtGetType( Aux2Id) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Missing pocket geometry : Error on DtMortise ' .. tostring( Proc.Id) + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sPocketing + if Proc.Prc ~= 53 then + sPocketing = WM.FindPocketing( 'Mortise', dToolDiam) + end + if not sPocketing then + sPocketing = WM.FindPocketing( 'Pocket', dToolDiam) + end + if not sPocketing then + local sErr = 'Error : Mortise or Pocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di svuotatura + local sName = 'DtMtPck_' .. ( 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( {{ Aux2Id, -1}}) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- verifico se necessarie più passate (distanza all'imbocco ortogonale all'asse) + local vtDiff = EgtEP( AuxId, GDB_RT.GLOB) - EgtSP( AuxId, GDB_RT.GLOB) + local vtAx = EgtEV( AuxId, GDB_RT.GLOB) - EgtSV( AuxId, GDB_RT.GLOB) + vtAx:normalize() + local vtOrtDiff = vtDiff - vtDiff * vtAx * vtAx + local dDist = vtOrtDiff:len() + -- calcolo le passate + local nPass = ceil( dDist / ( 1.9 * dToolDiam)) + local dStep = ( dDist - 0.95 * dToolDiam) / ( 2 * nPass) + for i = nPass, 1, -1 do + -- inserisco la lavorazione di contornatura + local sNameF = 'DtMt_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nPass) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto offset + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- sistemo il lato e la direzione di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bCW, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, false, true)) + -- dichiaro non si generano sfridi per VMill + local sUserNotes = 'MaxElev='.. EgtNumToString( dMaxMat - 0.1, 1) .. '; VMRS=0;' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return WPDM diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessFreeContour.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessFreeContour.lua new file mode 100644 index 0000000..2b65d7f --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessFreeContour.lua @@ -0,0 +1,2473 @@ +-- ProcessFreeContour.lua by Egaltech s.r.l. 2022/04/04 +-- Gestione calcolo profilo libero per Pareti +-- 2021/11/15 Penna e chiodature sono sempre riportate sulla faccia sopra anche se nel progetto sono sotto. +-- 2021/12/10 In taglio con lama aggiunta gestione SCC per testa Gearbox. +-- 2022/01/13 Aggiunta gestione massimo affondamento in Z anche per pulizia spigoli con fresa 60deg (WD.MAX_CLEAN_CRN60). +-- 2022/02/03 Corretto controllo massimo affondamento nella tavola. +-- 2022/02/21 Corretti allungamenti/accorciamenti tagli inclinati con fresa. Migliorata gestione tagli trasversali per macchine travi. +-- 2022/03/14 Corretto riconoscimento lato esterno per percorsi aperti. +-- 2022/03/16 Ulteriore modifica per riconoscimento lato esterno (aggiunto uso vExtr a GetFacesExternalSide). +-- 2022/04/03 Correzioni e modifiche per pulitura spigoli tipo 2 e 3. +-- 2022/04/19 Aggiunta passibilita' fresatura ad affondamento ridotto quando non possibile completa o sega a catena. + +-- Tabella per definizione modulo +local WPF = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') + +EgtOutLog( ' WProcessFreeContour started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') +if WD.CHECK_MIN_Z_SAW == nil then WD.CHECK_MIN_Z_SAW = true end +if not WD.MIN_Z_SAW then WD.MIN_Z_SAW = 0 end +if not WD.MAX_CLEAN_CRN60 then WD.MAX_CLEAN_CRN60 = 150 end +if not WD.MAX_CLEAN_CRN30 then WD.MAX_CLEAN_CRN30 = 68 end +local WHISK_OFFS = 0.1 +local WHISK_SAFE = 5 +local MIN_LEN_CUT = 250 + +-- variabili assegnazione parametri Q +local sTypeCornerCut = 'Q05' -- i +-- variabile settaggio doppia lavorazione su angoo > 90 +local bMakeTwinCut = true +-- variabile per valore sfondamento spigolo +local dExtraCorner = 1 +-- angolo sottosquadra ammesso per fresa cono 30° +local dAngleSmall = 70 + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPF.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 WPF.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) + -- recupero il tipo di lavorazione + local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0 + -- se tasca + if bPocket then + local bDown = ( vtN:getZ() < - 0.5) + return not bDown + -- se altrimenti profilo orizzontale + elseif abs( vtN:getZ()) < 0.5 then + return false + -- se penna o chiodatura va sempre bene (vengono sempre riportati sopra) + elseif nCntType == 10 or nCntType == 20 then + return true + -- 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 + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPF.FlipClassify( Proc, b3Raw) + local nFlip0 = 0 + local nFlip1 = 0 + + -- verifico se di tipo pocket + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- recupero la curva associata se esiste + 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) + local dVtNZ = vtN:getZ() + -- se tasca + if bPocket then + -- verifico se è lavorabile da sopra + nFlip0 = EgtIf( dVtNZ < -0.5, 0, 100) + -- verifico se e' lavorabile da fliped: cambio segno al versore + nFlip1 = EgtIf( -dVtNZ < -0.5, 0, 100) + + -- se altrimenti profilo orizzontale + elseif abs( dVtNZ) < WD.NZ_MINA then + return 0, 0 + -- se altrimenti profilo verticale che non interessa tutta la sezione + elseif Proc.Box:getMax():getZ() < b3Raw:getMax():getZ() - 2 then + return 0 , 0 + -- altrimenti è profilo verticale che interessa tutta la sezione + else + local dVtNZMedia = 0 + for i = 1, Proc.Fct do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT) + dVtNZMedia = dVtNZMedia + vtN:getZ() + end + dVtNZMedia = dVtNZMedia / Proc.Fct + if abs( dVtNZMedia) <= GEO.EPS_SMALL then + nFlip0 = 100 + nFlip1 = 100 + elseif dVtNZMedia >= 0 + GEO.EPS_SMALL then + nFlip0 = 75 + nFlip1 = 50 + else + nFlip0 = 50 + nFlip1 = 75 + end + end + return nFlip0, nFlip1 +end + +--------------------------------------------------------------------- +local function TestElleShape3( nIdGeom, nNumFacet) + -- valida solo nel caso di tre facce + if nNumFacet ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +local function TestElleShape4( nIdGeom, nNumFacet) + -- valida solo nel caso di quattro facce + if nNumFacet ~= 4 then return false end + -- determino se L con due facce terminali o O + local nFac3Adj = 0 + local dMinArea3 = GEO.INFINITO * GEO.INFINITO + local dMaxArea2 = 0 + for i = 1, 4 do + local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( nIdGeom, i - 1, GDB_ID.ROOT) + local dArea = dH * dV + if nCount == 2 then + dMaxArea2 = max( dMaxArea2, dArea) + elseif nCount == 3 then + dMinArea3 = min( dMinArea3, dArea) + nFac3Adj = nFac3Adj + 1 + end + end + if nFac3Adj ~= 2 then return false end + -- verifico se L profonda oppure lunga + if dMinArea3 < dMaxArea2 then + return 1 + else + return 2 + end +end + +--------------------------------------------------------------------- +local function VerifyCornerType( Proc) + -- Verifico il tipo di lavorazione su angolo : + -- 0 : niente + -- 1 : ripresa corner dopo pausa per rimozione sfridi (fresa 60deg) + -- 2 : ripresa corner senza pausa (fresa 30 deg) + -- 3 : scarico corner (tipo foro). + local nVal = EgtGetInfo( Proc.Id, sTypeCornerCut, 'i') + return ( nVal or 0) +end + +--------------------------------------------------------------------- +local function IsPointOnRawLongEdges( ptCen, b3Raw) + return ( abs( ptCen:getY() - b3Raw:getMin():getY()) < 0.1 or abs( ptCen:getY() - b3Raw:getMax():getY()) < 0.1) +end + +--------------------------------------------------------------------- +local function GetOtherRegions( nPartId) + local vOthers = {} + -- ciclo sui pezzi + local nOtherId = EgtGetFirstPartInRawPart( EgtGetFirstRawPart() or GDB_ID.NULL) + while nOtherId do + -- cerco le regioni marcate + local nCount = 0 + local nRegId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nOtherId, 'Outline') or GDB_ID.NULL) + while nRegId do + local vtN = EgtSurfFrNormVersor( nRegId, GDB_ID.ROOT) + if EgtExistsInfo( nRegId, 'REGION') and vtN and AreSameVectorApprox( vtN, Z_AX()) then + local b3Reg = EgtGetBBoxGlob( nRegId, GDB_BB.STANDARD) + if b3Reg then + nCount = nCount + 1 + table.insert( vOthers, { PartId = nOtherId, RegId = nRegId, Box = b3Reg}) + end + end + nRegId = EgtGetNext( nRegId) + end + -- se non trovate regioni marcate, cerco regioni con la normale corretta + if nCount == 0 then + local nRegId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nOtherId, 'Outline') or GDB_ID.NULL) + while nRegId do + local vtN = EgtSurfFrNormVersor( nRegId, GDB_ID.ROOT) + if EgtGetType( nRegId) == GDB_TY.SRF_FRGN and vtN and AreSameVectorApprox( vtN, Z_AX()) then + local b3Reg = EgtGetBBoxGlob( nRegId, GDB_BB.STANDARD) + if b3Reg then + table.insert( vOthers, { PartId = nOtherId, RegId = nRegId, Box = b3Reg}) + end + end + nRegId = EgtGetNext( nRegId) + end + end + -- passo al pezzo successivo + nOtherId = EgtGetNextPartInRawPart( nOtherId) + end + return vOthers +end + +--------------------------------------------------------------------- +local function ReorderFaces( nIdSurf, nNumFacet) + -- recupero le adiacenze di tutte le facce + local vAdj = {} + for i = 1, nNumFacet do + -- recupero le adiacenze della faccia + local vFacAdj = EgtSurfTmFacetAdjacencies( nIdSurf, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + vAdj[i] = nCount + end + -- sposto le facce isolate alla fine + for i = #vAdj, 1, -1 do + if vAdj[i] == 0 then + if vAdj[#vAdj] == 0 then + table.remove( vAdj, i) + end + EgtSurfTmSwapFacets( nIdSurf, i - 1, #vAdj) + end + end + -- se facce tutte isolate, esco + if #vAdj == 0 then return end + -- cerco la faccia non isolata con il minor numero di adiacenze + local nIdFace + local nAdjMin = 1000 + for i = 1, #vAdj do + if vAdj[i] < nAdjMin then + nAdjMin = vAdj[i] + nIdFace = i + end + end + -- se la faccia non isolata con minori adiacenze non è in prima posizione, eseguo scambio + if nIdFace and nIdFace ~= 1 and nAdjMin == 1 then + EgtSurfTmSwapFacets( nIdSurf, nIdFace-1, 0) + end + -- ordino le facce in modo da avere una sequenza di facce concatenate + for i = 1, #vAdj - 1 do + -- recupero l'angolo con la faccia precedente + local bAdj, _, _, _ = EgtSurfTmFacetsContact( nIdSurf, i-1, i, GDB_ID.ROOT) + -- se non ho adiacenza + if not bAdj then + for j = i+1, #vAdj do + bAdj, _, _, _ = EgtSurfTmFacetsContact( nIdSurf, i-1, j-1, GDB_ID.ROOT) + -- se ho adiacenza scambio le facce + if bAdj then + EgtSurfTmSwapFacets( nIdSurf, i, (j-1)) + break + end + end + end + end +end + +--------------------------------------------------------------------- +local function RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFaceToDel) + -- copio la superfice nel gruppo ausiliario + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + EgtSurfTmRemoveFacet( nNewProc, nFaceToDel) + local nNumFacet = EgtSurfTmFacetCount( nNewProc) + ReorderFaces( nNewProc, nNumFacet) + return nNewProc, nNumFacet +end + + +--------------------------------------------------------------------- +local function GetFacesExternalSide( Proc, vtExtr) + -- 3=sinistra, 4=destra + -- se meno di due facce considero esterno come dichiarato dal gruppo + local nNumFacet = EgtSurfTmFacetCount( Proc.Id) + if nNumFacet < 2 then return Proc.Grp end + -- se facce isolate, considero esterno come dichiarato dal gruppo + local bAdj, ptV1, ptV2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if not bAdj then return Proc.Grp end + -- calcolo dell'esterno rispetto all'avanzamento + local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local ptV = ( ptV1 + ptV2) / 2 + local vtDir1 = ptV - ptC1 + if ( vtN1 ^ vtDir1) * vtExtr > 0 then + return 4 + else + return 3 + end +end + +--------------------------------------------------------------------- +local function GetFacesData( Proc, bOpposite, bCalclForBlade, dToolDiam, dToolMaxDepth, dToolThick, nAddGrpId, b3Raw, nMasterNewProc) + --se richiesto, copio la superficie nel gruppo ausiliario + local nNewProc + if nMasterNewProc then + nNewProc = nMasterNewProc + else + nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + end + -- recupero i dati di tutte le facce + local vFace = {} + local nNumFacet = EgtSurfTmFacetCount( nNewProc) + for i = 1, nNumFacet do + -- indice faccia corrente e precedente + local nFac = EgtIf( bOpposite, nNumFacet - i, i - 1) + local nPrecFac + if bOpposite then + if nNumFacet > 2 then + nPrecFac = EgtIf( i == 1, 0, nFac + 1) + else + nPrecFac = EgtIf( i == 1, -1, nFac + 1) + end + else + if nNumFacet > 2 then + nPrecFac = EgtIf( i == 1, nNumFacet - 1, i - 2) + else + nPrecFac = EgtIf( i == 1, - 1, i - 2) + end + end + -- recupero centro e normale della faccia + local vtN = EgtSurfTmFacetNormVersor( nNewProc, nFac, GDB_ID.ROOT) + -- recupero le dimensioni della faccia + local frHV, dLen, dWidth = WL.GetFaceHvRefDim( nNewProc, nFac) + -- recupero l'angolo con la faccia precedente + local bAdj, ptLocP1, ptLocP2, dAng = EgtSurfTmFacetsContact( nNewProc, nPrecFac, nFac, GDB_ID.ROOT) + local dPrevAng = EgtIf( bAdj, dAng, 0) + -- se angolo con faccia precedente negativo, calcolo anche angolo tra le facce nel piano + local dPlanePrevAng = 0 + if dPrevAng < 0 then + local vtPrevN = EgtSurfTmFacetNormVersor( nNewProc, nPrecFac, GDB_ID.ROOT) + local dCosA = ( Z_AX() ^ vtPrevN) * ( Z_AX() ^ vtN) + dPlanePrevAng = -acos( dCosA) + end + -- calcolo l'angolo di inclinazione (dalla verticale) + local dSideAng = asin( vtN:getZ()) + -- salvo i dati + vFace[i] = { Fac = nFac, Cen = frHV:getOrigin(), Norm = vtN, Len = dLen, Width = dWidth, PrevAng = dPrevAng, PlPrevAng = dPlanePrevAng, SideAng = dSideAng} + if bAdj then + if ptLocP1:getZ() < ptLocP2:getZ() then + vFace[i].PPrev = ptLocP1 + else + vFace[i].PPrev = ptLocP2 + end + end + end + -- analizzo le facce + local dMaxWidth = 0 + for i = 1, #vFace do + -- aggiorno la massima larghezza + if vFace[i].Width > dMaxWidth then + dMaxWidth = vFace[i].Width + end + -- verifico l'affondamento + local dDepth = WD.CUT_EXTRA + if vFace[i].Width + WD.CUT_EXTRA > dToolMaxDepth then + dDepth = dToolMaxDepth - vFace[i].Width + end + -- lunghezza baffo + local dElev = vFace[i].Width + dDepth + local dWhisk = EgtIf( bCalclForBlade, ( dElev * sqrt( dToolDiam / dElev - 1) + WHISK_SAFE) , (dToolDiam/2) + WHISK_SAFE) + -- determino la lunghezza del taglio passante e il tipo di attacco e uscita + local dLen = vFace[i].Len + local dLenY = dLen * abs( vFace[i].Norm:getX()) / sqrt( 1 - vFace[i].Norm:getZ() * vFace[i].Norm:getZ()) + local nType = 0 + if vFace[i].PrevAng < -0.1 or + ( WD.BEAM_MACHINE and not IsPointOnRawLongEdges( vFace[i].Cen, b3Raw) and ( dLen > 0.5 * WD.CUT_MAX_LENGTH or dLenY > 0.4 * b3Raw:getDimY())) then + dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0) + nType = nType + 1 + end + if vFace[EgtIf( i < nNumFacet, i + 1, 1)].PrevAng < -0.1 or + ( WD.BEAM_MACHINE and not IsPointOnRawLongEdges( vFace[i].Cen, b3Raw) and ( dLen > 0.5 * WD.CUT_MAX_LENGTH or dLenY > 0.4 * b3Raw:getDimY())) then + dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0) + nType = nType + 2 + end + -- se lunghezza non significativa, non va inserito il taglio + if dLen < MIN_LEN_CUT then + nType = 4 + end + -- numero dei lati + local nEdges = #(EgtSurfTmFacetAdjacencies( nNewProc, i - 1)[1]) + -- assegno i nuovi dati + vFace[i].Depth = dDepth + vFace[i].Whisk = dWhisk + vFace[i].Type = nType + vFace[i].Edges = nEdges + end + -- recupero le regioni degli altri pezzi + local vOthers = GetOtherRegions( Proc.PartId) + -- verifico i baffi sporgenti dei tagli rispetto alle altre regioni + for i = 1, #vFace do + -- verifico il baffo iniziale + if vFace[i].Type ~= 4 and ( vFace[i].Type & 1) == 0 then + -- creo il rettangolo del baffo + local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize() + local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), -90) + local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, -90) + local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt + local ptDir = ptIni + ( vFace[i].Whisk - 2 * WHISK_OFFS) * vtDir + local ptCross = ptDir + ( dToolThick - 2 * WHISK_OFFS) * vtOrt + local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB) + local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD) + -- verifico se interferisce con gli altri pezzi + for j = 1, #vOthers do + if OverlapsXY( b3Wh, vOthers[j].Box) then + local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0) + if nClass ~= GDB_RC.OUT then + local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 2) ~= 0, -vFace[i].Whisk, 0) + if dLen >= MIN_LEN_CUT then + vFace[i].Type = vFace[i].Type + 1 + else + vFace[i].Type = 4 + end + break + end + end + end + EgtErase( WhId) + end + -- verifico il baffo finale + if vFace[i].Type ~= 4 and ( vFace[i].Type & 2) == 0 then + -- creo il rettangolo del baffo + local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize() + local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), 90) + local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, 90) + local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt + local ptDir = ptIni + ( vFace[i].Whisk - 2 * WHISK_OFFS) * vtDir + local ptCross = ptDir + ( dToolThick - 2 * WHISK_OFFS) * vtOrt + local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB) + local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD) + -- verifico se interferisce con gli altri pezzi + for j = 1, #vOthers do + if OverlapsXY( b3Wh, vOthers[j].Box) then + local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0) + if nClass ~= GDB_RC.OUT then + local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 1) ~= 0, -vFace[i].Whisk, 0) + if dLen >= MIN_LEN_CUT then + vFace[i].Type = vFace[i].Type + 2 + else + vFace[i].Type = 4 + end + break + end + end + end + EgtErase( WhId) + end + end + -- se ciclo chiuso + if abs( vFace[1].PrevAng) > 0.1 then + -- verifico se c'è un solo tipo 3 e nessun tipo 0, 1 o 2 + local nInd3 + local nTot3 = 0 + local nTot012 = 0 + for i = 1, #vFace do + local Face = vFace[i] + if Face.Type == 0 or Face.Type == 1 or Face.Type == 2 then + nTot012 = nTot012 + 1 + elseif Face.Type == 3 then + nTot3 = nTot3 + 1 + nInd3 = i + end + end + -- se trovato il caso, trasformo il 3 in 4 (per evitare problemi con fresature con la stessa faccia a inizio e fine) + if nTot3 == 1 and nTot012 == 0 then + vFace[nInd3].Type = 4 + end + end + + -- eventuali stampe + for i = 1, #vFace do + local Face = vFace[i] + local sOut = 'Face '..tostring( Face.Fac)..' C'..tostring( Face.Cen)..' N'..tostring( Face.Norm).. + ' L='..EgtNumToString( Face.Len, 1)..' W='..EgtNumToString( Face.Width, 1)..' Ap='..EgtNumToString( Face.PrevAng, 1).. + ' App='..EgtNumToString( Face.PlPrevAng, 1)..' D='..EgtNumToString( Face.Depth, 1)..' B='..EgtNumToString( Face.Whisk, 1).. + ' As='..EgtNumToString( Face.SideAng, 1)..' T='..tostring( Face.Type)..' E='..tostring( Face.Edges) + EgtOutLog( sOut) + end + + return vFace, dMaxWidth, nNewProc +end + +--------------------------------------------------------------------- +local function GetTunnelDimension( nId, nPartId, nAddGrpId) + -- ottengo i versori delle 4 facce e ottengo l'orientamento del tunnel + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- variabili dimensioni fessura e id faccia lunga + local dDimMin + local dDimMax + local nLongIdFace = 0 + local bNegFace + local bOppoFace = false + -- ottengo il versore ortogonale + local ptN1, vtN1 = EgtSurfTmFacetCenter( nId, 0, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( nId, 1, GDB_ID.ROOT) + local vtOrtho = vtN1 ^ vtN2 + if vtOrtho:isSmall() then + _, vtN2 = EgtSurfTmFacetCenter( nId, 2, GDB_ID.ROOT) + vtOrtho = vtN1 ^ vtN2 + bOppoFace = true + end + vtOrtho:normalize() + if vtOrtho:getZ() < -0.5 then + vtOrtho = -vtOrtho + bNegFace = true + end + -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta la profondità della fessura + local frFc = Frame3d( ptN1, vtOrtho) ; + local bBoxLoc = EgtGetBBoxRef( nId, GDB_BB.STANDARD, frFc) + local dDepth = bBoxLoc:getDimZ() + -- mi assicuro che la Z del punto utilizzato per creare la superficie sia alla Z inferiore del bounding box locale + local ptN2 = Point3d(ptN1) + ptN2:toLoc(frFc) + ptN2 = Point3d( ptN2:getX(), ptN2:getY(), bBoxLoc:getMin():getZ() + 2*GEO.EPS_SMALL) + ptN2:toGlob(frFc) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN2, vtOrtho, b3Solid, GDB_ID.ROOT) + if not nSurfInt then return end + -- ritaglio la superficie con le facce della fessura + for i = 1, nFacCnt do + local ptN, vtN = EgtSurfTmFacetCenter( nId, i - 1, GDB_ID.ROOT) + EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) + end + -- sposto la geometria trovata sulla Z minima (era su di 2 * GEO.EPS_SMALL) + EgtMove( nSurfInt, Point3d(0,0,-2*GEO.EPS_SMALL) - ORIG(), GDB_RT.GLOB) + -- mi faccio dare il contorno della superfice e la ricreo in modo più corretto + local nIdCont, nIdNum = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) + if not nIdCont then return end + -- elimino le entità allineate dello stesso tipo + EgtMergeCurvesInCurveCompo( nIdCont, 2*GEO.EPS_SMALL) + EgtErase(nSurfInt) + nSurfInt = EgtSurfTmByFlatContour( nAddGrpId, nIdCont, 2*GEO.EPS_SMALL) + -- elimino il contorno + EgtErase(nIdCont) + -- se normale negativa inverto + _, vtN1 = EgtSurfTmFacetCenter( nSurfInt, 0, GDB_ID.ROOT) + if vtN1:getZ() < -0.5 then EgtInvertSurf( nSurfInt) end + local _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT) + dDimMin = min( DimH, DimV) + dDimMax = max( DimH, DimV) + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nId, nFacCnt-1, GDB_ID.ROOT) + -- se faccia pari alla larghezza fessura + if abs(DimH - dDimMax) < GEO.EPS_SMALL or abs(DimV - dDimMax) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + -- altrimenti verifico anche con la faccia precedente + else + local nFaceToCheck = EgtIf( bOppoFace, nFacCnt-3, nFacCnt-2) + -- prendo le dimensioni della faccia e poi confronto con il minimo + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nId, nFaceToCheck, GDB_ID.ROOT) + -- se trovato con il minimo, questa seconda faccia non è la più lunga + if abs(DimH - dDimMin) < GEO.EPS_SMALL or abs(DimV - dDimMin) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + else + nLongIdFace = nFaceToCheck + end + end + if not dDimMax then + return dDimMin, dDimMax, dDepth, nil, nil + end + return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt +end + +--------------------------------------------------------------------- +local function ReorderFacesFromTab( nIdSurf, vFace) + + local nFacCnt = EgtSurfTmFacetCount( nIdSurf) + for i = 1, #vFace do + for j = 1, nFacCnt do + -- ottengo punto iniziale e versore della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nIdSurf, (j-1), GDB_ID.ROOT) + -- se versore e posizione coincidono e non corrispondono al numero faccia, faccio lo swap + if AreSameVectorExact( vFace[i].Norm, vtN) and AreSamePointEpsilon( vFace[i].Cen, ptC, 50*GEO.EPS_SMALL) then + if (j-1) ~= vFace[i].Fac then + EgtSurfTmSwapFacets( nIdSurf, vFace[i].Fac, (j-1)) + end + break + end + end + end + return nIdSurf +end + +--------------------------------------------------------------------- +local function MakeCustomPath( vGeom, nConeCut, dMillDiam, nAddGrpId, dThick, bClosed) + + local nPath = {} + local nPathData = {} + + for i = 1, #vGeom do + local dAng + -- ottengo curva inferiore 1 + local ptP1, ptP2, ptP3, vtV1, vtV2, dDim1, dDim2 = EgtSurfTmFacetOppositeSide( vGeom[i][1], vGeom[i][2], Z_AX() , GDB_ID.ROOT) + if i < #vGeom then + -- ricavo i punti e l'angolo interno + _, _, _, dAng = EgtSurfTmFacetsContact( vGeom[i][1], vGeom[i][2], vGeom[i+1][2], GDB_ID.ROOT) + elseif bClosed then + -- ricavo i punti e l'angolo interno + _, _, _, dAng = EgtSurfTmFacetsContact( vGeom[i][1], vGeom[i][2], vGeom[1][2], GDB_ID.ROOT) + else + dAng = 0 + end + -- creo linea + local nId1 = EgtLine( nAddGrpId, ptP1, ptP3, GDB_RT.GLOB) + table.insert( nPath, nId1) + table.insert( nPathData, {nId1, dAng}) + end + + -- creo il percorso e poi lo offsetto del raggio utensile + local AuxId = EgtCurveCompo( nAddGrpId, nPath, true) + EgtOffsetCurve( AuxId, dMillDiam / 2, GDB_OT.EXTEND) + -- spezzo il percorso nelle entità componenti + local nId1st, nIdCount = EgtExplodeCurveCompo( AuxId) + -- se il numero entità è diverso da quelle iniziali esco con errore + if nIdCount ~= #vGeom then + local sErr = 'Error : cannot make offset path' + return 0, sErr + end + -- resetto la tabella + nPath = {} + AuxId = nil + -- in base al tipo di ripresa spigolo modifico il percorso + if nConeCut == 2 then + -- acquisisco la lunghezza utensile + sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner30') + if not sMilling then + local sErr = 'Error : CleanCorner 30 not found in library' + return 0, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMillLength = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMillLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dMillLength + end + end + -- calcolo la lunghezza della linea da inserire in base all'angolo e alla lunghezza utensile + local dLenAdd = abs(( dMillLength * sin( 33)) - ( dMillDiam / 2)) + -- per ogni entità compongo la nuova lista per creare percorso + for i = 1, nIdCount do + -- aggiungo linea precedente + table.insert( nPath, ( nId1st + i - 1)) + -- se non è la linea finale e l'angolo tra le due facce è ammesso + if ( i < nIdCount or bClosed) and dThick <= ( WD.MAX_CLEAN_CRN30 + 20 * GEO.EPS_SMALL) and + nPathData[i][2] < 0 and nPathData[i][2] > -( 180 - dAngleSmall + 10 * GEO.EPS_SMALL) then + -- aggiungo una retta sulla bisettrice + local _, vtN2 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[i][2], GDB_ID.ROOT) + local _, vtN3 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[EgtIf( i == nIdCount, 1, i+1)][2], GDB_ID.ROOT) + local ptP1 = EgtEP( ( nId1st + i - 1), GDB_ID.ROOT) + -- sommo i tre versori per avere una direzione media + local vtExtrExit = vtN2 + vtN3 + vtExtrExit:normalize() + -- linea intermedia (componente lunghezza utensile in direzione bisettrice) + local pEnd = ptP1 + ( dLenAdd * vtExtrExit) + nAuxId = EgtLine( nAddGrpId, ptP1, pEnd, GDB_RT.GLOB) + table.insert( nPath, nAuxId) + -- linea di ritorno + nAuxId = EgtLine( nAddGrpId, pEnd, ptP1, GDB_RT.GLOB) + table.insert( nPath, nAuxId) + end + end + -- ricreo il percorso + AuxId = EgtCurveCompo( nAddGrpId, nPath, true) + -- altrimenti sfondo spigolo + elseif nConeCut == 3 then + -- per ogni entità compongo la nuova lista per creare percorso + for i = 1, nIdCount do + -- aggiungo linea precedente + table.insert( nPath, ( nId1st + i - 1)) + -- se non è la linea finale e l'angolo tra le due facce è ammesso + if ( i < nIdCount or bClosed) and nPathData[i][2] < 0 then + -- aggiungo una retta sulla bisettrice + local _, vtN2 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[i][2], GDB_ID.ROOT) + local _, vtN3 = EgtSurfTmFacetCenter( vGeom[i][1], vGeom[EgtIf( i == nIdCount, 1, i+1)][2], GDB_ID.ROOT) + local ptP1 = EgtEP( ( nId1st + i - 1), GDB_ID.ROOT) + -- sommo i tre versori per avere una direzione media + local vtExtrExit = vtN2 + vtN3 + vtExtrExit:normalize() + vtExtrExit = -vtExtrExit + -- calcolo di quanto entrare + local dLenAdd = abs( (dMillDiam/2) / cos( nPathData[i][2]/2)) + dExtraCorner - (dMillDiam/2) + -- linea intermedia (componente lunghezza utensile in direzione bisettrice) + local pEnd = ptP1 + ( dLenAdd * vtExtrExit) + nAuxId = EgtLine( nAddGrpId, ptP1, pEnd, GDB_RT.GLOB) + table.insert( nPath, nAuxId) + -- linea di ritorno + nAuxId = EgtLine( nAddGrpId, pEnd, ptP1, GDB_RT.GLOB) + table.insert( nPath, nAuxId) + end + end + -- ricreo il percorso + AuxId = EgtCurveCompo( nAddGrpId, nPath, true) + end + if not AuxId then + local sErr = 'Error : Impossibe make custom machining path' + return 0, sErr + end + + return AuxId +end + +--------------------------------------------------------------------- +local function CalcInterference( nNewProc, vtExtr, ptCentr, dDiam1, dDiam2, + dTall1, dTall2, dDiam3, dTall3) + + local ptCentrGrid1 = ptCentr + ( vtExtr * 0.01) + local frOriTool = Frame3d( ptCentrGrid1, vtExtr) + local bColl1 = EgtCDeConeSolid( frOriTool, dDiam1/2, dDiam2/2, dTall1, nNewProc, 0, GDB_RT.GLOB) + if bColl1 then return true end + local ptCentrGrid2 = ptCentr + ( vtExtr * ( dTall1 + 0.01)) + frOriTool = Frame3d( ptCentrGrid2, vtExtr) + local bColl2 = EgtCDeCylSolid( frOriTool, dDiam2/2, (dTall2-dTall1), nNewProc, 0, GDB_RT.GLOB) + if bColl2 then return true end + local ptCentrGrid3 = ptCentr + ( vtExtr * ( dTall2 + 0.01)) + frOriTool = Frame3d( ptCentrGrid3, vtExtr) + local bColl3 = EgtCDeCylSolid( frOriTool, dDiam3/2, (dTall3-dTall2), nNewProc, 0, GDB_RT.GLOB) + if bColl3 then return true end + -- restituisco risultato controllo collisioni + return false +end + +--------------------------------------------------------------------- +local function MakeLocalSurf( ptP1, ptP2, ptP3, nAddGrpId) + + if not ptP1 or not ptP2 or not ptP3 then + return nil + end + + local pAuxId = {} + local nAuxId, AuxId + nAuxId = EgtLine( nAddGrpId, ptP1, ptP2, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + nAuxId = EgtLine( nAddGrpId, ptP2, ptP3, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + nAuxId = EgtLine( nAddGrpId, ptP3, ptP1, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- trasformo in percorso + if #pAuxId ~= 3 then + return nil + end + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + -- se non c'é il percorso esco + if not AuxId then + return nil + end + -- creo la superfice piana + local nidFace = EgtSurfTmByFlatContour( nAddGrpId, AuxId, 0.01) + if not nidFace then + EgtErase(AuxId) + return nil + end + -- se normale negativa inverto + local _, vtN1 = EgtSurfTmFacetCenter( nidFace, 0, GDB_ID.ROOT) + if vtN1:getZ() < -0.5 then EgtInvertSurf( nidFace) end + + EgtErase(AuxId) + return nidFace +end + +--------------------------------------------------------------------- +local function AddMillCornerMachining( nPartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, dOffsAng, dDepthMach, + bThruThick, dThSurf, dDiam1, dDiam2, dTall1, + dTall2, dDiam3, dTall3, bMakeLocSurf, vFace) + -- variabili costruzione geometria + local pAuxId = {} + local nAuxId + local ptApPoint + local AuxId + local nNewProcLoc + -- se devo creare superfice locale + if bMakeLocSurf then + -- creo superfice locale o esco + local nSurfToAdd = MakeLocalSurf( tFacAdj[1][7], tFacAdj[1][8], tFacAdj[1][9], nAddGrpId) + if nSurfToAdd then + local nFacCntPre = EgtSurfTmFacetCount( nNewProc) + -- creo copia del percorso principale e gli aggiungo la nuova faccia + nNewProcLoc = EgtCopyGlob( nNewProc, nAddGrpId) + nNewProcLoc = EgtSurfTmBySewing( nAddGrpId, {nNewProcLoc,nSurfToAdd} , true) + -- riordino le facce + ReorderFacesFromTab( nNewProcLoc, vFace) + -- acquisisco il numero della faccia + nFacCnt = EgtSurfTmFacetCount( nNewProcLoc) + nFacInd = nFacCnt - 1 + else + return true, '' + end + else + nNewProcLoc = nNewProc + end + -- prendo il primo versore + local _, vtN1 = EgtSurfTmFacetCenter( nNewProcLoc, nFacInd, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1][1], GDB_ID.ROOT) + local _, vtN3 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1][2], GDB_ID.ROOT) + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1][1], GDB_ID.ROOT) + local _, ptLocP3, ptLocP4, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1][2], GDB_ID.ROOT) + -- se ho creato faccia locale su copia superficie, cancella la copia + if bMakeLocSurf then + EgtErase( nNewProcLoc) + end + local nIdIniPoint + local nIdEndPoint + if ptLocP1 and ptLocP2 then + if ( dist( ptLocP1, tFacAdj[1][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[1][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptLocP1, tFacAdj[1][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[1][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- versore direzione + local vtExtr = tFacAdj[1][nIdIniPoint] - tFacAdj[1][nIdEndPoint] + vtExtr:normalize() + -- versore direzione di uscita + local vtExtrExit + -- inserisco le prime tre linee + if nIdIniPoint and nIdEndPoint then + -- se fresatura da sotto salto la lavorazione + if vtExtr:getZ() < WD.DRILL_VZ_MIN then + local sErr = 'Error : Impossible insert clean corner from bottom' + EgtOutLog( sErr) + return false, sErr + end + -- sommo i tre versori per avere una direzione media + vtExtrExit = vtN2 + vtN3 + vtExtrExit:normalize() + -- se tipo 1 calcolo angolo tilt di 45° + if nTypeConeCut == 1 then + vtExtr = vtExtrExit + Z_AX() + -- altrimenti tipo 2, calcolo angolo tilt di 33° (dalla verticale) + else + vtExtr = vtExtrExit + Vector3d(0,0,1.539865) + end + vtExtr:normalize() + local vtCheck = Vector3d(vtExtr) + -- se ho un offset angolare ruoto il percorso + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + vtCheck:rotate( Z_AX(), dOffsAng) + end + -- controllo se c'è collisione con le facce della superfice + if nTypeConeCut == 1 and CalcInterference( nNewProc, vtCheck, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), dDiam1, dDiam2, + dTall1, dTall2, dDiam3, dTall3) then + local sErr = 'Collision detect from clean corner tool and surface' + EgtOutLog( sErr) + return true, '' + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdIniPoint], tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- se uso utensile cono 60° + if nTypeConeCut == 1 then + -- se offset angolare valido e/o negativo creo il baffo precedente + if dOffsAng < ( 100 * GEO.EPS_SMALL) then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[1][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + local dLenTrimExt = dist( tFacAdj[1][nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + Point3d( 0, 0, dDepthMach) + else + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint + Point3d( 0, 0, -dDepthMach), tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + end + end + -- inserisco le ultime tre linee + -- trovo il secondo punto sulla superfice di riferimento + ptLocP1, ptLocP2 = ptLocP3, ptLocP4 + if ptLocP1 and ptLocP2 then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[1][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + -- se uso utensile cono 60° + if nTypeConeCut == 1 then + -- se offset angolare valido e/o negativo creo il baffo precedente + if dOffsAng > -( 100 * GEO.EPS_SMALL) then + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + local dLenTrimExt = dist( tFacAdj[1][nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + Point3d( 0, 0, dDepthMach) + else + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint + Point3d( 0, 0, -dDepthMach), tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- ultima linea di distacco (5mm in direzione utensile) + local pEnd = tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach) + ( 5 * vtExtr) + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + else + -- linea di distacco (2mm in direzione utensile) + local pEnd = tFacAdj[1][nIdEndPoint] + ( 2 * vtExtr) + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint], pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- ultima linea di risalita in Z + local pIni = pEnd + pEnd = pIni + ( dThick * Z_AX()) + nAuxId = EgtLine( nAddGrpId, pIni, pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + end + -- trasformo in percorso + if #pAuxId > 0 then + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + end + -- se non c'é il percorso do errore + if not AuxId then + local sErr = 'Error : impossible make clean corner path' + EgtOutLog( sErr) + return false, sErr + end + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- se ho un offset angolare ruoto il percorso + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( AuxId, tFacAdj[1][nIdEndPoint], Z_AX(), dOffsAng, GDB_RT.GLOB) + end + -- inserisco la lavorazione + local sName = 'Clean_' .. ( EgtGetName( nNewProc) or tostring( nNewProc)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', nPartId) + -- se flag lavorazione spessore passante setto la nota per spostarla dopo i tagli di lama + if bThruThick and nTypeConeCut == 1 then + EgtSetInfo( nMchId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- 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) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4) + -- allungo inizio e fine di 10mm + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- setto affondamento 0 + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione +-- sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( 0.0, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + 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 + end + end + + return true, '' +end + +--------------------------------------------------------------------- +local function AddMillCorner( nTypeConeCut, vFace, Proc, nRawId, b3Raw, + dToolDiam, nAddGrpId, dThick, nMasterNewProc, dDepthMach, + bThruThick) + + local sMilling, dMaxDepth + -- se ripresa angolo con fresa cono 60° con ripresa + if nTypeConeCut == 1 then + -- recupero la lavorazione di fresatura + sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner60') + if not sMilling then + local sErr = 'Error : CleanCorner 60 not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- se ripresa angolo con fresa cono piccola senza ripresa + else + sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner30') + if not sMilling then + local sErr = 'Error : CleanCorner 30 not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMillTotDiam = 20 + local dMillDiamTh = 20 + local dToolLength = 20 + local dThickTool = 20 + local dSideAng = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh + dMillTotDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) or dMillTotDiam + dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dThickTool = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThickTool + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth -- qui è la distanza dal portautensile + -- calcolo il secondo diametro del cono + dMillTotDiam = dMillDiam + ( abs(dThickTool) * tan(dSideAng)) * 2 + end + end + -- copio la feature nel layer di appoggio + local nNewProc + if nMasterNewProc then + nNewProc = nMasterNewProc + else + nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + end + local nFacCnt = EgtSurfTmFacetCount( nNewProc) + local nFacInd, dDimMin, dDimMax, dDepth, nSurfInt + local bMakeLocSurf + if nFacCnt <= 4 then + -- ottengo le dimensioni apertura, la normale e la faccia inferiore + dDimMin, dDimMax, dDepth, _, _, nSurfInt = GetTunnelDimension( nNewProc, Proc.PartId, nAddGrpId) + if nSurfInt then + -- uso la dimensione minima anche nel caso che la cava sborda perchè la lavorazione potrebbe collidere con un pezzo limitrofo + local dMinWidth = dDimMin + nNewProc = EgtSurfTmBySewing( nAddGrpId, {nNewProc,nSurfInt} , true) + -- riordino le facce + ReorderFacesFromTab( nNewProc, vFace) + -- acquisisco il numero della faccia + nFacCnt = EgtSurfTmFacetCount( nNewProc) + nFacInd = nFacCnt - 1 + else + return true + --local sErr = 'Error : cannot create base surface' + --EgtOutLog( sErr) + --return false, sErr + end + else + bMakeLocSurf = true + end + -- verifico se ciclo chiuso + local bClosed = ( abs( vFace[1].PrevAng) > 0.1) + -- ciclo di inserimento delle fresate sulle facce del contorno in esame + local i = 1 + -- se faccia finale con fine non lavorato, forzo partenza da prima faccia non tutta saltata (tipo 4) + if bClosed and ( vFace[#vFace].Type == 4 or ( vFace[#vFace].Type & 2) ~= 0) then + while i <= #vFace and vFace[i].Type == 4 do + i = i + 1 + end + end + -- se facce tutte da saltare, parto dall'inizio + local bAllType4 = ( i > #vFace) + if bAllType4 or bClosed then i = 1 end + while i <= #vFace do + -- se tutta la faccia o la sua fine senza taglio, inserisco una fresatura + if ( vFace[i].Type & 2) ~= 0 or vFace[i].Type == 4 then + -- variabili costruzione geometria + local tFacAdj = {} + local nFace1 = vFace[i].Fac + local nFace2 + -- ricavo i tre punti per eventuale superficie locale + local ptLoc1, ptLoc2, ptLoc3 + -- punto precedente (punto precedente della faccia [i]) + ptLoc3 = vFace[i].PPrev + -- aggiungo geometria + i = i + 1 + local j = EgtIf( i <= #vFace, i, EgtIf( bClosed, 1, nil)) + if not j then + return true + end + nFace2 = vFace[j].Fac + -- punto in comune tra le due facce (punto precedente della faccia [j]) + ptLoc1 = vFace[j].PPrev + -- punto successivo ( precedente della faccia successiva) + j = j + 1 + local k = EgtIf( j <= #vFace, j, EgtIf( bClosed, 1, nil)) + -- se è un percorso aperto prendo il punto medio della seconda faccia come punto locale 2 + if not k then + ptLoc2 = Point3d( vFace[j-1].Cen:getX(), vFace[j-1].Cen:getY(), ptLoc1:getZ()) + else + ptLoc2 = vFace[k].PPrev + end + -- ricavo i punti e l'angolo interno + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( nNewProc, nFace1, nFace2, GDB_ID.ROOT) + -- se punti validi e angolo è interno e non è quasi piatto e >= 90 creo istanza + if ptP1 and ptP2 and dAng < 0 and dAng < -6 and dAng > EgtIf( nTypeConeCut == 1, -(90 + 10 * GEO.EPS_SMALL), -(180-dAngleSmall + 10 * GEO.EPS_SMALL)) then + local dLen = dist( ptP1, ptP2) + table.insert( tFacAdj, { nFace1, nFace2, dLen, ptP1, ptP2, dAng, ptLoc1, ptLoc2, ptLoc3}) + end + -- se ho un elemento creo percorso o percorsi in base al tipo di cono e all'apertura dall'angolo rispetto ai 90° + -- con una tolleranza di 2 gradi + if #tFacAdj > 0 then + if nTypeConeCut == 1 and bMakeTwinCut and (dAng + 90) > 2 then + local dAngOffs = (dAng + 90) / 2 + -- primo taglio + local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, -dAngOffs, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + -- secondo taglio + bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, dAngOffs, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + -- altrimenti ho un solo percorso + else + local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, 0, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + end + end + else + i = i + 1 + end + end + -- cancello la copia della superfice + if nNewProc then + EgtErase( nNewProc) + end + return true +end + +--------------------------------------------------------------------- +local function GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen) + local CosA = abs( vtNz) + if CosA >= 0.05 then + local SinA = sqrt( 1 - CosA * CosA) + local dRad = dDiamTh / 2 + dMillDiam / 2 * EgtIf( vtNz > 0, -1, 1) + local dSlantFreeLen = dFreeLen - ( dRad * CosA / SinA) + return min( dMaxDepth, dSlantFreeLen) + else + return dMaxDepth + end +end + +--------------------------------------------------------------------- +local function AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAddGrpId) + -- flag per fresature non passanti + local bNotThrou + local dThick + local dOriDepth + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local dFreeLen = 0 + local dDiamTh = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dDiamTh = EgtTdbGetCurrToolThDiam() + dFreeLen = EgtTdbGetCurrToolMaxDepth() + dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), dFreeLen) or dMaxDepth + end + end + -- verifico se ciclo chiuso + local bClosed = ( abs( vFace[1].PrevAng) > 0.1) + -- ciclo di inserimento delle fresate sulle facce del contorno in esame + local i = 1 + -- se faccia finale con fine non lavorato, forzo partenza da prima faccia non tutta saltata (tipo 4) + if bClosed and ( ( vFace[#vFace].Type == 4 and vFace[#vFace].Edges > 3) or ( vFace[#vFace].Type & 2) ~= 0) then + while i <= #vFace and vFace[i].Type == 4 and vFace[i].Edges > 3 and abs( vFace[i].SideAng) < 0.1 do + i = i + 1 + end + end + -- se facce tutte da saltare, parto dall'inizio + local bAllType4 = ( i > #vFace) + if bAllType4 then i = 1 end + while i <= #vFace do + -- se inizio faccia senza taglio e non è successiva di senza taglio, inserisco una fresatura + local j = EgtIf( i > 1, i - 1, EgtIf( bClosed, #vFace, nil)) + if ( vFace[i].Type & 1) ~= 0 and ( not j or vFace[j].Type == 0 or vFace[j].Type == 1 or abs( vFace[i].SideAng) > 0.1 or abs( vFace[j].SideAng) > 0.1) then + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return 0, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- calcolo l'affondamento + local dDepth = vFace[i].Width + WD.CUT_EXTRA + dThick = vFace[i].Width + local vtNz = vFace[i].Norm:getZ() + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW) + else + dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz)) + end + end + local dCurrMaxDepth = GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen) + -- se affondamento superiore ai limiti della fresa + if dDepth > dCurrMaxDepth then + dOriDepth = dDepth + -- lo limito e tolgo eventuali Tabs + dDepth = dCurrMaxDepth + EgtSetMachiningParam( MCH_MP.LEAVETAB, false) + bNotThrou = true + end + -- tolgo i Tabs se devo rimuovere lo sfrido + if nConeCut == 1 then EgtSetMachiningParam( MCH_MP.LEAVETAB, false) end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}}) + local dSal = 0 + if #vFace == 1 then dSal = -dMillDiam / 2 end + -- se angolo interno prima + if vFace[i].PrevAng < -30 then + local dSinA = -sin( vFace[i].PlPrevAng + 90) + local dTanA = -tan( vFace[i].PlPrevAng + 90) + dSal = -dMillDiam / 2 * ( 1 + ( 1 + dSinA) * dTanA) + min( 0, vFace[i].Width * vFace[i].Norm:getZ() * dTanA) + -- se faccia precedente inclinata verso il basso + if j and vFace[j].Norm:getZ() < -0.017 then + dSal = dSal + vFace[j].Width * vFace[j].Norm:getZ() + end + -- se angolo esterno prima + elseif vFace[i].PrevAng > 30 then + -- se faccia precedente inclinata verso il basso + if j and vFace[j].Norm:getZ() < -0.017 then + dSal = dSal - vFace[j].Width * vFace[j].Norm:getZ() + end + end + local dEal = vFace[i].Whisk - vFace[i].Len + -- se angolo interno prima e faccia precedente inclinata verso l'alto oltre 16.1deg + if vFace[i].PrevAng < -30 and j and vFace[j].Norm:getZ() < 0.96078 and vFace[j].Norm:getZ() > 0 then + dEal = dEal + vFace[j].Width * vFace[j].Norm:getZ() + end + -- se angolo interno dopo e faccia successiva inclinata verso l'alto oltre 16.1deg + local k = EgtIf( i < #vFace, i + 1, EgtIf( bClosed, 1, nil)) + if k and vFace[k].PrevAng < -30 and vFace[k].Norm:getZ() < 0.96078 and vFace[k].Norm:getZ() > 0 then + dEal = dEal + vFace[k].Width * vFace[k].Norm:getZ() + -- se l'inclinazione è inferiore a 46.1deg + if vFace[k].Norm:getZ() > 0.72055 then + dEal = dEal - vFace[k].Width + end + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if abs( vFace[i].Norm:getZ()) < GEO.EPS_SMALL then + nSCC = EgtIf( abs( vFace[i].Norm:getX()) > abs( vFace[i].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return 0, sErr + end + end + -- se tutta la faccia o la sua fine senza taglio, inserisco una fresatura + if ( vFace[i].Type & 2) ~= 0 or ( vFace[i].Type == 4 and vFace[i].Edges > 3) then + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return 0, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- calcolo l'affondamento + local dDepth = vFace[i].Width + WD.CUT_EXTRA + dThick = vFace[i].Width + local vtNz = vFace[i].Norm:getZ() + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW) + else + dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz)) + end + end + local dCurrMaxDepth = GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen) + -- se affondamento superiore ai limiti della fresa + if dDepth > dCurrMaxDepth then + dOriDepth = dDepth + -- lo limito e tolgo eventuali Tabs + dDepth = dCurrMaxDepth + EgtSetMachiningParam( MCH_MP.LEAVETAB, false) + bNotThrou = true + end + -- tolgo i Tabs se devo rimuovere lo sfrido + if nConeCut == 1 then EgtSetMachiningParam( MCH_MP.LEAVETAB, false) end + -- aggiungo geometria + local vGeom = {{ Proc.Id, vFace[i].Fac}} + local dSal = EgtIf( ( vFace[i].Type & 2) ~= 0, vFace[i].Whisk - vFace[i].Len, 0) + local dEal = 0 + local OrigI = i + local OrigH = j + local LastJ + i = i + 1 + local j = EgtIf( i <= #vFace, i, EgtIf( bAllType4 or not bClosed, nil, 1)) + while j and ( ( vFace[j].Type & 1) ~= 0 or ( vFace[j].Type == 4 and vFace[j].Edges > 3)) and abs( vFace[j].SideAng) < 0.1 and abs( vFace[OrigI].SideAng) < 0.1 do + table.insert( vGeom, { Proc.Id, vFace[j].Fac}) + LastJ = j + dEal = EgtIf( ( vFace[j].Type & 1) ~= 0, vFace[j].Whisk - vFace[j].Len, 0) + if ( vFace[j].Type & 1) ~= 0 then + break + end + i = i + 1 + j = EgtIf( j + 1 <= #vFace, j + 1, EgtIf( bAllType4 or not bClosed, nil, 1)) + end + -- se faccia singola è da fare tutta senza oltrepassare estremi + if #vFace == 1 and vFace[OrigI].Type == 4 and vFace[OrigI].Edges > 3 then + dSal = -dMillDiam / 2 + dEal = -dMillDiam / 2 + -- altrimenti va verificato + else + -- se lavorazione completa su faccia iniziale + if vFace[OrigI].Type == 4 and vFace[OrigI].Edges > 3 then + -- se angolo interno prima + if vFace[OrigI].PrevAng < -30 then + local dSinA = -sin( vFace[OrigI].PlPrevAng + 90) + local dTanA = -tan( vFace[OrigI].PlPrevAng + 90) + dSal = -dMillDiam / 2 * ( 1 + ( 1 + dSinA) * dTanA) + min( 0, vFace[OrigI].Width * vFace[OrigI].Norm:getZ() * dTanA) + -- se faccia precedente inclinata verso il basso + if OrigH and vFace[OrigH].Norm:getZ() < -0.017 then + dSal = dSal + vFace[OrigH].Width * vFace[OrigH].Norm:getZ() + end + -- se angolo esterno prima + elseif vFace[OrigI].PrevAng > 30 then + -- se faccia precedente inclinata verso il basso + if OrigH and vFace[OrigH].Norm:getZ() < -0.017 then + dSal = dSal - vFace[OrigH].Width * vFace[OrigH].Norm:getZ() + end + end + end + -- se lavorazione completa o finale su faccia finale + local LastFace = ( LastJ or OrigI) + local OrigK = EgtIf( LastFace < #vFace, LastFace + 1, EgtIf( bClosed, 1, nil)) + if ( vFace[LastFace].Type == 4 and vFace[LastFace].Edges > 3) or ( LastFace == OrigI and ( vFace[LastFace].Type & 2) ~= 0) then + -- se angolo interno dopo + if OrigK and vFace[OrigK].PrevAng < -30 then + local dSinA = -sin( vFace[OrigK].PlPrevAng + 90) + local dTanA = -sin( vFace[OrigK].PlPrevAng + 90) + dEal = -dMillDiam / 2 * ( 1 + ( 1 + dSinA) * dTanA) + min( 0, vFace[OrigI].Width * vFace[OrigI].Norm:getZ() * dTanA) + -- se faccia successiva inclinata verso il basso + if vFace[OrigK].Norm:getZ() < -0.017 then + dEal = dEal + vFace[OrigK].Width * vFace[OrigK].Norm:getZ() + end + -- se angolo esterno dopo + elseif OrigK and vFace[OrigK].PrevAng > 30 then + -- se faccia successiva inclinata verso il basso + if vFace[OrigK].Norm:getZ() < -0.017 then + dEal = dEal - vFace[OrigK].Width * vFace[OrigK].Norm:getZ() + end + end + end + -- per sola lavorazione finale + if LastFace == OrigI and ( vFace[LastFace].Type & 2) ~= 0 then + -- se angolo interno dopo e faccia successiva inclinata verso l'alto oltre 16.1 deg + if OrigK and vFace[OrigK].PrevAng < -30 and vFace[OrigK].Norm:getZ() < 0.96078 and vFace[OrigK].Norm:getZ() > 0 then + dSal = dSal + vFace[OrigK].Width * vFace[OrigK].Norm:getZ() + end + -- se angolo interno prima e faccia precedente inclinata verso l'alto oltre 16.1 deg + if vFace[OrigI].PrevAng < -30 and OrigH and vFace[OrigH].Norm:getZ() < 0.96078 and vFace[OrigH].Norm:getZ() > 0 then + dSal = dSal + vFace[OrigH].Width * vFace[OrigH].Norm:getZ() + -- se l'inclinazione è inferiore a 46.1deg + if vFace[OrigH].Norm:getZ() > 0.72055 then + dSal = dSal - vFace[OrigH].Width + end + end + end + -- se percorso chiuso e completo con fresa + if bClosed and bAllType4 then + dSal = 0 + dEal = 0 + end + -- se faccia singola non oltrepasso l'estremo finale + if #vFace == 1 then + dEal = -dMillDiam / 2 + end + end + -- se non devo scaricare l'angolo o la faccia è inclinata + if nConeCut <= 1 or abs( vFace[OrigI].SideAng) > 0.1 then + EgtSetMachiningGeometry( vGeom) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- tolgo i Tabs se devo rimuovere lo sfrido + if nConeCut == 1 then EgtSetMachiningParam( MCH_MP.LEAVETAB, false) end + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + -- posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if abs( vFace[OrigI].Norm:getZ()) < GEO.EPS_SMALL then + nSCC = EgtIf( abs( vFace[OrigI].Norm:getX()) > abs( vFace[OrigI].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- altrimenti se devo fare rientranza per inserimento utensile cono 30° + elseif nConeCut == 2 then + -- eseguo la costruzione del percorso + local nPathId, sErr = MakeCustomPath( vGeom, nConeCut, dMillDiam, nAddGrpId, dThick, bClosed and bAllType4) + if nPathId == 0 then return 0, sErr end + EgtSetMachiningGeometry({{ nPathId, -1}}) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- assegno affondamento +-- EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + if bNotThrou then + EgtSetMachiningParam( MCH_MP.DEPTH, ( dDepth - dOriDepth)) + else + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + end + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + -- altrimenti se devo scaricare l'angolo + elseif nConeCut == 3 then + -- eseguo la costruzione del percorso + local nPathId, sErr = MakeCustomPath( vGeom, nConeCut, dMillDiam, nAddGrpId, nil, bClosed and bAllType4) + if nPathId == 0 then return 0, sErr end + EgtSetMachiningGeometry({{ nPathId, -1}}) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno affondamento + if bNotThrou then + EgtSetMachiningParam( MCH_MP.DEPTH, ( dDepth - dOriDepth)) + else + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + end + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return 0, sErr + end + else + i = i + 1 + end + end + -- aggiungo eventuali fresature a metà faccia + for i =1, #vFace do + if vFace[i].Split then + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_M' + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return 0, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- calcolo l'affondamento + local dDepth = vFace[i].Width + WD.CUT_EXTRA + dThick = vFace[i].Width + local vtNz = vFace[i].Norm:getZ() + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, vFace[i].Width - WD.MIN_Z_SAW) + else + dDepth = min( dDepth, dDepth - WD.MIN_Z_SAW + dMillDiam * vtNz / sqrt( 1 - vtNz * vtNz)) + end + end + local dCurrMaxDepth = GetMaxDepth( vtNz, dMillDiam, dDiamTh, dMaxDepth, dFreeLen) + -- se affondamento superiore ai limiti della fresa + if dDepth > dCurrMaxDepth then + dOriDepth = dDepth + -- lo limito e tolgo eventuali Tabs + dDepth = dCurrMaxDepth + EgtSetMachiningParam( MCH_MP.LEAVETAB, false) + bNotThrou = true + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}}) + local dSal = vFace[i].Whisk - vFace[i].Len / 2 + local dEal = vFace[i].Whisk - vFace[i].Len / 2 + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if abs( vFace[i].Norm:getZ()) < GEO.EPS_SMALL then + nSCC = EgtIf( abs( vFace[i].Norm:getX()) > abs( vFace[i].Norm:getY()), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_YP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return 0, sErr + end + end + end + -- se fresature non sono passanti + if bNotThrou then + return 2, dMillDiam, dThick + end + + return 1, dMillDiam, dThick +end + +--------------------------------------------------------------------- +local function AddSawings( sSawing, vFace, Proc, nRawId, b3Raw) + -- flag per tagli non passanti + local bNotThrou + local dThick + -- recupero i dati dell'utensile + local dSawDiam = 0 + local dMaxDepth = 0 + local dSawThick = 0 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- Calcolo angolo 3° asse rot (da direz. utensile) + local sRot3Ang = 'A1=180' + if WD.GetChainSawBlockedAxis then + sRot3Ang = WD.GetChainSawBlockedAxis( 1) + end + -- ciclo di inserimento dei tagli con sega a catena + for i = 1, #vFace do + -- se inizio faccia non tagliato completamente, inserisco un ripasso con sega a catena + if ( vFace[i].Type & 1) ~= 0 then + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) + local nMchId = EgtAddMachining( sName, sSawing) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return 0, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- calcolo l'affondamento + local dDepth = vFace[i].Width + min( WD.CUT_EXTRA, -WD.MIN_Z_SAW) + dThick = vFace[i].Width + -- se affondamento superiore ai limiti della sega a catena + if dDepth > dMaxDepth then + dDepth = dMaxDepth + bNotThrou = true + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}}) + local dSal = - dSawDiam / 2 + local dEal = vFace[i].Whisk - vFace[i].Len - dSawDiam / 2 + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, sRot3Ang) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- posizione braccio porta testa + if vFace[i].Norm:getX() < 0.018 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.OPPOSITE) + EgtSetMachiningParam( MCH_MP.OFFSR, dSawThick) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return 0, sErr + end + end + -- se fine faccia non tagliato completamente o faccia non tagliata completamente e abbastanza lunga, inserisco un ripasso con sega a catena + if ( vFace[i].Type & 2) ~= 0 or ( vFace[i].Type == 4 and vFace[i].Edges > 3 and vFace[i].Len > dSawDiam + 1) then + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) + local nMchId = EgtAddMachining( sName, sSawing) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return 0, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- calcolo l'affondamento + local dDepth = vFace[i].Width + min( WD.CUT_EXTRA, -WD.MIN_Z_SAW) + dThick = vFace[i].Width + -- se affondamento superiore ai limiti della sega a catena + if dDepth > dMaxDepth then + dDepth = dMaxDepth + bNotThrou = true + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vFace[i].Fac}}) + local dSal = - dSawDiam / 2 + local dEal = - dSawDiam / 2 + if ( vFace[i].Type & 2) ~= 0 then + dSal = vFace[i].Whisk - vFace[i].Len - dSawDiam / 2 + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno utilizzo faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, sRot3Ang) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- posizione braccio porta testa + if vFace[i].Norm:getX() < 0.018 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.OPPOSITE) + EgtSetMachiningParam( MCH_MP.OFFSR, dSawThick) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return 0, sErr + end + end + end + -- se fresature non sono passanti + if bNotThrou then + return 2, dSawThick, dThick + end + return 1, dSawThick, dThick +end + +--------------------------------------------------------------------- +local function AddCuts( sCutting, vFace, Proc, nRawId, b3Raw, dSawThick) + -- ciclo di inserimento dei tagli sulle facce del contorno in esame + for i = 1, #vFace do + -- verifico se faccia da saltare, perchè macchina travi e faccia su bordo longitudinale esterno già finito + local bToSkip = ( WD.BEAM_MACHINE and IsPointOnRawLongEdges( vFace[i].Cen, b3Raw)) + -- se non è faccia da saltare, inserisco il taglio di lama + if not bToSkip and vFace[i].Type ~= 4 then + -- indice del successivo + local j = EgtIf( i < #vFace, i + 1, 1) + -- inserisco la lavorazione + local sName = 'Cut_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_' .. tostring( i) + local nMchId = EgtAddMachining( sName, sCutting) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + local dSpeed = EgtGetMachiningParam( MCH_MP.SPEED) + local sHead = EgtTdbGetCurrToolParam( MCH_TP.HEAD) + local bGearbox = EgtGetInfo( EgtGetHeadId( sHead) or GDB_ID.NULL, 'Gearbox', 'b') + -- aggiungo geometria + EgtSetMachiningGeometry( { { Proc.Id, vFace[i].Fac}}) + -- calcolo l'affondamento + local dDepth = vFace[i].Depth + local vtNz = vFace[i].Norm:getZ() + if WD.CHECK_MIN_Z_SAW then + if vtNz >= 0 then + dDepth = min( dDepth, -WD.MIN_Z_SAW) + else + dDepth = min( dDepth, -WD.MIN_Z_SAW + dSawThick * vtNz) + end + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- verifico se va invertita la direzione di lavorazione perchè faccia verso l'alto (angolo maggiore di 0.01 deg) + local bInvert = ( vFace[i].Norm:getZ() > 0.0001745) + -- imposto inversione + EgtSetMachiningParam( MCH_MP.INVERT, bInvert) + -- imposto lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bInvert, MCH_SAW_WS.LEFT, MCH_SAW_WS.RIGHT)) + -- lato mandrino ( standard a sinistra se rotazione CCW, altrimenti a destra, oppure da funzione di macchina) + local nHeadSide = EgtIf( dSpeed < 0, MCH_SAW_HS.LEFT, MCH_SAW_HS.RIGHT) + if WD.GetSawHeadSide then nHeadSide = WD.GetSawHeadSide( dSpeed, sHead) end + EgtSetMachiningParam( MCH_MP.HEADSIDE, nHeadSide) + -- assegno i dati di attacco (sicurezza solo se angolo interno) + local nLeadIn = MCH_SAW_LI.CENT + if ( not bInvert and ( vFace[i].Type & 1) ~= 0) or ( bInvert and ( vFace[i].Type & 2) ~= 0) then + nLeadIn = MCH_SAW_LI.STRICT + end + EgtSetMachiningParam( MCH_MP.LEADINTYPE, nLeadIn) + local dSal = 0 + if ( not bInvert and vFace[i].PrevAng < -0.1) or ( bInvert and vFace[j].PrevAng < -0.1) then + dSal = -WHISK_SAFE + end + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + -- assegno i dati di uscita (sicurezza solo se angolo interno) + local nLeadOut = MCH_SAW_LO.CENT + if ( not bInvert and ( vFace[i].Type & 2) ~= 0) or ( bInvert and ( vFace[i].Type & 1) ~= 0) then + nLeadOut = MCH_SAW_LO.STRICT + end + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nLeadOut) + local dEal = 0 + if ( not bInvert and vFace[j].PrevAng < -0.1) or ( bInvert and vFace[i].PrevAng < -0.1) then + dEal = -WHISK_SAFE + end + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- posizione braccio porta testa + if not bGearbox then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_NEAR) + end + -- eseguo + if not EgtApplyMachining( true, false) then + -- provo a invertire direzione, lato di lavoro e attacco/uscita + EgtSetMachiningParam( MCH_MP.INVERT, not bInvert) + EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( not bInvert, MCH_SAW_WS.LEFT, MCH_SAW_WS.RIGHT)) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, EgtIf( nLeadOut == MCH_SAW_LO.STRICT, MCH_SAW_LI.STRICT, MCH_SAW_LI.CENT)) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, EgtIf( nLeadIn == MCH_SAW_LI.STRICT, MCH_SAW_LO.STRICT, MCH_SAW_LO.CENT)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal) + -- ri-eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + -- se limite lunghezza di taglio e taglio lo supera + if WD.CUT_MAX_LENGTH and vFace[i].Len > WD.CUT_MAX_LENGTH then + -- sdoppio la lavorazione + local sSouName = EgtGetName( nMchId) + local nNewMchId = EgtCopyMachining( sSouName..'_B', sSouName) + --accorciamento iniziale della seconda + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, -vFace[i].Len/2) + --accorciamento finale della prima + EgtSetCurrMachining( nMchId) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, -vFace[i].Len/2) + -- segnalo spezzatura lavorazione faccia + vFace[i].Split = true + end + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByCut( Proc, nRawId, b3Raw) + local sWarn = '' + -- 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 : part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la curva associata + local bOpposite = false + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then + AuxId = AuxId + Proc.Id + local vtExtr= EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if vtExtr then + bOpposite = ( Proc.Grp == 4 and vtExtr:getZ() < 0) or ( Proc.Grp == 3 and vtExtr:getZ() > 0) + if GetFacesExternalSide( Proc, vtExtr) ~= Proc.Grp then + bOpposite = not bOpposite + end + end + end + -- altezza massima delle facce + local dWidth = 0 + for i = 1, Proc.Fct do + local _, _, dFctW = WL.GetFaceHvRefDim( Proc.Id, i - 1) + dWidth = max( dWidth, dFctW) + end + -- lettura parametri (probabile/i parametro/i Q) + local nConeCut = VerifyCornerType( Proc) + -- recupero la lavorazione di taglio con lama e i suoi parametri (dapprima cerco quella che possa tagliare completamente) + local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') + local sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard', dWidth, nTool_ID) + if not sCutting then + sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard', nil, nTool_ID) + sWarn = 'Warning : elevation bigger than max sawcut depth' + end + if not sCutting then + local sErr = 'Error : cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- gruppo ausiliario + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + -- recupero i dati di tutte le facce + local vFace, dMaxWidth, nNewProc = GetFacesData( Proc, bOpposite, true, dSawDiam, dSawMaxDepth, dSawThick, nAddGrpId, b3Raw, nil) + -- inserimento dei tagli di lama + local bCtOk, sCtErr = AddCuts( sCutting, vFace, Proc, nRawId, b3Raw, dSawThick) + if not bCtOk then return bCtOk, sCtErr end + -- se richiesta solo lama, esco + local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0 + if nCntType == 1 and nTool_ID ~= 0 then return true, sWarn end + -- se ci sono facce inclinate, escludo la sega a catena + local bSlanting = false + for i = 1, #vFace do + if abs( vFace[i].Norm:getZ()) > 0.01 then + bSlanting = true + break + end + end + -- recupero la lavorazione con sega a catena + local sSawing = WM.FindSawing( 'Sawing') + -- recupero la lavorazione di fresatura + local sMilling, dMillMaxDepth = WM.FindMilling( 'FreeContour', dMaxWidth + WD.CUT_EXTRA, nil, nil, nil, nil, true) + local sMilling2 = WM.FindMilling( 'FreeContour', nil, nil, nil, nil, nil, true) + if not sMilling and ( not sSawing or bSlanting) then + sMilling = sMilling2 + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- se possibile, inserimento delle fresature + local bDone = false + if sMilling then + local nMlOk, sMlErr, dThick = AddMillings( sMilling, vFace, Proc, nRawId, b3Raw, nConeCut, nAddGrpId) + if nMlOk == 0 then return false, sMlErr end + bDone = ( dThick ~= nil) + -- se ci sono almeno due facce e lavorato almeno un angolo + if Proc.Fct >= 2 and bDone then + -- se abilitata la lavorazione corner con stop macchina e lavorazione precedente passante e spessore sotto il limite + -- o con fresa cono piccola e spessore sotto il limite + if ( nConeCut == 1 and nMlOk == 1 and dThick <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL)) or + ( nConeCut == 2 and dThick <= ( WD.MAX_CLEAN_CRN30 + 20 * GEO.EPS_SMALL)) then + local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw, + sMlErr, nAddGrpId, dThick, nNewProc, 0, + true) + if not bMcok then return bMcok, sMcErr end + else + -- messaggi nel log + if nConeCut == 1 then + if nMlOk ~= 1 then + local sErr = 'Clean corner 60° not applid because Milling not thru the thickness' + EgtOutLog( sErr) + else + local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) .. + ' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2) + EgtOutLog( sErr) + end + elseif nConeCut == 2 then + local sErr = 'Clean corner 30° not applid because thickness: ' .. EgtNumToString( dThick, 2) .. + ' is bigger than parameter MAX_CLEAN_CRN30: ' .. EgtNumToString( WD.MAX_CLEAN_CRN30 , 2) + EgtOutLog( sErr) + end + end + end + -- altrimenti provo con la sega a catena + elseif sSawing then + local nCsOk, sCSErr, dThick = AddSawings( sSawing, vFace, Proc, nRawId, b3Raw) + if nCsOk == 0 then return false, sCsErr end + bDone = ( dThick ~= nil) + -- se ci sono almeno due facce e lavorato almeno un angolo + if Proc.Fct >= 2 and bDone then + -- se abilitata la lavorazione corner con stop macchina e lavorazione precedente passante e spessore sotto il limite + if nConeCut == 1 and nCsOk == 1 and dThick <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL) then + local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw, + sCSErr, nAddGrpId, nil, nNewProc, 0, + true) + if not bMcok then return bMcok, sMcErr end + else + if nConeCut == 1 then + if nCsOk ~= 1 then + local sErr = 'Clean corner 60° not applied because Chainsawing not thru the thickness' + EgtOutLog( sErr) + else + local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) .. + ' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2) + EgtOutLog( sErr) + end + elseif nConeCut == 2 then + local sErr = 'Not possible apply Clean corner 30° after use sawing' + EgtOutLog( sErr) + end + end + end + end + -- altrimenti provo con fresa ad affondamento ridotto + if not bDone then + local nMlOk, sMlErr, dThick = AddMillings( sMilling2, vFace, Proc, nRawId, b3Raw, nConeCut, nAddGrpId) + if nMlOk == 0 then return false, sMlErr end + -- se ci sono almeno due facce e lavorato almeno un angolo + if Proc.Fct >= 2 and dThick then + -- se abilitata la lavorazione corner con stop macchina e lavorazione precedente passante e spessore sotto il limite + -- o con fresa cono piccola e spessore sotto il limite + if ( nConeCut == 1 and nMlOk == 1 and dThick <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL)) or + ( nConeCut == 2 and dThick <= ( WD.MAX_CLEAN_CRN30 + 20 * GEO.EPS_SMALL)) then + local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw, + sMlErr, nAddGrpId, dThick, nNewProc, 0, + true) + if not bMcok then return bMcok, sMcErr end + else + -- messaggi nel log + if nConeCut == 1 then + if nMlOk ~= 1 then + local sErr = 'Clean corner 60° not applid because Milling not thru the thickness' + EgtOutLog( sErr) + else + local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) .. + ' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2) + EgtOutLog( sErr) + end + elseif nConeCut == 2 then + local sErr = 'Clean corner 30° not applid because thickness: ' .. EgtNumToString( dThick, 2) .. + ' is bigger than parameter MAX_CLEAN_CRN30: ' .. EgtNumToString( WD.MAX_CLEAN_CRN30 , 2) + EgtOutLog( sErr) + end + end + sWarn = 'Depth reduced to mill capabilities' + end + end + return true, sWarn +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 : 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 : 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) + local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') + -- recupero la lavorazione + local sMilling = WM.FindMilling( 'FreeContour', nil, nil, nTool_ID, nil, nil, true) + if not sMilling then + local sErr = 'Error : milling not found in library' + if nTool_ID then sErr = sErr .. ' (Tool_ID=' .. tostring( nTool_ID) .. ')' end + 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 = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth + end + end + -- eventuale spezzatura sul tratto più lungo se curva chiusa + --BL.PutStartOnLonger( AuxId) + -- verifiche per affondamento + if b3Aux:getDimZ() > b3Raw:getDimZ() - 1.0 then + dDepth = min( dDepth, b3Raw:getDimZ()) + WD.CUT_EXTRA + end + if dDepth > dMaxDepth then + -- lo limito e tolgo eventuali Tabs + dDepth = dMaxDepth + EgtSetMachiningParam( MCH_MP.LEAVETAB, false) + 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 + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- 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 + local nSCC = MCH_SCC.ADIR_ZP + if AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeByMark( 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 : 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 : 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) + local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') + -- recupero la lavorazione + local sMilling = WM.FindMilling( 'Text', nil, nil, nTool_ID) + if not sMilling then + local sErr = 'Error : milling not found in library' + if nTool_ID then sErr = sErr .. ' (Tool_ID=' .. tostring( nTool_ID) .. ')' end + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'FreeMark_' .. ( 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 + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se estrusione da sotto, inverto direzione fresa + if bToolInv then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeByNail( 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 : 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 : 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) + local nCntData = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') or 0 + if nCntData < 10 then + nCntData = nCntData + 10 + end + local dCntPar = EgtGetInfo( Proc.Id, 'CNT_PAR', 'd') or 100 + -- recupero la lavorazione + local sNailing = WM.FindNailing( nCntData) + if not sNailing then + local sErr = 'Error : nailing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Nail_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sNailing) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sNailing + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- 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, 10) + -- assegno lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) + -- se in doppio lungo Y, devo dimezzare opportunamente la lavorazione + local dExtraDelta = 0 + if Proc.Double == 2 then + dExtraDelta = 0.45 * dCntPar + if Proc.Delta > 0 then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, -Proc.DblAcc - dExtraDelta) + else + EgtSetMachiningParam( MCH_MP.STARTADDLEN, -Proc.DblAcc - dExtraDelta) + end + end + -- assegno parametri a note utente + local sUserNotes = 'Par=' .. EgtNumToString( dCntPar, 0) .. ';' + if Proc.Double and Proc.Double > 0 then + sUserNotes = sUserNotes .. 'Dbl=' .. EgtNumToString( Proc.Double, 0) .. ';' .. + 'Dlt=' .. EgtNumToString( abs( Proc.Delta) + dExtraDelta, 0) .. ';' + end + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + -- 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 bOpposite = false + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + local vtExtr + if AuxId then + AuxId = AuxId + Proc.Id + vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if vtExtr then + bOpposite = ( Proc.Grp == 4 and vtExtr:getZ() < 0) or ( Proc.Grp == 3 and vtExtr:getZ() > 0) + if GetFacesExternalSide( Proc, vtExtr) ~= Proc.Grp then + bOpposite = not bOpposite + end + end + end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + local bPocketBotface = false + -- se la curva è aperta non la svuoto + if not EgtCurveIsClosed( AuxId) then + bPocketBotface = true + end + -- recupero i dati della curva e del profilo + local dDepth = EgtIf( bPocketBotface, 0, abs( EgtCurveThickness( AuxId))) + local dOriDepth = dDepth + -- cerco la faccia di fondo della superfice (deve avere direzione circa quella di estrusione della curva) + local nFacet + for i = 1, Proc.Fct do + local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + if abs( vtN * vtExtr) > 0.99 then + nFacet = i - 1 + break + end + end + if not nFacet then + return MakeByCut( Proc, nRawId, b3Raw) + end + -- dati della faccia di fondo + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local dDiam = min( dH, dV) + local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId) + -- gruppo ausiliario + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + local nNewProc, nNumFacet = RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFacet) + -- se ho forma a L + local bIsL = ( nNumFacet == 2 or TestElleShape3( nNewProc, nNumFacet) or TestElleShape4( nNewProc, nNumFacet) == 2) + -- verifico se U + local bIsU = ( nNumFacet == 3 and not TestElleShape3( nNewProc, nNumFacet)) + local dMiddleFacetLength = 0 + if bIsU then + local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( nNewProc, 1, GDB_ID.ROOT) + -- prendo la linea di base + if abs( dElev - dH2) < 1 and abs( dElev - dV2) > 1 then + dMiddleFacetLength = dV2 + elseif abs( dElev - dV2) < 1 and abs( dElev - dH2) > 1 then + dMiddleFacetLength = dH2 + end + end + if Proc.Fct < 5 and (( bIsL and not bIsU) or ( bIsU and dMiddleFacetLength > dDiam * 2)) then dDiam = dDiam * 2 end + local nTool_ID = EgtGetInfo( Proc.Id, 'CNT_DATA', 'i') + -- recupero la lavorazione + local sPocketing = WM.FindPocketing( 'Pocket', dDiam, dDepth, nTool_ID) + if not sPocketing then + local sErr = 'Error : pocketing not found in library' + if nTool_ID then sErr = sErr .. ' (Tool_ID=' .. tostring( nTool_ID) .. ')' end + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local dThDiam = 100 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + 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 + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- aggiungo geometria + if bPocketBotface then + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + else + EgtSetMachiningGeometry( {{ AuxId, -1}}) + end + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameVectorApprox( vtExtr, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + local sWarn = '' + if bPocketBotface then + local dThElev = dThDiam / 2 * sqrt( vtExtr:getX() * vtExtr:getX() + vtExtr:getY() * vtExtr:getY()) + if dElev + dThElev > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth - dElev - dThElev + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + else + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( EgtIf( bPocketBotface, min( dElev, dMaxDepth), dMaxDepth), 1) .. ';') + -- eseguo + local bAppOk = EgtApplyMachining( true, false) + if not bAppOk and not bPocketBotface then + bPocketBotface = true + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + dDepth = 0 + local dThElev = dThDiam / 2 * sqrt( vtExtr:getX() * vtExtr:getX() + vtExtr:getY() * vtExtr:getY()) + if dElev + dThElev > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth - dElev - dThElev + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + bAppOk = EgtApplyMachining( true, false) + end + if not bAppOk then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- lettura parametri (probabile/i parametro/i Q) + local nConeCut = VerifyCornerType( Proc) + -- recupero i dati di tutte le facce + local vFace, dMaxWidth + vFace, dMaxWidth, nNewProc = GetFacesData( Proc, bOpposite, false, dMillDiam, dMaxDepth, (dMillDiam/2), nAddGrpId, b3Raw, nNewProc) + -- se ci sono almeno due facce + if Proc.Fct >= 2 then + -- se abilitata la lavorazione corner con stop macchina e affondamento non superiore al limite + local dDepthMach = EgtIf( bPocketBotface, dDepth, ( dDepth - dOriDepth)) + if nConeCut == 1 and dDepthMach <= ( WD.MAX_CLEAN_CRN60 + 20 * GEO.EPS_SMALL) then + local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw, + dMillDiam, nAddGrpId, nil, nNewProc, dDepthMach) + if not bMcok then return bMcok, sMcErr end + else + EgtErase( nNewProc) + if nConeCut == 1 then + local sErr = 'Clean corner 60° not applid because thickness: ' .. EgtNumToString( dThick, 2) .. + ' is bigger than parameter MAX_CLEAN_CRN60: ' .. EgtNumToString( WD.MAX_CLEAN_CRN60 , 2) + EgtOutLog( sErr) + elseif nConeCut == 2 then + local sErr = 'Clean corner 30° is not applied on pocketing' + EgtOutLog( sErr) + end + end + end + return true, sWarn +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPF.Make( Proc, nRawId, b3Raw) + -- recupero la tipologia (contorno o tasca) + local bPocket = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- se svuotatura + if bPocket then + return MakeByPocket( Proc, nRawId, b3Raw) + -- altrimenti contorno + else + -- riordino le facce + ReorderFaces( Proc.Id, EgtSurfTmFacetCount( Proc.Id)) + -- recupero il tipo di lavorazione + local nCntType = EgtGetInfo( Proc.Id, 'CNT_TYPE', 'i') or 0 + -- se fresatura + if nCntType == 2 then + return MakeByMill( Proc, nRawId, b3Raw) + -- se marcatura + elseif nCntType == 10 then + return MakeByMark( Proc, nRawId, b3Raw) + -- se chiodatura + elseif nCntType == 20 then + return MakeByNail( Proc, nRawId, b3Raw) + -- altrimenti, taglio con lama e pulizia angoli con fresa + else + return MakeByCut( Proc, nRawId, b3Raw) + end + end +end + +--------------------------------------------------------------------- +return WPF diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessLapJoint.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessLapJoint.lua new file mode 100644 index 0000000..25b34b8 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessLapJoint.lua @@ -0,0 +1,2579 @@ +-- WProcessLapJoint.lua by Egaltech s.r.l. 2022/02/04 +-- Gestione calcolo mezzo-legno per Pareti +-- 2021/08/27 DS Se tre o più facce con flag PCKT=1 forzo svuotatura con fresa (per Variant). +-- 2021/08/29 DS Se svuotatura di fianco setto flag per farla dopo i tagli. +-- 2021/09/03 DS Se due facce con sottosquadra ora si restituisce mesaaggio di errore. +-- 2021/10/05 FM Gestione lavorazioni SideMill con creazione gola passaggio gambo utensile +-- 2021/11/29 DS Correzione lav.ni SideMill quando più profonde che larghe. +-- 2022/01/04 DS Se U con fondo verso basso o alto non ci possono essere spigoli verticali da pulire. +-- 2022/01/17 ES Migliorata scelta fresa per lavorazione di fianco sotto. +-- 2022/02/03 DS Gorge larga come gambo più sicurezza. +-- 2022/02/04 DS In svuotatura aggiunta gestione WD.MAXDIAM_POCK_CORNER in presenza di almeno un angolo interno. + +-- Tabella per definizione modulo +local WPL = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') +local FreeContour = require( 'WProcessFreeContour') + +EgtOutLog( ' WProcessLapJoint started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') +local WHISK_OFFS = 0.1 +local WHISK_SAFE = 5 +local MIN_LEN_CUT = 30 + +-- variabili assegnazione parametri Q +local Q_FORCE_BLADE = '' -- i +local Q_SIDE_MILL = '' -- d +local Q_CORNER_CUT = '' -- i + +-- variabile settaggio doppia lavorazione su angoo > 90 +local bMakeTwinCut = true +-- angolo sottosquadra ammesso per fresa cono 30° +local dAngleSmall = 70 + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPL.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or + ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or + ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or + ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or + ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or + ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or + ( ( Proc.Grp == 4) and Proc.Prc == 39) +end + +--------------------------------------------------------------------- +local function AssignQIdent( Proc) + + -- reset assegnazione parametri Q + Q_FORCE_BLADE = '' + Q_SIDE_MILL = '' + Q_CORNER_CUT = '' + + if Proc.Grp == 0 and Proc.Prc == 12 then + Q_FORCE_BLADE = 'Q01' -- i + Q_SIDE_MILL = 'Q02' -- i + Q_CORNER_CUT = '' -- i + elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then + Q_FORCE_BLADE = '' -- i + Q_SIDE_MILL = 'Q08' -- i + Q_CORNER_CUT = 'Q05' -- i + else + Q_FORCE_BLADE = 'Q01' -- i + Q_SIDE_MILL = 'Q03' -- i + Q_CORNER_CUT = 'Q05' -- i + end + -- le altre features gestite non hanno parametri Q +end + +--------------------------------------------------------------------- +local function EvaluateQParam( Proc) + + local bForceUseBlade = false + if #Q_FORCE_BLADE == 0 or EgtGetInfo( Proc.Id, Q_FORCE_BLADE, 'i') == 1 then + bForceUseBlade = true + end + + -- Verifico se utilizzare la fresa di lato : + -- 0 : niente + -- 1 : utilizzo fresa di lato (alla faccia selezionata) + local nUseSideMillAsBlade = EgtGetInfo( Proc.Id, Q_SIDE_MILL, 'i') or 0 + + -- Verifico il tipo di lavorazione su angolo : + -- 0 : niente + -- 1 : ripresa corner dopo pausa per rimozione sfridi (fresa 60deg) + -- 2 : ripresa corner senza pausa (fresa 30 deg) + -- 3 : scarico corner (tipo foro). + local nTypeCornerCut = EgtGetInfo( Proc.Id, Q_CORNER_CUT, 'i') or 0 + + return nTypeCornerCut, nUseSideMillAsBlade, bForceUseBlade +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPL.Classify( Proc, b3Raw) + -- se 1 faccia + if Proc.Fct == 1 then + -- dati della faccia + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se è lavorabile da sopra + return vtN:getZ() >= WD.NZ_MINA + -- se 2 facce + elseif Proc.Fct == 2 then + -- dati delle facce + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile da sopra o di fianco + return ( vtN[1]:getZ() >= - 0.01 or vtN[2]:getZ() >= - 0.01) + -- se più di 2 facce + else + local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + -- se trovata faccia di fondo + if nFacInd >= 0 then + -- determino componente Z della normale più diretta verso il basso + local dMinNz = 1 + for i = 1, Proc.Fct do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT) + if vtN:getZ() < dMinNz then + dMinNz = vtN:getZ() + end + end + -- dati della faccia + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- per lavorare alcune superfici che sono di poco negative controllo che la minima Z sia al di sopra del punto minimo calcolato per + -- una lama da 500 + local bAllowNegativeFace + if vtN:getZ() < - 0.01 then + if vtN:getZ() > - 0.088 and Proc.Box:getMin():getZ() - b3Raw:getMin():getZ() - (500 * abs(vtN:getZ())) >= 0 then + bAllowNegativeFace = true + end + end + -- verifico se la faccia è lavorabile da sopra o di fianco + if ( vtN:getZ() >= WD.NZ_MINA or ( dMinNz < -0.866 and Proc.Fct >= 3 and ( vtN:getZ() > - 0.01 or bAllowNegativeFace))) then + Proc.Stype = 1 + return true + -- altrimenti verifico la eventuale seconda faccia + elseif nFacInd2 then + -- dati della faccia + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd2, GDB_ID.ROOT) + local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd2, GDB_ID.ROOT) + -- restituisco se faccia lavorabile + Proc.Stype = 2 + return ( vtN2:getZ() >= WD.NZ_MINA or ( dMinNz < -0.866 and Proc.Fct >= 3 and vtN2:getZ() > - 0.01)) + -- se tre facce + elseif Proc.Fct == 3 then + -- verifico se U da sopra + -- dati della faccia + local nFac2 = EgtIf( nFacInd == 0, 1, 0) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFac2, GDB_ID.ROOT) + Proc.Stype = 3 + return ( abs( ( vtN ^ vtN2) * Z_AX()) >= WD.NZ_MINA) + -- altrimenti non lavorabile + else + return false + end + -- se altrimenti tunnel + elseif nFacInd == -1 then + -- dati delle prime tre facce + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + vtN[3] = EgtSurfTmFacetNormVersor( Proc.Id, 2, GDB_ID.ROOT) + -- verifico se è lavorabile da sopra + local vtAxN = vtN[1] ^ vtN[2] + if vtAxN:isSmall() then vtAxN = vtN[1] ^ vtN[3] end + Proc.Stype = 4 + return ( abs( vtAxN:getZ()) >= WD.NZ_MINA) + -- altrimenti non lavorabile + else + return false + end + end +end + +-- funzione che verifica se faccia lavorabile da sopra +local function VerifyVtN( ProcId, nFct) + local nFlip0 = 0 + local nFlip1 = 0 + -- dati della faccia + local vtN = EgtSurfTmFacetNormVersor( ProcId, nFct, GDB_ID.ROOT) + local dVtNZ = vtN:getZ() + -- verifico se è lavorabile da sopra + nFlip0 = EgtIf( dVtNZ >= WD.NZ_MINA, 100, 0) + -- verifico se e' lavorabile da fliped: cambio segno al versore + nFlip1 = EgtIf( -dVtNZ >= WD.NZ_MINA, 100, 0) + return nFlip0, nFlip1 +end + +-- funzione che fa la media dei versori per assegnare punteggi flip +local function VerifyVtNMedia(ProcId, nFct1, nFct2) + local nFlip0 = 0 + local nFlip1 = 0 + -- dati delle facce + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( ProcId, nFct1, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( ProcId, nFct2, GDB_ID.ROOT) + local dVtN1Z = vtN[1]:getZ() + local dVtN2Z = vtN[2]:getZ() + -- se entrambi i versori positivi + if (dVtN1Z >= - 0.01 and dVtN2Z >= - 0.01) then + -- posso lavorarlo da sopra + nFlip0 = 100 + -- se almeno un versore positivo + elseif (dVtN1Z >= - 0.01 or dVtN2Z >= - 0.01) then + -- calcolo media dei versori: se positiva tende verso alto + local dVtNMedia = ( dVtN1Z + dVtN2Z) / 2 + if dVtNMedia >= 0 - GEO.EPS_SMALL and dVtNMedia <= 0 + GEO.EPS_SMALL then + nFlip0 = 100 + elseif dVtNMedia >= 0 + GEO.EPS_SMALL then + nFlip0 = 75 + else + nFlip0 = 25 + end + -- se entrambi i versori negativi, impossibile da fare + else + nFlip0 = 0 + end + -- verifico se e' lavorabile da fliped: cambio segno ai versori + dVtN1Z = -dVtN1Z + dVtN2Z = -dVtN2Z + -- se entrambi i versori positivi + if (dVtN1Z >= - 0.01 and dVtN2Z >= - 0.01) then + -- posso lavorarlo da sopra + nFlip1 = 100 + -- se almeno un versore positivo + elseif (dVtN1Z >= - 0.01 or dVtN2Z >= - 0.01) then + -- calcolo media dei versori: se positiva tende verso alto + local dVtNMedia = ( dVtN1Z + dVtN2Z) / 2 + if dVtNMedia >= 0 - GEO.EPS_SMALL and dVtNMedia <= 0 + GEO.EPS_SMALL then + nFlip1 = 100 + elseif dVtNMedia >= 0 + GEO.EPS_SMALL then + nFlip1 = 75 + else + nFlip1 = 25 + end + -- se entrambi i versori negativi, impossibile da fare + else + nFlip0 = 0 + end + return nFlip0, nFlip1 +end + +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPL.FlipClassify( Proc) + local nFlip0 = -1 + local nFlip1 = -1 + -- se 1 faccia + if Proc.Fct == 1 then + -- verifico che la normale permetta la lavorazione da sopra ed assegno punteggio di conseguenza + nFlip0, nFlip1 = VerifyVtN( Proc.Id, 0) + -- se 2 facce + elseif Proc.Fct == 2 then + -- calcolo la media delle normali delle facce ed assegno punteggio maggiore se positiva + nFlip0, nFlip1 = VerifyVtNMedia(Proc.Id, 0, 1) + -- se più di 2 facce + else + local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + if nFacInd == -2 then return 0, 0 end + -- se 3 facce + if Proc.Fct == 3 then + -- se forma ad U + if not nFacInd2 or nFacInd2 == 0 then + -- verifico che la normale del fondo permetta la lavorazione da sopra ed assegno punteggio di conseguenza + nFlip0, nFlip1 = VerifyVtN( Proc.Id, nFacInd) + -- se non ad U + else + -- calcolo la media delle normali delle facce di fondo ed assegno punteggio maggiore se positiva + nFlip0, nFlip1 = VerifyVtNMedia(Proc.Id, nFacInd, nFacInd2) + end + -- se 4 facce + elseif Proc.Fct == 4 then + -- se senza fondo (tunnel) + if not nFacInd or nFacInd == -1 then + -- dati delle facce + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + vtN[3] = EgtSurfTmFacetNormVersor( Proc.Id, 2, GDB_ID.ROOT) + vtN[4] = EgtSurfTmFacetNormVersor( Proc.Id, 3, GDB_ID.ROOT) + -- verifico se è lavorabile da sopra + local vtAxN = vtN[1] ^ vtN[2] + if vtAxN:isSmall() then + vtAxN = vtN[1] ^ vtN[3] + end + if ( abs( vtAxN:getZ()) >= WD.NZ_MINA) then + -- calcolo la media dei versori delle facce + local dVtNMedia = ( vtN[1]:getZ() + vtN[2]:getZ() + vtN[3]:getZ() + vtN[4]:getZ()) / 4 + if dVtNMedia >= 0 - GEO.EPS_SMALL and dVtNMedia <= 0 + GEO.EPS_SMALL then + nFlip0 = 100 + nFlip1 = 100 + elseif dVtNMedia >= 0 + GEO.EPS_SMALL then + nFlip0 = 75 + nFlip1 = 25 + else + nFlip0 = 25 + nFlip1 = 75 + end + end + -- se con fondo + else + -- calcolo la media delle normali delle facce di fondo ed assegno punteggio maggiore se positiva + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd2, GDB_ID.ROOT) + if vtN[1]:getZ() == -1 or vtN[2]:getZ() == -1 then return 0, 100 end + if vtN[1]:getZ() == 1 or vtN[2]:getZ() == 1 then return 100, 0 end + nFlip0, nFlip1 = VerifyVtNMedia(Proc.Id, nFacInd, nFacInd2) + end + -- se 5 facce + elseif Proc.Fct == 5 then + -- verifico che la normale del fondo permetta la lavorazione da sopra ed assegno punteggio di conseguenza + nFlip0, nFlip1 = VerifyVtN( Proc.Id, nFacInd) + end + end + return nFlip0, nFlip1 +end + +--------------------------------------------------------------------- +local function TestElleShape3( nIdGeom, nNumFacet) + -- valida solo nel caso di tre facce + if nNumFacet ~= 3 then return false end + -- determino se L con una faccia terminale o U con tre facce + local bIsL = true + for i = 1, 3 do + local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + if nCount == 1 then + bIsL = false + break + end + end + return bIsL +end + +--------------------------------------------------------------------- +local function TestElleShape4( nIdGeom, nNumFacet) + -- valida solo nel caso di quattro facce + if nNumFacet ~= 4 then return false end + -- determino se L con due facce terminali o O + local nFac3Adj = 0 + local dMinArea3 = GEO.INFINITO * GEO.INFINITO + local dMaxArea2 = 0 + for i = 1, 4 do + local vFacAdj = EgtSurfTmFacetAdjacencies( nIdGeom, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( nIdGeom, i - 1, GDB_ID.ROOT) + local dArea = dH * dV + if nCount == 2 then + dMaxArea2 = max( dMaxArea2, dArea) + elseif nCount == 3 then + dMinArea3 = min( dMinArea3, dArea) + nFac3Adj = nFac3Adj + 1 + end + end + if nFac3Adj ~= 2 then return false end + -- verifico se L profonda oppure lunga + if dMinArea3 < dMaxArea2 then + return 1 + else + return 2 + end +end + +--------------------------------------------------------------------- +local function GetOtherRegions( nPartId) + local vOthers = {} + local nOtherId = EgtGetFirstPartInRawPart( EgtGetFirstRawPart() or GDB_ID.NULL) + while nOtherId do + local nRegId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( nOtherId, 'Outline') or GDB_ID.NULL) + while nRegId do + local vtN = EgtSurfFrNormVersor( nRegId, GDB_ID.ROOT) + if EgtExistsInfo( nRegId, 'REGION') and vtN and AreSameVectorApprox( vtN, Z_AX()) then + local b3Reg = EgtGetBBoxGlob( nRegId, GDB_BB.STANDARD) + if b3Reg then + table.insert( vOthers, { PartId = nOtherId, RegId = nRegId, Box = b3Reg}) + end + end + nRegId = EgtGetNext( nRegId) + end + nOtherId = EgtGetNextPartInRawPart( nOtherId) + end + return vOthers +end + +--------------------------------------------------------------------- +local function ReorderFaces( nIdSurf, nNumFacet) + -- cerco una faccia senza precedenti + local nFirstFac + for i = 1, nNumFacet do + -- centro e normale della faccia + local ptCen, vtN = EgtSurfTmFacetCenter( nIdSurf, i - 1, GDB_ID.ROOT) + -- verifico con le altre facce + local bFoundPrec + for j = 1, nNumFacet do + if j ~= i then + -- verifico se è precedente + local bAdj, ptP1, _, _ = EgtSurfTmFacetsContact( nIdSurf, i - 1, j - 1, GDB_ID.ROOT) + if bAdj and ( vtN ^ ( ptCen - ptP1)) * Z_AX() > 0 then + bFoundPrec = true + break + end + end + end + if not bFoundPrec then + nFirstFac = i + break + end + end + -- se trovata, la metto al primo posto + if nFirstFac and nFirstFac ~= 1 then + EgtSurfTmSwapFacets( nIdSurf, nFirstFac - 1, 0) + end + -- ordino le facce in modo da avere una sequenza ordinata con le normali a destra + for i = 1, nNumFacet - 1 do + -- centro e normale della faccia + local ptCen, vtN = EgtSurfTmFacetCenter( nIdSurf, i - 1, GDB_ID.ROOT) + -- cerco la successiva + for j = i + 1, nNumFacet do + -- verifico se è successiva + local bAdj, ptP1, _, _ = EgtSurfTmFacetsContact( nIdSurf, i - 1, j - 1, GDB_ID.ROOT) + if bAdj and ( vtN ^ ( ptP1 - ptCen)) * Z_AX() > 0 then + EgtSurfTmSwapFacets( nIdSurf, i, j - 1) + break + end + end + end +end + +--------------------------------------------------------------------- +local function RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFaceToDel) + -- copio la superfice nel gruppo ausiliario + local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + EgtSurfTmRemoveFacet( nNewProc, nFaceToDel) + local nNumFacet = EgtSurfTmFacetCount( nNewProc) + ReorderFaces( nNewProc, nNumFacet) + return nNewProc, nNumFacet +end + +--------------------------------------------------------------------- +local function GetFacesData( nNewProc, bOpposite, bCalclForBlade, dToolDiam, dToolMaxDepth, dToolThick, nAddGrpId, nPartId) + + local nNumFacet = EgtSurfTmFacetCount( nNewProc) + local vFace = {} + -- recupero i dati di tutte le facce + for i = 1, nNumFacet do + -- indici faccia corrente e precedente + local nFac = EgtIf( bOpposite, nNumFacet - i, i - 1) + local nPrecFac + if bOpposite then + nPrecFac = EgtIf( i == 1, 0, nFac + 1) + else + nPrecFac = EgtIf( i == 1, nNumFacet - 1, i - 2) + end + -- recupero centro e normale della faccia + local ptCen, vtN = EgtSurfTmFacetCenter( nNewProc, nFac, GDB_ID.ROOT) + -- recupero le dimensioni della faccia + local _, dLen, dWidth = WL.GetFaceHvRefDim( nNewProc, nFac) + -- recupero l'angolo con la faccia precedente + local bAdj, ptLocP1, ptLocP2, dAng = EgtSurfTmFacetsContact( nNewProc, nPrecFac, nFac, GDB_ID.ROOT) + -- verifico che l'adiacenza sia veramente con il precedente (percorro con normale a destra) + if bAdj then + if ( vtN ^ ( ptLocP1 - ptCen)) * Z_AX() > 0 then + bAdj = false + end + end + -- salvo i dati + vFace[i] = { Fac = nFac, Cen = ptCen, Norm = vtN, Len = dLen, Width = dWidth, AngPrev = EgtIf( bAdj, dAng, 0)} + if bAdj then + if ptLocP1:getZ() < ptLocP2:getZ() then + vFace[i].PPrev = ptLocP1 + else + vFace[i].PPrev = ptLocP2 + end + end + end + -- analizzo le facce + local dMaxWidth = 0 + for i = 1, #vFace do + -- aggiorno la massima larghezza + if vFace[i].Width > dMaxWidth then + dMaxWidth = vFace[i].Width + end + -- verifico l'affondamento + local dDepth = WD.CUT_EXTRA + if vFace[i].Width + WD.CUT_EXTRA > dToolMaxDepth then + dDepth = dToolMaxDepth - vFace[i].Width + end + -- lunghezza baffo + local dElev = vFace[i].Width + dDepth + local dWhisk = EgtIf( bCalclForBlade, ( dElev * sqrt( dToolDiam / dElev - 1) + WHISK_SAFE), (dToolDiam/2) + WHISK_SAFE) + -- determino la lunghezza del taglio passante e il tipo di attacco e uscita + local dLen = vFace[i].Len + local nType = 0 + if vFace[i].AngPrev < -0.1 then + dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0) + nType = nType + 1 + end + if vFace[EgtIf( i < nNumFacet, i + 1, 1)].AngPrev < -0.1 then + dLen = dLen - EgtIf( bCalclForBlade, dWhisk, 0) + nType = nType + 2 + end + -- se lunghezza non significativa, non va inserito il taglio + if dLen < MIN_LEN_CUT then + nType = 4 + end + vFace[i].Depth = dDepth + vFace[i].Whisk = dWhisk + vFace[i].Type = nType + end + -- recupero le regioni degli altri pezzi + local vOthers = GetOtherRegions( nPartId) + -- verifico i baffi sporgenti dei tagli rispetto alle altre regioni + for i = 1, #vFace do + -- verifico il baffo iniziale + if vFace[i].Type ~= 4 and ( vFace[i].Type & 1) == 0 then + -- creo il rettangolo del baffo + local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize() + local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), -90) + local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, -90) + local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt + local ptDir = ptIni + ( vFace[i].Whisk - WHISK_OFFS) * vtDir + local ptCross = ptDir + ( dToolThick - WHISK_OFFS) * vtOrt + local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB) + local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD) + -- verifico se interferisce con gli altri pezzi + for j = 1, #vOthers do + if OverlapsXY( b3Wh, vOthers[j].Box) then + local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0) + if nClass ~= GDB_RC.OUT then + local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 2) ~= 0, -vFace[i].Whisk, 0) + if dLen >= MIN_LEN_CUT then + vFace[i].Type = vFace[i].Type + 1 + else + vFace[i].Type = 4 + end + break + end + end + end + EgtErase( WhId) + end + -- verifico il baffo finale + if vFace[i].Type ~= 4 and ( vFace[i].Type & 2) == 0 then + -- creo il rettangolo del baffo + local vtOrt = Vector3d( vFace[i].Norm:getX(), vFace[i].Norm:getY(), 0) ; vtOrt:normalize() + local vtDir = Vector3d( vtOrt) ; vtDir:rotate( Z_AX(), 90) + local vtUp = Vector3d( vtDir) ; vtUp:rotate( vFace[i].Norm, 90) + local ptIni = vFace[i].Cen + vFace[i].Width / 2 * vtUp + ( vFace[i].Len / 2 + WHISK_OFFS) * vtDir + WHISK_OFFS * vtOrt + local ptDir = ptIni + ( vFace[i].Whisk - WHISK_OFFS) * vtDir + local ptCross = ptDir + ( dToolThick - WHISK_OFFS) * vtOrt + local WhId = EgtSurfFrRectangle3P( nAddGrpId, ptIni, ptCross, ptDir, GDB_RT.GLOB) + local b3Wh = EgtGetBBoxGlob( WhId or GDB_ID.NULL, GDB_BB.STANDARD) + -- verifico se interferisce con gli altri pezzi + for j = 1, #vOthers do + if OverlapsXY( b3Wh, vOthers[j].Box) then + local nClass = EgtSurfFrChunkSimpleClassify( WhId, 0, vOthers[j].RegId, 0) + if nClass ~= GDB_RC.OUT then + local dLen = vFace[i].Len - vFace[i].Whisk + EgtIf( ( vFace[i].Type & 1) ~= 0, -vFace[i].Whisk, 0) + if dLen >= MIN_LEN_CUT then + vFace[i].Type = vFace[i].Type + 2 + else + vFace[i].Type = 4 + end + break + end + end + end + EgtErase( WhId) + end + end + -- eventuali stampe + for i = 1, #vFace do + local Face = vFace[i] + local sOut = 'Face '..tostring( Face.Fac)..' C'..tostring( Face.Cen)..' N'..tostring( Face.Norm).. + ' L='..EgtNumToString( Face.Len, 1)..' W='..EgtNumToString( Face.Width, 1)..' Ap='..EgtNumToString( Face.AngPrev, 1).. + ' D='..EgtNumToString( Face.Depth, 1)..' B='..EgtNumToString( Face.Whisk, 1)..' T='..tostring( Face.Type) + EgtOutLog( sOut, 3) + end + + return vFace, dMaxWidth, nNewProc +end + +--------------------------------------------------------------------- +local function GetTunnelDimension( nId, nPartId, nAddGrpId) + -- ottengo i versori delle 4 facce e ottengo l'orientamento del tunnel + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nId) + -- recupero l'ingombro della trave + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + -- variabili dimensioni fessura e id faccia lunga + local dDimMin + local dDimMax + local nLongIdFace = 0 + local bNegFace + local bOppoFace = false + -- ottengo il versore ortogonale + local ptN1, vtN1 = EgtSurfTmFacetCenter( nId, 0, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( nId, 1, GDB_ID.ROOT) + local vtOrtho = vtN1 ^ vtN2 + if vtOrtho:isSmall() then + if nFacCnt >= 3 then + _, vtN2 = EgtSurfTmFacetCenter( nId, 2, GDB_ID.ROOT) + vtOrtho = vtN1 ^ vtN2 + bOppoFace = true + else + return + end + end + if vtOrtho:getZ() < -0.5 then + vtOrtho = -vtOrtho + bNegFace = true + end + -- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta la profondità della fessura + local frFc = Frame3d( ptN1, vtOrtho) ; + local bBoxLoc = EgtGetBBoxRef( nId, GDB_BB.STANDARD, frFc) + local dDepth = bBoxLoc:getDimZ() + -- mi assicuro che la Z del punto utilizzato per creare la superficie sia alla Z inferiore del bounding box locale + local ptN2 = Point3d(ptN1) + ptN2:toLoc(frFc) + ptN2 = Point3d( ptN2:getX(), ptN2:getY(), bBoxLoc:getMin():getZ() + 2*GEO.EPS_SMALL) + ptN2:toGlob(frFc) + -- creo superficie intermedia + local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN2, vtOrtho, b3Solid, GDB_ID.ROOT) + -- ritaglio la superficie con le facce della fessura + for i = 1, nFacCnt do + local ptN, vtN = EgtSurfTmFacetCenter( nId, i - 1, GDB_ID.ROOT) + EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT) + end + -- sposto la geometria trovata sulla Z minima (era su di 2 * GEO.EPS_SMALL) + EgtMove( nSurfInt, Point3d(0,0,-2*GEO.EPS_SMALL) - ORIG(), GDB_RT.GLOB) + -- mi faccio dare il contorno della superfice e la ricreo in modo più corretto + local nIdCont, nIdNum = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId) + -- elimino le entità allineate dello stesso tipo + EgtMergeCurvesInCurveCompo( nIdCont, 2*GEO.EPS_SMALL) + EgtErase(nSurfInt) + nSurfInt = EgtSurfTmByFlatContour( nAddGrpId, nIdCont, 2*GEO.EPS_SMALL) + -- elimino il contorno + EgtErase(nIdCont) + -- se normale negativa inverto + _, vtN1 = EgtSurfTmFacetCenter( nSurfInt, 0, GDB_ID.ROOT) + if vtN1:getZ() < -0.5 then EgtInvertSurf( nSurfInt) end + local _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT) + dDimMin = min( DimH, DimV) + dDimMax = max( DimH, DimV) + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nId, nFacCnt-1, GDB_ID.ROOT) + -- se faccia pari alla larghezza fessura + if abs(DimH - dDimMax) < GEO.EPS_SMALL or abs(DimV - dDimMax) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + -- altrimenti verifico anche con la faccia precedente + else + local nFaceToCheck = EgtIf( bOppoFace, nFacCnt-3, nFacCnt-2) + -- prendo le dimensioni della faccia e poi confronto con il minimo + _, DimH, DimV = EgtSurfTmFacetMinAreaRectangle( nId, nFaceToCheck, GDB_ID.ROOT) + -- se trovato con il minimo, questa seconda faccia non è la più lunga + if abs(DimH - dDimMin) < GEO.EPS_SMALL or abs(DimV - dDimMin) < GEO.EPS_SMALL then + nLongIdFace = nFacCnt-1 + else + nLongIdFace = nFaceToCheck + end + end + if not dDimMax then + return dDimMin, dDimMax, dDepth, nil, nil + end + return dDimMin, dDimMax, dDepth, vtOrtho, nLongIdFace, nSurfInt +end + +--------------------------------------------------------------------- +local function ReorderFacesFromTab( nIdSurf, vFace) + + local nFacCnt = EgtSurfTmFacetCount( nIdSurf) + for i = 1, #vFace do + for j = 1, nFacCnt do + -- ottengo punto iniziale e versore della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nIdSurf, (j-1), GDB_ID.ROOT) + -- se versore e posizione coincidono e non corrispondono al numero faccia, faccio lo swap + if AreSameVectorExact( vFace[i].Norm, vtN) and AreSamePointEpsilon( vFace[i].Cen, ptC, 50*GEO.EPS_SMALL) then + if j - 1 ~= vFace[i].Fac then + EgtSurfTmSwapFacets( nIdSurf, vFace[i].Fac, (j-1)) + end + break + end + end + end + return nIdSurf +end + +--------------------------------------------------------------------- +local function CalcInterference( nNewProc, vtExtr, ptCentr, dDiam1, dDiam2, + dTall1, dTall2, dDiam3, dTall3) + + local ptCentrGrid1 = ptCentr + ( vtExtr * 0.01) + local frOriTool = Frame3d( ptCentrGrid1, vtExtr) + local bColl1 = EgtCDeConeSolid( frOriTool, dDiam1/2, dDiam2/2, dTall1, nNewProc, 0, GDB_RT.GLOB) + if bColl1 then return true end + local ptCentrGrid2 = ptCentr + ( vtExtr * ( dTall1 + 0.01)) + frOriTool = Frame3d( ptCentrGrid2, vtExtr) + local bColl2 = EgtCDeCylSolid( frOriTool, dDiam2/2, (dTall2-dTall1), nNewProc, 0, GDB_RT.GLOB) + if bColl2 then return true end + local ptCentrGrid3 = ptCentr + ( vtExtr * ( dTall2 + 0.01)) + frOriTool = Frame3d( ptCentrGrid3, vtExtr) + local bColl3 = EgtCDeCylSolid( frOriTool, dDiam3/2, (dTall3-dTall2), nNewProc, 0, GDB_RT.GLOB) + if bColl3 then return true end + -- restituisco risultato controllo collisioni + return false +end + +--------------------------------------------------------------------- +local function MakeLocalSurf( ptP1, ptP2, ptP3, nAddGrpId) + + if not ptP1 or not ptP2 or not ptP3 then + return nil + end + + local pAuxId = {} + local nAuxId, AuxId + nAuxId = EgtLine( nAddGrpId, ptP1, ptP2, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + nAuxId = EgtLine( nAddGrpId, ptP2, ptP3, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + nAuxId = EgtLine( nAddGrpId, ptP3, ptP1, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- trasformo in percorso + if #pAuxId ~= 3 then + return nil + end + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + -- se non c'é il percorso esco + if not AuxId then + return nil + end + -- creo la superfice piana + local nidFace = EgtSurfTmByFlatContour( nAddGrpId, AuxId, 0.01) + if not nidFace then + EgtErase(AuxId) + return nil + end + -- se normale negativa inverto + local _, vtN1 = EgtSurfTmFacetCenter( nidFace, 0, GDB_ID.ROOT) + if vtN1:getZ() < -0.5 then EgtInvertSurf( nidFace) end + + EgtErase(AuxId) + return nidFace +end + +--------------------------------------------------------------------- +local function AddMillCornerMachining( nPartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, dOffsAng, dDepthMach, + bThruThick, dThSurf, dDiam1, dDiam2, dTall1, + dTall2, dDiam3, dTall3, bMakeLocSurf, vFace) + -- variabili costruzione geometria + local pAuxId = {} + local nAuxId + local ptApPoint + local AuxId + local nNewProcLoc + -- se devo creare superfice locale + if bMakeLocSurf then + -- creo superfice locale o esco + local nSurfToAdd = MakeLocalSurf( tFacAdj[1][7], tFacAdj[1][8], tFacAdj[1][9], nAddGrpId) + if nSurfToAdd then + local nFacCntPre = EgtSurfTmFacetCount( nNewProc) + -- creo copia del percorso principale e gli aggiungo la nuova faccia + nNewProcLoc = EgtCopyGlob( nNewProc, nAddGrpId) + nNewProcLoc = EgtSurfTmBySewing( nAddGrpId, {nNewProcLoc,nSurfToAdd} , true) + -- riordino le facce + nNewProcLoc = ReorderFacesFromTab( nNewProcLoc, vFace) + -- acquisisco il numero della faccia + nFacCnt = EgtSurfTmFacetCount( nNewProcLoc) + nFacInd = nFacCnt - 1 + else + local sErr = 'Cannot make local bottom surface' + EgtOutLog( sErr) + return true, '' + end + else + nNewProcLoc = nNewProc + end + -- prendo il primo versore + local _, vtN1 = EgtSurfTmFacetCenter( nNewProcLoc, nFacInd, GDB_ID.ROOT) + local _, vtN2 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1][1], GDB_ID.ROOT) + local _, vtN3 = EgtSurfTmFacetCenter( nNewProcLoc, tFacAdj[1][2], GDB_ID.ROOT) + -- trovo il punto sulla superfice di riferimento + local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1][1], GDB_ID.ROOT) + local _, ptLocP3, ptLocP4, _ = EgtSurfTmFacetsContact( nNewProcLoc, nFacInd, tFacAdj[1][2], GDB_ID.ROOT) + -- se ho creato faccia locale su copia superficie, cancella la copia + if bMakeLocSurf then + EgtErase( nNewProcLoc) + end + local nIdIniPoint + local nIdEndPoint + if ptLocP1 and ptLocP2 then + if ( dist( ptLocP1, tFacAdj[1][4]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[1][4]) < GEO.EPS_SMALL) then + nIdEndPoint = 4 + nIdIniPoint = 5 + elseif ( dist( ptLocP1, tFacAdj[1][5]) < GEO.EPS_SMALL) or ( dist( ptLocP2, tFacAdj[1][5]) < GEO.EPS_SMALL) then + nIdEndPoint = 5 + nIdIniPoint = 4 + end + end + -- versore direzione + local vtExtr = tFacAdj[1][nIdIniPoint] - tFacAdj[1][nIdEndPoint] + vtExtr:normalize() + -- versore direzione di uscita + local vtExtrExit + -- inserisco le prime tre linee + if nIdIniPoint and nIdEndPoint then + -- se fresatura da sotto salto la lavorazione + if vtExtr:getZ() < WD.DRILL_VZ_MIN then + local sErr = 'Error : Impossible insert clean corner from bottom' + EgtOutLog( sErr) + return false, sErr + end + -- sommo i tre versori per avere una direzione media + vtExtrExit = vtN2 + vtN3 + vtExtrExit:normalize() + -- se tipo 1 calcolo angolo tilt di 45° + if nTypeConeCut == 1 then + vtExtr = vtExtrExit + Z_AX() + -- altrimenti tipo 2, calcolo angolo tilt di 33° (dalla verticale) + else + vtExtr = vtExtrExit + Vector3d(0,0,1.539865) + end + vtExtr:normalize() + local vtCheck = Vector3d(vtExtr) + -- se ho un offset angolare ruoto il percorso + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + vtCheck:rotate( Z_AX(), dOffsAng) + end + -- controllo se c'è collisione con le facce della superfice + if nTypeConeCut == 1 and CalcInterference( nNewProc, vtCheck, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), dDiam1, dDiam2, + dTall1, dTall2, dDiam3, dTall3) then + local sErr = 'Collision detect from clean corner tool and surface' + EgtOutLog( sErr) + return true, '' + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdIniPoint], tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- se uso utensile cono 60° + if nTypeConeCut == 1 then + -- se offset angolare valido e/o negativo creo il baffo precedente + if dOffsAng < ( 100 * GEO.EPS_SMALL) then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[1][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + local dLenTrimExt = dist( tFacAdj[1][nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + Point3d( 0, 0, dDepthMach) + else + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint + Point3d( 0, 0, -dDepthMach), tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + end + end + -- inserisco le ultime tre linee + -- trovo il secondo punto sulla superfice di riferimento + ptLocP1, ptLocP2 = ptLocP3, ptLocP4 + if ptLocP1 and ptLocP2 then + -- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro + if dist( tFacAdj[1][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then + ptApPoint = ptLocP2 + else + ptApPoint = ptLocP1 + end + -- se uso utensile cono 60° + if nTypeConeCut == 1 then + -- se offset angolare valido e/o negativo creo il baffo precedente + if dOffsAng > -( 100 * GEO.EPS_SMALL) then + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + local dLenTrimExt = dist( tFacAdj[1][nIdEndPoint], ptApPoint) - (( dToolDiam/2) + 0.2) + -- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta + if dLenTrimExt > 10 * GEO.EPS_SMALL then + EgtTrimExtendCurveByLen( nAuxId , -dLenTrimExt, ptApPoint + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + -- prendo il nuovo punto finale + ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB) + Point3d( 0, 0, dDepthMach) + else + -- se ho l'offset angolare ruoto la linea per compensare la rotazione che verrà applicata + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( nAuxId, tFacAdj[1][nIdEndPoint], Z_AX(), -dOffsAng, GDB_RT.GLOB) + end + end + table.insert( pAuxId, nAuxId) + -- creo linea di ritorno + nAuxId = EgtLine( nAddGrpId, ptApPoint + Point3d( 0, 0, -dDepthMach), tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + -- ultima linea di distacco (5mm in direzione utensile) + local pEnd = tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach) + ( 5 * vtExtr) + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint] + Point3d( 0, 0, -dDepthMach), pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + else + -- linea di distacco (2mm in direzione utensile) + local pEnd = tFacAdj[1][nIdEndPoint] + ( 2 * vtExtr) + nAuxId = EgtLine( nAddGrpId, tFacAdj[1][nIdEndPoint], pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + -- ultima linea di risalita in Z + local pIni = pEnd + pEnd = pIni + ( dThick * Z_AX()) + nAuxId = EgtLine( nAddGrpId, pIni, pEnd, GDB_RT.GLOB) + table.insert( pAuxId, nAuxId) + end + end + -- trasformo in percorso + if #pAuxId > 0 then + AuxId = EgtCurveCompo( nAddGrpId, pAuxId, true) + end + -- se non c'é il percorso do errore + if not AuxId then + local sErr = 'Error : impossible make clean corner path' + EgtOutLog( sErr) + return false, sErr + end + -- modifico versore direzione + EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB) + -- se ho un offset angolare ruoto il percorso + if abs(dOffsAng) > 100 * GEO.EPS_SMALL then + EgtRotate( AuxId, tFacAdj[1][nIdEndPoint], Z_AX(), dOffsAng, GDB_RT.GLOB) + end + -- inserisco la lavorazione + local sName = 'Clean_' .. ( EgtGetName( nNewProc) or tostring( nNewProc)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', nPartId) + -- se flag lavorazione spessore passante setto la nota per spostarla dopo i tagli di lama + if bThruThick and nTypeConeCut == 1 then + EgtSetInfo( nMchId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- 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) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 4) + -- allungo inizio e fine di 10mm + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 10) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 10) + -- setto affondamento 0 + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- Note utente con dichiarazione nessuna generazione sfridi per Vmill + local sUserNotes = 'VMRS=0;' + -- aggiungo alle note massima elevazione +-- sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';' + sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( 0.0, 1) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + 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 + end + end + + return true, '' +end + +--------------------------------------------------------------------- +local function AddMillCorner( nTypeConeCut, vFace, Proc, nRawId, b3Raw, + dToolDiam, nAddGrpId, dThick, nMasterNewProc, dDepthMach, + bThruThick) + + local sMilling, dMaxDepth + -- se ripresa angolo con fresa cono 60° con ripresa + if nTypeConeCut == 1 then + -- recupero la lavorazione di fresatura + sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner60') + if not sMilling then + local sErr = 'Error : CleanCorner 60 not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- se ripresa angolo con fresa cono piccola senza ripresa + else + sMilling, dMaxDepth = WM.FindMilling( 'CleanCorner30') + if not sMilling then + local sErr = 'Error : CleanCorner 30 not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMillTotDiam = 20 + local dMillDiamTh = 20 + local dToolLength = 20 + local dThickTool = 20 + local dSideAng = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh + dMillTotDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) or dMillTotDiam + dSideAng = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAng + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dThickTool = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThickTool + dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth -- qui è la distanza dal portautensile + -- calcolo il secondo diametro del cono + dMillTotDiam = dMillDiam + ( abs(dThickTool) * tan(dSideAng)) * 2 + end + end + -- copio la feature nel layer di appoggio + local nNewProc + if nMasterNewProc then + nNewProc = nMasterNewProc + else + nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL + end + local nFacCnt = EgtSurfTmFacetCount( nNewProc) + local nFacInd, dDimMin, dDimMax, dDepth, nSurfInt + local bMakeLocSurf + if nFacCnt <= 4 then + -- ottengo le dimensioni apertura, la normale e la faccia inferiore + dDimMin, dDimMax, dDepth, _, _, nSurfInt = GetTunnelDimension( nNewProc, Proc.PartId, nAddGrpId) + if nSurfInt then + -- uso la dimensione minima anche nel caso che la cava sborda perchè la lavorazione potrebbe collidere con un pezzo limitrofo + local dMinWidth = dDimMin + nNewProc = EgtSurfTmBySewing( nAddGrpId, {nNewProc,nSurfInt} , true) + -- riordino le facce + nNewProc = ReorderFacesFromTab( nNewProc, vFace) + -- acquisisco il numero della faccia + nFacCnt = EgtSurfTmFacetCount( nNewProc) + nFacInd = nFacCnt - 1 + else + local sErr = 'Error : cannot create base surface' + EgtOutLog( sErr) + return false, sErr + end + else + bMakeLocSurf = true + end + -- verifico se ciclo chiuso + local bClosed = ( abs( vFace[1].AngPrev) > 0.1) + -- ciclo di inserimento delle fresate sulle facce del contorno in esame + local i = 1 + -- se faccia finale con fine non lavorato, forzo partenza da prima faccia non tutta saltata (tipo 4) + if bClosed and ( vFace[#vFace].Type == 4 or ( vFace[#vFace].Type & 2) ~= 0) then + while i <= #vFace and vFace[i].Type == 4 do + i = i + 1 + end + end + -- se facce tutte da saltare, parto dall'inizio + local bAllType4 = ( i > #vFace) + if bAllType4 or bClosed then i = 1 end + while i <= #vFace do + -- se tutta la faccia o la sua fine senza taglio, inserisco una fresatura + if ( vFace[i].Type & 2) ~= 0 or vFace[i].Type == 4 then + -- variabili costruzione geometria + local tFacAdj = {} + local nFace1 = vFace[i].Fac + local nFace2 + -- ricavo i tre punti per eventuale superficie locale + local ptLoc1, ptLoc2, ptLoc3 + -- punto precedente (punto precedente della faccia [i]) + ptLoc3 = vFace[i].PPrev + -- aggiungo geometria + i = i + 1 + local j = EgtIf( i <= #vFace, i, EgtIf( bClosed, 1, nil)) + if not j then + return true + end + nFace2 = vFace[j].Fac + -- punto in comune tra le due facce (punto precedente della faccia [j]) + ptLoc1 = vFace[j].PPrev + -- punto successivo ( precedente della faccia successiva) + j = j + 1 + local k = EgtIf( j <= #vFace, j, EgtIf( bClosed, 1, nil)) + -- se è un percorso aperto prendo il punto medio della seconda faccia come punto locale 2 + if not k then + ptLoc2 = Point3d( vFace[j-1].Cen:getX(), vFace[j-1].Cen:getY(), ptLoc1:getZ()) + else + ptLoc2 = vFace[k].PPrev + end + -- ricavo i punti e l'angolo interno + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( nNewProc, nFace1, nFace2, GDB_ID.ROOT) + -- se punti validi e angolo è interno e non è quasi piatto e >= 90 creo istanza + if ptP1 and ptP2 and dAng < 0 and dAng < -6 and dAng > EgtIf( nTypeConeCut == 1, -(90 + 10 * GEO.EPS_SMALL), -(180-dAngleSmall + 10 * GEO.EPS_SMALL)) then + local dLen = dist( ptP1, ptP2) + table.insert( tFacAdj, { nFace1, nFace2, dLen, ptP1, ptP2, dAng, ptLoc1, ptLoc2, ptLoc3}) + end + -- se ho un elemento creo percorso o percorsi in base al tipo di cono e all'apertura dall'angolo rispetto ai 90° + -- con una tolleranza di 2 gradi + if #tFacAdj > 0 then + if nTypeConeCut == 1 and bMakeTwinCut and (dAng + 90) > 2 then + local dAngOffs = (dAng + 90) / 2 + -- primo taglio + local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, -dAngOffs, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + -- secondo taglio + bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, dAngOffs, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + -- altrimenti ho un solo percorso + else + local bOk, sErr = AddMillCornerMachining( Proc.PartId, nNewProc, nFacInd, tFacAdj, nTypeConeCut, nAddGrpId, + dToolDiam, dThick, sMilling, 0, dDepthMach, + bThruThick, dDepth, dMillDiam, dMillTotDiam, abs(dThickTool), + dMaxDepth, dMillDiamTh, dToolLength, bMakeLocSurf, vFace) + if not bOk then return bOk, sErr end + end + end + else + i = i + 1 + end + end + -- cancello la copia della superfice + if nNewProc then + EgtErase(nNewProc) + end + return true +end + +--------------------------------------------------------------------- +local function MakeByChainSaw( Proc, nFacet, nRawId, b3Raw, dElev, dH, dV) + local sWarn + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacet)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error : main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Cerco una faccia adiacente alla principale sul lato più lungo + local nFacAdj + local dMaxLen = 0 + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacet, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + local vtAdjN = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT) + if dLen > dMaxLen - 1 and vtAdjN:getZ() > -0.1 then + nFacAdj = vAdj[i] + dMaxLen = dLen + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) + end + end + end + if not nFacAdj then + local sErr = 'Error : long adjacent face not found' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero la lavorazione + local sSawing = WM.FindSawing( 'Sawing') + if not sSawing then + local sErr = 'Error : chainsawing not found in library' + EgtOutLog( sErr) + return false, sErr, 'MNF' + end + -- Recupero i dati dell'utensile + local dSawWidth = 75 + local dSawThick = 8 + local dMaxDepth = 200 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + if dSawThick > dV + 10 * GEO.EPS_SMALL then + local sErr = 'Error : chainsaw too thick' + EgtOutLog( sErr) + return false, sErr + end + -- Calcolo uso faccia + local nFaceUse = WL.GetNearestParalOpposite( vtN) + -- Calcolo angolo 3° asse rot (da direz. utensile) + local sRot3Ang = 'A1=180' + if WD.GetChainSawBlockedAxis then + sRot3Ang = WD.GetChainSawBlockedAxis( 1) + end + -- Calcolo angoli iniziali suggeriti + local sStartAngs + if WD.GetChainSawStartAngs then + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) + sStartAngs = WD.GetChainSawStartAngs( vtN2) + end + -- Lati chiusi + local bOpenStart = false + local bOpenEnd = false + -- Verifico se necessarie più passate + local nStep = ceil( ( dV - 10 * GEO.EPS_SMALL) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- Applico la lavorazione con sega a catena a questa faccia + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, sRot3Ang) + -- imposto angoli iniziali suggeriti + if sStartAngs then + EgtSetMachiningParam( MCH_MP.INITANGS, sStartAngs) + end + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- se necessario, limito l'affondamento + if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')' + dDepth = dMaxDepth - dElev + EgtOutLog( sWarn) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH '..EgtNumToString( dDepth, 1)) + end + -- imposto elevazione + local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 2) .. ';' + EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + elseif EgtIsMachiningEmpty() then + _, sWarn = EgtGetMachMgrWarning( 0) + EgtSetOperationMode( nMchFId, false) + return false, sWarn + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nFacet, nOthFac, nRawId, b3Raw, dSideDist) + -- dati della faccia e dell'altra + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local dDiam = min( dH, dV) + local _, vtRef = EgtSurfTmFacetCenter( Proc.Id, nOthFac, GDB_ID.ROOT) + -- recupero la lavorazione + local sMilling = WM.FindMilling( 'Side') + if not sMilling then return false end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMillLen = 10 + local dMillTotLen = 30 + local dMaxDepth = 0 + local dThDiam = 100 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMillLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dMillLen + dMillTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dMillTotLen + dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + end + end + if dMillDiam < dDiam or dMaxDepth < dElev then + local sErr = 'Error : Side Elevation too big' + EgtOutLog( sErr) + return false, sErr + end + local dMillExtra = dMillTotLen - dMillLen + if Proc.Box:getMin():getZ() - dMillExtra < b3Raw:getMin():getZ() - 10 * GEO.EPS_SMALL then + local sErr = 'Error : Tool collide with table' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di contornatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + -- sistemo i parametri di attacco e uscita + local dAddLen = ( WD.MID_GAP or 50) - ( WD.MID_SIC or 5) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) -- -dMillDiam/2 + dAddLen) + EgtSetMachiningParam( MCH_MP.LITANG, 0) + EgtSetMachiningParam( MCH_MP.LIPERP, dSideDist + WD.CUT_SIC) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) -- -dMillDiam/2 + dAddLen) + EgtSetMachiningParam( MCH_MP.LOTANG, 0) + EgtSetMachiningParam( MCH_MP.LOPERP, dSideDist + WD.CUT_SIC) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto modo di lavorare la faccia + local nFaceUse = WL.GetNearestOrthoOpposite( vtRef, vtN) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, sCustomMach, dMaxDepthOnSide, bEnablePreMill, bMachFromDn, dAng, bAsEnablePreMill, nSinglePass) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local dThick = min( dH, dV) + local frFace = Frame3d( ptC, vtN) + local b3Proc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFace) + local dSideElev = b3Proc:getDimZ() + local sMilling + -- se ho lavorazione custom + if sCustomMach then + sMilling = sCustomMach + -- altrimenti la cerco + else + sMilling = WM.FindMilling( 'SideGroove') + end + if not sMilling then + local sErr = 'Error : SideGroove not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMillLen = 10 + local dMillTotLen = 30 + local dMaxMat = 0 + local dMillDiamTh = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMillLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dMillLen + dMillTotLen = EgtTdbGetCurrToolParam( MCH_TP.TOTLEN) or dMillTotLen + if ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE) ~= 0 then + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dMaxMat + if not dMaxDepthOnSide or dMaxDepthOnSide < 0.1 then + dMaxDepthOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + end + else + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + if not dMaxDepthOnSide or dMaxDepthOnSide < 0.1 then + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') + end + end + dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh + end + end + local dMaxSideElev = EgtIf( dMaxDepthOnSide and dMaxDepthOnSide > 0, dMaxDepthOnSide, dMillDiam / 2 - 30) + -- se profondità ribasso è maggiore della capacità dichiarata nelle note o di quella netta al gambo utensile + if ( not bEnablePreMill and bMachFromDn) and ( dElev > dMaxSideElev or dElev >= ( 0.5 * ( dMillDiam - dMillDiamTh))) then + local sErr = 'Error : Side Elevation too big' + EgtOutLog( sErr) + return false, sErr + end + local dMillExtra = dMillTotLen - dMillLen + if Proc.Box:getMin():getZ() - dMillExtra < b3Raw:getMin():getZ() - 10 * GEO.EPS_SMALL then + local sErr = 'Error : Tool collide with table' + EgtOutLog( sErr) + return false, sErr + end + if Proc.Fct == 2 and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + 100 * GEO.EPS_SMALL and dMaxMat > dThick + 10 * GEO.EPS_SMALL then + local sErr = 'Error : Tool thickness is too big' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che la lavorazione sia passante dal grezzo + local dLongGorge = max( dH, dV) + local dExtraLongExtPlus = 0 + local dExtraLongExtNeg = 0 + local dExtraLongIni = 0 + local dExtraLongEnd = 0 + local bStartPos + local bInvertMach + local nModifyLeadInOut = 0 + local nFace2ndFace + local dMaxDistToOut = EgtIf( bMachFromDn, 1800, 300) + -- se orientato lungo la Y + if abs( vtN:getX()) > 0.866 then + dExtraLongExtPlus = abs( Proc.Box:getMax():getY() - b3Raw:getMax():getY()) + dExtraLongExtNeg = abs( Proc.Box:getMin():getY() - b3Raw:getMin():getY()) + if dLongGorge + dMillDiamTh < b3Raw:getDimY() then + nModifyLeadInOut = 1 + -- se non può sbordare da nessuna parte do errore + if dExtraLongExtPlus > dMaxDistToOut and dExtraLongExtNeg > dMaxDistToOut and dElev > dMaxDistToOut then + local sErr = 'Error : Not possible insert SideMill groove machining' + EgtOutLog( sErr) + return false, sErr + end + -- se non sborda solo dai lati + if dElev < dExtraLongExtPlus and dElev < dExtraLongExtNeg then + nModifyLeadInOut = 2 + end + end + -- se la distanza superiore è minore della distanza inferiore segno di partire dalla parte positiva + if dExtraLongExtPlus < dExtraLongExtNeg then + bStartPos = true + end + -- se normale su X positivo parte dall'alto + if vtN:getX() > 0.866 then + -- se deve partire dalla parte negativa setto il flag di inversione lavorazione + if not bStartPos then + bInvertMach = true + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + else + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + end + -- asseggno lato di lavoro seconda faccia + if bMachFromDn then + nFace2ndFace = MCH_MILL_FU.ORTUP_LEFT + else + nFace2ndFace = MCH_MILL_FU.ORTHO_LEFT + end + -- altrimenti normale su X negativa parte dal basso + else + -- se deve partire dalla parte positiva setto il flag di inversione lavorazione + if bStartPos then + bInvertMach = true + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + else + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + end + -- asseggno lato di lavoro seconda faccia + if bMachFromDn then + nFace2ndFace = MCH_MILL_FU.ORTUP_RIGHT + else + nFace2ndFace = MCH_MILL_FU.ORTHO_RIGHT + end + end + -- altrimenti orientato lungo la X + elseif abs( vtN:getY()) > 0.866 then + dExtraLongExtPlus = abs( Proc.Box:getMax():getX() - b3Raw:getMax():getX()) + dExtraLongExtNeg = abs( Proc.Box:getMin():getX() - b3Raw:getMin():getX()) + if dLongGorge + dMillDiamTh < b3Raw:getDimX() then + nModifyLeadInOut = 1 + -- se non può sbordare da nessuna parte do errore + if dExtraLongExtPlus > dMaxDistToOut and dExtraLongExtNeg > dMaxDistToOut and dElev > dMaxDistToOut then + local sErr = 'Error : Not possible insert SideMill groove machining' + EgtOutLog( sErr) + return false, sErr + end + -- se non sborda solo dai lati + if dElev < dExtraLongExtPlus and dElev < dExtraLongExtNeg then + nModifyLeadInOut = 2 + end + end + -- se la distanza positiva è minore della distanza negativa segno di partire dalla parte positiva + if dExtraLongExtPlus < dExtraLongExtNeg then + bStartPos = true + end + -- se normale su Y positivo parte da sinistra (parte negativa) + if vtN:getY() > 0.866 then + -- se deve partire dalla parte positiva setto il flag di inversione lavorazione + if bStartPos then + bInvertMach = true + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + else + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + end + -- assegno lato di lavoro seconda faccia + if bMachFromDn then + nFace2ndFace = MCH_MILL_FU.ORTUP_FRONT + else + nFace2ndFace = MCH_MILL_FU.ORTHO_FRONT + end + -- altrimenti normale su Y negativa parte da destra (parte positiva) + else + -- se deve partire dalla parte negativa setto il flag di inversione lavorazione + if not bStartPos then + bInvertMach = true + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + else + dExtraLongIni = EgtIf( nModifyLeadInOut == 2, 1, dExtraLongExtPlus + dMillDiam/2 + 5) + dExtraLongEnd = EgtIf( nModifyLeadInOut > 0, 1, dExtraLongExtNeg + dMillDiam/2 + 5) + end + -- assegno lato di lavoro seconda faccia + if bMachFromDn then + nFace2ndFace = MCH_MILL_FU.ORTUP_BACK + else + nFace2ndFace = MCH_MILL_FU.ORTHO_BACK + end + end + end + if not bEnablePreMill and not bAsEnablePreMill then + dExtraLongIni = 0 + dExtraLongEnd = 0 + end + -- se ho abilitato la lavorazione di fresatura per garantire passaggio gambo utensile, inserisco la lavorazione + local bThroughRaw = false + if bEnablePreMill then + -- verifico se feature e' passante + if ((Proc.Box:getMin():getX() < ( b3Raw:getMin():getX() + 50)) and (Proc.Box:getMax():getX() > ( b3Raw:getMax():getX() - 50))) or + ((Proc.Box:getMin():getY() < ( b3Raw:getMin():getY() + 50)) and (Proc.Box:getMax():getY() > ( b3Raw:getMax():getY() - 50))) then + bThroughRaw = true + end + + -- recupero la lavorazione di taglio + local sCuttingGorge = WM.FindCutting( 'Standard') + if not sCuttingGorge then + local sErr = 'Error : Sawblade not found in library' + EgtOutLog( sErr) + return false, sErr + end + + -- acquisisco dati utensile lama + local dSawThickness = 0 + local dSawDiam = 0 + if EgtMdbSetCurrMachining( sCuttingGorge) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawThickness = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThickness + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + + -- calcolo larghezza canale + local dGorgeWidth = dMillDiam + -- verifico se elevazione minore per fare meno tagli + if dElev + 2 * WD.COLL_SIC < dGorgeWidth then + dGorgeWidth = max( dElev + 2 * WD.COLL_SIC, 0) + end + + -- sottraggo lato esterno lapjoint per ottenere larghezza netta del gorge + dGorgeWidth = dGorgeWidth - dSideElev + + -- calcolo quanti passi devo fare in larghezza per scaricare l'area di impegno utensile + local nNumStep = ceil( ( dGorgeWidth) / ( WD.SAWGORGE_INTERAX or 100)) + -- calcolo larghezza passate + local dC = 0 + if ( nNumStep - 1) > 0 then + dC = ( dGorgeWidth) / ( nNumStep) + else + nNumStep = 1 + end + + -- dati utensile fresa piccola + local dMillDiamFirst = 0 + local dMaxMatFirst = 0 + local bMillInvert = false + local bSawInvertSE = false + + -- se non passante, aggiungo fresatura area della fresa + if not bThroughRaw and nNumStep - 1 > 0 then + local SquareId -- Id della composita da fresare + local dSawShortening = sqrt( b3Raw:getDimZ() * ( dSawDiam - b3Raw:getDimZ())) -- da calcolare in base a raggio lama e spessore grezzo + -- gruppo ausiliario + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + -- disegno quadrato di fresatura + local p3Start + -- se orientato lungo la Y (direzione) + if abs( vtN:getX()) > 0.866 then + local dStartX = EgtIf( vtN:getX() > 0.866, Proc.Box:getMax():getX(), Proc.Box:getMin():getX()) + local dStartY = EgtIf( bStartPos, Proc.Box:getMin():getY(), Proc.Box:getMax():getY()) + p3Start = Point3d( dStartX, dStartY, Proc.Box:getMin():getZ()) + local vtNPerp = Vector3d( vtN) + vtNPerp:rotate(-Z_AX(), 90 * EgtIf( bStartPos, 1, -1) * EgtIf( vtN:getX() > 0.866, 1, -1)) + local FirstLineId = EgtLinePVL( nAddGrpId, p3Start, vtNPerp, dMillDiam / 2 , GDB_RT.GLOB) -- Y_AX() + local SecondLineId = EgtLinePVL( nAddGrpId, EgtEP( FirstLineId, GDB_RT.GLOB), vtN, dMillDiam - dSideElev, GDB_RT.GLOB) -- -X_AX() + local dThirdLineLen = min( (dMillDiam / 2) + ( Proc.Box:getMax():getY() - Proc.Box:getMin():getY()), dSawShortening + 10) + local ThirdLineId = EgtLinePVL( nAddGrpId, EgtEP( SecondLineId, GDB_RT.GLOB), -vtNPerp, dThirdLineLen, GDB_RT.GLOB) -- -Y_AX() + local FourthLineId = EgtLinePVL( nAddGrpId, EgtEP( ThirdLineId, GDB_RT.GLOB), -vtN, dMillDiam -dSideElev , GDB_RT.GLOB) -- X_AX() + SquareId = EgtCurveCompo( nAddGrpId, { FirstLineId, SecondLineId, ThirdLineId, FourthLineId}) + bMillInvert = EgtIf( vtN:getX() > 0.866, not (bStartPos or false), bStartPos or false) + bSawInvertSE = EgtIf( vtN:getX() > 0.866, bStartPos or false, not (bStartPos or false)) + -- altrimenti orientato lungo la X + elseif abs( vtN:getY()) > 0.866 then + local dStartX = EgtIf( bStartPos, Proc.Box:getMin():getX(), Proc.Box:getMax():getX()) + local dStartY = EgtIf( vtN:getY() > 0.866, Proc.Box:getMax():getY(), Proc.Box:getMin():getY()) + p3Start = Point3d( dStartX, dStartY, Proc.Box:getMin():getZ()) + local vtNPerp = Vector3d( vtN) + vtNPerp:rotate(-Z_AX(), 90 * EgtIf( bStartPos, -1, 1) * EgtIf( vtN:getY() > 0.866, 1, -1)) + local FirstLineId = EgtLinePVL( nAddGrpId, p3Start, vtNPerp, dMillDiam / 2 , GDB_RT.GLOB) -- Y_AX() + local SecondLineId = EgtLinePVL( nAddGrpId, EgtEP( FirstLineId, GDB_RT.GLOB), vtN, dMillDiam -dSideElev, GDB_RT.GLOB) -- -X_AX() + local dThirdLineLen = min( (dMillDiam / 2) + ( Proc.Box:getMax():getX() - Proc.Box:getMin():getX()), dSawShortening + 10) + local ThirdLineId = EgtLinePVL( nAddGrpId, EgtEP( SecondLineId, GDB_RT.GLOB), -vtNPerp, dThirdLineLen, GDB_RT.GLOB) -- -Y_AX() + local FourthLineId = EgtLinePVL( nAddGrpId, EgtEP( ThirdLineId, GDB_RT.GLOB), -vtN, dMillDiam -dSideElev , GDB_RT.GLOB) -- X_AX() + SquareId = EgtCurveCompo( nAddGrpId, { FirstLineId, SecondLineId, ThirdLineId, FourthLineId}) + bMillInvert = EgtIf( vtN:getY() > 0.866, bStartPos or false, not (bStartPos or false)) + bSawInvertSE = EgtIf( vtN:getY() > 0.866, not (bStartPos or false), bStartPos or false) + end + + -- recupero la lavorazione + local sMillingGorge = WM.FindMilling( 'Gorge', nil, nil, nil, 80) + if not sMillingGorge then + local sErr = 'Error : Gorge not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- acquisisco dati utensile + if EgtMdbSetCurrMachining( sMillingGorge) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiamFirst = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiamFirst + dMaxMatFirst = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMatFirst + end + end + -- inserisco la lavorazione di fresatura + local sNameGorge = 'Gorge_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. tostring( nFacet) .. '_' .. tostring( nNm) + local nMchFId = EgtAddMachining( sNameGorge, sMillingGorge) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameGorge .. '-' .. sMillingGorge + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( SquareId) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if abs( vtN:getZ()) < GEO.EPS_SMALL then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto modo di lavorare la faccia + local nFaceUse = WL.GetNearestParalOpposite( Z_AX(), vtN) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto elevazione e step + local dStep = EgtGetMachiningParam( MCH_MP.STEP) + if dStep < GEO.EPS_SMALL then dStep = dMaxMat end + ---- se sto lavorando la gola centrale setto l'elevazione e l'affondamento + --if nSinglePass and nSinglePass == 0 then + -- local dZElev = b3Raw:getDimZ() + -- local dDepth = Proc.Box:getMax():getZ() - b3Raw:getMin():getZ() + -- EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dZElev, 3) .. ';') + -- EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + --end + EgtSetMachiningParam( MCH_MP.STEP, dStep) + -- imposto invert in base al lato fresa + local bWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE) + if bWorkSide == MCH_MILL_WS.RIGHT then + bMillInvert = not bMillInvert + end + EgtSetMachiningParam( MCH_MP.INVERT, bMillInvert) + -- aggiungo allungamenti iniziali e finali + EgtSetMachiningParam( EgtIf( bMillInvert, MCH_MP.STARTADDLEN, MCH_MP.ENDADDLEN), -dMillDiamFirst / 2 - dSawThickness / 2) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + -- inserisco la lavorazione + local nNm = 0 + -- passi di allargamento + for i = 1, nNumStep - 1 do + nNm = nNm + 1 + -- inserisco la lavorazione di taglio sfrido gorge + local sNameGorge = 'GorgeCut_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. tostring( nFacet) .. '_' .. tostring( nNm) + local nMchFId = EgtAddMachining( sNameGorge, sCuttingGorge) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameGorge .. '-' .. sCuttingGorge + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- assegno invert + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- assegno il lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) -- EgtIf( bMillInvert, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)) + -- assegno l'attacco e l'uscita + if not bThroughRaw and bSawInvertSE then + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.CENT) + -- aggiungo allungamento finale + if not bThroughRaw then + EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( dMillDiam / 2) - ( dMillDiamFirst / 2)) + end + elseif not bThroughRaw and not bSawInvertSE then + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LO.CENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LI.STRICT) + -- aggiungo allungamento finale + if not bThroughRaw then + EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( dMillDiam / 2) - ( dMillDiamFirst / 2)) + end + else + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LO.CENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LI.CENT) + end + -- aggiungo l'offset laterale + EgtSetMachiningParam( MCH_MP.OFFSL, ( dSideElev - dSawThickness + ( dC * ( i)))) + -- nessun criterio per il braccio è necessario + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + -- inserisco la lavorazione di ribasso o gola + local sName = EgtIf( bEnablePreMill ~= nil, 'SideMill_', 'Mill_') .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- se ho abilitato la lavorazione di lama per garantire passaggio utensile, setto la nota per spostare la fresatura dopo i tagli di lama + if bEnablePreMill or bAsEnablePreMill then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + -- imposto posizione braccio porta testa + --local nSCC = MCH_SCC.ADIR_ZP + --if abs( vtN:getZ()) < GEO.EPS_SMALL then + -- nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + --end + local nSCC = MCH_SCC.ADIR_NEAR + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto modo di lavorare la faccia + local nFaceUse = WL.GetNearestParalOpposite( Z_AX(), vtN) + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto elevazione e step + local dStep = EgtGetMachiningParam( MCH_MP.STEP) + if dStep < GEO.EPS_SMALL then dStep = 0.75 * dMaxMat end + local nStep = ceil( ( dThick - dMaxMat) / dStep) + dStep = max( ( dThick - dMaxMat) / max( nStep, 1), 0) + local dMaxElev = max( ( nStep + 1) * dStep - GEO.EPS_SMALL, 0) + if nSinglePass and nSinglePass > 0 then + dStep = 0 + if nSinglePass == 1 then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) + end + end + EgtSetMachiningParam( MCH_MP.STEP, dStep) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMaxElev, 3) .. ';') + -- setto il lato di lavoro standard + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- modifico ingressi e uscita + -- se ho inserito il pretaglio modifico + if bEnablePreMill or bAsEnablePreMill then + if nModifyLeadInOut > 0 then + -- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita + if dElev > ( 0.5 * dMillDiam) then + if nModifyLeadInOut == 1 then + -- setto il tipo di passo a una via + EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.ONEWAY) + -- modifico il tipo di uscita + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.PERP_TG) + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + -- modifico dati supplementari uscita + EgtSetMachiningParam( MCH_MP.LOPERP, 0.5) + EgtSetMachiningParam( MCH_MP.LOTANG, -( dLongGorge + dExtraLongIni + dExtraLongEnd)) + else + EgtSetMachiningParam( MCH_MP.LIPERP, dElev) + EgtSetMachiningParam( MCH_MP.LOPERP, dElev) + end + end + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + if bInvertMach then + -- setto il lato di lavoro invertito + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + else + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + -- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita + if dElev > ( 0.5 * dMillDiam) then + -- setto allungamenti perpendicolari + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + end + end + -- se richiesto, setto la nota per spostare la lavorazione alla fine + if not WD.SIDEMILL_BEFORE then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + else + if nModifyLeadInOut > 0 then + -- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita + if dElev > ( 0.5 * dMillDiam) then + -- setto il tipo di passo a una via + EgtSetMachiningParam( MCH_MP.STEPTYPE, 1) + end + if bInvertMach then + -- setto il lato di lavoro invertito + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + end + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + -- se richiesto, setto la nota per spostare la lavorazione alla fine + if not WD.SIDEMILL_BEFORE then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- verifico se devo lavorare anche la seconda faccia basandomi sul valore dell'angolo interno + if dAng and dAng > -90 + 10 * GEO.EPS_SMALL then + local nOtherFacet = abs( nFacet - 1) + -- inserisco la lavorazione di contornatura + local sName = 'Mill_Oth_Fac_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nOtherFacet}}) + -- imposto posizione braccio porta testa + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nOtherFacet, GDB_ID.ROOT) + local nSCC = MCH_SCC.ADIR_ZP + if AreSameOrOppositeVectorApprox( vtN2, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto modo di lavorare la faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFace2ndFace) + EgtSetMachiningParam( MCH_MP.STEP, 0) + local dMaxElev = dMaxMat + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMaxElev, 3) .. ';') + if bMachFromDn then + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) + else + EgtSetMachiningParam( MCH_MP.INVERT, false) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- modifico ingressi e uscita + -- se ho inserito il pretaglio modifico + if bEnablePreMill or bAsEnablePreMill then + if nModifyLeadInOut > 0 then + -- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita + if dElev > ( 0.5 * dMillDiam) then + -- setto il tipo di passo a una via + EgtSetMachiningParam( MCH_MP.STEPTYPE, 1) + -- modifico il tipo di uscita + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 5) + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + -- modifico dati supplementari uscita + EgtSetMachiningParam( MCH_MP.LOPERP, 0.5) + EgtSetMachiningParam( MCH_MP.LOTANG, -( dLongGorge + dExtraLongIni + dExtraLongEnd)) + end + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + if bInvertMach then + -- setto il lato di lavoro invertito + if bMachFromDn then + EgtSetMachiningParam( MCH_MP.INVERT, false) + else + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + else + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + -- Invece del numero di passi in sgrossatura confronto il raggio fresa con l'elevazione dalla normale + -- per vedere se devo modificare l'uscita + -- if nNumStep > 1 then + if dElev > ( 0.5 * dMillDiam) then + -- setto allungamenti perpendicolari + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + end + end + -- se richiesto, setto la nota per spostare la lavorazione alla fine + if not WD.SIDEMILL_BEFORE then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + else + if nModifyLeadInOut > 0 then + -- Confronto il raggio fresa con l'elevazione dalla normale per vedere se devo modificare l'uscita + if dElev > ( 0.5 * dMillDiam) then + -- setto il tipo di passo a una via + EgtSetMachiningParam( MCH_MP.STEPTYPE, 1) + end + if bInvertMach then + -- setto il lato di lavoro invertito + if bMachFromDn then + EgtSetMachiningParam( MCH_MP.INVERT, false) + else + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + end + -- setto allungamenti iniziali e finali + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLongIni) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLongEnd) + -- se richiesto, setto la nota per spostare la lavorazione alla fine + if not WD.SIDEMILL_BEFORE then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + + return true +end + +--------------------------------------------------------------------- +local function MakeByPocketing( Proc, nFacet, nRawId, b3Raw, bCheckQPar) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT) + local dElev = WL.GetFaceElevation( Proc.Id, nFacet, nRawId) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + local dDiam = min( dH, dV) + -- gruppo ausiliario + local nAddGrpId = WL.GetAddGroup( Proc.PartId) + local nNewProc, nNumFacet = RemoveBottomFaceAndReorder( Proc, nAddGrpId, nFacet) + -- se forma ad L + local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc.Id, Proc.Fct) or TestElleShape4( Proc.Id, Proc.Fct) == 2) + if bIsL then + dDiam = 2 * dDiam + end + -- se forma ad U + local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc.Id, Proc.Fct)) + if bIsU then + local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT) + -- prendo la linea di base + local dMiddleFacetLength = 0 + if abs( dElev - dH2) < 1 and abs( dElev - dV2) > 1 then + dMiddleFacetLength = dV2 + elseif abs( dElev - dV2) < 1 and abs( dElev - dH2) > 1 then + dMiddleFacetLength = dH2 + end + if dMiddleFacetLength > dDiam then + dDiam = min( 2 * dDiam, dMiddleFacetLength) + end + end + -- in presenza di angoli interni, limito secondo impostazione globale il diametro massimo utensile + if Proc.Fct == 3 and bIsL then + dDiam = min( dDiam, WD.MAXDIAM_POCK_CORNER or 1000) + elseif Proc.Fct >= 4 then + dDiam = min( dDiam, WD.MAXDIAM_POCK_CORNER or 1000) + end + -- recupero la lavorazione + local sPocketing = WM.FindPocketing( 'Pocket', dDiam, dElev) + if not sPocketing then + sPocketing = WM.FindPocketing( 'Pocket', dDiam) + if not sPocketing then + local sErr = 'Error : pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local dThDiam = 100 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepth = EgtIf( WD.MILL_MAX_DEPTH_AS_MAT, EgtTdbGetCurrToolParam( MCH_TP.MAXMAT), EgtTdbGetCurrToolMaxDepth()) or dMaxDepth + dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam + 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 + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- se lavorazione di fianco setto la nota per spostarla dopo i tagli di lama + if vtN:getZ() < WD.NZ_MINA then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacet}}) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameVectorApprox( vtN, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + local dThElev = dThDiam / 2 * sqrt( vtN:getX() * vtN:getX() + vtN:getY() * vtN:getY()) + local dDepth = 0 + local sWarn = '' + if dElev + dThElev > dMaxDepth + 10 * GEO.EPS_SMALL then + dDepth = dMaxDepth - dElev - dThElev + sWarn = 'Warning : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( min( dElev, dMaxDepth), 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- verifica parametro Q per pulitura spigoli + if bCheckQPar and not ( bIsU and AreSameOrOppositeVectorApprox( vtN, Z_AX())) then + -- lettura parametri (probabile/i parametro/i Q) + local nConeCut = EvaluateQParam( Proc) + -- recupero i dati di tutte le facce + local vFace, dMaxWidth = GetFacesData( nNewProc, false, false, dMillDiam, dMaxDepth, (dMillDiam/2), nAddGrpId, Proc.PartId) + -- se abilitata la lavorazione corner con stop macchina + if nConeCut == 1 then + local bMcok, sMcErr = AddMillCorner( nConeCut, vFace, Proc, nRawId, b3Raw, + dMillDiam, nAddGrpId, dMaxWidth, nNewProc, dDepth) + if not bMcok then return bMcok, sMcErr end + elseif nConeCut == 2 then + local sErr = 'Clean corner 30° is not applied on pocketing' + EgtOutLog( sErr) + EgtErase( nNewProc) + else + EgtErase( nNewProc) + end + else + EgtErase( nNewProc) + end + return true, sWarn +end + +--------------------------------------------------------------------- +local function MakeOneFace( Proc, nRawId, b3Raw) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- dimensioni della faccia + local _, dDimH, dDimV = WL.GetFaceHvRefDim( Proc.Id, 0) + -- recupero la lavorazione di taglio con lama e i suoi parametri + local sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard') + -- se non inclinata o capacità di taglio non sufficiente, provo con svuotatura + if not sCutting or vtN:getZ() > 0.866 or dSawMaxDepth < dDimV + WD.CUT_SIC then + -- faccio con svuotatura + local nFacet = 0 + return MakeByPocketing( Proc, nFacet, nRawId, b3Raw) + end + -- eseguo il taglio di lama + local sName = 'Cut_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_' .. tostring( Proc.Id) + local nMchId = EgtAddMachining( sName, sCutting) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( { { Proc.Id, 0}}) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- assegno il lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- assegno l'attacco e l'uscita + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.CENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.CENT) + -- nessun criterio per il braccio è necessario + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeTwoFaces( Proc, nRawId, b3Raw) + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- determino l'intersezione tra le due facce + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if not bAdj then + return false, 'Feature with two faces not adjacentes' + end + -- se equivalente ad un contorno + if abs( ptP1:getZ() - ptP2:getZ()) > 0.9 * b3Raw:getDimZ() then + -- verifico ordinamento (esterno a destra) + if ( vtN[1] ^ ( ptP1 - ptC[1])) * Z_AX() < 0 then + EgtSurfTmSwapFacets( Proc.Id, 0, 1) + end + -- applico lavorazione di contorno libero + return FreeContour.Make( Proc, nRawId, b3Raw) + end + -- versore della linea di intersezione + local vtX = ptP2 - ptP1 ; vtX:normalize() + -- larghezza delle facce ortogonalmente all'intersezione + local dDimY = {} + for i = 1, 2 do + local vtY = vtN[i] ^ vtX ; vtY:normalize() + local frRef = Frame3d( ptC[i], ptC[i] + 100 * vtX, ptC[i] + 100 * vtY) + local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, i - 1, GDB_BB.STANDARD, frRef) + dDimY[i] = b3Ref:getDimY() + end + -- recupero la lavorazione di taglio con lama e i suoi parametri + local sCutting, dSawDiam, dSawThick, dSawMaxDepth = WM.FindCutting( 'Standard') + -- se parametro Q abilita lavorazione ribasso con fresa di fianco + local _, nUseMillOnSide = EvaluateQParam( Proc) + local dMaxZVers, dMinZVers + if nUseMillOnSide >= 1 then + dMaxZVers = 0.866 + dMinZVers = 0.5 + else + dMaxZVers = 0.95 + dMinZVers = 0.1 + end + -- se di fianco in basso + local dMaxThick, dMinSideElev + if vtN[1]:getZ() < -dMaxZVers or vtN[2]:getZ() < -dMaxZVers then + if vtN[1]:getZ() < -0.5 then + dMaxThick = dDimY[2] + dMinSideElev = dDimY[1] + elseif vtN[2]:getZ() < -0.5 then + dMaxThick = dDimY[1] + dMinSideElev = dDimY[2] + end + end + local sMillOnSide, dTMaxDepth, dMaxMat, dDiam = WM.FindMilling( 'SideMill', nil, nil, nil, nil, dMaxThick, nil, dMinSideElev) + local bEnableMillOnSide + if sMillOnSide and nUseMillOnSide >= 1 then + dMaxZVers = 0.866 + dMinZVers = 0.5 + bEnableMillOnSide = true + else + dMaxZVers = 0.95 + dMinZVers = 0.1 + end + -- se di fianco in basso + if vtN[1]:getZ() < -dMaxZVers or vtN[2]:getZ() < -dMaxZVers then + -- cerco la faccia verticale o quasi + local nFacet = EgtIf( abs( vtN[1]:getZ()) < dMinZVers, 0, 1) + -- cerco nei parametri utensili la nota di affondamento di fianco SIDEDEPTH + local dMaxDepthOnSide = 0 + local dMillDiam = 0 + local dMillDiamTh = 0 + if bEnableMillOnSide and EgtMdbSetCurrMachining( sMillOnSide) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMillDiamTh = EgtTdbGetCurrToolThDiam() or dMillDiamTh + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide + dMaxDepthOnSide = min( dMaxDepthOnSide, 0.5 * ( dMillDiam - dMillDiamTh)) + end + end + local dMaxDist = 300 + if bEnableMillOnSide and dMaxDepthOnSide > 0 then + dMaxDist = dMaxDepthOnSide + end + -- se vicino al bordo del grezzo e non troppo larga, provo con fresatura di fianco + local ptMid = ( ptP1 + ptP2) / 2 + local bMakeFirstGroove + local bMachFromDn = true + local bInsertMach + local dSideDist + -- per evitare errori in casi di pezzi molto stretti, verifico le distanze in base alla direzione della faccia + -- se normale verso X + if vtN[nFacet+1]:getX() > 0.99 then + dSideDist = abs( ptMid:getX() - b3Raw:getMax():getX()) + -- altrimenti se normale verso X- + elseif vtN[nFacet+1]:getX() < -0.99 then + dSideDist = abs( ptMid:getX() - b3Raw:getMin():getX()) + -- altrimenti se normale verso Y+ + elseif vtN[nFacet+1]:getY() > 0.99 then + dSideDist = abs( ptMid:getY() - b3Raw:getMax():getY()) + -- altrimenti se normale verso Y- + elseif vtN[nFacet+1]:getY() < -0.99 then + dSideDist = abs( ptMid:getY() - b3Raw:getMin():getY()) + end + if dSideDist and dSideDist < dMaxDist then + bInsertMach = true + bMakeFirstGroove = false + -- altrimenti la distanza è maggiore e se è sempre abilitata la lavorazione MillOnSide + elseif bEnableMillOnSide and dMaxDepthOnSide then + bInsertMach = true + bMakeFirstGroove = true + end + -- se posso eseguire la lavorazione per distanza inferiore utensile o lavorazione preceduta da sgossatura gola + if bInsertMach then + return MakeSideGrooveByMill( Proc, nFacet, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng) + else + local sErr = 'Error feature not machinable (dimensions)' + EgtOutLog( sErr) + return false, sErr + end + -- se altrimenti di fianco in alto + elseif vtN[1]:getZ() > dMaxZVers or vtN[2]:getZ() > dMaxZVers then + -- cerco la faccia con il maggior numero di adiacenze (e minor elevazione) + local nFacInd, _, nFacInd2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + if nFacInd == -2 then + local sErr = 'Error feature with 2 faces with undercut' + EgtOutLog( sErr) + return false, sErr + end + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + local dSideDist + local ptMid = ( ptP1 + ptP2) / 2 + -- faccia orizzontale + local nFacet = EgtIf( vtN:getZ() >= WD.NZ_MINA, nFacInd, nFacInd2) + -- faccia verticale + local nFacetVert = EgtIf( nFacet == nFacInd, nFacInd2, nFacInd) + local vtNV = EgtSurfTmFacetNormVersor( Proc.Id, nFacetVert, GDB_ID.ROOT) + -- per evitare errori in casi di pezzi molto stretti, verifico le distanze in base alla direzione della faccia +-- local dSideDist = min( abs( ptMid:getX() - b3Raw:getMin():getX()), abs( ptMid:getX() - b3Raw:getMax():getX()), +-- abs( ptMid:getY() - b3Raw:getMin():getY()), abs( ptMid:getY() - b3Raw:getMax():getY())) + -- se normale verso X + if vtNV:getX() > 0.99 then + dSideDist = abs( ptMid:getX() - b3Raw:getMax():getX()) + -- altrimenti se normale verso X- + elseif vtNV:getX() < -0.99 then + dSideDist = abs( ptMid:getX() - b3Raw:getMin():getX()) + -- altrimenti se normale verso Y+ + elseif vtNV:getY() > 0.99 then + dSideDist = abs( ptMid:getY() - b3Raw:getMax():getY()) + -- altrimenti se normale verso Y- + elseif vtNV:getY() < -0.99 then + dSideDist = abs( ptMid:getY() - b3Raw:getMin():getY()) + end + -- cerco nei parametri utensili la nota di affondamento di fianco SIDEDEPTH + local dMaxDepthOnSide = 0 + local dMillDiam = 0 + if bEnableMillOnSide and EgtMdbSetCurrMachining( sMillOnSide) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide + end + end + -- 2021.10.08 E.S. in base a richieste del cliente: + -- Se parametro Q riduce utilizzo lavorazione di lato come lama ed elevazione laterale supera il 60% diametro utensile + -- disabilito + if nUseMillOnSide == 2 and dSideDist > 0.6 * dMillDiam then + bEnableMillOnSide = false + end + -- per il fianco in alto non ci sono problemi di inserimento massimo laterale, setto la variabile pari al raggio utensile - 1mm + dMaxDepthOnSide = ( 0.5 * dMillDiam) - 1 + local dMaxDist = 300 + if bEnableMillOnSide and dMaxDepthOnSide > 0 then + dMaxDist = dMaxDepthOnSide + end + -- se vicino al bordo del grezzo e non troppo larga, provo con fresatura di fianco + local bMakeFirstGroove = false + local bLikeAsMakeFirstGroove + local bMachFromDn = false + local bInsertMach + if dSideDist and dSideDist < dMaxDist then + -- se abilitata SideMill + if bEnableMillOnSide and dMaxDepthOnSide > 0 then + bLikeAsMakeFirstGroove = false + return MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, bLikeAsMakeFirstGroove) + elseif MakeByMill( Proc, nFacet, 1 - nFacet, nRawId, b3Raw, dSideDist) then + return true + end + elseif bEnableMillOnSide and dMaxDepthOnSide > 0 then + bLikeAsMakeFirstGroove = true + local bOk, sErr = MakeSideGrooveByMill( Proc, nFacetVert, nRawId, b3Raw, EgtIf( bEnableMillOnSide and dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, bMachFromDn, dAng, bLikeAsMakeFirstGroove) + if bOk then return true end + end + -- se non inclinate o capacità di taglio non sufficiente o non molto grandi (80mm), provo con contornatura o svuotatura + if not sCutting or dSawMaxDepth < dDimY[1] + WD.CUT_SIC or dSawMaxDepth < dDimY[2] + WD.CUT_SIC or dDimY[1] < 80 or dDimY[2] < 80 then + -- eseguo la svuotatura + return MakeByPocketing( Proc, nFacet, nRawId, b3Raw) + end + -- se una delle due facce rivolta verso il basso + elseif vtN[1]:getZ() < -0.001 or vtN[2]:getZ() < -0.001 then + -- cerco la faccia rivolta verso l'alto + local nFacet + if vtN[1]:getZ() > 0 then + nFacet = 0 + elseif vtN[2]:getZ() > 0 then + nFacet = 1 + else + local sErr = 'Error feature with 2 faces facing down' + EgtOutLog( sErr) + return false, sErr + end + -- eseguo la svuotatura + return MakeByPocketing( Proc, nFacet, nRawId, b3Raw) + end + -- ordino i tagli per fare prima quello meno inclinato + local nOrd = { 0, 1} + if vtN[2]:getZ() > vtN[1]:getZ() then + nOrd = { 1, 0} + end + -- eseguo i tagli di lama + for i = 1, 2 do + -- inserisco la lavorazione + local sName = 'Cut_' .. ( EgtGetName( Proc.PartId) or tostring( Proc.PartId)) .. '_' .. tostring( Proc.Id) .. '_' .. tostring( i) + local nMchId = EgtAddMachining( sName, sCutting) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchId, 'Part', Proc.PartId) + -- aggiungo geometria + EgtSetMachiningGeometry( { { Proc.Id, nOrd[i]}}) + -- percorso da non invertire + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, 0) + -- assegno il lato di lavoro + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + -- assegno l'attacco e l'uscita + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.CENT) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.CENT) + -- nessun criterio per il braccio è necessario + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.NONE) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +local function MakeMoreFaces( Proc, nRawId, b3Raw) + -- con una faccia di fondo valida + if Proc.Stype == 1 or Proc.Stype == 2 then + -- recupero eventuale flag forzatura svuotatura + local bPckt = ( EgtGetInfo( Proc.Id, 'PCKT', 'i') == 1) + -- cerco la faccia con il maggior numero di adiacenze + local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + -- se necessario scambio le facce + if Proc.Stype == 2 then + nFacInd, dElev, nFacInd2, dElev2 = nFacInd2, dElev2, nFacInd, dElev + end + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- se di fianco + if not bPckt and Proc.Fct >= 3 and vtN:getZ() < WD.NZ_MINA then + -- recupero elevazione faccia in feature + local dSideElev = WL.GetFaceElevation( Proc.Id, nFacInd) + -- se abilitata lavorazione ribasso con fresa di fianco e parametro Q03 abilitato + local sMillOnSide, dTMaxDepth, dMaxMat, dDiam = WM.FindMilling( 'SideMill', nil, nil, nil, nil, min( dH, dV), nil, dSideElev) + local _, nUseMillOnSide = EvaluateQParam( Proc) + -- se ho abilitata lavorazione di fresa di fianco + if Proc.Fct >= 3 and sMillOnSide and nUseMillOnSide >= 1 then + -- cerco nei parametri utensili la nota di affondamento di fianco SIDEDEPTH + local dMaxDepthOnSide = 0 + local dMillDiam = 0 + if EgtMdbSetCurrMachining( sMillOnSide) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') or dMaxDepthOnSide + end + end + local bMakeFirstGroove + local bLikeAsMakeFirstGroove + local bInsertMach + local dElevToPiece = WL.GetFaceElevation( Proc.Id, nFacInd, nRawId) + -- Se distanza dal grezzo è minore della Max lavorazione laterale utensile + if dElevToPiece < dMaxDepthOnSide then + bInsertMach = true + bMakeFirstGroove = false + -- altrimenti la distanza è maggiore e se è sempre abilitata la lavorazione MillOnSide + elseif dMaxDepthOnSide > 0 then + bInsertMach = true + bMakeFirstGroove = true + end + -- se posso eseguire la lavorazione per distanza inferiore utensile o lavorazione preceduta da sgossatura gola + -- e gola più grande o uguale spessore utensile + if bInsertMach and dMaxMat <= min( dH, dV) + 20 * GEO.EPS_SMALL then + local nSinglePass = 0 + bLikeAsMakeFirstGroove = bMakeFirstGroove + -- se positivo setto il flag per lavorare singola passata bassa e disabilito sgrossatura + if vtN:getZ() > 20 * GEO.EPS_SMALL then + nSinglePass = 1 + bMakeFirstGroove = false + -- se negativo setto il flag per lavorare singola passata alta e disabilito sgrossatura + elseif vtN:getZ() < -20 * GEO.EPS_SMALL then + nSinglePass = 2 + bMakeFirstGroove = false + end + return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, EgtIf( dMaxDepthOnSide, sMillOnSide, nil), dMaxDepthOnSide, bMakeFirstGroove, nil, nil, bLikeAsMakeFirstGroove, nSinglePass) + end + else + -- fresatura (se definita) + local sMilling = WM.FindMilling( 'SideGroove') + -- recupero i dati dell'utensile + local dMaxMat = 1000 + local dMaxDepthOnSide = 0 + if sMilling and EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + local dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + if ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE) ~= 0 then + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dMaxMat + dMaxDepthOnSide = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) + else + dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat + dMaxDepthOnSide = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd') + end + if not dMaxDepthOnSide then + local dMillDiamTh = EgtTdbGetCurrToolThDiam() or 60 + dMaxDepthOnSide = ( dMillDiam - dMillDiamTh) / 2 + end + end + end + if sMilling and dElev < dMaxDepthOnSide and dMaxMat <= min( dH, dV) + 20 * GEO.EPS_SMALL then + return MakeSideGrooveByMill( Proc, nFacInd, nRawId, b3Raw, sMilling) + -- altrimenti sega a catena + else + return MakeByChainSaw( Proc, nFacInd, nRawId, b3Raw, dElev, dH, dV) + end + end + end + local nFacet = EgtIf( bPckt or vtN:getZ() >= WD.NZ_MINA, nFacInd, nFacInd2) + if nFacet then + -- eseguo la svuotatura + return MakeByPocketing( Proc, nFacet, nRawId, b3Raw, true) + else + local sErr = 'Side milling not possible' + EgtOutLog( sErr) + return true, sErr + + end + -- fessura verticale + elseif Proc.Stype == 3 then + -- riordino le facce come contorno libero da lavorare a destra (sono una U) + -- porto la faccia centrale in seconda posizione (indice 1) + local nFacInd = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + if nFacInd ~= 1 then + EgtSurfTmSwapFacets( Proc.Id, 1, nFacInd) + end + -- verifico se la prima (indice 0) la deve precedere o seguire + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local bAdj, ptAdj, _, _ = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if bAdj and ( vtN ^ ( ptAdj - ptC)) * Z_AX() < 0 then + EgtSurfTmSwapFacets( Proc.Id, 0, 2) + end + -- applico lavorazione di contorno libero + return FreeContour.Make( Proc, nRawId, b3Raw) + -- tunnel + elseif Proc.Stype == 4 then + -- riordino le facce come contorno libero da lavorare a destra (formano un anello chiuso e quindi posso partire da una qualunque) + for i = 1, Proc.Fct - 2 do + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT) + for j = i + 1, Proc.Fct do + local bAdj, ptAdj, _, _ = EgtSurfTmFacetsContact( Proc.Id, i - 1, j - 1, GDB_ID.ROOT) + if bAdj and ( vtN ^ ( ptAdj - ptC)) * Z_AX() > 0 then + if i ~= j - 1 then + EgtSurfTmSwapFacets( Proc.Id, i, j - 1) + end + break + end + end + end + -- applico lavorazione di contorno libero + return FreeContour.Make( Proc, nRawId, b3Raw) + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPL.Make( Proc, nRawId, b3Raw) + -- in base al tipo di feature attribuisco il significato dei parametri Q + AssignQIdent( Proc) + if Proc.Fct == 1 then + return MakeOneFace( Proc, nRawId, b3Raw) + elseif Proc.Fct == 2 then + return MakeTwoFaces( Proc, nRawId, b3Raw) + else + return MakeMoreFaces( Proc, nRawId, b3Raw) + end +end + +--------------------------------------------------------------------- +return WPL diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessMark.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessMark.lua new file mode 100644 index 0000000..71af91f --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessMark.lua @@ -0,0 +1,152 @@ +-- WProcessMark.lua by Egaltech s.r.l. 2021/04/20 +-- Gestione calcolo marcatura per Pareti + +-- Tabella per definizione modulo +local WPMK = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' WProcessMark started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPMK.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 60) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPMK.Classify( Proc, b3Raw) + -- recupero il versore estrusione o normale se testo + local vtN + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtN = EgtCurveExtrusion( Proc.Id, GDB_ID.ROOT) + else + vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtN then + return false + end + -- verifico se la marcatura è lavorabile (solo da sopra) + return ( vtN:getZ() > WD.NZ_MINA) +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPMK.FlipClassify( Proc) + local nFlip0, nFlip1 + local vtN + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtN = EgtCurveExtrusion( Proc.Id, GDB_ID.ROOT) + else + vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtN then + return false + end + -- verifico se la marcatura è lavorabile (solo da sopra) + nFlip0 = EgtIf( vtN:getZ() > WD.NZ_MINA, 100, 0) + nFlip1 = EgtIf( - vtN:getZ() > WD.NZ_MINA, 100, 0) + return nFlip0, nFlip1 + +end + + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPMK.Make( Proc, nRawId, b3Raw) + -- recupero eventuale geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero i dati della marcatura + local vtExtr + if EgtGetType( Proc.Id) ~= GDB_TY.EXT_TEXT then + vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + else + vtExtr = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + end + -- verifico sia una curva/testo + if not vtExtr then + local sErr = 'Error : Mark with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che la marcatura non sia orientata verso il basso + if vtExtr:getZ() < WD.NZ_MINA then + local sErr = 'Error : Mark from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = WM.FindMilling( 'Text') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + -- eventuale lavorazione su seconda geometria + if AuxId then + -- inserisco la lavorazione di fresatura + local sName2 = 'Decor2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchF2Id = EgtAddMachining( sName, sMilling) + if not nMchF2Id then + local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling + 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 + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchF2Id, false) + return false, sErr + end + -- se geometria a X maggiore, la sposto prima + local ptS1 = EgtSP( Proc.Id, GDB_ID.ROOT) + local ptS2 = EgtSP( AuxId, GDB_ID.ROOT) + if ptS2:getX() > ptS1:getX() then + EgtRelocateGlob( nMchF2Id, nMchFId, GDB_IN.BEFORE) + end + end + return true +end + +--------------------------------------------------------------------- +return WPMK diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessMortise.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessMortise.lua new file mode 100644 index 0000000..860e751 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessMortise.lua @@ -0,0 +1,303 @@ +-- WProcessMortise.lua by Egaltech s.r.l. 2021/07/30 +-- Gestione calcolo mortase per Pareti + +-- Tabella per definizione modulo +local WPM = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') + +EgtOutLog( ' WProcessMortise started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPM.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 50) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 53)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature: decide se la feature è in una posizione che per lavorala +-- deve essere ribaltata o no +function WPM.Classify( Proc, b3Raw) + -- recupero e verifico il percorso supplementare + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero versore estrusione della curva supplementare e non più della superficie + -- perché quest'ultima potrebbe non avere il fondo e dare quindi un risultato non corretto + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtExtr then + return false + end + if not vtN then + return false + end + -- Confronto le direzioni Z dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante + if abs( vtExtr:getZ() - vtN:getZ()) > 10 * GEO.EPS_SMALL then + return true + -- altrimenti è chiusa + else + -- verifico se la mortasa è lavorabile da sopra + return ( vtN:getZ() > WD.NZ_MINA) + end +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPM.FlipClassify( Proc) + -- recupero e verifico il percorso supplementare + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero versore estrusione della curva supplementare e non più della superficie + -- perché quest'ultima potrebbe non avere il fondo e dare quindi un risultato non corretto + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtExtr then + return false + end + if not vtN then + return false + end + -- Confronto le direzioni Z dei 2 versori : se diverse la faccia 0 non è il fondo => mortasa passante + if abs( vtExtr:getZ() - vtN:getZ()) > 10 * GEO.EPS_SMALL then + return 100, 100 + -- altrimenti è chiusa + else + -- verifico se la mortasa è lavorabile da sopra + nFlip0 = EgtIf( vtN:getZ() > WD.NZ_MINA, 100, 0) + nFlip1 = EgtIf( - vtN:getZ() > WD.NZ_MINA, 100, 0) + end + + return nFlip0, nFlip1 + +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPM.Make( Proc, nRawId, b3Raw) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero versore estrusione della curva supplementare + local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT) + -- recupero i dati della faccia di fondo + local frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT) + local ptC = ORIG() + local vtN = V_NULL() + if frMor then + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + end + -- verifico se è presente il fondo (sempre faccia 0) + local bClosedBtm = AreSameVectorApprox( vtExtr, vtN) + -- Se curva di contorno aperta + local dLenOpenSide = 0 + if not EgtCurveIsClosed( AuxId) then + -- se c'è il fondo + if bClosedBtm then + local NewId, nCount = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id)) + if NewId then + -- elimino eventuali loop interni (non dovrebbero comunque esserci) + for i = 1, nCount - 1 do + EgtErase( NewId + i) + end + -- sostituisco il loop esterno alla curva originale + EgtModifyCurveExtrusion( NewId, vtExtr, GDB_ID.ROOT) + EgtRelocate( NewId, AuxId, GDB_IN.AFTER) + EgtErase( AuxId) + EgtChangeId( NewId, AuxId) + -- sistemo i lati aperti + local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, 0)[1] + if vFacAdj then + local sOpen = '' + for i = 1, #vFacAdj do + if vFacAdj[i] < 0 then + sOpen = sOpen .. EgtIf( #sOpen > 0, ',', '') .. tostring( i - 1) + local dLen = dist( EgtUP( AuxId, i-1), EgtUP( AuxId, i)) + dLenOpenSide = max( dLen, dLenOpenSide) + end + end + if #sOpen > 0 then + EgtSetInfo( AuxId, 'OPEN', sOpen) + end + end + end + -- altrimenti aperta + else + dLenOpenSide = dist( EgtSP( AuxId), EgtEP( AuxId)) + local _, nCrvCnt = EgtCurveDomain( AuxId) + EgtCloseCurveCompo( AuxId) + EgtSetInfo( AuxId, 'OPEN', nCrvCnt) + end + end + -- Se mortasa passante + if not bClosedBtm then + -- creo superficie chiusa + local nFlat = EgtSurfTmByFlatContour( EgtGetParent( AuxId), AuxId, 0.05) + if nFlat then + -- la superficie deve sempre essere rivolta verso l'alto + local vtNN = EgtSurfTmFacetNormVersor( nFlat, 0, GDB_ID.ROOT) + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + -- verifico se copiare la geometria lungo l'asse Z + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frMor) + local bxMax = b3Aux:getMax() + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local bxMin = b3Mor:getMin() + local dMove = bxMin:getZ() - bxMax:getZ() + if vtNN:getZ() < 0.1 then dMove = -dMove end + -- se il percorso ausiliario è esterno al grezzo, lo riavvicino + if abs( dMove) > GEO.EPS_SMALL then + AuxId = EgtCopyGlob( AuxId, WL.GetAddGroup( Proc.PartId)) + EgtMove( AuxId, Vector3d( 0, 0, dMove), GDB_RT.GLOB) + EgtMove( nFlat, Vector3d( 0, 0, dMove), GDB_RT.GLOB) + frMor, dL, dW = EgtSurfTmFacetMinAreaRectangle( nFlat, 0, GDB_ID.ROOT) + ptC = frMor:getOrigin() + vtN = frMor:getVersZ() + end + -- cancello le prove del misfatto (superficie piana) + EgtErase( nFlat) + end + end + -- scrivo info nel log + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- Se mortasa chiusa + local bForceOneSide + local bRevertSide + if bClosedBtm then + -- verifico che la mortasa non sia orientata verso il basso (limite -5 deg) + if vtN:getZ() < WD.NZ_MINA then + local sErr = 'Error : Mortise from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- altrimenti passante + else + -- determino se la mortasa da lavorare sul lato opposto sia di angolo inferiore a quello consentito + if abs( vtN:getZ()) > 0.1 then + bForceOneSide = true + end + -- determino se è meglio lavorare la mortasa nel lato opposto + if vtN:getZ() < -GEO.EPS_SMALL then + bRevertSide = true + end + end + + -- determino altezza della mortasa + local b3Mor = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frMor) + local dMorH = b3Mor:getDimZ() + -- elevazione del punto centro + local _, dCenElev = WL.GetPointDirDepth( Proc.PartId, ptC, vtN) + dMorH = max( dMorH, dCenElev or 0) + -- determino larghezza della mortasa + if dL < dW then dL, dW = dW, dL end + dW = max( dW, min( 2 * dW, dLenOpenSide)) + -- recupero la lavorazione + local sPocketing + if Proc.Prc ~= 53 then + sPocketing = WM.FindPocketing( 'Mortise', dW) + end + if not sPocketing then + sPocketing = WM.FindPocketing( 'Pocket', dW) + end + if not sPocketing then + local sErr = 'Error : Mortise or Pocket not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + local bCW = true + 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) + local dSpeed = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) or 0 + bCW = ( dSpeed >= 0) + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'Mort_' .. ( 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 + -- verifico se invertire versore estrusione geometria + if bRevertSide then + EgtModifyCurveExtrusion( AuxId, -vtExtr, GDB_ID.ROOT) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo la direzione di lavoro + EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bCW, true, false)) + -- imposto posizione braccio porta testa + if vtN:getY() < GEO.EPS_SMALL then + if bRevertSide then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + end + else + if bRevertSide then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + end + local sWarn + local nDepthMin + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + if dMorH > dMaxDepth + 10 * GEO.EPS_SMALL then + sWarn = 'Warning in mortise : elevation (' .. EgtNumToString( dMorH,1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth,1) .. ')' + -- se non ho invertito la direzione di estrusione + if not bRevertSide then + nDepthMin = dMaxDepth - EgtIf( not bClosedBtm and not bForceOneSide, dMorH * 2, dMorH) + else + nDepthMin = dMaxDepth + end + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + dMorH = dMaxDepth + EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')') + else + if not bClosedBtm and not bForceOneSide then -- se mortasa passante setto metà profondità + nDepthMin = -dMorH + EgtSetMachiningParam( MCH_MP.DEPTH, nDepthMin) + elseif bRevertSide then + EgtSetMachiningParam( MCH_MP.DEPTH, dMorH) + end + end + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMorH, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + + return true, sWarn +end + +--------------------------------------------------------------------- +return WPM diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessSawCut.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessSawCut.lua new file mode 100644 index 0000000..5a9ede2 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessSawCut.lua @@ -0,0 +1,58 @@ +-- WProcessSawCut.lua by Egaltech s.r.l. 2021/04/28 +-- Gestione calcolo taglio di lama per Pareti + +-- Tabella per definizione modulo +local WPSC = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') +local Cut = require( 'WProcessCut') + +EgtOutLog( ' WProcessSawCut started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPSC.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 13) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPSC.Classify( Proc, b3Raw) + -- recupero i dati del versore direzione di accesso della lavorazione + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtDir = EgtSV( AuxId, GDB_ID.ROOT) + return ( vtDir:getZ() > 0.5) +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPSC.FlipClassify( Proc) + -- recupero i dati del versore direzione di accesso della lavorazione + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if not AuxId then return false end + AuxId = AuxId + Proc.Id + local vtDir = EgtSV( AuxId, GDB_ID.ROOT) + local vtDirZ = vtDir:getZ() + nFlip0 = EgtIf( vtDirZ > 0.5, 100, 0) + nFlip1 = EgtIf( - vtDirZ > 0.5, 100, 0) + + return nFlip0, nFlip1 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPSC.Make( Proc, nRawId, b3Raw) + return Cut.Make( Proc, nRawId, b3Raw) +end + +--------------------------------------------------------------------- +return WPSC diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessText.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessText.lua new file mode 100644 index 0000000..a67651e --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessText.lua @@ -0,0 +1,104 @@ +-- WProcessText.lua by Egaltech s.r.l. 2021/04/20 +-- Gestione calcolo testi per Travi + +-- Tabella per definizione modulo +local WPT = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' WProcessText started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPT.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 61) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function WPT.Classify( Proc, b3Raw) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + return false + end + -- verifico se il testo è lavorabile (solo da sopra) + return ( vtN:getZ() > WD.NZ_MINA) +end + +---------------------------------------------------------------------- +-- Classificazione del flip della feature per nesting +-- return nFlip0, nFlip1 +function WPT.FlipClassify( Proc) + local nFlip0, nFlip1 + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + return false + end + -- verifico se il testo è lavorabile (solo da sopra) + nFlip0 = EgtIf( vtN:getZ() > WD.NZ_MINA, 100, 0) + nFlip1 = EgtIf( - vtN:getZ() > WD.NZ_MINA, 100, 0) + return nFlip0, nFlip1 + +end + + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function WPT.Make( Proc, nRawId, b3Raw) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + local sErr = 'Error : Text with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che il testo non sia orientato verso il basso + if vtN:getZ() < WD.NZ_MINA then + local sErr = 'Error : Text from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sMilling = WM.FindMilling( 'Text') + if not sMilling then + local sErr = 'Error : milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Text_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -1}}) + -- imposto posizione braccio porta testa + if vtN:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return WPT diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessVariant.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessVariant.lua new file mode 100644 index 0000000..303be65 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WProcessVariant.lua @@ -0,0 +1,115 @@ +-- WProcessVariant.lua by Egaltech s.r.l. 2021/08/27 +-- Gestione calcolo Feature Custom (Variant) per Pareti + +-- Tabella per definizione modulo +local WPV = {} + +-- Include +require( 'EgtBase') +local WL = require( 'WallLib') + +EgtOutLog( ' WProcessVariant started', 1) + +-- Dati +local WD = require( 'WallData') +local WM = require( 'WMachiningLib') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function WPV.Identify( Proc) + return (( Proc.Grp == 0 or Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 900) +end + +--------------------------------------------------------------------- +-- Classificazione della feature: decide se la feature è in una posizione lavorabile +local function ClassifyCode_1( Proc, b3Raw) + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then + AuxId = AuxId + Proc.Id + end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing containement geometry' + EgtOutLog( sErr) + return false + end + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + return ( vtExtr:getZ() > -0.01) +end + +--------------------------------------------------------------------- +function WPV.Classify( Proc, b3Raw) + -- recupero il codice identificativo + local sCode = EgtGetInfo( Proc.Id, 'DES') + -- gestione in base al codice + if sCode == '1' then + return ClassifyCode_1( Proc, b3Raw) + else + return false + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +local function MakeCode_1( Proc, nRawId, b3Raw) + -- recupero e verifico l'entità curva associata + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then + AuxId = AuxId + Proc.Id + end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error : missing containement geometry' + EgtOutLog( sErr) + return false, sErr + end + local vtExtr = EgtCurveExtrusion( AuxId or GDB_ID.NULL, GDB_ID.ROOT) + -- recupero la lavorazione + local sSurfFin = WM.FindSurfacing( 'Finishing') + if not sSurfFin then + local sErr = 'Error : surface finishing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di finitura superficie + local sName = 'SurfFin_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sSurfFin) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSurfFin + EgtOutLog( sErr) + return false, sErr + end + EgtSetInfo( nMchFId, 'Part', Proc.PartId) + -- se lavorazione di fianco setto la nota per spostarla dopo i tagli di lama + if vtExtr:getZ() < WD.NZ_MINA then + EgtSetInfo( nMchFId, 'MOVE_AFTER', 1) + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -1},{AuxId, -1}}) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_ZP + if AreSameVectorApprox( vtExtr, Z_AX()) then + nSCC = EgtIf( Proc.Box:getDimX() >= Proc.Box:getDimY(), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_XP) + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +function WPV.Make( Proc, nRawId, b3Raw) + -- recupero il codice identificativo + local sCode = EgtGetInfo( Proc.Id, 'DES') + -- gestione in base al codice + if sCode == '1' then + return MakeCode_1( Proc, nRawId, b3Raw) + else + return false, 'Feature Id Code non recognized for machining' + end +end + +--------------------------------------------------------------------- +return WPV diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WallExec.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WallExec.lua new file mode 100644 index 0000000..a43e1e7 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WallExec.lua @@ -0,0 +1,691 @@ +-- WallExec.lua by Egaltech s.r.l. 2022/04/03 +-- 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 +_G.package.loaded.CutData = nil +_G.package.loaded.MillingData = nil +_G.package.loaded.PocketingData = nil +_G.package.loaded.DrillData = nil +_G.package.loaded.SawingData = nil +local WD = require( 'WallData') +if WALL and WALL.NESTINGCORNERBL then WD.NESTING_CORNER = 'BL' end + +-- Carico le librerie +_G.package.loaded.WMachiningLib = nil +_G.package.loaded.WallLib = nil +_G.package.loaded.WProcessCut = nil +_G.package.loaded.WProcessDoubleCut = nil +_G.package.loaded.WProcessSawCut = nil +_G.package.loaded.WProcessLapJoint = nil +_G.package.loaded.WProcessDrill = nil +_G.package.loaded.WProcessMortise = nil +_G.package.loaded.WProcessDtMortise = nil +_G.package.loaded.WProcessMark = nil +_G.package.loaded.WProcessText = nil +_G.package.loaded.WProcessFreeContour = nil +_G.package.loaded.WProcessVariant = nil +local WM = require( 'WMachiningLib') +local WL = require( 'WallLib') +local Cut = require( 'WProcessCut') +local DoubleCut = require( 'WProcessDoubleCut') +local SawCut = require( 'WProcessSawCut') +local LapJoint = require( 'WProcessLapJoint') +local Drill = require( 'WProcessDrill') +local Mortise = require( 'WProcessMortise') +local DtMortise = require( 'WProcessDtMortise') +local Mark = require( 'WProcessMark') +local Text = require( 'WProcessText') +local FreeContour = require( 'WProcessFreeContour') +local Variant = require( 'WProcessVariant') + + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle pareti nel pannello *** +------------------------------------------------------------------------------------------------------------- +function WallExec.ProcessWalls( dRawL, dRawW, dRawH, vWall, bMachGroupOk, bNewProcess, nRawOutlineId) + + -- Creazione nuovo gruppo di lavoro + if not bMachGroupOk then + 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 + end + + -- Impostazione della tavola + EgtSetTable( 'Tab') + + -- Area tavola + local b3Tab = EgtGetTableArea() + -- Calcolo posizione estremo di riferimento della tavola rispetto a sua origine in BL + local OrigOnTab + local nCorner + local sOrigCorner = WD.ORIG_CORNER or 'BR' + if WD.GetOrigCorner then + sOrigCorner = WD.GetOrigCorner( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'REFPOS', 'i') or 1) + end + if sOrigCorner == 'TL' then + nCorner = MCH_CR.TL + OrigOnTab = Point3d( 0, b3Tab:getDimY(), 0) + elseif sOrigCorner == 'BL' then + nCorner = MCH_CR.BL + OrigOnTab = Point3d( 0, 0, 0) + elseif sOrigCorner == 'TR' then + nCorner = MCH_CR.TR + OrigOnTab = Point3d( b3Tab:getDimX(), b3Tab:getDimY(), 0) + elseif sOrigCorner == 'BR' then + nCorner = MCH_CR.BR + OrigOnTab = Point3d( b3Tab:getDimX(), 0, 0) + elseif sOrigCorner == 'TM' then + nCorner = MCH_CR.TR + OrigOnTab = Point3d( WD.MID_REF, b3Tab:getDimY(), 0) + elseif sOrigCorner == 'BM' then + nCorner = MCH_CR.BR + OrigOnTab = Point3d( WD.MID_REF, 0, 0) + end + -- Impostazione dell'attrezzaggio di default + EgtImportSetup() + -- Creazione del grezzo e suo posizionamento in macchina + local nRaw = GDB_ID.NULL + if nRawOutlineId and nRawOutlineId ~= GDB_ID.NULL then + nRaw = EgtAddRawPartWithPart( 0, nRawOutlineId, 0, WD.RAWCOL) + else + nRaw = EgtAddRawPart( Point3d(0,0,0), dRawL, dRawW, dRawH, WD.RAWCOL) + end + EgtMoveToCornerRawPart( nRaw, OrigOnTab, nCorner) + EgtSetInfo( nRaw, 'ORD', 1) + -- 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() + local vtOffs = b3Part:getMin() - b3Solid:getMin() + -- creo o pulisco gruppo geometrie aggiuntive + if not WL.CreateOrEmptyAddGroup( Pz) then + local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz) + return false, sOut + end + -- inserisco il pezzo nel grezzo + EgtDeselectPartObjs( Pz) + local ptPos + if bNewProcess then + local sNestingRef = ( WALL.NESTING_REF or WD.NESTING_CORNER) + if sNestingRef == 'TL' then + ptPos = Point3d( vWall[i].PosX, dRawW - PartWidth - vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + elseif sNestingRef == 'TR' then + ptPos = Point3d( dRawL - PartLen - vWall[i].PosX, dRawW - PartWidth - vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + elseif sNestingRef == 'BR' then + ptPos = Point3d( dRawL - PartLen - vWall[i].PosX, vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + else -- 'BL' + ptPos = Point3d( vWall[i].PosX, vWall[i].PosZ, ( dRawH - PartHeight) / 2) + vtOffs + end + else + local dPosH = EgtIf( vWall[i].PosY < 0.1, ( dRawH - PartHeight) / 2, vWall[i].PosY) + ptPos = Point3d( dRawL - vWall[i].PosX - PartLen, vWall[i].PosZ, dPosH) + vtOffs + end + EgtAddPartToRawPart( Pz, ptPos, nRaw) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle pareti *** +------------------------------------------------------------------------------------------------------------- +function WallExec.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 + table.insert( vProc, Proc) + -- se foro + if Drill.Identify( Proc) then + -- assegno diametro e facce di ingresso e uscita (dati tabelle sempre per riferimento) + Proc.Diam, Proc.Fcs, Proc.Fce = Drill.GetData( Proc, b3Raw) + -- verifico se necessaria seconda lavorazione da parte opposta per foro più lungo della punta + if Drill.Split( Proc, b3Raw) then + -- aggiorno flags prima parte foro (dati tabelle sempre per riferimento) + Proc.Flg = 2 + -- definisco dati seconda parte + local Proc2 = {} + Proc2.PartId = PartId + Proc2.Id = ProcId + Proc2.Grp = nGrp + Proc2.Prc = nPrc + Proc2.Flg = -2 + Proc2.Box = BBox3d( Proc.Box) + Proc2.Fct = Proc.Fct + Proc2.Diam = Proc.Diam + Proc2.Fcs = Proc.Fce + Proc2.Fce = Proc.Fcs + Proc2.CutId = Proc.CutId + Proc2.TaskId = Proc.TaskId + table.insert( vProc, Proc2) + end + end + 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 taglio + if Cut.Identify( Proc) then + local bOk = Cut.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se taglio doppio + elseif DoubleCut.Identify( Proc) then + local bOk = DoubleCut.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se taglio con lama + elseif SawCut.Identify( Proc) then + local bOk = SawCut.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se tasca + elseif LapJoint.Identify( Proc) then + local bOk = LapJoint.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se foratura + elseif Drill.Identify( Proc) then + local bOk = Drill.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se mortasatura + elseif Mortise.Identify( Proc) then + local bOk = Mortise.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se mortasatura a coda di rondine + elseif DtMortise.Identify( Proc) then + local bOk = DtMortise.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se marcatura + elseif Mark.Identify( Proc) then + local bOk = Mark.Classify( Proc, b3Raw) + if not bOk then Proc.Flg = 0 end + -- se testo + elseif Text.Identify( Proc) then + local bOk = Text.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 + -- se feature custom (Variant) + elseif Variant.Identify( Proc) then + local bOk = Variant.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 Dbl=%2d Dlt=%.1f Box=%s', + Proc.PartId, Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId, + Proc.Flg, Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, Proc.Double or 0, Proc.Delta or 0, tostring( Proc.Box)) + EgtOutLog( sOut) + end +end + +------------------------------------------------------------------------------------------------------------- +local function AddFeatureMachining( Proc, nRawId, b3Raw) + local bOk = true + local sErr = '' + EgtOutLog( ' * Process ' .. tostring( Proc.Id) .. ' *', 1) + -- se taglio (1/2-010-X) o taglio longitudinale (0/3/4-010-X) + if Cut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = Cut.Make( Proc, nRawId, b3Raw) + -- se taglio doppio (1/2-011-X) o taglio doppio longitudinale (0-012-X) + elseif DoubleCut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = DoubleCut.Make( Proc, nRawId, b3Raw) + -- se taglio con lama (0/3/4-013-X) + elseif SawCut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = SawCut.Make( Proc, nRawId, b3Raw) + -- se tasca (3/4-030-X) o similari + elseif LapJoint.Identify( Proc) then + -- esecuzione tasca + bOk, sErr = LapJoint.Make( Proc, nRawId, b3Raw) + -- se foratura ( 3/4-040-X) + elseif Drill.Identify( Proc) then + -- esecuzione foratura + bOk, sErr = Drill.Make( Proc, nRawId, b3Raw) + -- se mortasatura (3/4-050-X) o similari + elseif Mortise.Identify( Proc) then + -- esecuzione mortasatura + bOk, sErr = Mortise.Make( Proc, nRawId, b3Raw) + -- se mortasatura a coda di rondine (3/4-055-X) + elseif DtMortise.Identify( Proc) then + -- esecuzione mortasatura a coda di rondine + bOk, sErr = DtMortise.Make( Proc, nRawId, b3Raw) + -- se marcatura (3/4-060-X) + elseif Mark.Identify( Proc) then + -- esecuzione marcatura + bOk, sErr = Mark.Make( Proc, nRawId, b3Raw) + -- se testo (4-061-X) + elseif Text.Identify( Proc) then + -- esecuzione incisione testo + bOk, sErr = Text.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) + -- se feature custom (Variant) + elseif Variant.Identify( Proc) then + -- esecuzione + bOk, sErr = Variant.Make( Proc, nRawId, b3Raw) + -- altrimenti feature non riconosciuta + else + bOk = false + sErr = 'Feature type non recognized for machining' + end + return bOk, sErr +end + +------------------------------------------------------------------------------------------------------------- +local function MoveMachiningsAtEnd( nPhase, nType, sStartName, sProperty) + local nOperId = EgtGetPhaseDisposition( nPhase) + local nLastId = EgtGetLastOperation() + local nInsertId = nLastId + while nOperId do + local nNextOperId = EgtGetNextOperation( nOperId) + if EgtGetOperationPhase( nOperId) == nPhase and EgtGetOperationType( nOperId) == nType and + ( ( EgtGetInfo( nOperId, 'MOVE_AFTER', 'i') == 1 ) or + ( not sStartName or string.sub( EgtGetName( nOperId), 1, #sStartName) == sStartName)) then + EgtRelocateGlob( nOperId, nInsertId, GDB_IN.AFTER) + nInsertId = nOperId + end + if nOperId == nLastId then + break + end + nOperId = nNextOperId + end +end + +------ Ordinamento dei tagli, delle fresature e delle forature ------- +local function SpSorting( TabCut, PrevMch, nType, bOneWay) + + -- ordino le lavorazioni (in gruppi di max 1000 entità se 32bit 10000 se 64bit) + --EgtOutLog('Dati per ShortestPath :') + local SP_MAX_ENT = EgtIf( EgtIs64bit(), 10000, 1000) + local nBase = 0 + while nBase < #TabCut do + -- calcolo ordinamento + EgtSpInit() + for i = 1, min( #TabCut - nBase, SP_MAX_ENT) do + local ptS = TabCut[nBase+i].Start + local ptE = TabCut[nBase+i].End + EgtSpAddPoint( ptS:getX(), ptS:getY(), ptS:getZ(), 0, 0, + ptE:getX(), ptE:getY(), ptE:getZ(), 0, 0) + end + EgtSpSetAngularParams( 1000, 40, 2000, 60) + EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 50000, 0, 0, 0, 0) + if WD.BEAM_MACHINE and (nType & MCH_OY.SAWING) == MCH_OY.SAWING then + EgtSpSetOpenBound( false, SHP_OB.NEAR_PNT, -50000, 0, 0, 0, 0) + end + EgtSpSetZzOwStep( 10) + local nType = EgtIf( bOneWay, SHP_TY.ONEWAY_YM, SHP_TY.OPEN) + local vOrd = EgtSpCalculate( nType) + EgtSpTerminate() + -- applico ordinamento calcolato + if vOrd then + for i = 1, #vOrd do + EgtRelocateGlob( TabCut[nBase+vOrd[i]].Mch, PrevMch, GDB_IN.AFTER) + PrevMch = TabCut[nBase+vOrd[i]].Mch + end + end + -- incremento la base + nBase = nBase + SP_MAX_ENT + end + + return PrevMch +end + +local function ContainsStartName( nOperId, StartNames) + local bFound = false + for i = 1, #StartNames do + local sStartName = StartNames[i] + if string.sub( EgtGetName( nOperId), 1, #sStartName) == sStartName then + bFound = true + end + end + return bFound +end + +------ Ordinamento dei tagli, delle fresature e delle forature ------- +local function SortMach( nPhase, PrevMch, nPartId, nType, StartNames, bExistName, sInfo, bExistInfo, bOneWay, bByTool, bByToolAngle) + -- dichiarazione tabella + local TabCut = {} + -- Recupero gli identificativi delle lavorazioni e annullo eventuali allungamenti e Id di altre lavorazioni rappresentate + local nOperId = EgtGetNextOperation( PrevMch) + while nOperId do + local nOperType = EgtGetOperationType( nOperId) + -- Se appartiene alla fase corrente e taglio con lama non da sopra (sempre su 1 sola entità) + if EgtGetOperationPhase( nOperId) == nPhase and ( nType & nOperType) == nOperType and + ( not nPartId or EgtGetInfo( nOperId, 'Part', 'i') == nPartId) and + ( not StartNames or ( bExistName and ContainsStartName( nOperId, StartNames)) or + ( not bExistName and not ContainsStartName( nOperId, StartNames))) and + ( not sInfo or ( bExistInfo and EgtGetInfo( nOperId, sInfo, 'i') == 1) or + ( not bExistInfo and EgtGetInfo( nOperId, sInfo, 'i') ~= 1)) then + -- non si deve cambiare lo stato di attivazione della lavorazione (se disabilitata errata) + EgtSetCurrMachining( nOperId) + if not EgtIsMachiningEmpty() then + -- punto iniziale e finale e direzione della lavorazione + local ptStart = EgtGetMachiningStartPoint() + local ptEnd = EgtGetMachiningEndPoint() + local sTUUID = '' + local nToolType = 0 + local nToolDiam = 0 + local nToolDir = 0 + if bByTool then + sTUUID = EgtGetMachiningParam( MCH_MP.TUUID) + local sToolName = EgtTdbGetToolFromUUID( sTUUID) + if EgtTdbSetCurrTool( sToolName) then + nToolType = EgtTdbGetCurrToolParam( MCH_TP.TYPE) + nToolDiam = EgtTdbGetCurrToolParam( MCH_TP.TOTDIAM) + else + sTUUID = '' + end + end + if bByToolAngle then + local nClId = EgtGetFirstNameInGroup( nOperId, 'CL') + local nPathId = EgtGetFirstInGroup( nClId or GDB_ID.NULL) + local vtTool = EgtGetInfo( nPathId, 'EXTR', 'v') + nToolDir = EgtIf( vtTool:getZ() > 0.999999, 1, 0) + end + table.insert( TabCut, {Mch=nOperId, Ent=nEntId, Start=ptStart, End=ptEnd, Tool=sTUUID, ToolType=nToolType, ToolDiam=nToolDiam, ToolDir=nToolDir}) + end + end + -- Passo alla operazione successiva + nOperId = EgtGetNextOperation( nOperId) + end + + if bByTool then + function ToolCompare(a,b) + if a.ToolType < b.ToolType then + return true + elseif a.ToolType == b.ToolType then + if a.ToolDiam > b.ToolDiam then + return true + elseif a.ToolDiam == b.ToolDiam then + if a.Tool < b.Tool then + return true + elseif a.Tool == b.Tool then + if bByToolAngle then + if a.ToolDir > b.ToolDir then + return true + elseif a.ToolDir == b.ToolDir then + return a.Mch < b.Mch + end + else + return a.Mch < b.Mch + end + end + end + end + return false + end + -- test della funzione di ordinamento + if EgtGetDebugLevel() >= 3 then + EgtOutLog( ' CompareFeatures Test ') + local bCompTest = true + for i = 1, #TabCut do + for j = i + 1, #TabCut do + local bComp1 = ToolCompare( TabCut[i], TabCut[j]) + local bComp2 = ToolCompare( TabCut[j], TabCut[i]) + if bComp1 == bComp2 then + bCompTest = false + EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', TabCut[i].Mch, TabCut[j].Mch)) + end + end + end + if bCompTest then + EgtOutLog( ' ALL OK') + end + end + + table.sort(TabCut, ToolCompare) +-- table.sort(TabCut, function(a,b) return a.ToolType < b.ToolType and a.ToolDiam > b.ToolDiam and a.Tool < b.Tool end) + local SupportTabCut = {} + local nPrevTUUID = 0 + local nPrevTDirZ = 1 + for i = 1, #TabCut do + -- se tuuid uguale al precedente, lo aggiungo alla lista + if nPrevTUUID == TabCut[i].Tool and ( not bByToolAngle or nPrevTDirZ == TabCut[i].ToolDir) then + table.insert( SupportTabCut, TabCut[i]) + -- se tuuid diverso, + else + -- faccio calcolare la lista + PrevMch = SpSorting( SupportTabCut, PrevMch, nType, bOneWay) + -- cancello la lista e aggiorno tuuid corrente + SupportTabCut = {} + nPrevTUUID = TabCut[i].Tool + if bByToolAngle then + nPrevTDirZ = TabCut[i].ToolDir + end + table.insert( SupportTabCut, TabCut[i]) + end + end + -- calcolo ultima lista + if #SupportTabCut > 0 then + PrevMch = SpSorting( SupportTabCut, PrevMch, nType, bOneWay) + end + else + PrevMch = SpSorting( TabCut, PrevMch, nType, bOneWay) + end + + return PrevMch + +end + +------------------------------------------------------------------------------------------------------------- +local function SortMachinings( nPhase, PrevMch, nPartId) + -- Chiodature + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Nail_'}, true) + -- Tagli con sega a catena che sono rifiniture di spigoli + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MORTISING, { 'Csaw_'}, false) + -- Forature orizzontali con punte lunghe + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING, { 'LhDrill_'}, true, 'MOVE_AFTER', false, true) + -- Preforature per fori inclinati + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.POCKETING, { 'PreDrill_'}, true) + -- Forature e Svuotature + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING + MCH_OY.POCKETING + MCH_OY.MILLING, { 'SideMill_', 'Clean_'}, false, 'MOVE_AFTER', false, false, true) +-- -- Forature *** +-- PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING, nil, nil, 'MOVE_AFTER', false) +-- -- Svuotature *** +-- PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.POCKETING, nil, nil, 'MOVE_AFTER', false) +-- -- Fresature che sono rifiniture di spigoli +-- PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Clean_'}, false, 'MOVE_AFTER', false, false, true) + -- Lavorazioni di superficie + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_MY.SURFFINISHING, nil, nil, 'MOVE_AFTER', false) + -- Fresature per gole + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Gorge_'}, true, 'MOVE_AFTER', false) + -- Fresature che sono rifiniture di spigoli + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'SideMill_'}, true, 'MOVE_AFTER', false, false, true, true) + -- Fresature che sono puliture di spigoli + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'Clean_'}, true, 'MOVE_AFTER', false, false, true) + -- Tagli per gole + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.SAWING, { 'GorgeCut_'}, true) + -- Tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.SAWING) + -- Qui rimozione sfridi (se ci sono lavorazioni successive) + -- Fresature dei lapjoint che necessitano di gorge + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, { 'SideMill_'}, true, 'MOVE_AFTER', true, false, true, true) + -- Tagli con sega a catena che vanno fatti dopo i tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MORTISING, { 'Csaw_'}, true) + -- Fresature (puliture di spigoli) che vanno fatte dopo i tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.MILLING, nil, nil, 'MOVE_AFTER', true) + -- Forature che vanno fatte dopo i tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.DRILLING, nil, nil, 'MOVE_AFTER', true) + -- Svuotature che vanno fatte dopo i tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_OY.POCKETING, nil, nil, 'MOVE_AFTER', true) + -- Lavorazioni di superficie che vanno fatte dopo i tagli con lama + PrevMch = SortMach( nPhase, PrevMch, nPartId, MCH_MY.SURFFINISHING, nil, nil, 'MOVE_AFTER', true) + return PrevMch +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 dei pezzi + local vPart = {} + local nPartId = EgtGetFirstPartInRawPart( nRawId) + while nPartId do + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + table.insert( vPart, {Id=nPartId, Box=b3Solid}) + nPartId = EgtGetNextPartInRawPart( nPartId) + end + -- raccolgo l'elenco delle feature da lavorare, ciclando sui pezzi + local vProc = {} + for i = 1, #vPart do + -- recupero le feature di lavorazione della parete + local vPartProc = WallExec.CollectFeatures( vPart[i].Id, b3Raw) + vProc = EgtJoinTables( vProc, vPartProc) + end + -- classifico le feature + ClassifyFeatures( vProc, b3Raw) + -- Eventuale determinazione delle feature lavorabili in parallelo (implementata nella configurazione macchina) + -- si impostano i flag Double (nil/0=no, 1=su X, 2=su Y) e Delta (offset tra T14 e T12 positivo o negativo) + if WD.FindFeaturesInDouble then + WD.FindFeaturesInDouble( vProc, b3Raw) + end + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc) + end + EgtOutLog( ' *** AddMachinings ***', 1) + -- 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 + elseif not Proc.Double then + local sMsg = 'Feature not machinable by orientation' + table.insert( Stats, {Err=1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId}) + end + end + EgtOutLog( ' *** End AddMachinings ***', 1) + -- se macchina pareti + if not WD.BEAM_MACHINE then + -- riordino le lavorazioni tra tutti i pezzi + local nPhase = 1 + local PrevMch = EgtGetPhaseDisposition( nPhase) + SortMachinings( nPhase, PrevMch) + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + EgtApplyAllMachinings() + -- altrimenti macchina travi + else + -- dichiaro lavorazione pareti + EgtSetInfo( EgtGetCurrMachGroup() or GDB_ID.NULL, 'Wall', '1') + -- ordino i pezzi secondo le X decrescenti + local function CompareParts( P1, P2) + return P1.Box:getCenter():getX() > P2.Box:getCenter():getX() + end + table.sort( vPart, CompareParts) + -- riordino le lavorazioni sui singoli pezzi + local nPhase = 1 + local PrevMch = EgtGetPhaseDisposition( nPhase) + for i = 1, #vPart do + PrevMch = SortMachinings( nPhase, PrevMch, vPart[i].Id) + end + -- aggiungo dati su prima disposizione + local nDispId = EgtGetPhaseDisposition( 1) + EgtSetInfo( nDispId, 'TYPE', 'START') + EgtSetInfo( nDispId, 'ORD', 1) + -- aggiungo flag su ultima lavorazione + local nLastMchId = EgtGetLastActiveOperation() + EgtSetCurrMachining( nLastMchId) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'Cut;') + -- aggiungo disposizione per lo scarico + EgtAddPhase() + local nRawId = EgtGetFirstRawPart() + EgtKeepRawPart( nRawId, 1) + local nDisp2Id = EgtGetPhaseDisposition( 2) + EgtSetInfo( nDisp2Id, 'TYPE', 'END') + EgtSetInfo( nDisp2Id, 'ORD', 1) + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings() + if not bApplOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err = 1, Msg=sApplErrors, Rot=0, CutId=0, TaskId=0}) + elseif sApplWarns and #sApplWarns > 0 then + -- non interessano perchè riguardano lo scarico delle travi + end + end + -- restituzione risultati + return ( nTotErr == 0), Stats +end + +------------------------------------------------------------------------------------------------------------- +return WallExec diff --git a/ProgramData/EgtCAM5/Wall/LuaLibs/WallLib.lua b/ProgramData/EgtCAM5/Wall/LuaLibs/WallLib.lua new file mode 100644 index 0000000..365f5d7 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/LuaLibs/WallLib.lua @@ -0,0 +1,320 @@ +-- WallLib.lua by Egaltech s.r.l. 2022/04/04 +-- Libreria globale per Pareti + +-- Tabella per definizione modulo +local WallLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' WallLib started', 1) + +------------------------------------------------------------------------------------------------------------- +function WallLib.GetAddGroup( PartId) + -- recupero il nome del gruppo di lavoro corrente + local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL) + if not sMchGrp then return nil, nil end + -- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco + local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp) + -- restituisco Id e Nome + return AddGrpId, sMchGrp +end + +------------------------------------------------------------------------------------------------------------- +function WallLib.CreateOrEmptyAddGroup( PartId) + -- recupero i dati del gruppo aggiuntivo + local AddGrpId, sMchGrp = WallLib.GetAddGroup( PartId) + if not sMchGrp then return false end + -- se esiste lo svuoto + if AddGrpId then + return EgtEmptyGroup( AddGrpId) + end + -- altrimenti lo creo + AddGrpId = EgtGroup( PartId or GDB_ID.NULL) + if not AddGrpId then return false end + -- assegno nome, flag di layer per gruppo di lavoro e colore + EgtSetName( AddGrpId, sMchGrp) + EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup()) + EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 50)) + return true +end + +------------------------------------------------------------------------------------------------------------- +function WallLib.GetPointDirDepth( nRawId, ptP, vtDir) + -- recupero il solido del grezzo + local nSolId = EgtGetFirstNameInGroup( nRawId, 'RawSolid') + if not nSolId then return end + -- interseco con la retta + local bOk, vType, vPar = EgtLineSurfTmInters( ptP, vtDir, nSolId, GDB_RT.GLOB) + if not bOk then return end + if not vPar or #vPar == 0 then return -2 end + local dLenIn, dLenOut + for i = 1, #vPar do + if vPar[i] < 0 then + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = -1 + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN then + dLenIn = -2 + end + else + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = vPar[i] + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN or vType[i] == GDB_SLT.TOUCH then + dLenOut = vPar[i] + end + end + end + return dLenIn, dLenOut +end + +--------------------------------------------------------------------- +function WallLib.GetFaceElevation( nSurfId, nFac, nRawId) + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFac, GDB_ID.ROOT) + if not ptC or not vtN then return 0 end + local frOCS = Frame3d( ptC, vtN) ; + local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS) + local dElev = b3Box:getMax():getZ() + if nRawId then + local _, dCenElev = WallLib.GetPointDirDepth( nRawId, ptC, vtN) + if dCenElev and dCenElev > dElev then dElev = dCenElev end + local dOffsX = min( 20, b3Box:getDimX() / 4) + local _, dP1Elev = WallLib.GetPointDirDepth( nRawId, ptC + dOffsX * frOCS:getVersX(), vtN) + if dP1Elev and dP1Elev > dElev then dElev = dP1Elev end + local _, dP2Elev = WallLib.GetPointDirDepth( nRawId, ptC - dOffsX * frOCS:getVersX(), vtN) + if dP2Elev and dP2Elev > dElev then dElev = dP2Elev end + local dOffsY = min( 20, b3Box:getDimY() / 4) + local _, dP3Elev = WallLib.GetPointDirDepth( nRawId, ptC + dOffsY * frOCS:getVersY(), vtN) + if dP3Elev and dP3Elev > dElev then dElev = dP3Elev end + local _, dP4Elev = WallLib.GetPointDirDepth( nRawId, ptC - dOffsY * frOCS:getVersY(), vtN) + if dP4Elev and dP4Elev > dElev then dElev = dP4Elev end + end + return dElev +end + +--------------------------------------------------------------------- +function WallLib.GetFaceWithMostAdj( nSurfId, nPartId, bCompare3Fc, dCosSideAng) + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nSurfId) + if not dCosSideAng then + dCosSideAng = -0.09 + end + -- recupero le normali delle facce + local vvtN = {} + for i = 1, nFacCnt do + local _, vtN = EgtSurfTmFacetCenter( nSurfId, i - 1, GDB_ID.ROOT) + vvtN[i] = vtN ; + end + -- adiacenze e sottosquadra delle facce + local vAdj = {} + local vUcut = {} + local vOrtho = {} + local vBlind = {} + for i = 1, nFacCnt do + -- recupero le adiacenze del loop esterno + local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + vAdj[i] = nCount + -- ne determino eventuale sottosquadra ( dal valore passato o - 3deg) e ortogonalità + local bUcut = false + local bOrtho = true + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + local vtN = vvtN[i] + local vtN2 = vvtN[vFacAdj[j]+1] + local dResV = vtN * vtN2 + if dResV < dCosSideAng - GEO.EPS_SMALL then + bUcut = true + end + if abs( dResV) > 2 * GEO.EPS_SMALL then + bOrtho = false + end + end + end + -- verifico se schermata da altra faccia + local bBlind = false + for j = 1, nFacCnt do + if i ~= j then + if vvtN[i] * vvtN[j] < -0.5 then + bBlind = true + end + end + end + -- assegno i risultati + vUcut[i] = bUcut + vOrtho[i] = bOrtho + vBlind[i] = bBlind + end + -- se 4 facce tutte con adiacenza 2, allora è un tunnel + if nFacCnt == 4 then + if vAdj[1] == 2 and vAdj[2] == 2 and vAdj[3] == 2 and vAdj[4] == 2 then + -- se tutte le facce sono ortogonali tra loro esco con un flag che ne indica questa propietà + if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true and vOrtho[4] == true then + return -1, GEO.INFINITO, true + else + return -1, GEO.INFINITO + end + end + end + -- se 3 facce con una che ha 2 adiacenze e le altre hanno 1 adiacenza, allora è una semi-fessura + if bCompare3Fc and nFacCnt == 3 then + local nCount2Adc = 0 + local nCount1Adc = 0 + -- ottengo il numero di facce con due adiacenze e il numero di facce con una adiacenza + for i = 1, #vAdj do + if vAdj[i] == 2 then + nCount2Adc = nCount2Adc + 1 + elseif vAdj[i] == 1 then + nCount1Adc = nCount1Adc + 1 + end + end + -- se il numero di adiacenze corrisponde + if nCount2Adc == 1 and nCount1Adc == 2 then + if vOrtho[1] == true and vOrtho[2] == true and vOrtho[3] == true then + return -1, GEO.INFINITO, true + else + return -1, GEO.INFINITO + end + end + end + -- recupero le facce non in sottosquadra e con il maggior numero di adiacenze + local nFacInd = {} + local nMaxAdj = -1 + local nSupAdj = -1 + for i = 1, nFacCnt do + if not vUcut[i] and not vBlind[i] then + if vAdj[i] >= nMaxAdj and vAdj[i] > 0 then + table.insert( nFacInd, i - 1) + nMaxAdj = vAdj[i] + elseif vAdj[i] > 0 then + table.insert( nFacInd, i - 1) + end + end + if vAdj[i] > nSupAdj then + nSupAdj = vAdj[i] + end + end + -- verifico non ci sia una faccia in sottosquadra con adiacenza superiore + if nSupAdj > nMaxAdj then + return -2, GEO.INFINITO + end + -- premio la faccia con minore elevazione + local nFacOpt, nFacOpt2 + local nOptAdj, nOptAdj2 + local dMinElev, dMinElev2 = GEO.INFINITO, GEO.INFINITO + for i = 1, #nFacInd do + local dElev = WallLib.GetFaceElevation( nSurfId, nFacInd[i], nPartId) + if dElev < dMinElev and ( not nOptAdj or vAdj[nFacInd[i]+1] >= nOptAdj) then + if dMinElev < dMinElev2 then + nFacOpt2 = nFacOpt + nOptAdj2 = nOptAdj + dMinElev2 = dMinElev + end + nFacOpt = nFacInd[i] + nOptAdj = vAdj[nFacInd[i]+1] + dMinElev = dElev + elseif dElev < dMinElev2 and ( not nOptAdj2 or vAdj[nFacInd[i]+1] >= nOptAdj2) then + nFacOpt2 = nFacInd[i] + nOptAdj2 = vAdj[nFacInd[i]+1] + dMinElev2 = dElev + end + end + return nFacOpt, dMinElev, nFacOpt2, dMinElev2 +end + +--------------------------------------------------------------------- +function WallLib.GetFaceHvRefDim( nSurfId, nFacet) + -- recupero centro e normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + if not ptC or not vtN then return end + -- riferimento tipo OCS della faccia (X orizz, Y max pendenza, Z normale) + local frHV = Frame3d( ptC, vtN) + if frHV:getVersY():getZ() < 0 then + frHV:rotate( ptC, vtN, 180) + end + -- determino l'ingombro in questo riferimento + local b3HV = EgtSurfTmGetFacetBBoxRef( nSurfId, nFacet, GDB_BB.STANDARD, frHV) + -- aggiusto l'origine del riferimento per metterlo nel centro del box + local ptBoxCen = b3HV:getCenter() + frHV:move( ptBoxCen:getX() * frHV:getVersX() + ptBoxCen:getY() * frHV:getVersY()) + -- restituisco i valori calcolati + return frHV, b3HV:getDimX(), b3HV:getDimY() +end + +--------------------------------------------------------------------- +function WallLib.GetNearestParalOpposite( vtRef) + -- devo confrontare la componente orizzontale con quella verticale + local dHorSq = vtRef:getX() * vtRef:getX() + vtRef:getY() * vtRef:getY() + local dVertSq =vtRef:getZ() * vtRef:getZ() + -- se prevalente la componente orizzontale + if dHorSq >= dVertSq then + if abs( vtRef:getX()) > abs( vtRef:getY()) then + if vtRef:getX() > 0 then + return MCH_MILL_FU.PARAL_LEFT + else + return MCH_MILL_FU.PARAL_RIGHT + end + else + if vtRef:getY() > 0 then + return MCH_MILL_FU.PARAL_FRONT + else + return MCH_MILL_FU.PARAL_BACK + end + end + -- altrimenti prevale la verticale + else + if vtRef:getZ() > 0 then + return MCH_MILL_FU.PARAL_DOWN + else + return MCH_MILL_FU.PARAL_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function WallLib.GetNearestOrthoOpposite( vtRef, vtNorm) + -- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa + local vtMyRef = Vector3d( vtRef) + if vtNorm then + vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm + vtMyRef:normalize() + end + -- devo confrontare la componente orizzontale con quella verticale + local dHorSq = vtMyRef:getX() * vtMyRef:getX() + vtMyRef:getY() * vtMyRef:getY() + local dVertSq = vtMyRef:getZ() * vtMyRef:getZ() + -- se prevalente la componente orizzontale + if dHorSq >= dVertSq then + if abs( vtMyRef:getX()) >= abs( vtMyRef:getY()) then + if vtMyRef:getX() > 0 then + return MCH_MILL_FU.ORTHO_LEFT + else + return MCH_MILL_FU.ORTHO_RIGHT + end + else + if vtMyRef:getY() > 0 then + return MCH_MILL_FU.ORTHO_FRONT + else + return MCH_MILL_FU.ORTHO_BACK + end + end + -- altrimenti prevale la verticale + else + if vtMyRef:getZ() > 0 then + return MCH_MILL_FU.ORTHO_DOWN + else + return MCH_MILL_FU.ORTHO_TOP + end + end + return nil +end + +------------------------------------------------------------------------------------------------------------- +return WallLib diff --git a/ProgramData/EgtCAM5/Wall/NestFlipAndRotate.lua b/ProgramData/EgtCAM5/Wall/NestFlipAndRotate.lua new file mode 100644 index 0000000..3990fab --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/NestFlipAndRotate.lua @@ -0,0 +1,454 @@ +-- NestFlipAndRotate.lua by Egaltech s.r.l. 2021/11/25 +-- Flip e rotazione ottimali per il nesting in base all'analisi delle features + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- NFAR.PARTID = +NFAR.RAW_GRAIN_DIR_X = true + +local sLog = 'Flip And Rotate Part ' .. tostring( NFAR.PARTID) +EgtOutLog( sLog) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Wall\\WallData.lua') then + NFAR.ERR = 12 + NFAR.MSG = 'Error not configured for walls machine : ' .. sMachine + WriteErrToLogFile( NFAR.ERR, NFAR.MSG) + PostErrView( NFAR.ERR, NFAR.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua') + +-- Carico le librerie +_G.package.loaded.WallExec = nil +local WE = require( 'WallExec') +_G.package.loaded.WProcessLapJoint = nil +local LapJoint = require( 'WProcessLapJoint') +_G.package.loaded.WProcessDrill = nil +local Drill = require( 'WProcessDrill') +_G.package.loaded.WProcessCut = nil +local Cut = require( 'WProcessCut') +_G.package.loaded.WProcessDoubleCut = nil +local DoubleCut = require( 'WProcessDoubleCut') +_G.package.loaded.WProcessSawCut = nil +local SawCut = require( 'WProcessSawCut') +_G.package.loaded.WProcessFreeContour = nil +local FreeContour = require( 'WProcessFreeContour') +_G.package.loaded.WProcessMortise = nil +local Mortise = require( 'WProcessMortise') +_G.package.loaded.WProcessDtMortise = nil +local DtMortise = require( 'WProcessDtMortise') +_G.package.loaded.WProcessMark = nil +local Mark = require( 'WProcessMark') +_G.package.loaded.WProcessText = nil +local Text = require( 'WProcessText') + +-- Carico i dati globali +local WD = require( 'WallData') + +local function ClassifyFlip( vPartProc, b3Part) + + local FlipFeatureStates = {} + local bLapJoints = false + + for nInd = 1, #vPartProc do + if LapJoint.Identify( vPartProc[nInd]) then + -- setto parametro Q + if vPartProc[nInd].Prc == 30 then + EgtSetInfo( vPartProc[nInd].Id, "Q08", 1) + EgtSetInfo( vPartProc[nInd].Id, "Q08A", 1) + else + EgtSetInfo( vPartProc[nInd].Id, "Q03", 1) + EgtSetInfo( vPartProc[nInd].Id, "Q03A", 1) + end + bLapJoints = true + local nFlip0, nFlip1 = LapJoint.FlipClassify(vPartProc[nInd]) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif Drill.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = Drill.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif Cut.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = Cut.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif DoubleCut.Identify( vPartProc[nInd]) then + -- setto parametro Q + if vPartProc[nInd].Prc == 12 then + EgtSetInfo( vPartProc[nInd].Id, "Q02", 1) + EgtSetInfo( vPartProc[nInd].Id, "Q02A", 1) + end + local nFlip0, nFlip1 = DoubleCut.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif SawCut.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = SawCut.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif FreeContour.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = FreeContour.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif Mortise.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = Mortise.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif DtMortise.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = DtMortise.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif Mark.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = Mark.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + elseif Text.Identify( vPartProc[nInd]) then + local nFlip0, nFlip1 = Text.FlipClassify(vPartProc[nInd], b3Part) + if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then + table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1}) + end + end + end + + return FlipFeatureStates, bLapJoints +end + + +local function ClassifyRotation( vPartProc) + + local RotateFeatureStates = {} + for nInd = 1, #vPartProc do + if Drill.Identify( vPartProc[nInd]) then + local nRot0, nRot90, nRot180, nRot270 = Drill.RotateClassify(vPartProc[nInd], ValidRotations) + if nRot0 and nRot0 >= 0 then + table.insert( RotateFeatureStates, { Rot0 = nRot0, Rot90 = nRot90, Rot180 = nRot180, Rot270 = nRot270}) + end + end + end + + return RotateFeatureStates +end + +--- + +local vPartProc = WE.CollectFeatures( NFAR.PARTID) +local b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) +local bManualFlip = EgtGetInfo( NFAR.PARTID, "MANUALFLIP", 'b') +local bManualRot = EgtGetInfo( NFAR.PARTID, "MANUALROT", 'b') + +-- FLIP +local FlipFeatureStates, bLapJoints = ClassifyFlip( vPartProc, b3Part) + +if not bManualFlip then + local bFlip + -- analizzo stati flip delle feature + local nFlip0Min = 100 + local nFlip0Cnt = 0 + local nFlip1Min = 100 + local nFlip1Cnt = 0 + -- calcolo punteggio minimo e sua molteplicita' per entrambi i lati + for nInd = 1, #FlipFeatureStates do + if FlipFeatureStates[nInd].Flip0 < nFlip0Min then + nFlip0Min = FlipFeatureStates[nInd].Flip0 + nFlip0Cnt = 1 + elseif FlipFeatureStates[nInd].Flip0 == nFlip0Min then + nFlip0Cnt = nFlip0Cnt + 1 + end + if FlipFeatureStates[nInd].Flip1 < nFlip1Min then + nFlip1Min = FlipFeatureStates[nInd].Flip1 + nFlip1Cnt = 1 + elseif FlipFeatureStates[nInd].Flip1 == nFlip1Min then + nFlip1Cnt = nFlip1Cnt + 1 + end + end + -- calcolo lato con punteggio minore o molteplicita' piu' alta + if nFlip0Min == nFlip1Min then + if nFlip0Cnt > nFlip1Cnt then + bFlip = true + elseif nFlip0Cnt < nFlip1Cnt then + bFlip = false + elseif bLapJoints then + -- se equivalenti ma ci sono lap joints, fisso il flip per non avere problemi con le aree di lavorazione nel nesting + bFlip = false + end + elseif nFlip0Min < nFlip1Min then + bFlip = true + else + bFlip = false + end + + if bFlip ~= nil then + -- se una posizione è più conveniente dell'altra setto info nel pezzo + EgtSetInfo( NFAR.PARTID, "NestAllowFlip", false) + EgtSetInfo( NFAR.PARTID, "NestFlip", bFlip) + else + EgtSetInfo( NFAR.PARTID, "NestAllowFlip", true) + end + + if bFlip then + -- flip pezzo + EgtRotate( NFAR.PARTID, b3Part:getCenter(), X_AX(), 180, GDB_RT.GLOB) + -- modifico le info del pezzo + local nPartFlip = EgtGetInfo( NFAR.PARTID, "INVERTED", 'i') or 0 + local nTotFlip = EgtIf( nPartFlip == 180, 0, 180) + EgtSetInfo( NFAR.PARTID, "INVERTED", nTotFlip) + EgtSetInfo( NFAR.PARTID, "FLIPROTMODIFIED", 1) + end +end + +-- rimuovo parametri Q +local b3PartInside = BBox3d( b3Part) +b3PartInside:expand( - WD.INSIDE_RAW_TOL) +for nInd = 1, #vPartProc do + local Proc = vPartProc[nInd] + + if LapJoint.Identify( Proc) then + -- cerco la faccia rivolta verso l'alto e la faccia rivolta verso il basso + local nFaceInd = -1 + local nFaceDownInd = -1 + for nIdx = 0, Proc.Fct - 1 do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if vtN:getZ() > 0.95 then + nFaceInd = nIdx + elseif vtN:getZ() < - 0.95 then + nFaceDownInd = nIdx + end + end + -- se è lap joint dall'alto + if nFaceInd ~= -1 and nFaceDownInd == -1 then + local ptCen = EgtSurfTmFacetCenter( Proc.Id, nFaceInd, GDB_ID.ROOT) + -- se all'interno rimuovo info Q + if EnclosesPointXY( b3PartInside, ptCen) then + -- resetto parametro Q + if Proc.Prc == 30 then + EgtRemoveInfo( Proc.Id, "Q08") + EgtRemoveInfo( Proc.Id, "Q08A") + else + EgtRemoveInfo( Proc.Id, "Q03") + EgtRemoveInfo( Proc.Id, "Q03A") + end + end + end + + elseif DoubleCut.Identify( Proc) then + -- verifico se due facce e rivolto verso l'alto + if Proc.Fct == 2 then + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + + if ( vtN[1]:getZ() >= 0.95 or vtN[2]:getZ() >= 0.95) then + local nFaceInd = EgtIf( vtN[1]:getZ() >= 0.95, 0, 1) + local ptCen = EgtSurfTmFacetCenter( Proc.Id, nFaceInd, GDB_ID.ROOT) + -- se all'interno rimuovo info Q + if EnclosesPointXY( b3PartInside, ptCen) then + -- resetto parametro Q + if Proc.Prc == 12 then + EgtRemoveInfo( Proc.Id, "Q02") + EgtRemoveInfo( Proc.Id, "Q02A") + end + end + end + end + end +end + + +-- ROTATION +nRotate = 0 +-- venatura +EgtRemoveInfo( NFAR.PARTID, "HasGrainDirection") +local bGrain = false +local sGrainInfo = EgtGetInfo( NFAR.PARTID, "GRAINDIRECTION", 's') +if sGrainInfo then + local sGrainAlign = string.sub( sGrainInfo, 7) + local sGrainDir = string.sub( sGrainInfo, 1, 5) + if sGrainAlign == "1" and ( sGrainDir == "1,0,0" or sGrainDir == "0,1,0") then + EgtSetInfo( NFAR.PARTID, "HasGrainDirection", 1) + bGrain = true + -- trovo la rotazione ( a meno di 180°) che deve avere il pezzo per essere allineato con la venatura del grezzo + local nGrainRot = 0 + if ( sGrainDir == "1,0,0" and not NFAR.RAW_GRAIN_DIR_X) or ( sGrainDir == "0,1,0" and NFAR.RAW_GRAIN_DIR_X) then + nGrainRot = 90 + end + + local nPartRot = EgtGetInfo( NFAR.PARTID, "ROTATED", 'i') or 0 + if ( nGrainRot == 0 and ( nPartRot == 90 or nPartRot == 270)) or ( nGrainRot == 90 and ( nPartRot == 0 or nPartRot == 180)) then + local b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) + nRotate = 90 + end + end +end + +if not bManualRot then + + local RotateFeatureStates = ClassifyRotation( vPartProc) + + -- analizzo stati rotazione delle feature + local nRot0Min = 100 + local nRot0Cnt = 0 + local nRot90Min = 100 + local nRot90Cnt = 0 + local nRot180Min = 100 + local nRot180Cnt = 0 + local nRot270Min = 100 + local nRot270Cnt = 0 + -- calcolo punteggio minimo e sua molteplicita' per tutte le rotazioni + for nInd = 1, #RotateFeatureStates do + if RotateFeatureStates[nInd].Rot0 < nRot0Min then + nRot0Min = RotateFeatureStates[nInd].Rot0 + nRot0Cnt = 1 + elseif RotateFeatureStates[nInd].Rot0 == nRot0Min then + nRot0Cnt = nRot0Cnt + 1 + end + if RotateFeatureStates[nInd].Rot90 < nRot90Min then + nRot90Min = RotateFeatureStates[nInd].Rot90 + nRot90Cnt = 1 + elseif RotateFeatureStates[nInd].Rot90 == nRot90Min then + nRot90Cnt = nRot90Cnt + 1 + end + if RotateFeatureStates[nInd].Rot180 < nRot180Min then + nRot180Min = RotateFeatureStates[nInd].Rot180 + nRot180Cnt = 1 + elseif RotateFeatureStates[nInd].Rot180 == nRot180Min then + nRot180Cnt = nRot180Cnt + 1 + end + if RotateFeatureStates[nInd].Rot270 < nRot270Min then + nRot270Min = RotateFeatureStates[nInd].Rot270 + nRot270Cnt = 1 + elseif RotateFeatureStates[nInd].Rot270 == nRot270Min then + nRot270Cnt = nRot270Cnt + 1 + end + end + + -- se c'e' qualche stato di rotazione + local MinList = { { Rot = 0, Score = nRot0Min, ScoreCnt = nRot0Cnt}, + { Rot = 90, Score = nRot90Min, ScoreCnt = nRot90Cnt}, + { Rot = 180, Score = nRot180Min, ScoreCnt = nRot180Cnt}, + { Rot = 270, Score = nRot270Min, ScoreCnt = nRot270Cnt}} + local nRotateOpt = 0 + if #RotateFeatureStates > 0 then + -- calcolo lato con punteggio minore o molteplicita' piu' alta + local nRotMax = 0 + local nScoreMax = 0 + local nScoreCnt = 0 + for nInd = 1, #MinList do + if MinList[nInd].Score > nScoreMax then + nRotMax = MinList[nInd].Rot + nScoreMax = MinList[nInd].Score + nScoreCnt = MinList[nInd].ScoreCnt + elseif MinList[nInd].Score == nScoreMax then + if MinList[nInd].ScoreCnt > nScoreCnt then + nRotMax = MinList[nInd].Rot + nScoreMax = MinList[nInd].Score + nScoreCnt = MinList[nInd].ScoreCnt + end + end + end + nRotateOpt = nRotMax + else + nRotateOpt = 0 + end + + local bRotNest = false + local nStepRotNest = 0 + -- se calcolate limitazioni su rotazioni + if MinList and #MinList > 0 then + -- verifico condizioni da permettere al nesting + if MinList[1].Score >= 50 and MinList[2].Score >= 50 and MinList[3].Score >= 50 and MinList[4].Score >= 50 then + bRotNest = true + nStepRotNest = 90 + elseif (nRotateOpt == 0 and MinList[3].Score >= 50) or ( nRotateOpt == 90 and MinList[4].Score >= 50) then + bRotNest = true + nStepRotNest = 180 + end + else + -- altrimenti permetto tutto + bRotNest = true + nStepRotNest = 90 + end + + -- verifico se ci sono fori lungo Y che bloccano la rotazione + local bDrillOnY = ( nStepRotNest == 180) + + local b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) + + if bGrain then + -- se venatura eseguo rotazione solo se è di 180° + if nRotateOpt == 180 then + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), nRotateOpt, GDB_RT.GLOB) + nRotate = nRotate + nRotateOpt + end + nStepRotNest = 180 + else + -- eseguo rotazione + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), nRotateOpt, GDB_RT.GLOB) + nRotate = nRotate + nRotateOpt + end + + -- verifico se rotazione è valida ( pezzo contenuto nel grezzo) solo se no venatura + if not bGrain then + b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) + local bValidRotationForRaw = b3Part:getDimX() < WD.MAX_LENGTH and b3Part:getDimY() < WD.MAX_WIDTH + local bRotatedIsValid = b3Part:getDimY() < WD.MAX_LENGTH and b3Part:getDimX() < WD.MAX_WIDTH + if not bValidRotationForRaw and bRotatedIsValid then + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) + nRotate = nRotate + 90 + nStepRotNest = 180 + end + end + + -- se no venatura e non ci sono fori verifico se il pezzo cade + if not bGrain and not bDrillOnY then + b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD) + local bValidRotation = b3Part:getDimX() > ( WD.INTRULLI or 1200) + -- verifico se ruotata resta valida + local bRotatedIsValid = b3Part:getDimY() > ( WD.INTRULLI or 1200) + -- se non è valida ma ruotato lo sarebbe, ruoto + if not bValidRotation and bRotatedIsValid and nStepRotNest ~= 180 then + EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) + nRotate = nRotate + 90 + nStepRotNest = 180 + elseif bValidRotation and not bRotatedIsValid then + -- se fosse valida ma la sua ruotata no, allora blocco lo step nella rotazione del nesting + nStepRotNest = 180 + end + end + + -- setto info nel pezzo + if nRotate > 0 then + local nPartRot = EgtGetInfo( NFAR.PARTID, "ROTATED", 'i') or 0 + local nTotRot = nPartRot - nRotate + nTotRot = EgtIf( nTotRot < 0, nTotRot + 360, nTotRot) + EgtSetInfo( NFAR.PARTID, "ROTATED", nTotRot) + EgtSetInfo( NFAR.PARTID, "FLIPROTMODIFIED", 1) + end + + EgtSetInfo( NFAR.PARTID, "NestStepRot", nStepRotNest) + EgtSetInfo( NFAR.PARTID, "NestRot", nRotate) + EgtSetInfo( NFAR.PARTID, "NestAllowRot", bRotNest) +end + + +NFAR.ERR = 0 \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Wall/NestProcess.lua b/ProgramData/EgtCAM5/Wall/NestProcess.lua new file mode 100644 index 0000000..2e8ea8b --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/NestProcess.lua @@ -0,0 +1,2241 @@ +-- NestProcess.lua by Egaltech s.r.l. 2021/05/25 +-- Gestione nesting automatico pareti + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Per test +--NEST = {} +--NEST.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl' +--NEST.MACHINE = 'Essetre-90480019_MW' +--NEST.FLAG = 3 +--NEST.MIN_ANGLE_PNT = 60 +--NEST.DRILL_MACH_AREA = 0 +NEST.LAP_JOINT_U_MACH_AREA = 1 -- 0 +NEST.MACH_AREA_USE_OTHER_DIAM = 1 -- 0 +NEST.MACH_AREA_OTHER_DIAM = 200 +NEST.MACH_AREA_IGNORE_3rdFACE = 1 -- 0 + + +local sLog = 'NestProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. LEN["1"] .. ', ' .. WIDTH["1"] +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( NEST.FILE, '.txt') +EgtEraseFile( sLogFile) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Wall\\WallData.lua') then + NEST.ERR = 12 + NEST.MSG = 'Error not configured for walls machine : ' .. sMachine + WriteErrToLogFile( NEST.ERR, NEST.MSG) + PostErrView( NEST.ERR, NEST.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua') + +-- Carico le librerie +_G.package.loaded.WallExec = nil +local WE = require( 'WallExec') +_G.package.loaded.WallLib = nil +local WL = require( 'WallLib') +_G.package.loaded.WProcessLapJoint = nil +local LapJoint = require( 'WProcessLapJoint') +_G.package.loaded.WProcessDrill = nil +local Drill = require( 'WProcessDrill') +_G.package.loaded.WProcessDoubleCut = nil +local DoubleCut = require( 'WProcessDoubleCut') +_G.package.loaded.WProcessFreeContour = nil +local FreeContour = require( 'WProcessFreeContour') + +-- Carico i dati globali +local WD = require( 'WallData') + +-- lista dei pezzi con flip o rotazione +local PartStates = {} + +-- 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 ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) 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 ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) 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 + +-- Funzione per trovare nome MachGroup +local function NewMachGroupName() + local nMachGroupId = EgtGetFirstMachGroup() + if not nMachGroupId then return 1 end + local nMaxMachGroup = 0 + while nMachGroupId do + sMachGroupName = EgtGetMachGroupName(nMachGroupId) + local nMachGroupName = tonumber(sMachGroupName) + if nMachGroupName > nMaxMachGroup then + nMaxMachGroup = nMachGroupName + end + nMachGroupId = EgtGetNextMachGroup(nMachGroupId) + end + return nMaxMachGroup + 1 +end + +-- Funzione che crea il rettangolo della lavorazione +local function CreateToolRectangle( ptP1, dValP1, ptP2, dValP2, vtFace, dValFace, nOutlineGrp) + local dExtra = 5 + local vtX = ptP2 - ptP1 + vtX:normalize() + -- creo il rettangolo della lavorazione + ptP1 = ptP1 - vtX * ( dValP1 + dExtra) + ptP2 = ptP2 + vtX * ( dValP2 + dExtra) + ptP2 = ptP2 + vtFace * ( dValFace + dExtra) + --local nId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX(), ptP2:getY(), 0), Point3d( ptP1:getX(), ptP1:getY(), 0)) + local nId = EgtRectangle2P( nOutlineGrp, ptP2, ptP1) + return nId +end + +-- Funzione che verifica se la lavorazione è lap joint dal basso ed eventualmente ne calcola l'area di lavorazione +local function IdentifyLJFromBottom( Proc, bCompute, nOutlineGrp) + + local bLJFromBottom = false + local nRectId + local vtFace + + local dMinCompZ = 0.95 + if Proc.Fct == 2 then + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + + -- se rivolto verso il basso + if ( vtN[1]:getZ() < - dMinCompZ or vtN[2]:getZ() < - dMinCompZ) then + vtFace = EgtIf( vtN[1]:getZ() < - dMinCompZ, vtN[2], vtN[1]) + if not ( vtFace:getZ() > dMinCompZ or vtFace:getZ() < - dMinCompZ) then + bLJFromBottom = true + if bCompute then + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + -- creo il rettangolo della lavorazione + nRectId = CreateToolRectangle( ptP1, WD.SIDEMILL_DIAM_DOWN / 2, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace, WD.SIDEMILL_DIAM_DOWN, nOutlineGrp) + end + end + end + + + elseif Proc.Fct == 3 then + local nFacInd, dElev, nFacInd2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + + -- se nel mezzo di una faccia + if not nFacInd2 then + if nFacInd ~= -2 and nFacInd ~= GDB_ID.NULL then + vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + if not ( vtFace:getZ() > dMinCompZ or vtFace:getZ() < - dMinCompZ) then + local nOtherFace = EgtIf( nFacInd == 0, 1, 0) + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOtherFace, GDB_ID.ROOT) + if abs( ptP1:getZ() - ptP2:getZ()) < GEO.EPS_SMALL then + bLJFromBottom = true + if bCompute then + nRectId = CreateToolRectangle( ptP1, WD.SIDEMILL_DIAM_DOWN / 2, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace, WD.SIDEMILL_DIAM_DOWN, nOutlineGrp) + end + end + end + end + + -- se dal basso + else + local nFaceZ = -1 + for nIdx = 0, 2 do + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if vtN2:getZ() < - dMinCompZ then + nFaceZ = nIdx + break + end + end + if nFaceZ ~= -1 then + local nFace = EgtIf( nFaceZ == nFacInd, nFacInd2, nFacInd) + local nOtherFace = EgtIf( nFaceZ + nFace == 3, 0, EgtIf( nFaceZ + nFace == 2, 1, 2)) + vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nFace, GDB_ID.ROOT) + --vtFace[2] = EgtSurfTmFacetNormVersor( Proc.Id, nOtherFace, GDB_ID.ROOT) + bLJFromBottom = true + if bCompute then + local bAdj, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFace, nFaceZ, GDB_ID.ROOT) + local bAdj2, ptP3, ptP4 = EgtSurfTmFacetsContact( Proc.Id, nFace, nOtherFace, GDB_ID.ROOT) + if AreSamePointApprox( ptP2, ptP3) or AreSamePointApprox( ptP2, ptP4) then + ptP1, ptP2 = ptP2, ptP1 + end + local dVal = EgtIf( NEST.MACH_AREA_IGNORE_3rdFACE == 1, WD.SIDEMILL_DIAM_DOWN / 2, 0) + nRectId = CreateToolRectangle( ptP1, dVal, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace, WD.SIDEMILL_DIAM_DOWN, nOutlineGrp) + end + end + end + + elseif Proc.Fct == 4 then + local nFacInd, dElev, nFacInd2, dElev2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + if nFacInd ~= -2 and nFacInd ~= GDB_ID.NULL then + vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + + if not ( vtFace:getZ() > dMinCompZ or vtFace:getZ() < - dMinCompZ) then + local nOtherFace = -1 + for nIdx = 0, 3 do + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if vtN2:getZ() > dMinCompZ or vtN2:getZ() < - dMinCompZ then + nOtherFace = nIdx + break + end + end + if nOtherFace ~= -1 and nOtherFace ~= nFacInd and nOtherFace ~= nFacInd2 then + bLJFromBottom = true + if bCompute then + local bAdj, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nOtherFace, GDB_ID.ROOT) + local bAdj2, ptP3, ptP4 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacInd2, GDB_ID.ROOT) + if AreSamePointApprox( ptP2, ptP3) or AreSamePointApprox( ptP2, ptP4) then + ptP1, ptP2 = ptP2, ptP1 + end + nRectId = CreateToolRectangle( ptP1, 0, ptP2, WD.SIDEMILL_DIAM_DOWN / 2, vtFace, WD.SIDEMILL_DIAM_DOWN, nOutlineGrp) + end + end + end + + if nFacInd2 and nFacInd2 ~= GDB_ID.NULL then + local vtFace2 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd2, GDB_ID.ROOT) + if ( vtFace2:getZ() < - dMinCompZ or vtFace:getZ() < - dMinCompZ) then + bLJFromBottom = true + if vtFace:getZ() < -dMinCompZ then vtFace = vtFace2 end + if bCompute then + local bAdj, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacInd2, GDB_ID.ROOT) + nRectId = CreateToolRectangle( ptP1, 0, ptP2, 0, vtFace, WD.SIDEMILL_DIAM_DOWN, nOutlineGrp) + end + end + end + + end + end + + if bLJFromBottom then + return vtFace, nRectId + else + return + end +end + +-- Funzione che verifica se la lavorazione è lap joint da sopra ed eventualmente ne calcola l'area di lavorazione +local function IdentifyLJFromTop( Proc, bCompute, nOutlineGrp) + + local bLJFromTop = false + local vtFace, nRectId + + if not WD.SIDEMILL_DIAM_UP or WD.SIDEMILL_DIAM_UP < GEO.EPS_SMALL then return end + + local dMinComp = 0.95 + if Proc.Fct == 2 then + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + + -- se rivolto verso l'alto + if (vtN[1]:getZ() > dMinComp or vtN[2]:getZ() > dMinComp) then + bLJFromTop = true + vtFace = EgtIf( vtN[1]:getZ() > dMinComp, vtN[2], vtN[1]) + if bCompute then + local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local b3Face = EgtSurfTmGetFacetBBoxGlob( Proc.Id, EgtIf( vtN[1]:getZ() > dMinComp, 0, 1), GDB_BB.STANDARD) + local dDim = 0 + if vtFace:getX() > dMinComp or vtFace:getX() < - dMinComp then + dDim = b3Face:getDimX() + elseif vtFace:getY() > dMinComp or vtFace:getY() < - dMinComp then + dDim = b3Face:getDimY() + end + local dValFace = max( dDim + WD.SIDEMILL_DIAM_UP / 2, WD.SIDEMILL_DIAM_UP) + local dVal = WD.SIDEMILL_DIAM_UP / 2 + if NEST.MACH_AREA_USE_OTHER_DIAM == 1 then + dVal = NEST.MACH_AREA_OTHER_DIAM / 2 + end + nRectId = CreateToolRectangle( ptP1, dVal, ptP2, dVal, vtFace, dValFace, nOutlineGrp) + end + end + + -- caso 3 facce + elseif Proc.Fct == 3 then + local nFacInd, dElev, nFacInd2 = WL.GetFaceWithMostAdj( Proc.Id, Proc.PartId) + + -- forma ad U + if not nFacInd2 and nFacInd ~= GDB_ID.NULL and NEST.LAP_JOINT_U_MACH_AREA == 1 then + local vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtFace:getZ() > dMinComp then + bLJFromTop = true + if bCompute then + local b3Face = EgtSurfTmGetFacetBBoxGlob( Proc.Id, nFacInd, GDB_BB.STANDARD) + local nOtherFace = EgtIf( nFacInd == 0, 1, 0) + local vtNOther = EgtSurfTmFacetNormVersor( Proc.Id, nOtherFace, GDB_ID.ROOT) + local vtDir = EgtIf( AreSameOrOppositeVectorApprox( vtNOther, X_AX()), Y_AX(), X_AX()) + local dVal = WD.SIDEMILL_DIAM_UP / 2 + 5 + local ptMin = b3Face:getMin() - dVal * vtDir + local ptMax = b3Face:getMax() + dVal * vtDir + -- nRectId = EgtRectangle2P( nOutlineGrp, Point3d(ptMax:getX(), ptMax:getY(), 0), Point3d( ptMin:getX(), ptMin:getY(), 0)) + nRectId = EgtRectangle2P( nOutlineGrp, ptMax, ptMin) + end + end + + elseif nFacInd2 then + local nFaceZ = -1 + for nIdx = 0, 2 do + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if vtN2:getZ() > dMinComp then + nFaceZ = nIdx + break + end + end + if nFaceZ ~= -1 then + local nFace = EgtIf( nFaceZ == nFacInd, nFacInd2, nFacInd) + local nOtherFace = EgtIf( nFaceZ + nFace == 3, 0, EgtIf( nFaceZ + nFace == 2, 1, 2)) + local vtFace = {} + vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nFace, GDB_ID.ROOT) + --vtFace = EgtSurfTmFacetNormVersor( Proc.Id, nOtherFace, GDB_ID.ROOT) + bLJFromTop = true + if bCompute then + local bAdj, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, nFace, nFaceZ, GDB_ID.ROOT) + local bAdj2, ptP3, ptP4 = EgtSurfTmFacetsContact( Proc.Id, nFace, nOtherFace, GDB_ID.ROOT) + if AreSamePointApprox( ptP2, ptP3) or AreSamePointApprox( ptP2, ptP4) then + ptP1, ptP2 = ptP2, ptP1 + end + + local b3Face = EgtSurfTmGetFacetBBoxGlob( Proc.Id, nFaceZ, GDB_BB.STANDARD) + local dDim = 0 + if vtFace:getX() > dMinComp or vtFace:getX() < - dMinComp then + dDim = b3Face:getDimX() + elseif vtFace:getY() > dMinComp or vtFace:getY() < - dMinComp then + dDim = b3Face:getDimY() + end + local dValFace = max( dDim + WD.SIDEMILL_DIAM_UP / 2, WD.SIDEMILL_DIAM_UP) + local dVal = WD.SIDEMILL_DIAM_UP / 2 + if NEST.MACH_AREA_USE_OTHER_DIAM == 1 then + dVal = NEST.MACH_AREA_OTHER_DIAM / 2 + end + nRectId = CreateToolRectangle( ptP1, 0, ptP2, dVal, vtFace, dValFace, nOutlineGrp) + end + end + end + end + + if bLJFromTop then + return vtFace, nRectId + else + return + end +end + +-- Funzione che crea le regioni occupate dalle lavorazioni +local function ComputeToolOutlines( nPartId) + + local ToolOutlineId = {} + EgtRemoveInfo( nPartId, "ToolOutlines") + + -- recupero il gruppo con gli outlines degli utensili + local nOutlineGrp = EgtGetFirstNameInGroup(GDB_ID.ROOT, "ToolOutlines") + if not nOutlineGrp or nOutlineGrp == GDB_ID.NULL then + nOutlineGrp = EgtGroup( GDB_ID.ROOT) + EgtSetName( nOutlineGrp, "ToolOutlines") + EgtSetStatus( nOutlineGrp, GDB_ST.OFF) + end + + local vPartProc = WE.CollectFeatures( nPartId, b3Raw) + for nInd = 1, #vPartProc do + + local Proc = vPartProc[nInd] + + -- lap joint + if LapJoint.Identify( Proc) then + -- verifico se dal basso + local _ , nRectId = IdentifyLJFromBottom( Proc, true, nOutlineGrp) + if nRectId then + EgtSetColor( nRectId, EgtStdColor("BLUE")) + table.insert( ToolOutlineId, nRectId) + else + -- verifico se dall'alto + local _ , nRectId = IdentifyLJFromTop( Proc, true, nOutlineGrp) + if nRectId then + EgtSetColor( nRectId, EgtStdColor("AQUA")) + local nPrId = EgtGetInfo( Proc.Id, "PRID", 'i') + EgtSetInfo( nRectId, "PRID", nPrId) + table.insert( ToolOutlineId, nRectId) + end + end + end + + -- fori + if NEST.DRILL_MACH_AREA == 1 and Drill.Identify( Proc) then + -- recupero dati del foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + local dLen = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + local dDiam = 2 * EgtArcRadius( AuxId) + + -- verifico se la lunghezza del foro è maggiore della lunghezza della punta + if bOpen and AreSameOrOppositeVectorApprox( vtExtr, Y_AX()) and dLen > WD.HOR_DRILL_LEN - 1 then + local ptP1 = Proc.Box:getMin() + local ptP2 = Proc.Box:getMax() + local dExtra = 10 + ptP1 = ptP1 - ( WD.MAX_WIDTH - dLen + dExtra) * Y_AX() + ptP2 = ptP2 + ( WD.MAX_WIDTH - dLen + dExtra) * Y_AX() + + --local nId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX(), ptP2:getY(), 0), Point3d( ptP1:getX(), ptP1:getY(), 0)) + local nId = EgtRectangle2P( nOutlineGrp, ptP2, ptP1) + EgtSetColor( nId, EgtStdColor("AQUA")) + if nId ~= GDB_ID.NULL then table.insert(ToolOutlineId, nId) end + end + end + + -- lati inclinati free contour + if FreeContour.Identify( Proc) then + local bPocket = EgtGetInfo( Proc.Id, 'PCKT', 'b') + if not bPocket then + for nInd = 0, Proc.Fct - 1 do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nInd, GDB_ID.ROOT) + -- se inclinato + if abs( vtN:getZ()) > GEO.EPS_SMALL then + local bUnderCut = vtN:getZ() < - GEO.EPS_SMALL + + local dCosAlpha = (vtN ^ Z_AX()):len() + local dVal + if bUnderCut then + dVal = ( NEST.OFFSET + 0.1) / dCosAlpha + else + dVal = ( NEST.OFFSET + 0.1) * dCosAlpha + end + + local frLoc, dDimX, dDimY = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nInd, GDB_ID.ROOT) + local b3Face = EgtSurfTmGetFacetBBoxRef( Proc.Id, nInd, GDB_BB.STANDARD, frLoc) + local ptA = b3Face:getMin() + local ptC = b3Face:getMax() + local ptB = ptA + dDimY * Y_AX() + local ptD = ptA + dDimX * X_AX() + ptA:toGlob( frLoc) + ptB:toGlob( frLoc) + ptC:toGlob( frLoc) + ptD:toGlob( frLoc) + + local ptP1, ptP2 + if bUnderCut then + ptP1 = EgtIf( ptA:getZ() > ptC:getZ(), ptA, ptC) + ptP2 = EgtIf( ptB:getZ() > ptD:getZ(), ptB, ptD) + else + ptP1 = EgtIf( ptA:getZ() < ptC:getZ(), ptA, ptC) + ptP2 = EgtIf( ptB:getZ() < ptD:getZ(), ptB, ptD) + end + + local vtDir = ptP2 - ptP1 + vtDir:normalize() + ptP1 = ptP1 - vtDir * 0.5 * NEST.OFFSET + ptP2 = ptP2 + vtDir * 0.5 * NEST.OFFSET + local vtNxy = Vector3d( vtN:getX(), vtN:getY(), 0) + vtNxy:normalize() + local ptP4 = ptP2 + dVal * vtNxy + + local nRectId = EgtRectangle3P( nOutlineGrp, ptP1, ptP4, ptP2) + EgtSetColor( nRectId, EgtStdColor("AQUA")) + if nRectId ~= GDB_ID.NULL then table.insert( ToolOutlineId, nRectId) end + + end + end + end + end + + end + + return ToolOutlineId +end + + +local function ClassifyDrillsOnLateralFaces( nPartId, dMinSheetWidth) + + local dDeltaRaw = WD.MAX_WIDTH - dMinSheetWidth + NEST.KERF + local DrillClassif + local DrillOnFaces = { F = {nbr = 0, closed = false, long = false, OnlyOnRef = false}, B = {nbr = 0, closed = false, long = false, OnlyOnRef = false}, + L = {nbr = 0, closed = false, long = false, OnlyOnRef = false}, R = {nbr = 0, closed = false, long = false, OnlyOnRef = false}} + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + local ptPartMin = b3Part:getMin() + local ptPartMax = b3Part:getMax() + + local vPartProc = WE.CollectFeatures( nPartId) + for nInd = 1, #vPartProc do repeat + + if Drill.Identify( vPartProc[nInd]) then + + -- identifico su quali facce si trova il foro + local bOpen = ( vPartProc[nInd].Fcs ~= 0 and vPartProc[nInd].Fce ~= 0) + local AuxId = EgtGetInfo( vPartProc[nInd].Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + vPartProc[nInd].Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then break end + local ptDrill = EgtCP( AuxId, GDB_RT.GLOB) + local dLen = abs( EgtCurveThickness( AuxId)) + local bLong = dLen > WD.HOR_DRILL_LEN - 1 + local bOnlyOnRef = dLen + dDeltaRaw > WD.HOR_DRILL_LEN - GEO.EPS_SMALL and not bLong + + -- faccia Front + local dTol = GEO.EPS_SMALL + if ( abs( ptDrill:getY() - ptPartMin:getY()) < dTol) then + DrillOnFaces.F.nbr = DrillOnFaces.F.nbr + 1 + if bOnlyOnRef then DrillOnFaces.F.OnlyOnRef = true end + if bOpen then + DrillOnFaces.B.nbr = DrillOnFaces.B.nbr + 1 + if bOnlyOnRef then DrillOnFaces.B.OnlyOnRef = true end + else + DrillOnFaces.F.closed = true + + end + if bLong then + DrillOnFaces.F.long = true + if bOpen then DrillOnFaces.B.long = true end + end + + -- faccia Back + elseif ( abs( ptDrill:getY() - ptPartMax:getY()) < dTol) then + DrillOnFaces.B.nbr = DrillOnFaces.B.nbr + 1 + if bOnlyOnRef then DrillOnFaces.B.OnlyOnRef = true end + if bOpen then + DrillOnFaces.F.nbr = DrillOnFaces.F.nbr + 1 + if bOnlyOnRef then DrillOnFaces.F.OnlyOnRef = true end + else + DrillOnFaces.B.closed = true + end + if bLong then + DrillOnFaces.B.long = true + if bOpen then DrillOnFaces.F.long = true end + end + + -- faccia Left + elseif ( abs( ptDrill:getX() - ptPartMin:getX()) < dTol) then + DrillOnFaces.L.nbr = DrillOnFaces.L.nbr + 1 + if bOnlyOnRef then DrillOnFaces.L.OnlyOnRef = true end + if bOpen then + DrillOnFaces.R.nbr = DrillOnFaces.R.nbr + 1 + if bOnlyOnRef then DrillOnFaces.R.OnlyOnRef = true end + else + DrillOnFaces.L.closed = true + end + if bLong then + DrillOnFaces.L.long = true + if bOpen then DrillOnFaces.R.long = true end + end + + -- faccia Right + elseif ( abs( ptDrill:getX() - ptPartMax:getX()) < dTol) then + DrillOnFaces.R.nbr = DrillOnFaces.R.nbr + 1 + if bOnlyOnRef then DrillOnFaces.R.OnlyOnRef = true end + if bOpen then + DrillOnFaces.L.nbr = DrillOnFaces.L.nbr + 1 + if bOnlyOnRef then DrillOnFaces.L.OnlyOnRef = true end + else + DrillOnFaces.R.closed = true + end + if bLong then + DrillOnFaces.R.long = true + if bOpen then DrillOnFaces.L.long = true end + end + end + end + + until true + end + + -- identifico la faccia da mettere sul lato del grezzo + local sDrillFace, nMax = '', -100 + for k, v in pairs( DrillOnFaces) do + if v.nbr > nMax or ( v.nbr == nMax and not DrillOnFaces[sDrillFace].OnlyOnRef and v.OnlyOnRef) then + sDrillFace, nMax = k, v.nbr + end + end + + local sDrillFace2 + if nMax > 0 then + if sDrillFace == 'F' or sDrillFace == 'B' then + -- cerco chi vince tra faccia left e right + if DrillOnFaces.L.nbr > DrillOnFaces.R.nbr then + sDrillFace2 = 'L' + elseif DrillOnFaces.L.nbr < DrillOnFaces.R.nbr then + sDrillFace2 = 'R' + elseif DrillOnFaces.L.nbr == DrillOnFaces.R.nbr and DrillOnFaces.L.nbr > 0 then + if DrillOnFaces.L.OnlyOnRef then + sDrillFace2 = 'L' + else + sDrillFace2 = 'R' + end + end + + else + -- cerco chi vince tra faccia front e back + if DrillOnFaces.F.nbr > DrillOnFaces.B.nbr then + sDrillFace2 = 'F' + elseif DrillOnFaces.F.nbr < DrillOnFaces.B.nbr then + sDrillFace2 = 'B' + elseif DrillOnFaces.F.nbr == DrillOnFaces.B.nbr and DrillOnFaces.F.nbr > 0 then + if DrillOnFaces.F.OnlyOnRef then + sDrillFace2 = 'F' + else + sDrillFace2 = 'B' + end + end + end + end + + + if NEST.DRILL_MACH_AREA == 0 then + DrillOnFaces[sDrillFace].long = false + end + + if nMax > 0 then + DrillClassif = { sCase = sDrillFace, bClosed = DrillOnFaces[sDrillFace].closed, bLong = DrillOnFaces[sDrillFace].long, bOnlyOnRef = DrillOnFaces[sDrillFace].OnlyOnRef } + end + + local DrillClassif2 + if sDrillFace2 then + if NEST.DRILL_MACH_AREA == 0 then + DrillOnFaces[sDrillFace2].long = false + end + DrillClassif2 = { sCase = sDrillFace2, bClosed = DrillOnFaces[sDrillFace2].closed, bLong = DrillOnFaces[sDrillFace2].long, bOnlyOnRef = DrillOnFaces[sDrillFace2].OnlyOnRef } + end + + + return DrillClassif, DrillClassif2 +end + +local function ClassifyLapJointsFromBottom( nPartId) + + local res = { Nbr = 0, sCase = '', bParall = false} + + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local ptPartMin = b3Part:getMin() + local ptPartMax = b3Part:getMax() + + local vtLapJoints = {} + local dMinComponentVal = 0.95 + local vPartProc = WE.CollectFeatures( nPartId) + for nInd = 1, #vPartProc do + + if LapJoint.Identify( vPartProc[nInd]) then + -- verifico se LJ da sotto + local vtFace = IdentifyLJFromBottom( vPartProc[nInd], false) + if vtFace then + if vtFace:getX() > dMinComponentVal then + vtLapJoints["R"] = 1 + elseif vtFace:getX() < - dMinComponentVal then + vtLapJoints["L"] = 1 + elseif vtFace:getY() > dMinComponentVal then + vtLapJoints["B"] = 1 + elseif vtFace:getY() < - dMinComponentVal then + vtLapJoints["F"] = 1 + end + end + end + end + + local nCnt = 0 + for _ in pairs(vtLapJoints) do nCnt = nCnt + 1 end + + if nCnt == 1 then + res.Nbr = 1 + for k, _ in pairs( vtLapJoints) do + res.sCase = k + end + + elseif nCnt == 2 then + res.Nbr = 2 + if vtLapJoints["F"] and vtLapJoints["B"] then + res.bParall = true + res.sCase = "F" + elseif vtLapJoints["R"] and vtLapJoints["L"] then + res.bParall = true + res.sCase = "R" + else + res.bParall = false + if vtLapJoints["B"] and vtLapJoints["R"] then + res.sCase = 'BR' + elseif vtLapJoints["B"] and vtLapJoints["L"] then + res.sCase = 'BL' + elseif vtLapJoints["F"] and vtLapJoints["R"] then + res.sCase = 'FR' + elseif vtLapJoints["F"] and vtLapJoints["L"] then + res.sCase = 'FL' + end + end + + elseif nCnt == 3 then + res.Nbr = 3 + if not vtLapJoints["F"] then + res.sCase = "F" + elseif not vtLapJoints["B"] then + res.sCase = "B" + elseif not vtLapJoints["R"] then + res.sCase = "R" + elseif not vtLapJoints["L"] then + res.sCase = "L" + end + + elseif nCnt == 4 then + res.Nbr = 4 + elseif nCnt ~= 0 then + return + end + + return res + +end + + +local function CreateDefectOnAngle( nPartId, RawPart, bDrillLong, bOnOppositeAng) + + local PartTab = {} + -- recupero il gruppo dove salvo i defects + local nOutlineGrp = EgtGetFirstNameInGroup(GDB_ID.ROOT, "SheetDefects") + if not nOutlineGrp or nOutlineGrp == GDB_ID.NULL then + nOutlineGrp = EgtGroup( GDB_ID.ROOT) + EgtSetName( nOutlineGrp, "SheetDefects") + EgtSetStatus( nOutlineGrp, GDB_ST.OFF) + end + + local dExtraMachArea = WD.SIDEMILL_DIAM_DOWN -- per tenere conto dell'area di lavorazione + local dExtra = NEST.KERF + + -- local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + local b3PartX = b3Part:getDimX() + local b3PartY = b3Part:getDimY() + -- se ho fori lunghi devo riservare tutto lo spazio + if bDrillLong then + b3PartY = RawPart.Width + end + + -- calcolo i punti che definiscono il rettangolo + local ptP1, ptP2 + if ( WD.ORIG_CORNER == 'TL' and not bOnOppositeAng) or ( WD.ORIG_CORNER == 'BL' and bOnOppositeAng) then + -- angolo TL + ptP1 = Point3d( 0, RawPart.Width - b3PartY - dExtra, 0) + ptP2 = Point3d( b3PartX + dExtra, RawPart.Width, 0) + PartTab.posX = NEST.KERF + PartTab.posY = RawPart.Width - b3Part:getDimY() - NEST.KERF + elseif ( WD.ORIG_CORNER == 'BL' and not bOnOppositeAng) or ( WD.ORIG_CORNER == 'TL' and bOnOppositeAng) then + -- angolo BL + ptP1 = Point3d( 0, 0, 0) + ptP2 = Point3d( b3PartX + dExtra, b3PartY + dExtra, 0) + PartTab.posX = NEST.KERF + PartTab.posY = NEST.KERF + elseif ( WD.ORIG_CORNER == 'TR' and not bOnOppositeAng) or ( WD.ORIG_CORNER == 'BR' and bOnOppositeAng) then + -- angolo TR + ptP1 = Point3d( RawPart.Len - b3PartX - dExtra, RawPart.Width - b3PartY - dExtra, 0) + ptP2 = Point3d( RawPart.Len, RawPart.Width, 0) + PartTab.posX = RawPart.Len - b3Part:getDimX() - NEST.KERF + PartTab.posY = RawPart.Width - b3Part:getDimY() - NEST.KERF + elseif ( WD.ORIG_CORNER == 'BR' and not bOnOppositeAng) or ( WD.ORIG_CORNER == 'TR' and bOnOppositeAng) then + -- angolo BR + ptP1 = Point3d( RawPart.Len - b3PartX - dExtra, 0, 0) + ptP2 = Point3d( RawPart.Len, b3PartY + dExtra, 0) + PartTab.posX = RawPart.Len - b3Part:getDimX() - NEST.KERF + PartTab.posY = NEST.KERF + end + + PartTab.Id = tonumber(nPartId) + PartTab.DefectId = EgtRectangle2P( nOutlineGrp, Point3d(ptP2:getX() + dExtraMachArea, ptP2:getY() + dExtraMachArea , 0), Point3d( ptP1:getX() - dExtraMachArea , ptP1:getY() - dExtraMachArea, 0)) + EgtSetName( PartTab.DefectId, "Defect") + + return PartTab + +end + + +local function RotateOptimalCase( nPartId, nAngle, nAngleValidRot, RawPart, nPnt1, nPnt2) + + local bOptimal = false + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), nAngle, GDB_RT.GLOB) + local nRotate = nAngle + local nAnglePnt + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + -- b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local bIsValidRotation = b3Part:getDimX() < RawPart.Len - 2 * NEST.KERF + GEO.EPS_SMALL and b3Part:getDimY() < RawPart.Width - 2 * NEST.KERF + GEO.EPS_SMALL + if bIsValidRotation then + bOptimal = true + nAnglePnt = nPnt1 + else + bOptimal = false + -- ruoto nella migliore posizione ammissibile + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), nAngleValidRot, GDB_RT.GLOB) + nRotate = nRotate + nAngleValidRot + nAnglePnt = nPnt2 + end + + if nRotate >= 360 then + nRotate = nRotate - 360 + end + + return nAnglePnt, nRotate, bOptimal + +end + +local function RotateOptimalCaseDrill( nPartId, bCanRotate, nPnt1, nPnt2) + + local nRotate = 0 + local nAnglePnt + + if bCanRotate then + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), 180, GDB_RT.GLOB) + nRotate = 180 + nAnglePnt = nPnt1 + else + nAnglePnt = nPnt2 + end + + return nAnglePnt, nRotate +end + + +-- Funzione che classifica i pezzi in base alla loro necessità di stare negli angoli +local function ClassifyAngles( nPartId, RawPart, sRefOrig, bLockedRot, dMinSheetWidth) + + -- elimino eventuali info + EgtSetInfo( nPartId, "NestOnEdge", 0) + EgtSetInfo( nPartId, "NestOnAngle", 0) + EgtSetInfo( nPartId, "OnlyOnRefSide", 0) + + local nAngle + local nRotate = 0 + local bOptimal + local bManual = false + local bOnly180Rot = EgtGetInfo( nPartId, "HasGrainDirection", 'b') or false + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + + -- fori + local DrillClassif, DrillClassif2 = ClassifyDrillsOnLateralFaces( nPartId, dMinSheetWidth) + local bDrill = false + local bDrillOpen = false + local bLongDrill = false + + if DrillClassif then + bDrill = true + bDrillOpen = not DrillClassif.bClosed + bLongDrill = DrillClassif.bLong + if DrillClassif.bOnlyOnRef then + EgtSetInfo( nPartId, "OnlyOnRefSide", 1) + end + end + + -- oriento il pezzo in base al foro + if bDrill and not bLockedRot then + local RotationAngles + if sRefOrig == 'TL' or sRefOrig == 'TR' then + RotationAngles = { F = 180, B = 0, L = 270, R = 90} + else + RotationAngles = { F = 0, B = 180, L = 90, R = 270} + end + + -- se rotazione è libera + if not bOnly180Rot then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), RotationAngles[DrillClassif.sCase], GDB_RT.GLOB) + nRotate = nRotate + RotationAngles[DrillClassif.sCase] + + -- verifico se la rotazione è valida + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + -- b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local bIsValidRotation = b3Part:getDimX() < RawPart.Len - 2 * NEST.KERF + GEO.EPS_SMALL and b3Part:getDimY() < RawPart.Width - 2 * NEST.KERF + GEO.EPS_SMALL + if not bIsValidRotation then + -- ritorno nella posizione originaria + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), - RotationAngles[DrillClassif.sCase], GDB_RT.GLOB) + nRotate = nRotate - RotationAngles[DrillClassif.sCase] + -- se ho un'altra posizione possibile ruoto in quella + if DrillClassif2 then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), RotationAngles[DrillClassif2.sCase], GDB_RT.GLOB) + nRotate = nRotate + RotationAngles[DrillClassif2.sCase] + bDrillOpen = not DrillClassif2.bClosed + bLongDrill = DrillClassif2.bLong + if DrillClassif2.bOnlyOnRef then + EgtSetInfo( nPartId, "OnlyOnRefSide", 1) + end + else + -- dimentico di avere il foro + bDrill = false + end + end + + -- se posso ruotare solo di 180° per venatura + else + if RotationAngles[DrillClassif.sCase] == 0 or RotationAngles[DrillClassif.sCase] == 180 then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), RotationAngles[DrillClassif.sCase], GDB_RT.GLOB) + nRotate = nRotate + RotationAngles[DrillClassif.sCase] + else + -- vedo se ho un'altra posizione possibile + if DrillClassif2 and ( RotationAngles[DrillClassif2.sCase] == 0 or RotationAngles[DrillClassif2.sCase] == 180) then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), RotationAngles[DrillClassif2.sCase], GDB_RT.GLOB) + nRotate = nRotate + RotationAngles[DrillClassif2.sCase] + bDrillOpen = not DrillClassif2.bClosed + bLongDrill = DrillClassif2.bLong + if DrillClassif2.bOnlyOnRef then + EgtSetInfo( nPartId, "OnlyOnRefSide", 1) + end + else + -- dimentico di avere il foro + bDrill = false + end + end + end + end + + -- se non ho venature e fori scelgo una posizione che non faccia cadere il pezzo + if not bDrill and not bOnly180Rot and not bLockedRot then + b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local bIsValid = b3Part:getDimX() > ( WD.INTRULLI or 1200) + local bRotatedIsValid = b3Part:getDimY() > ( WD.INTRULLI or 1200) + if not bIsValid and not bRotatedIsValid then + EgtSetInfo( nPartId, "REDUCECUT", 1) + elseif not bIsValid or not bRotatedIsValid then + bOnly180Rot = true + EgtSetInfo( nPartId, "NestStepRot", 180) + end + if not bIsValid and bRotatedIsValid then + EgtRotate( nPartId, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB) + nRotate = nRotate + 90 + end + end + + + -- lap joints + local ResLapJoints = ClassifyLapJointsFromBottom( nPartId) + b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local bAdd = true + + if ResLapJoints.Nbr > 0 and bLockedRot then + b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + if b3Part:getDimX() > ( WD.INTRULLI or 1200) then + EgtSetInfo( nPartId, "REDUCECUT", 1) + end + local PartAngleClassification = { PartId = tostring( nPartId), Angle = 100, nRotate = 0, bDrill = true, bLongDrill = true} + return PartAngleClassification + end + + -- se anche fori oppure possibile solo rotazione di 180° per non far cadere il pezzo + if bDrill or bOnly180Rot then + local bCanRotate = not bDrill or ( bDrill and bDrillOpen) + + if ResLapJoints.Nbr == 0 then + nAngle = 0 + if not bDrill then bAdd = false end + + elseif ResLapJoints.Nbr == 1 then + if (( sRefOrig == 'TL' or sRefOrig == 'TR') and ResLapJoints.sCase == 'B' ) or + (( sRefOrig == 'BL' or sRefOrig == 'BR') and ResLapJoints.sCase == 'F' ) then + nAngle = 20 + elseif (( sRefOrig == 'TL' or sRefOrig == 'TR') and ResLapJoints.sCase == 'F' ) or + (( sRefOrig == 'BL' or sRefOrig == 'BR') and ResLapJoints.sCase == 'B' ) then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 20, 100) + nRotate = nRotate + nRotate2 + elseif ResLapJoints.sCase == 'R' then + if bCanRotate then bManual = true end + if sRefOrig == 'TL' or sRefOrig == 'BL'then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 40, 0) + nRotate = nRotate + nRotate2 + else + nAngle = 40 + end + elseif ResLapJoints.sCase == 'L' then + if bCanRotate then bManual = true end + if sRefOrig == 'TR' or sRefOrig == 'BR' then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 40, 0) + nRotate = nRotate + nRotate2 + else + nAngle = 40 + end + end + + elseif ResLapJoints.Nbr == 2 then + if ResLapJoints.bParall then + if ResLapJoints.sCase == 'F' then + nAngle = 100 + else + nAngle = 80 + end + else + if (( sRefOrig == 'TL' or sRefOrig == 'TR') and (ResLapJoints.sCase == 'BL' or ResLapJoints.sCase == 'BR')) or + (( sRefOrig == 'BL' or sRefOrig == 'BR') and (ResLapJoints.sCase == 'FL' or ResLapJoints.sCase == 'FR')) then + nAngle = 40 + else + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 40, 100) + nRotate = nRotate + nRotate2 + end + end + + elseif ResLapJoints.Nbr == 3 then + if (( sRefOrig == 'TL' or sRefOrig == 'TR') and ResLapJoints.sCase == 'F' ) or + (( sRefOrig == 'BL' or sRefOrig == 'BR') and ResLapJoints.sCase == 'B' ) then + nAngle = 80 + elseif (( sRefOrig == 'TL' or sRefOrig == 'TR') and ResLapJoints.sCase == 'B' ) or + (( sRefOrig == 'BL' or sRefOrig == 'BR') and ResLapJoints.sCase == 'F' ) then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 80, 100) + nRotate = nRotate + nRotate2 + elseif ResLapJoints.sCase == 'R' then + if bCanRotate then bManual = true end + if sRefOrig == 'TR' or sRefOrig == 'BR' then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 100, 100) + nRotate = nRotate + nRotate2 + end + nAngle = 100 + elseif ResLapJoints.sCase == 'L' then + if bCanRotate then bManual = true end + if sRefOrig == 'TL' or sRefOrig == 'BL' then + nAngle, nRotate2 = RotateOptimalCaseDrill( nPartId, bCanRotate, 100, 100) + nRotate = nRotate + nRotate2 + end + nAngle = 100 + end + + elseif ResLapJoints.Nbr == 4 then + nAngle = 100 + end + + + -- no fori + else + if ResLapJoints.Nbr == 0 then + bAdd = false + + elseif ResLapJoints.Nbr == 1 then + if sRefOrig == 'TL' or sRefOrig == 'TR' then + RotationAngles = { F = 180, B = 0, R = 90, L = 270} + elseif sRefOrig == 'BL'or sRefOrig == 'BR' then + RotationAngles = { F = 0, B = 180, R = 270, L = 90} + end + local nAngleValidRot = EgtIf( sRefOrig == 'TL' or sRefOrig == 'BR', 90, 270) + nAngle, nRotate2, bOptimal = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 20, 40) + nRotate = nRotate + nRotate2 + if not bOptimal then bManual = true end + + elseif ResLapJoints.Nbr == 2 then + if ResLapJoints.bParall then + -- se lap joints su lati paralleli + RotationAngles = { F = 90, R = 0} + nAngle, nRotate2 = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], 90, RawPart, 80, 100) + nRotate = nRotate + nRotate2 + else + -- se lap joints su lati adiacenti + if sRefOrig == 'TR' then + RotationAngles = { FR = 90, BR = 0, BL = 270, FL = 180} + elseif sRefOrig == 'TL' then + RotationAngles = { FR = 180, BR = 90, BL = 0, FL = 270} + elseif sRefOrig == 'BR' then + RotationAngles = { FR = 0, BR = 270, BL = 180, FL = 90} + elseif sRefOrig == 'BL' then + RotationAngles = { FR = 270, BR = 180, BL = 90, FL = 0} + end + local nAngleValidRot = EgtIf( sRefOrig == 'TL' or sRefOrig == 'BR', 270, 90) + nAngle, nRotate2, bOptimal = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 40, 40) + nRotate = nRotate + nRotate2 + + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local bCanRotate = b3Part:getDimX() < RawPart.Width + if bOptimal and bCanRotate then bManual = true end + end + + elseif ResLapJoints.Nbr == 3 then + if sRefOrig == 'TL' or sRefOrig == 'TR' then + RotationAngles = { F = 0, B = 180, R = 270, L = 90} + elseif sRefOrig == 'BL' or sRefOrig == 'BR' then + RotationAngles = { F = 180, B = 0, R = 90, L = 270} + end + local nAngleValidRot = EgtIf( sRefOrig == 'TL' or sRefOrig == 'BR', 90, 270) + nAngle, nRotate2, bOptimal = RotateOptimalCase( nPartId, RotationAngles[ResLapJoints.sCase], nAngleValidRot, RawPart, 80, 100) + nRotate = nRotate + nRotate2 + if not bOptimal then bManual = true end + + elseif ResLapJoints.Nbr == 4 then + nAngle, nRotate2 = RotateOptimalCase( nPartId, 0, 90, RawPart, 100, 100) + nRotate = nRotate + nRotate2 + end + + end + + + -- aggiorno le info di rotazione del pezzo + if nRotate >= 360 then + nRotate = nRotate - 360 + end + if nRotate > 0 then + local nPartRot = EgtGetInfo( nPartId, "ROTATED", 'i') or 0 + local nTotRot = nPartRot - nRotate + nTotRot = EgtIf( nTotRot < 0, nTotRot + 360, nTotRot) + EgtSetInfo( nPartId, "ROTATED", nTotRot) + EgtSetInfo( nPartId, "MODIFIEDFORNEST", 1) + end + + if not bAdd then + return + end + + local PartAngleClassification = { PartId = tostring( nPartId), Angle = nAngle, nRotate = nRotate, bDrill = bDrill, bLongDrill = bLongDrill, bManual = bManual} + + local bCanBeOnOtherEdge = not bDrill or ( bDrill and RawPart.Width >= WD.MINRAWY_HOR_DRILL) + if bOnly180Rot then + if bCanBeOnOtherEdge then + EgtSetInfo( nPartId, "NestAllowRot", 1) + EgtSetInfo( nPartId, "NestStepRot", 180) + else + EgtSetInfo( nPartId, "NestAllowRot", 0) + EgtSetInfo( nPartId, "NestStepRot", 0) + end + end + + -- verifico se il pezzo cade (caso di foro) + b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + if b3Part:getDimX() > ( WD.INTRULLI or 1200) then + EgtSetInfo( nPartId, "REDUCECUT", 1) + end + + return PartAngleClassification +end + + +local function ComputeRestrictedZones( RawParts) + + local dTotArea = 0 + -- area totale dei pezzi + for nPartId, nCount in pairs( PART) do + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + local dPartArea = b3Part:getDimX() * b3Part:getDimY() + dTotArea = dTotArea + dPartArea * nCount + end + + -- stimo il numero di angoli disponibili + local vSheetNbrEstimate = {} + local nSheetNbrEstimate = 0 + local nSheetNbrCorrection = - 2 + local nAnglesNbrEstimate = 0 + local nAngelsNbrCorrection = 0 + + local vRawDistrib = {} + if #RawParts == 1 then + vRawDistrib = {1} + elseif #RawParts == 2 then + vRawDistrib = {0.7, 0.3} + else + for nInd = 1, #RawParts do + table.insert( vRawDistrib, 1 / #RawParts) + end + end + + local dMaxSheetWidth = -100 + local nMaxSheet = 1 + local dMinSheetWidth = WD.MAX_WIDTH + for nInd = 1, #RawParts do + local dSheetArea = RawParts[nInd].Len * RawParts[nInd].Width + if RawParts[nInd].Width > dMaxSheetWidth + GEO.EPS_SMALL then + dMaxSheetWidth = RawParts[nInd].Width + nMaxSheet = nInd + elseif abs( RawParts[nInd].Width - dMaxSheetWidth) < GEO.EPS_SMALL then + if RawParts[nInd].Len > RawParts[nMaxSheet].Len then + nMaxSheet = nInd + end + end + if RawParts[nInd].Width < dMinSheetWidth then + dMinSheetWidth = RawParts[nInd].Width + end + + vSheetNbrEstimate[nInd] = min( ceil( dTotArea * vRawDistrib[nInd] / dSheetArea) + nSheetNbrCorrection, RawParts[nInd].Qty) + if vSheetNbrEstimate[nInd] <= 0 then + vSheetNbrEstimate[nInd] = min( RawParts[nInd].Qty, 1) + end + + nSheetNbrEstimate = nSheetNbrEstimate + vSheetNbrEstimate[nInd] + nAnglesNbrEstimate = nAnglesNbrEstimate + vSheetNbrEstimate[nInd] * 2 + end + nAnglesNbrEstimate = nAnglesNbrEstimate + nAngelsNbrCorrection + + + -- classificazione dei pezzi in base alla loro necessità di stare negli angoli + local nTotParts = 0 + for _ in pairs( PART) do nTotParts = nTotParts + 1 end + local nPartIndex = 0 + local AngleClassification = {} + for nPartId, nCount in pairs( PART) do + nPartIndex = nPartIndex + 1 + local bManualRot = EgtGetInfo( nPartId, "MANUALROT", 'b') + local PartClassif = ClassifyAngles(tonumber(nPartId), RawParts[nMaxSheet], WD.ORIG_CORNER, bManualRot, dMinSheetWidth) + if PartClassif then + for nI = 1, nCount do + local newTab = {PartId = PartClassif.PartId, Angle = PartClassif.Angle, nRotate = PartClassif.nRotate, bDrill = PartClassif.bDrill, bLongDrill = PartClassif.bLongDrill, bManual = PartClassif.bManual} + table.insert( AngleClassification, newTab) + end + end + + if EgtProcessEvents( nPartIndex / nTotParts * 100, 0) == 1 then + return false + end + end + + table.sort( AngleClassification, function(a, b) return a.Angle > b.Angle end) + + + local vManuallyDone = {} + local vPartsManuallyDone = {} + for nInd = 1, #vSheetNbrEstimate do + for nInd2 = 1, vSheetNbrEstimate[nInd] do + table.insert( vManuallyDone, { RawPartId = nInd, Done = 0, Parts = {}}) + end + end + local nSheetNbr = #vManuallyDone + local vFilledSheets = {} + for nInd = 1, #vSheetNbrEstimate do + for nInd2 = 1, vSheetNbrEstimate[nInd] do + table.insert( vFilledSheets, { Width = RawParts[nInd].Width, OrigWidth = RawParts[nInd].Width}) + end + end + + for nInd = 1, #AngleClassification do + + if AngleClassification[nInd].Angle >= NEST.MIN_ANGLE_PNT and AngleClassification[nInd].Angle > 0 then + + -- verifico di avere ancora angoli a disposizione secondo la stima dei grezzi + local bFound = false + local nBoxLayerId = EgtGetFirstNameInGroup( AngleClassification[nInd].PartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + local dPartWidth = b3Part:getDimY() + NEST.KERF + for nInd2 = 1, #vFilledSheets do + if dPartWidth < vFilledSheets[nInd2].Width then + -- verifico se il grezzo aveva già un pezzo in un angolo + if abs( vFilledSheets[nInd2].Width - vFilledSheets[nInd2].OrigWidth) < GEO.EPS_SMALL then + vFilledSheets[nInd2].Width = vFilledSheets[nInd2].Width - dPartWidth - WD.SIDEMILL_DIAM_DOWN + else + -- se il grezzo aveva già un pezzo nell'angolo, dopo il pezzo corrente non ne posso mettere altri + vFilledSheets[nInd2].Width = 0 + end + bFound = true + break + end + end + + -- se ho ancora angoli a disposizione oppure il pezzo deve stare necessariamente sull'angolo per essere lavorato + if bFound or AngleClassification[nInd].Angle == 100 then + -- verifico se va nestato manualmente + if AngleClassification[nInd].bManual then + + -- trovo il punto della lista dove inserirlo + local nIdx = -1 + local bOnOppositeSide = false + for nInd2 = 1, #vManuallyDone do + -- verifico se il pezzo può stare sull'altro angolo + local bOnlyOnRef = EgtGetInfo( AngleClassification[nInd].PartId, "OnlyOnRefSide", 'b') + local bCanBeOnOtherAngle = not bOnlyOnRef and + ( not AngleClassification[nInd].bDrill or + ( AngleClassification[nInd].bDrill and not AngleClassification[nInd].bLongDrill and RawParts[vManuallyDone[nInd2].RawPartId].Width >= WD.MINRAWY_HOR_DRILL)) + + if #(vManuallyDone[nInd2].Parts) == 0 then + -- verifico che il pezzo stia in questo grezzo + local b3Part = EgtGetBBoxGlob( AngleClassification[nInd].PartId, GDB_BB.STANDARD) + if b3Part:getDimX() < RawParts[vManuallyDone[nInd2].RawPartId].Len and b3Part:getDimY() < RawParts[vManuallyDone[nInd2].RawPartId].Width then + nIdx = nInd2 + break + end + + elseif #(vManuallyDone[nInd2].Parts) == 1 and bCanBeOnOtherAngle then + -- verifico se il pezzo già posizionato nell'angolo non ha fori lunghi + if not vManuallyDone[nInd2].Parts[1].bLongDrill then + -- oriento il pezzo in modo ottimale per andare su quell'angolo + local sRefOrig + if WD.ORIG_CORNER == 'TL' then sRefOrig = 'BL' end + if WD.ORIG_CORNER == 'BL' then sRefOrig = 'TL' end + if WD.ORIG_CORNER == 'TR' then sRefOrig = 'BR' end + if WD.ORIG_CORNER == 'BR' then sRefOrig = 'TR' end + local bManTmp + local res = ClassifyAngles( AngleClassification[nInd].PartId, RawParts[vManuallyDone[nInd2].RawPartId], sRefOrig, bManTmp, dMinSheetWidth) + -- verifico sia compatibile con pezzo già inserito + local b3OtherPart = EgtGetBBoxGlob( vManuallyDone[nInd2].Parts[1].Id, GDB_BB.STANDARD) + local b3Part = EgtGetBBoxGlob( AngleClassification[nInd].PartId, GDB_BB.STANDARD) + local dExtra = 2 * NEST.KERF + WD.SIDEMILL_DIAM_DOWN + 1 + -- se è compatibile assegno questa rotazione al pezzo + if b3Part:getDimY() + b3OtherPart:getDimY() + dExtra < RawParts[vManuallyDone[nInd2].RawPartId].Width then + nIdx = nInd2 + bOnOppositeSide = true + -- aggiorno le info di rotazione + if res.nRotate > 0 then + local nPartRot = EgtGetInfo( AngleClassification[nInd].PartId, "ROTATED", 'i') or 0 + local nTotRot = nPartRot - res.nRotate + nTotRot = EgtIf( nTotRot < 0, nTotRot + 360, nTotRot) + EgtSetInfo( AngleClassification[nInd].PartId, "ROTATED", nTotRot) + EgtSetInfo( AngleClassification[nInd].PartId, "MODIFIEDFORNEST", 1) + end + break + end + -- altrimenti lo riporto nella sua posizione originaria + EgtRotate( AngleClassification[nInd].PartId, b3Part:getCenter(), Z_AX(), - res.nRotate, GDB_RT.GLOB) + end + end + end + + -- nesto il pezzo a mano + if nIdx ~= -1 then + -- aree di lavorazione + local nToolOutlineIds = ComputeToolOutlines( AngleClassification[nInd].PartId) + local sInfo = "" + for nInd = 1, #nToolOutlineIds do + sInfo = sInfo .. tostring(nToolOutlineIds[nInd]) .. "," + end + -- salvo tra le info del pezzo gli id delle sue aree di lavorazione + if sInfo ~= "" then + EgtSetInfo( AngleClassification[nInd].PartId, "ToolOutlines", sInfo) + end + + -- calcolo defect corrispondente al pezzo + local PartTab = CreateDefectOnAngle( AngleClassification[nInd].PartId, RawParts[vManuallyDone[nIdx].RawPartId], AngleClassification[nInd].bLongDrill, bOnOppositeSide) + PartTab.bLongDrill = AngleClassification[nInd].bLongDrill + table.insert( vManuallyDone[nIdx].Parts, PartTab) + table.insert( vPartsManuallyDone, tonumber( AngleClassification[nInd].PartId)) + + else + -- aggiungo info per il nesting per ricordare che andrà su angolo + EgtSetInfo( AngleClassification[nInd].PartId, "NestOnAngle", 1) + end + else + -- se non va nestato manualmente segno info per nesting + EgtSetInfo( AngleClassification[nInd].PartId, "NestOnAngle", 1) + end + + else + -- se non ho più angoli a disposizione lo metto sul lato + EgtSetInfo(AngleClassification[nInd].PartId, "NestOnEdge", 1) + end + + else + EgtSetInfo(AngleClassification[nInd].PartId, "NestOnEdge", 1) + end + + end + + local nInd = 1 + while nInd <= #vManuallyDone do + if #(vManuallyDone[nInd].Parts) == 0 then + table.remove( vManuallyDone, nInd) + else + nInd = nInd + 1 + end + end + + return vManuallyDone, vPartsManuallyDone +end + + + +-- Funzione che sposta e aggiunge pezzi per nesting +local function AddRawParts(RawParts, vDoneManually) + + local OUTLINE = "Outline" + for nIndex = 1, #RawParts do + RawParts[nIndex].PartId = {} + + -- pannelli con pezzi inseriti manualmente + local nTotSheetWithDefects = 0 + for nInd = 1, #vDoneManually do + if vDoneManually[nInd].RawPartId == nIndex then + -- creo pannello del materiale + local SheetPartId = EgtGroup(GDB_ID.ROOT) + table.insert( RawParts[nIndex].PartId, SheetPartId) + EgtSetName(SheetPartId, "Sheet") + local SheetLayerId = EgtGroup(SheetPartId) + EgtSetName(SheetLayerId, OUTLINE) + local SheetOutlineId = EgtRectangle2P(SheetLayerId, Point3d(0,0,0), Point3d(RawParts[nIndex].Len + 0.1, RawParts[nIndex].Width + 0.1, 0), GDB_RT.GLOB) + EgtSetName(SheetOutlineId, OUTLINE) + -- creo foglio per nesting + EgtAutoNestAddSheet( SheetPartId, SheetOutlineId, NEST.KERF, 0, 1) + -- aggiungo defects + for nInd2 = 1, #(vDoneManually[nInd].Parts) do + EgtAutoNestAddDefectToSheet( SheetPartId, vDoneManually[nInd].Parts[nInd2].DefectId) + end + vDoneManually[nInd].SheetId = SheetPartId + nTotSheetWithDefects = nTotSheetWithDefects + 1 + end + end + + -- pannelli senza pezzi inseriti manualmente + local SheetPartId = EgtGroup(GDB_ID.ROOT) + table.insert( RawParts[nIndex].PartId, SheetPartId) + EgtSetName(SheetPartId, "Sheet") + local SheetLayerId = EgtGroup(SheetPartId) + EgtSetName(SheetLayerId, OUTLINE) + local SheetOutlineId = EgtRectangle2P(SheetLayerId, Point3d(0,0,0), Point3d(RawParts[nIndex].Len + 0.1, RawParts[nIndex].Width + 0.1, 0), GDB_RT.GLOB) + -- EgtModifyCurveThickness(SheetOutlineId, -Material.T_mm) + EgtSetName(SheetOutlineId, OUTLINE) + + -- creo foglio per nesting + EgtAutoNestAddSheet( SheetPartId, SheetOutlineId, NEST.KERF, 1, RawParts[nIndex].Qty - nTotSheetWithDefects) -- EgtAutoNestAddSheet( SheetId, OutlineId, dKerf, nPriority, nCount) + end +end + + + +local function AddParts(RawParts, vPartsDoneManually) + + -- cerco la width massima dei grezzi + local dRawMaxWidth = - 100 + for nIndex = 1, #RawParts do + if RawParts[nIndex].Width > dRawMaxWidth then + dRawMaxWidth = RawParts[nIndex].Width + end + end + + -- valori correttivi per vincoli StripX e StripY + local dStripYCorr = GEO.EPS_SMALL + local dStripXCorr = GEO.EPS_SMALL + if NEST.CORNER == NST_CORNER.TL or NEST.CORNER == NST_CORNER.TR then + dStripYCorr = 0.1 - GEO.EPS_SMALL + end + if NEST.CORNER == NST_CORNER.BR or NEST.CORNER == NST_CORNER.TR then + dStripXCorr = 0.1 - GEO.EPS_SMALL + end + + local nTotParts = 0 + for _ in pairs( PART) do nTotParts = nTotParts + 1 end + local nPartIndex = 0 + -- ciclo su pezzi per aggiungerli al nesting + for nPartId, nCount in pairs( PART) do repeat + + -- conto quanti pezzi di questo tipo sono già stati posizionati a mano + nManuallyDone = 0 + for nJ = 1, #vPartsDoneManually do + if vPartsDoneManually[nJ] == tonumber( nPartId) then + nManuallyDone = nManuallyDone + 1 + end + end + + if nManuallyDone == nCount then + -- se tutti posizionati passo al pezzo successivo + break + else + -- posiziono con il nesting solo quelli mancanti + nCount = nCount - nManuallyDone + end + + nPartIndex = nPartIndex + 1 + + -- calcolo bbox pezzo per rotazioni + local b3Part = EgtGetBBoxGlob( nPartId, GDB_BB.STANDARD) + + -- recupero eventuali stati di flip e rotazione dalle info del pezzo + local bFlipNest = true + local bFlip = false + local bRotNest = true + local nStepRotNest = 90 + local nRotate = 0 + + -- flip + local bManualFlip = EgtGetInfo( nPartId, "MANUALFLIP", 'b') + if bManualFlip then + bFlipNest = false + elseif EgtExistsInfo( nPartId, "NestFlip") then + bFlipNest = EgtGetInfo( nPartId, "NestAllowFlip", 'b') + bFlip = EgtGetInfo( nPartId, "NestFlip", 'b') + end + + -- rotation + local bManualRot = EgtGetInfo( nPartId, "MANUALROT", 'b') + if bManualRot then + bRotNest = false + elseif EgtExistsInfo( nPartId, "NestRot") then + nStepRotNest = EgtGetInfo( nPartId, "NestStepRot", 'i') + nRotate = EgtGetInfo( nPartId, "NestRot", 'i') + bRotNest = EgtGetInfo( nPartId, "NestAllowRot", 'b') + -- verifico se rotazione è valida (pezzo è contenuto nel grezzo) + local bValidRotationInRaw = b3Part:getDimX() < RawParts[1].Len - 2 * NEST.KERF + GEO.EPS_SMALL and b3Part:getDimY() < dRawMaxWidth - 2 * NEST.KERF + GEO.EPS_SMALL + if not bValidRotationInRaw then + bRotNest = true + nStepRotNest = 90 + end + end + + -- aggiungo stato a lista stati del pezzo + -- table.insert( PartStates, { PartId = tonumber(nPartId), Flip = bFlip, Rotate = nRotate}) + + +-- local bFtDown = false +-- local vPartProc = WE.CollectFeatures( nPartId, b3Raw) +-- for nInd = 1, #vPartProc do +-- if LapJoint.Identify( vPartProc[nInd]) then +-- local nFacOpt, dMinElev, nFacOpt2, dMinElev2 = WL.GetFaceWithMostAdj( vPartProc[nInd].Id, vPartProc[nInd].PartId) +-- if nFacOpt >= 0 then +-- local vtN = EgtSurfTmFacetNormVersor( vPartProc[nInd].Id, nFacOpt, GDB_ID.ROOT) +-- if vtN:getZ() < -0.09 then +-- bFtDown = true +-- break +-- end +-- end +-- end +-- LapJoint.FlipClassify(vPartProc[nInd]) +-- end +-- -- ruoto se necessario +-- if bFtDown then +-- local b3Solid = EgtGetBBoxGlob(nPartId, GDB_BB.IGNORE_TEXT) +-- local ptRotCen = b3Solid:getCenter() +-- EgtRotate( nPartId, ptRotCen, X_AX(), 180, GDB_RT.GLOB) +-- end + +-- -- recupero le feature di lavorazione della parete +-- local bFtDown = false +-- local vPartProc = WE.CollectFeatures( nPartId, b3Raw) +-- for nInd = 1, #vPartProc do +-- if LapJoint.Identify( vPartProc[nInd]) then +-- local nFacOpt, dMinElev, nFacOpt2, dMinElev2 = WL.GetFaceWithMostAdj( vPartProc[nInd].Id, vPartProc[nInd].PartId) +-- if nFacOpt >= 0 then +-- local vtN = EgtSurfTmFacetNormVersor( vPartProc[nInd].Id, nFacOpt, GDB_ID.ROOT) +-- if vtN:getZ() < -0.09 then +-- bFtDown = true +-- break +-- end +-- end +-- end +-- end +-- -- ruoto se necessario +-- if bFtDown then +-- local b3Solid = EgtGetBBoxGlob(nPartId, GDB_BB.IGNORE_TEXT) +-- local ptRotCen = b3Solid:getCenter() +-- EgtRotate( nPartId, ptRotCen, X_AX(), 180, GDB_RT.GLOB) +-- end + + -- recupero vecchio contorno se già presente + local nOutlineLayer = EgtGetFirstNameInGroup(nPartId, "Outline") + local nOldOutline = EgtGetFirstNameInGroup(nOutlineLayer, 'ON_TMP') + local nOutline, nCnt + + -- se l'outline non è stato calcolato oppure il pezzo è stato modificato, lo ricalcolo + local bPartIsModified = EgtGetInfo( nPartId, "MODIFIEDFORNEST", 'b') + if not nOldOutline or bPartIsModified then + + -- elimino il vecchio contorno se pesente + while ( nOldOutline) do + EgtErase(nOldOutline or GDB_ID.NULL) + nOldOutline = EgtGetFirstNameInGroup( nOutlineLayer, 'ON_TMP') + end + + -- Recupero o ricalcolo il solido + local SolidId = EgtBeamGetSolid( nPartId) + if not SolidId or not EgtGetInfo( SolidId, 'VALID') then + EgtBeamCalcSolid( nPartId, true) + SolidId = EgtBeamGetSolid( nPartId) + end + nOutline, nCnt = EgtGetSurfTmSilhouette( SolidId, Z_AX(), 10, nOutlineLayer, GDB_RT.GLOB) + EgtBeamShowSolid( nPartId, false) + + for nInd = 0, nCnt - 1 do + EgtSetName( nOutline + nInd, 'ON_TMP') + EgtSetStatus( nOutline + nInd, 0) + end + + local nCurrOutline = nOutline + if nCnt > 0 then + local frSum + EgtScale( nOutline, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB) + EgtModifyCurveExtrusion( nOutline, Z_AX(), GDB_RT.GLOB) + + -- verifico che la prima curva sia l'unico loop esterno + local vCrvRef = EgtCurveArea( nOutline) + for nInd = 1, nCnt - 1 do + local vCrv = EgtCurveArea( nOutline + nInd) + -- se trovo più loop esterni uso come contorno quello del box (quindi forzo nCurrOutline a nil) + if abs( vCrv * vCrvRef - 1) < GEO.EPS_SMALL then + nCurrOutline = nil + for nInd2 = 0, nCnt - 1 do + EgtErase( nOutline + nInd2) + end + nCnt = 1 + break + end + end + + --local frSum = EgtSurfFlatRegion(nOutlineLayer, nOutline) + --EgtSaveFile("c:\\Temp\\ProvaNesting.nge") + -- -- per ogni contorno creo flat region e le sommo + -- for nIndex = 0, nCnt - 1 do + -- EgtScale( nOutline + nIndex, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB) + -- EgtModifyCurveExtrusion( nOutline + nIndex, Z_AX(), GDB_RT.GLOB) + -- local frCurr = EgtSurfFlatRegion(nOutlineLayer, nOutline + nIndex) + -- if frCurr then + -- if frSum then + -- EgtSurfFrAdd(frSum, frCurr) + -- else + -- frSum = frCurr + -- end + -- end + -- EgtErase(frCurr) + -- end + -- --EgtSaveFile("c:/Temp/ProvaNesting.nge") + -- -- calcolo contorno della flat region somma + -- nCurrOutline = EgtExtractSurfFrChunkLoops(frSum, 0, nOutlineLayer) + -- EgtErase(frSum) + -- -- cancello contorni + -- for nIndex = 0, nCnt do + -- EgtErase(nOutline + nIndex) + -- end + end + + if nCurrOutline and nCurrOutline ~= GDB_ID.NULL then + nOutline = nCurrOutline + else + -- se non ho trovato contorno, lo recupero dal Box + local nBoxLayer = EgtGetFirstNameInGroup(nPartId, "Box") + local nBox = EgtGetFirstNameInGroup(nBoxLayer, "Box") + local BBox = EgtGetBBoxGlob(nBox, GDB_BB.STANDARD) + nOutline = EgtRectangle2P(nOutlineLayer, Point3d( BBox:getMin():getX(), BBox:getMin():getY(), 0), Point3d( BBox:getMax():getX(), BBox:getMax():getY(), 0), GDB_RT.GLOB) + EgtOutLog("Impossible creating silhouette for part " .. tostring(nPartId)) + nCnt = 1 + end + --if nCnt == 0 then + -- -- se non ho trovato contorno, lo recupero dal Box + -- local nBoxLayer = EgtGetFirstNameInGroup(nPartId, "Box") + -- local nBox = EgtGetFirstNameInGroup(nBoxLayer, "Box") + -- local BBox = EgtGetBBoxGlob(nBox, GDB_BB.STANDARD) + -- nOutline = EgtRectangle2P(nOutlineLayer, Point3d( BBox:getMin():getX(), BBox:getMin():getY(), 0), Point3d( BBox:getMax():getX(), BBox:getMax():getY(), 0), GDB_RT.GLOB) + -- EgtOutLog("Impossible creating silhouette for part " .. tostring(nPartId)) + --else + -- --EgtScale( nOutline, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB) + -- --EgtModifyCurveExtrusion( nOutline, Z_AX(), GDB_RT.GLOB) + -- --EgtSaveFile("c:/Temp/ProvaNesting.nge") + -- EgtScale( nOutline, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB) + -- EgtModifyCurveExtrusion( nOutline, Z_AX(), GDB_RT.GLOB) + -- local frSum = EgtSurfFlatRegion(nOutlineLayer, nOutline) + -- EgtSaveFile("c:\\Temp\\ProvaNesting.nge") + -- -- per ogni contorno creo flat region e le sommo + -- for nIndex = 1, nCnt - 1 do + -- EgtScale( nOutline + nIndex, GLOB_FRM(), 1, 1, 0, GDB_RT.GLOB) + -- EgtModifyCurveExtrusion( nOutline + nIndex, Z_AX(), GDB_RT.GLOB) + -- local frCurr = EgtSurfFlatRegion(nOutlineLayer, nOutline + nIndex) + -- if frCurr then + -- EgtSurfFrAdd(frSum, frCurr) + -- end + -- end + -- -- calcolo contorno della flat region somma + -- nOutline = EgtExtractSurfFrChunkLoops(frSum, 0, nOutlineLayer) + -- -- cancello contorni successivi + -- for nIndex = 1, nCnt do + -- EgtErase(nOutline + nIndex) + -- end + --end + + EgtSetName( nOutline, 'ON_TMP') + EgtSetStatus( nOutline, 0) + + else + -- altrimenti uso l'outline già calcolato + nOutline = nOldOutline + -- recupero il valore di nCnt + local vOutlinesIds = EgtGetNameInGroup( nOutlineLayer, 'ON_TMP') + nCnt = #vOutlinesIds + end + + + --[[ local nOutline + local nTrimesh + local bFirst = true + local bSecond = false + local bUseBox = false + nTrimesh = EgtGetFirstNameInGroup( nOutlineLayer, "1-Out") + if not nTrimesh then + nTrimesh = EgtGetFirstNameInGroup( nOutlineLayer, "2-Out") + end + if not nTrimesh then + nTrimesh = EgtGetFirstNameInGroup( nOutlineLayer, "3-Out") + end + if not nTrimesh then + nTrimesh = EgtGetFirstNameInGroup( nOutlineLayer, "4-Out") + end + -- se trovato contorno + if nTrimesh then + -- recupero la curva associata + local nAuxId = EgtGetInfo(nTrimesh, "AUXID", 'i') + nOutline = nTrimesh + nAuxId + -- verifico che il contorno sia verticale + local nFacetCount = EgtSurfTmFacetCount(nTrimesh) + for nIndex = 0, nFacetCount - 1 do + local vtNorm = EgtSurfTmFacetNormVersor(nTrimesh, nIndex, GDB_ID.ROOT) + if abs( vtNorm:getZ()) > 10 * GEO.EPS_SMALL then + bUseBox = true + break + end + end + -- se due compo o una e lati inclinati + if bUseBox then + -- calcolo box della trimesh + local b3Outline = EgtGetBBoxGlob(nTrimesh, GDB_BB.IGNORE_TEXT) + local ptP1 = Point3d( b3Outline:getMin():getX(), b3Outline:getMin():getY(), 0) + local ptP2 = Point3d( b3Outline:getMax():getX(), b3Outline:getMax():getY(), 0) + -- creo outline del box + nOutline = EgtRectangle2P(nOutlineLayer, ptP1, ptP2, GDB_RT.GLOB) + EgtSetStatus(nOutline, GDB_ST.OFF) + end + -- altrimenti cerco la regione sopra + else + -- cancello precedenti contorni calcolati + local nOldONId = EgtGetFirstNameInGroup( nOutlineLayer, 'ON_TMP') + if nOldONId then + EgtErase( nOldONId) + end + -- cerco la regione sopra + local nReg + for i = 1, 4 do + local sRegName = string.format( '%d-Top', i) + nReg = EgtGetFirstNameInGroup( nOutlineLayer, sRegName) + if nReg then + local vtNorm = EgtSurfFrNormVersor( nReg, GDB_ID.ROOT) + if vtNorm:getZ() > 0.99 then break end + end + end + if not nReg then + EgtOutLog("Errore: regione superiore non trovata") + end + -- recupero contorno della regione + local OutId, nCnt = EgtExtractSurfFrChunkLoops( nReg, 0, nOutlineLayer) + if OutId and nCnt > 1 then + for i = 2, nCnt do + EgtErase( OutId + i - 1) + end + end + if OutId then + EgtSetName( OutId, 'ON_TMP') + nOutline = OutId + end + end + ]]-- + + + -- calcolo aree lavorazione + local nToolOutlineIds = ComputeToolOutlines( nPartId) + if bFlipNest and #nToolOutlineIds > 0 then + bFlipNest = false + end + + if nOutline then + -- aggiungo pezzo al nesting + EgtAutoNestAddPart( nPartId, nOutline, bFlipNest, bRotNest, nStepRotNest, 0, nCount) + -- EgtAutoNestAddPart( PartId, OutlineId, bCanFlip, bCanRotate, dRotStep, nPriority, nCount) + end + -- aggiungo finestre + for nInd = 1, nCnt - 1 do + local tmp1, tmp2, area = EgtCurveArea( nOutline + nInd) + if area > WD.NEST_HOLE_MIN_AREA then + EgtModifyCurveExtrusion( nOutline + nInd, Z_AX(), GDB_RT.GLOB) + EgtAutoNestAddHoleToPart( nPartId, nOutline + nInd) + end + end + + -- aggiungo aree di lavorazione del pezzo + local sInfo = "" + for nInd = 1, #nToolOutlineIds do + EgtAutoNestAddToolOutlineToPart( nPartId, nToolOutlineIds[nInd]) + sInfo = sInfo .. tostring(nToolOutlineIds[nInd]) .. "," + end + -- salvo tra le info del pezzo gli id delle sue aree di lavorazione + if sInfo ~= "" then + EgtSetInfo( nPartId, "ToolOutlines", sInfo) + end + + -- Eventuali vincoli StripX e StripY + local bOnEdge = EgtGetInfo(nPartId, "NestOnEdge", 'b') + local bOnAngle = EgtGetInfo(nPartId, "NestOnAngle", 'b') + if bOnEdge or bOnAngle then + local nBoxLayerId = EgtGetFirstNameInGroup( nPartId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local b3Part = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + + -- punto di riferimento sul pezzo + local ptRef + local dval = 10 + if ( WD.ORIG_CORNER == 'TL' or WD.ORIG_CORNER == 'TR') then + ptRef = Point3d( b3Part:getMax():getX() - b3Part:getDimX() / 2, b3Part:getMax():getY() - dval, 0) + else + ptRef = Point3d( b3Part:getMin():getX() + b3Part:getDimX() / 2, b3Part:getMin():getY() + dval, 0) + end + + -- vincolo StripY + local bOnlyOnRefSide = EgtGetInfo( nPartId, "OnlyOnRefSide", 'b') + if bOnlyOnRefSide then + if WD.ORIG_CORNER == 'BL' or WD.ORIG_CORNER == 'BR' then + EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + dval + dStripYCorr, 100000) + else + EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, - 1000, dRawMaxWidth + 1000 - ( NEST.KERF + dval - dStripYCorr)) + end + else + EgtAutoNestSetStripYconstraintToPart( nPartId, ptRef, NEST.KERF + dval + dStripYCorr, dRawMaxWidth - 2 * ( NEST.KERF + dval)) + end + + -- se sull'angolo aggiungo anche vincolo StripX + if bOnAngle then + if WD.ORIG_CORNER == 'TL' or WD.ORIG_CORNER == 'BL' then + EgtAutoNestSetStripXconstraintToPart( nPartId, ptRef, NEST.KERF + b3Part:getDimX() / 2 + dStripXCorr, 100000) + else + EgtAutoNestSetStripXconstraintToPart( nPartId, ptRef, -100, RawParts[1].Len + 100 - NEST.KERF - b3Part:getDimX() / 2 + dStripXCorr) + end + end + end + + -- verifico se anullato nesting + if EgtProcessEvents( 100 + ( nPartIndex / nTotParts * 100), 0) == 1 then + return false + end + until true + end + + return true +end + +-- Inizializzo contatori errori e avvisi +local nErrCnt = 0 +local nWarnCnt = 0 +local bOk = true +NEST.ERR = 0 + +-- resetto gruppo di lavorazione corrente +EgtResetCurrMachGroup() + +-- inizio nesting automatico +EgtAutoNestStart() + +-- lista dei grezzi +local RawParts = {} +-- creo tabella dei grezzi +for sIndex, dLen in pairs( LEN) do + RawParts[tonumber(sIndex)] = { Len = dLen} +end +for sIndex, dWidth in pairs( WIDTH) do + RawParts[tonumber(sIndex)].Width = dWidth +end +for sIndex, nQty in pairs( QTY) do + RawParts[tonumber(sIndex)].Qty = nQty +end +for sIndex, sMaterial in pairs( MATERIAL) do + RawParts[tonumber(sIndex)].Material = sMaterial +end + +-- +local vDoneManually, vPartsDoneManually = ComputeRestrictedZones( RawParts) + +-- creo grezzi e li aggiungo al nesting +AddRawParts(RawParts, vDoneManually) + +if not bOk then + EgtOutLog("Interruzione nesting") + NEST.ERR = 1 +end + +-- calcolo rotazioni e flip ed aggiungo pezzi al nesting +if bOk then + bOk = AddParts(RawParts, vPartsDoneManually) +end + +if not bOk then + EgtOutLog("Interruzione nesting") + NEST.ERR = 1 +end + +if bOk then + -- aggiungo offset tra pezzi + EgtAutoNestSetInterpartGap( NEST.OFFSET) + + -- Impostazione corner di inizio del nesting (NST_CORNER.BL, TL, BR, TR) + EgtAutoNestSetStartCorner( NEST.CORNER) + + -- Report dei dati di nesting per debug + EgtAutoNestSetReportFile( EgtGetTempDir() .. '\\LastNest.json') + + -- imposto tempo di nesting e lo avvio + EgtAutoNestCompute( true, NEST.TIME) +end + +-- Variabili di calcolo +local nNestedParts, nParts, nSheets, nNestings, dTotFillRatio +local bNestingOk = bOk +-- Attesa fine calcolo +local nTime = 0 +while bNestingOk do + bNestingOk, nStat = EgtAutoNestGetComputationStatus() + if nStat == 2 or nStat == 3 then + nNestedParts, nParts, nSheets, nNestings, dTotFillRatio = EgtAutoNestGetResults() + --EgtOutText( string.format( 'Parts : %d/%d Filling : %.2f%%', nNestedParts, nParts, 100 * dTotFillRatio)) + end + if nStat == 3 then break end + nTime = nTime + 1 + if EgtProcessEvents( nTime / NEST.TIME * 100, 995) == 1 then + bNestingOk = EgtAutoNestCancelComputation() + bOk = false + EgtOutLog("Interruzione nesting") + NEST.ERR = 1 + break + end +end + + +local dXCorr = 0 +local dYCorr = 0 +if NEST.CORNER == NST_CORNER.TL then + dYCorr = - 0.1 +elseif NEST.CORNER == NST_CORNER.TR then + dYCorr = - 0.1 + dXCorr = - 0.1 +elseif NEST.CORNER == NST_CORNER.BR then + dXCorr = - 0.1 +end + + +-- se nesting andato bene +if bNestingOk then + + -- disposizione sheet e parts + local SheetId = GDB_ID.NULL + local vtAdd = V_NULL() + local MachGroupList = {} + local nPartCount = 0 + local Sheet = {PartList = {}} + local bFirstSheet = true + for i = 0, 999 do + local nType, nId, nFlag, dX, dY, dAngRot = EgtAutoNestGetOneResult( i) + if not nType then break end + -- se sheet + if nType > 0 then + MachGroupList = {} + for MGIndex = 1, nType do + -- creo gruppo di lavorazione + local MachGroupName = NewMachGroupName() + local nMachGroup = EgtAddMachGroup(MachGroupName, sCurrMachName) + table.insert( MachGroupList, { MGId = nMachGroup}) + for nIndex = 1, #RawParts do + for nInd2 = 1, #(RawParts[nIndex].PartId) do + if RawParts[nIndex].PartId[nInd2] == nId then + EgtSetInfo(nMachGroup, "PANELLEN", RawParts[nIndex].Len) + EgtSetInfo(nMachGroup, "PANELWIDTH", RawParts[nIndex].Width) + EgtSetInfo(nMachGroup, "MATERIAL", NEST.MATERIAL) + EgtSetInfo(nMachGroup, "AUTONEST", 1) + -- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione + EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID) + EgtSetInfo( nMachGroup, "PATTID", nMachGroup) + end + end + end + + -- aggiungo pezzi nestati a mano + nPartCount = 0 + for nInd = 1, #vDoneManually do + if vDoneManually[nInd].SheetId == nId then + vDoneManually[nInd].Done = 1 + for nInd2 = 1, #(vDoneManually[nInd].Parts) do + nPartCount = nPartCount + 1 + local nPartDuploId = EgtDuploNew( vDoneManually[nInd].Parts[nInd2].Id) + + -- aggiungo le curve corrispondenti alle aree di lavorazione del pezzo + local sToolOutlines = EgtGetInfo( vDoneManually[nInd].Parts[nInd2].Id, "ToolOutlines", 's') + if sToolOutlines then + -- recupero o creo il gruppo per gli outlines + local nToolOutlinesGrp = EgtGetFirstNameInGroup( nPartDuploId, "ToolOutlines") + if not nToolOutlinesGrp then + nToolOutlinesGrp = EgtGroup( nPartDuploId) + EgtSetName( nToolOutlinesGrp, "ToolOutlines") + EgtSetStatus( nToolOutlinesGrp, GDB_ST.ON) + end + + for str in string.gmatch(sToolOutlines, "([^"..",".."]+)") do + EgtCopyGlob( tonumber(str), nToolOutlinesGrp) + end + end + + -- applico flip, rotazione e traslazione pezzo e box da nesting + EgtSetInfo( nMachGroup, "PART" .. nPartCount, nPartDuploId .. "," .. EgtNumToString( vDoneManually[nInd].Parts[nInd2].posX, 3) .. "," .. EgtNumToString( vDoneManually[nInd].Parts[nInd2].posY, 3) .. "," .. 0 .."," .. 0) + EgtSetInfo( nPartDuploId, "POSX", vDoneManually[nInd].Parts[nInd2].posX) + EgtSetInfo( nPartDuploId, "POSY", vDoneManually[nInd].Parts[nInd2].posY) + end + end + end + + + end + + -- altrimenti pezzo + else + nPartCount = nPartCount + 1 + for MGIndex = 1, #MachGroupList do + local nMachGroup = MachGroupList[MGIndex].MGId + --EgtSetCurrMachGroup(nMachGroup) + -- se c'e' un grezzo valido + if nMachGroup and nMachGroup ~= GDB_ID.NULL then + -- creo pezzo copia + local nPartDuploId = EgtDuploNew( nId) + -- applico flip e rotazioni fatte durante verifica posizionamento pezzo + -- local b3Part = EgtGetBBoxGlob( nPartDuploId, GDB_BB.STANDARD) + local nPartInd + -- for nInd = 1, #PartStates do + -- if PartStates[nInd].PartId == nId then + -- -- if PartStates[nInd].Flip then + -- -- EgtRotate( nPartDuploId, b3Part:getCenter(), X_AX(), 180, GDB_RT.GLOB) + -- -- end + -- -- if PartStates[nInd].Rotate and PartStates[nInd].Rotate > 0 then + -- -- EgtRotate( nPartDuploId, b3Part:getCenter(), Z_AX(), PartStates[nInd].Rotate, GDB_RT.GLOB) + -- -- end + -- nPartInd = nInd + -- end + -- end + + + + -- aggiungo le curve corrispondenti alle aree di lavorazione del pezzo + local sToolOutlines = EgtGetInfo( nId, "ToolOutlines", 's') + if sToolOutlines then + -- recupero o creo il gruppo per gli outlines + local nToolOutlinesGrp = EgtGetFirstNameInGroup( nPartDuploId, "ToolOutlines") + if not nToolOutlinesGrp then + nToolOutlinesGrp = EgtGroup( nPartDuploId) + EgtSetName( nToolOutlinesGrp, "ToolOutlines") + EgtSetStatus( nToolOutlinesGrp, GDB_ST.ON) + end + + for str in string.gmatch(sToolOutlines, "([^"..",".."]+)") do + EgtCopyGlob( tonumber(str), nToolOutlinesGrp) + end + end + + -- applico flip, rotazione e traslazione pezzo e box da nesting + if nFlag == 1 then + EgtRotate( nPartDuploId, ORIG(), X_AX(), 180, GDB_RT.GLOB) + end + EgtRotate( nPartDuploId, ORIG(), Z_AX(), dAngRot, GDB_RT.GLOB) + EgtMove( nPartDuploId, Vector3d( dX, dY, 0), GDB_RT.GLOB) + + local nBoxLayerId = EgtGetFirstNameInGroup( nPartDuploId, "Box") + local nBoxId = EgtGetFirstNameInGroup( nBoxLayerId, "Box") + local PartBBox = EgtGetBBoxGlob(nBoxId, GDB_BB.STANDARD) + local ptPos = Point3d( PartBBox:getMin():getX(), PartBBox:getMin():getY(), 0) + EgtSetInfo( nMachGroup, "PART" .. nPartCount, nPartDuploId .. "," .. EgtNumToString( ptPos:getX() + dXCorr, 3) .. "," .. EgtNumToString( ptPos:getY() + dYCorr, 3) .. "," .. 0 .."," .. 0) + EgtSetInfo( nPartDuploId, "POSX", ptPos:getX() + dXCorr) + EgtSetInfo( nPartDuploId, "POSY", ptPos:getY() + dYCorr) + + local nPartRot = EgtGetInfo( nId, "ROTATED", 'i') or 0 + local nTotRot = dAngRot - nPartRot + nTotRot = EgtIf( nTotRot < 0, nTotRot + 360, nTotRot) + EgtSetInfo( nPartDuploId, "ROT", nTotRot) + + local nPartFlip = EgtGetInfo( nId, "INVERTED", 'i') + nPartFlip = EgtIf( nPartFlip == 180, 1, 0) + local nTotFlip = EgtIf( nPartFlip ~= nFlag, 180, 0) + EgtSetInfo( nPartDuploId, "FLIP", nTotFlip) + + end + end + end + end + + -- creo gruppi di lavorazione per fogli con pezzi nestati solo a mano + for nInd = 1, #vDoneManually do + if vDoneManually[nInd].Done == 0 then + -- creo gruppo di lavorazione + local MachGroupName = NewMachGroupName() + local nMachGroup = EgtAddMachGroup(MachGroupName, sCurrMachName) + table.insert( MachGroupList, { MGId = nMachGroup}) + for nIndex = 1, #RawParts do + for nInd2 = 1, #(RawParts[nIndex].PartId) do + if RawParts[nIndex].PartId[nInd2] == vDoneManually[nInd].SheetId then + EgtSetInfo(nMachGroup, "PANELLEN", RawParts[nIndex].Len) + EgtSetInfo(nMachGroup, "PANELWIDTH", RawParts[nIndex].Width) + EgtSetInfo(nMachGroup, "MATERIAL", NEST.MATERIAL) + EgtSetInfo(nMachGroup, "AUTONEST", 1) + -- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione + EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID) + EgtSetInfo( nMachGroup, "PATTID", nMachGroup) + end + end + end + + -- aggiungo pezzi nestati a mano + nPartCount = 0 + for nInd2 = 1, #(vDoneManually[nInd].Parts) do + nPartCount = nPartCount + 1 + local nPartDuploId = EgtDuploNew( vDoneManually[nInd].Parts[nInd2].Id) + + -- aggiungo le curve corrispondenti alle aree di lavorazione del pezzo + local sToolOutlines = EgtGetInfo( vDoneManually[nInd].Parts[nInd2].Id, "ToolOutlines", 's') + if sToolOutlines then + -- recupero o creo il gruppo per gli outlines + local nToolOutlinesGrp = EgtGetFirstNameInGroup( nPartDuploId, "ToolOutlines") + if not nToolOutlinesGrp then + nToolOutlinesGrp = EgtGroup( nPartDuploId) + EgtSetName( nToolOutlinesGrp, "ToolOutlines") + EgtSetStatus( nToolOutlinesGrp, GDB_ST.ON) + end + + for str in string.gmatch(sToolOutlines, "([^"..",".."]+)") do + EgtCopyGlob( tonumber(str), nToolOutlinesGrp) + end + end + + -- applico flip, rotazione e traslazione pezzo e box da nesting + EgtSetInfo( nMachGroup, "PART" .. nPartCount, nPartDuploId .. "," .. EgtNumToString( vDoneManually[nInd].Parts[nInd2].posX, 3) .. "," .. EgtNumToString( vDoneManually[nInd].Parts[nInd2].posY, 3) .. "," .. 0 .."," .. 0) + EgtSetInfo( nPartDuploId, "POSX", vDoneManually[nInd].Parts[nInd2].posX) + EgtSetInfo( nPartDuploId, "POSY", vDoneManually[nInd].Parts[nInd2].posY) + end + end + end + + + -- creo grezzi per ogni gruppo di lavorazione + local MachGroupToTCnt = EgtGetMachGroupCount() + local MachGroupIndex = 0 + _G.WALL = {} + WALL.FILE = NEST.FILE + WALL.MACHINE = NEST.MACHINE + WALL.FLAG = 6 -- CREATE_PANEL + WALL.NESTING_REF = 'BL' + nMachGroup = EgtGetFirstMachGroup() + while nMachGroup do + EgtSetCurrMachGroup( nMachGroup) + if EgtGetInfo( nMachGroup, "AUTONEST",'i') == 1 then + MachGroupIndex = MachGroupIndex + 1 + EgtRemoveInfo( nMachGroup, "AUTONEST") + EgtSetInfo( nMachGroup, "UPDATEUI", 1) + dofile( EgtGetSourceDir() .. "BatchProcessNew.lua") + -- aggiorno interfaccia + EgtProcessEvents( 200 + ( MachGroupIndex / MachGroupToTCnt * 100), 0) + end + + -- ciclo sui duplo per sistemare Q + local nRawPartId = EgtGetFirstRawPart() + -- recupero box grezzo ridotto della tolleranza + local b3Raw = EgtGetRawPartBBox( nRawPartId) + b3Raw:expand( - WD.INSIDE_RAW_TOL) + EgtOutLog( 'RawBox='..tostring( b3Raw)) + + local nPartDuploId = EgtGetFirstPartInRawPart( nRawPartId) + while nPartDuploId do + local vPartProc = WE.CollectFeatures( nPartDuploId) + for ProcIndex = 1, #vPartProc do + local Proc = vPartProc[ProcIndex] + + if LapJoint.Identify( Proc) then + -- cerco la faccia rivolta verso l'alto e la faccia rivolta verso il basso + local nFaceInd = -1 + local nFaceDownInd = -1 + for nIdx = 0, Proc.Fct - 1 do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nIdx, GDB_ID.ROOT) + if vtN:getZ() > 0.95 then + nFaceInd = nIdx + elseif vtN:getZ() < - 0.95 then + nFaceDownInd = nIdx + end + end + -- se è lap joint dall'alto + if nFaceInd ~= -1 and nFaceDownInd == -1 then + local ptCen = EgtSurfTmFacetCenter( Proc.Id, nFaceInd, GDB_ID.ROOT) + -- se all'interno rimuovo info Q + if EnclosesPointXY( b3Raw, ptCen) then + -- resetto parametro Q + if Proc.Prc == 30 then + EgtRemoveInfo( Proc.Id, "Q08") + EgtRemoveInfo( Proc.Id, "Q08A") + else + EgtRemoveInfo( Proc.Id, "Q03") + EgtRemoveInfo( Proc.Id, "Q03A") + end + end + end + + elseif DoubleCut.Identify( Proc) then + -- verifico se due facce e rivolto verso l'alto + if Proc.Fct == 2 then + local vtN = {} + vtN[1] = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT) + vtN[2] = EgtSurfTmFacetNormVersor( Proc.Id, 1, GDB_ID.ROOT) + + if ( vtN[1]:getZ() >= 0.95 or vtN[2]:getZ() >= 0.95) then + local nFaceInd = EgtIf( vtN[1]:getZ() >= 0.95, 0, 1) + local ptCen = EgtSurfTmFacetCenter( Proc.Id, nFaceInd, GDB_ID.ROOT) + -- se all'interno rimuovo info Q + if EnclosesPointXY( b3Raw, ptCen) then + -- resetto parametro Q + if Proc.Prc == 12 then + EgtRemoveInfo( Proc.Id, "Q02") + EgtRemoveInfo( Proc.Id, "Q02A") + end + end + end + end + end + end + nPartDuploId = EgtGetNextPartInRawPart(nPartDuploId) + end + nMachGroup = EgtGetNextMachGroup(nMachGroup) + end + +else + EgtOutLog("Errore: nesting fallito") + NEST.ERR = 2 +end + +EgtResetCurrMachGroup() + + -- cancello rettangolo del materiale per nesting +for RawPartId = 1, #RawParts do + EgtErase(RawParts[RawPartId].PartId) +end + +local nOutlineGrp = EgtGetFirstNameInGroup(GDB_ID.ROOT, "ToolOutlines") +if nOutlineGrp and nOutlineGrp ~= GDB_ID.NULL then EgtErase( nOutlineGrp) end +local nSheetDefectsGrp = EgtGetFirstNameInGroup(GDB_ID.ROOT, "SheetDefects") +if nSheetDefectsGrp and nSheetDefectsGrp ~= GDB_ID.NULL then EgtErase( nSheetDefectsGrp) end + +-- EgtSaveFile( "C:\\EgtData\\EgtBEAMWALL\\Temp\\file.nge") + +EgtOutLog( ' +++ NestProcess completed') diff --git a/ProgramData/EgtCAM5/Wall/Overturn.lua b/ProgramData/EgtCAM5/Wall/Overturn.lua new file mode 100644 index 0000000..7edac61 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/Overturn.lua @@ -0,0 +1,32 @@ +-- Rotate.lua by Egaltech s.r.l. 2020/04/06 +-- Gestione ribaltamento di una Parete + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna parete selezionata', 'Overturn Parete', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la parete ' .. sName, 'Overturn Parete', 'ERROR') + return +end + +-- eseguo rotazione di 180 gradi attorno asse X +local ptRot = b3Solid:getMin() + Vector3d( 0, b3Solid:getDimY() / 2, b3Solid:getDimZ() / 2) +EgtRotate( nPartId, ptRot, X_AX(), 180, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Wall/Process.lua b/ProgramData/EgtCAM5/Wall/Process.lua new file mode 100644 index 0000000..c4ad254 --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/Process.lua @@ -0,0 +1,309 @@ +-- Process.lua by Egaltech s.r.l. 2021/07/27 +-- Gestione calcolo disposizione e lavorazioni per Pareti +-- Si opera sulla macchina corrente +-- 2020/12/09 Come per BatchProcess.lua si gestiscono anche rotazioni di inversione con valori negativi. +-- 2021/10/27 Come per BatchProcess.lua nel controllo spessore si deve considerare anche PosY. + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti +local sMachDir = EgtGetCurrMachineDir() +if not sMachDir then + EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Pareti', 'ERROR') + return +end +if not EgtExistsFile( sMachDir .. '\\Wall\\WallData.lua') then + EgtOutBox( 'La macchina corrente non è configurata per lavorare pareti', 'Lavora Pareti', 'ERROR') + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua') + +-- Segnalazione avvio +EgtOutLog( '*** Wall Process Start ***', 1) + +-- Carico le librerie +_G.package.loaded.WallExec = nil +local WE = require( 'WallExec') +local WL = require( 'WallLib') + +-- Carico i dati globali +local WD = require( 'WallData') + +-- Variabili di modulo +local vWall = {} +local dRawH + +------------------------------------------------------------------------------------------------------------- +-- *** Recupero le pareti selezionate *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessInputData() + + -- Recupero le travi selezionate + local nId = EgtGetFirstSelectedObj() + while nId do + local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) + if nPartId then + local bFound = false + for i = 1, #vWall do + if vWall[i].Id == nPartId then + bFound = true + break + end + end + if not bFound then + table.insert( vWall, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + end + nId = EgtGetNextSelectedObj() + end + if #vWall == 0 then + EgtOutBox( 'Non sono state selezionate pareti', 'Lavora Pareti', 'ERROR') + return false + else + local sOut = '' + for i = 1, #vWall do + sOut = sOut .. vWall[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Pareti selezionate : ' .. 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 + EgtOutBox( 'Box non definito per la parete ' .. vWall[i].Name, 'Lavora Pareti', 'ERROR') + return false + else + vWall[i].Box = b3Solid + end + end + + -- Ne recupero la posizione + local CurrX = 50 + for i = 1, #vWall do + local PosX = EgtGetInfo( vWall[i].Id, 'POSX', 'd') or CurrX + vWall[i].PosX = PosX + CurrX = CurrX + vWall[i].Box:getDimX() + 50 + if WD.USE_POSY then + local PosY = EgtGetInfo( vWall[i].Id, 'POSY', 'd') or 0 + vWall[i].PosY = max( PosY, 0) + else + vWall[i].PosY = 0 + end + local PosZ = EgtGetInfo( vWall[i].Id, 'POSZ', 'd') or 50 + vWall[i].PosZ = PosZ + end + + -- Recupero informazione se progetto o produzione + local bProj = ( EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL, 'PROJECT', 'i') == 1) + + -- 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 then + if abs( dRotAng) > GEO.EPS_ANG_SMALL and not EgtExistsInfo( vWall[i].Id, 'ROTATED_DONE') then + local ptRotCen = b3Solid:getCenter() + EgtRotate( vWall[i].Id, ptRotCen, X_AX(), dRotAng, GDB_RT.GLOB) + b3Solid:rotate( ptRotCen, X_AX(), dRotAng) + end + EgtSetInfo( vWall[i].Id, 'ROTATED_DONE', dRotAng) + end + -- inversione + local dInvAng = EgtGetInfo( vWall[i].Id, 'INVERTED', 'd') + if dInvAng then + if abs( dInvAng - 180) > GEO.EPS_ANG_SMALL and abs( dInvAng + 180) > GEO.EPS_ANG_SMALL and not EgtExistsInfo( vWall[i].Id, 'INVERTED_DONE') then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vWall[i].Id, ptInvCen, Z_AX(), dInvAng - 180, GDB_RT.GLOB) + b3Solid:rotate( ptInvCen, Z_AX(), dInvAng - 180) + end + EgtSetInfo( vWall[i].Id, 'INVERTED_DONE', dInvAng) + end + -- correzioni per rotazioni non centrate di produzioni TS3 (quasi sempre multipli di 90 deg) + local sType = EgtGetInfo( vWall[i].Id, 'TYPE', 's') + if not bProj and dRotAng and dInvAng and sType ~= 'LAYER' then + if abs( dInvAng - 0) < GEO.EPS_ANG_SMALL then + if abs( dRotAng - 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + end + elseif abs( dInvAng - 90) < GEO.EPS_ANG_SMALL or abs( dInvAng + 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + if abs( dRotAng - 180) < GEO.EPS_ANG_SMALL or abs( dRotAng + 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL or abs( dRotAng + 90) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + end + elseif abs( dInvAng - 180) < GEO.EPS_ANG_SMALL or abs( dInvAng + 180) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + if abs( dRotAng - 0) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 270) < GEO.EPS_ANG_SMALL or abs( dRotAng + 90) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + elseif abs( dRotAng - 90) < GEO.EPS_ANG_SMALL or abs( dRotAng + 270) < GEO.EPS_ANG_SMALL then + vWall[i].PosZ = vWall[i].PosZ - vWall[i].Box:getDimY() + end + elseif abs( dInvAng - 270) < GEO.EPS_ANG_SMALL or abs( dInvAng + 90) < GEO.EPS_ANG_SMALL then + if abs( dRotAng - 0) < GEO.EPS_ANG_SMALL then + vWall[i].PosX = vWall[i].PosX - vWall[i].Box:getDimX() + end + end + end + end + + -- Ne verifico le dimensioni + dRawH = vWall[1].Box:getDimZ() + vWall[1].PosY + local vWallErr = {} + for i = 2, #vWall do + local dDimH = vWall[i].Box:getDimZ() + vWall[i].PosY + 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' + EgtDeselectPartObjs( vWall[vWallErr[i]].Id) + table.remove( vWall, vWallErr[i]) + end + EgtOutLog( sOut, 1) + EgtOutBox( sOut, 'Lavora Pareti', 'INFO') + EgtDraw() + return false + end + EgtDeselectAll() + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle pareti nel grezzo *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessWalls() + + -- Ingombro totale delle pareti + local b3Tot = BBox3d( ORIG()) + for i = 1, #vWall do + 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( dBoxL + 0.05, 1) .. ', Wtot=' .. EgtNumToString( dBoxW + 0.05, 1) .. ')', + {'Lunghezza grezzo', EgtNumToString( dPanelLen, 1)}, + {'Larghezza grezzo', EgtNumToString( dPanelWidth, 1)}) + if not vsVal then + EgtDraw() + return + end + local dRawL = EgtEvalNumExpr( vsVal[1]) + if not dRawL then + local sOut = 'Lunghezza grezzo errata : ' .. vsVal[1] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Pareti', 'WARNING') + EgtDraw() + return false + end + dRawL = min( dRawL, WD.MAX_LENGTH) + local dRawW = EgtEvalNumExpr( vsVal[2]) + if not dRawW then + local sOut = 'Larghezza grezzo errata : ' .. vsVal[2] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Pareti', 'WARNING') + EgtDraw() + return false + end + dRawW = min( dRawW, WD.MAX_WIDTH ) + + -- 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)..') ' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Pareti', 'WARNING') + EgtDraw() + return false + 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)..')' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Pareti', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo le pareti nel grezzo + return WE.ProcessWalls( dRawL, dRawW, dRawH, vWall) +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessFeatures() + + local bOk, Stats = WE.ProcessFeatures() + local nErrCnt = 0 + local nWarnCnt = 0 + local sOutput = '' + for i = 1, #Stats do + if Stats[i].Err > 0 then + nErrCnt = nErrCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + elseif Stats[i].Err < 0 then + nWarnCnt = nWarnCnt + 1 + sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].CutId, Stats[i].TaskId, Stats[i].Msg) + end + end + if #sOutput > 0 then EgtOutLog( sOutput) end + if nErrCnt > 0 then + EgtOutBox( sOutput, 'Lavora Pareti', 'ERRORS') + EgtDraw() + return false + elseif nWarnCnt > 0 then + EgtOutBox( sOutput, 'Lavora Pareti', 'WARNINGS') + EgtDraw() + return true + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Esecuzione *** +------------------------------------------------------------------------------------------------------------- +if not MyProcessInputData() then return end + +if not MyProcessWalls() then return end + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +if not MyProcessFeatures() then return end diff --git a/ProgramData/EgtCAM5/Wall/Rotate.lua b/ProgramData/EgtCAM5/Wall/Rotate.lua new file mode 100644 index 0000000..e12c7af --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/Rotate.lua @@ -0,0 +1,31 @@ +-- Swap.lua by Egaltech s.r.l. 2020/04/06 +-- Gestione rotazione nel piano di una Parete + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna parete selezionata', 'Rotate Parete', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la parete ' .. sName, 'Rotate Parete', 'ERROR') + return +end + +-- eseguo rotazione di 90 gradi attorno asse Z +EgtRotate( nPartId, b3Solid:getCenter(), Z_AX(), 90, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ProgramData/EgtCAM5/Wall/Wall.ini b/ProgramData/EgtCAM5/Wall/Wall.ini new file mode 100644 index 0000000..6b018dd --- /dev/null +++ b/ProgramData/EgtCAM5/Wall/Wall.ini @@ -0,0 +1,8 @@ +[Wall] +BtlEnable=1 +BaseDir=C:\EgtData\Wall +BtlExec=BatchProcess.lua +Button1=Process.lua,Images\Process.png,Lavora Pareti +Button2=Rotate.lua,Images\Rotate.png,Ruota Parete +Button3=Overturn.lua,Images\Overturn.png,Ribalta Parete +Button4=WallMachinings,Images\WallMachinings.png,Lista lavorazioni diff --git a/ProgramData/EgtCAM5/setBackup.bat b/ProgramData/EgtCAM5/setBackup.bat new file mode 100644 index 0000000..e91d977 --- /dev/null +++ b/ProgramData/EgtCAM5/setBackup.bat @@ -0,0 +1,3 @@ +REM copia conf standard del DataRoot.ini +cd "C:\Program Files (x86)\Egaltech\EgtCAM5" +copy DataRoot.ini DataRoot.orig.ini /y diff --git a/ProgramData/EgtCAM5/setProd.bat b/ProgramData/EgtCAM5/setProd.bat new file mode 100644 index 0000000..60d2626 --- /dev/null +++ b/ProgramData/EgtCAM5/setProd.bat @@ -0,0 +1,4 @@ +REM copia il DataRoot.ini orginale a default +cd "C:\Program Files (x86)\Egaltech\EgtCAM5" +copy DataRoot.orig.ini DataRoot.ini /y + diff --git a/ProgramData/EgtCAM5/setTest.bat b/ProgramData/EgtCAM5/setTest.bat new file mode 100644 index 0000000..5bf17a9 --- /dev/null +++ b/ProgramData/EgtCAM5/setTest.bat @@ -0,0 +1,7 @@ +REM copia conf standard del DataRoot.ini +REM cd "C:\Program Files (x86)\Egaltech\EgtCAM5" +REM copy DataRoot.ini DataRoot.orig.ini /y + +REM Copio DataRoot di Test per attivare le funzionalità +copy C:\EgtDev\refactorwall\ProgramData\EgtCAM5\DataRoot.ini "C:\Program Files (x86)\Egaltech\EgtCAM5\DataRoot.ini" /Y +

W`0ޛ< 而ɻVa\vvp"ɋn〯lsZG^"^H*f}FG.RNy~Gr %9~Q;_+&E꛶wn5VIև  _AC˷|+\͋q:OlSԡ(㳋ȄۛE]<A=#|sm_E}쫨,\:k r$M~~%0mز'}v'ooĐd576n푦>dnh&DNmvsCq7Y5u04ZàCG>}λpGD>n; [؞̍*?>o;A w2C@ai40Ӱ-6[fo˘}՘t:_t n{mֹգ!M6kR׵ر@۵qm]B?c@A3XvfCPw epCSĞS +W,Sn4앯K&wohZFMl28i4Cdd('DBLg[|=_i]ʤxc7 Ro${->-nuaa S5lWq<8y9w}IUlXP=,5: Hm0:EpFk4GFe ljJXDҪAG &,5*Yed9Y4d Z)Rl" ʭ&}tlx(,`zxg<@ļcC6KKnF M + 2IƱLhm2nMsac WMRrC5|1RzA:ۭ.60iP4 R6:߸:<!ZMǢmw'yL=iVPq[yjqoqw?wyq =ji4 P1PvD._`mFEP5mtƔ=JW#dh^5 .8!> +stream +xڭ}_9{}|̺Cf}]] ރǮnY5'TdfU<@9Ő((7a7SKf:e||LrX#r,3}ڪ鸴u +5W*%ot4|,1\0ݱLOԈ?Mrlsv?Cܿ**kIRQZ,V'0%qw!313N׀=RZaL5Pk9d+k8볤틅7ǔJG[H1Ev`P97{r\kzDߞh)ؠ MTb56l撺B#qH uɵײM?O~31eY)[ˬW+ljdD|57$rkJ0o.T+hT]]ceC|vHg{i>N$rZ,%_c="< WC^y{3})_iA{QoB;'"c5ϽJoOg=ХSYfX +9V^c$oqQ9^M%HaI_R#{Ooڄ&%3&j46'VvEqz= +D`-fМ jؙ%㖎}Y{-৖JӉ0q~tTJGûוM$_93QQ-CI$پj۷tc_etD-{h}H-E*]rd"\:9$Dˮ"7A T,!nwq}j4g2{ny8I2[3y&U|m'\e喏IDIƲ6hLiVL#DOg=PUIf=M[!e&vĨX>d͆|ʛ$U&5* +Ex5&r{6ڃ n ]Ү׵4zlRti%+6H/caW6Bk4H RF +M"!'S7yiziY1H-ysySE-O]<~H6tkuA(uy(jjl :1$lް8LN GA`'i ^ Z:D:H avIstDi` r9f=#!wT˛O@ +,‰ <gYEmdb[!Q1ss6ifw:*$#l6pVDtxA?H7]I1M3֣8c +5My2FY58*N9kF@- 3;κOCj,ӅhHH &84 XFjy۟$}*oS;s2@l2z uG,!Ss;åTd#yƞIw%8*!݋L Lbq6(79·qW1Obp)eh=Tҿ[Q{%R v񺇨G m[1ʳ#NZSث @PpHhj R /g- Z=)ǐ\rV*,wk(+!ì|=7y+P2Ϛm =i%{KU7},u$^qy]8ѯE7Z/Y>ҬZhzᠼԈSV 3(֊˂x_j/J+ `8:]U0}s"Z ^zU +oX!Q\7F7ҬV/PX8WHܼ43CPqz%n?HKX ^~ۥeM4lZf9RNh173.g V 5{1$*!mLF;zE?K9ijFjYH3h1ײvj+g-' Nμ^A +m瓳>͵tZٕyfg=`w鱯Au^>5z.MotW;uWi¿Iw} Mw-Yyz'+KayIW=\[X[{Nv>Kʚzbe>Fz鰯CD0>kg;HeV׵pE+ViXnw A۽5DnnptF4ۇ 1>p?+Zm)m:K +B|n1ݴ-DSQm/oW#8Pk\4`mG\y<,wf,GLrvctyX #."%ҶЕdi0*;G>iM.@anKT3 2M}'<~\YRJ)Fh/%ke7fFßmۛcHek?o70~ͷO/c̻q݆z6.w۽MkK~|P^>yٽ_bԦ :ߣ5w/HT۰=XI}sx6jD6+u6{qcC+W͙{Vkn:ohR7m-Hxnw&w_:uk_cv_~kyb#ѡI~Ze(G=Y\# +S\^YrDdOw飯㻯V5պBAk蘩Y$ +w7_v_EQZ&Jlq:Csޓ<0۹u5h +zmd^w/1h[HM:'+>g>PMhκ3/HOwZg vu;/ [b÷ SN3֦YTz.Ht²]owM0j+Wu&Vo(=A#ic&['v>=v} +[8p^>q53٣HK[|̅~sT/69.?ctvP:\4R#彨PI?id(Gsqj +j*$$1tv 'M\ + +PR_Fb>Z%AY))߉8o'rM {x8O2"sVWLwW#dhϟ| yMR%4JRUZtf{H2ʎĻ07,R ZAiH%JGv?EN(i%WcLJ\|0H<5c^ A# @}cV d>3cH\g#[8 י뀠g䖏舦e%uWQJji^c{-EI&~C:D_݌꒶tn9–Aźt|< Ήt-Gfgqp#EnE+lI~>~)bE:N!32į6hz0Q@J(i:Xf51tɰr hIiYP}Cq$bT :CK;a,2N6Lo0.G &)>Yr 3? ,6U.e{.Lcj0r&ÿ@sN w'd6paF&.(\*DnAL{4ʟkI,SoS H ]8Sut؁%VP2! +;R"l7DgDsHW>PZgS˕jl+ T/oV<47r kMiuNl;wR6&|Ͼ-kf) 3.6f9.ڠUtq@/(.g KŒQz5H3Ѳd_K0Nlȡp +zxб`5m/,KlR\dttY>1J4GU+^%cݍ@lDKo쮕*kxsEn\0D4dA6ZJEitX DSaqYܸ$8hB@n)ȔgVv~"~re&|aPp}(ُ4$!oKcepa-Crg%*TY' &~^O{S]|*Z&LC0 +&`BQh^r^9`jtIfᦱffJS^x5W\^ɽ QmY>CY1.kJuVJMu-)7謂WQpKNoa]Pwm-~;;9MViVy9+qȭ&#` 5@zUtJCXrk`Yj"DU?My'pmZ$e㱯J8Mn81?uÅn*}S$KU(3YܐHv:":EPݕDZ=ܡbLkzhn`Pb\]`E +'"(T|8p$rCB#A$u5ء8IPCtAI-^z8 J,MJQ'8:U L&WgGEeVjPFK](&$ը!(I&VaNMlt5e5-d6E< 0ٚ)%B쌥gWabF,Nxl0USՌa`V|}_L f͑9XL`pXC%(UʃQ!jldޤF" ֡ d(baVt(I'@hȰYŘBm) Ea4] 6A8)dZ'ĤYZ +"FŰqRݙ(^"Y"% E`tn)drz[%Kjyw[2`$L*)90K3&Tt6GW(7lS:C02HXmT H&X{5&Y$Djt7نFJF3rX Y2F;h1+'w. e1+x-3a:U+#U?JBN?bJ2ZS5a!C$P +K4|+$5[ 4u<q֋qKSGd&ZA\KjK:/Xq}aˡ.cgJc4ֽG.òA4kBX@ 64f:yݸFTh yY3i,@4+“ּt 7uucJj죡ܵ6# +ا5qCʫ6ʃ\kA;@.Cv4FjٹrDF oFR|>㼧hUBrC޺MZOΓD-csdCID$4D rJTJcRAQ @3l0a.؁W9SNI^C[y |Ԙt+l-̨c}FEwM0=xDG]pK2͆ju,3'xJM(cTG 1+8+U_.M+V 4/F`x,p&VurN DR,fu4C/EPKOCR^E:JUCy!*$}Q@9m<|GXt C8"wƸ@{OszW eˠ% tIW+ JQʁ3ig1 :Y_*u2ݦ"-N;9tkh3W:!}Ũ{>NκkIKOY7Aֳ_˜ceJ3{ *:gyϬ.$Իdkh7")Kʾ Q[mA6 /8qFJxeo^?S/И kx_BFങl8C!&|&9'RaN0.ȰHi X`* uI\m5#ȱǑ'=gW8`2ZaXOb,_6upn˄"lt<ۊyrxJAr'U͚pwWU.1v}d`[v,;i ۯ:֍dꔠse9j}+ףs~I?U nةBGG.fb> +stream +xڵn}bw̤Ոc OE<02%@>u-ҁjj_vv1=ygov.%Y[%Ŵ${Hw4'H wkJXքwkrjio7b-@'-W\ f`3,tXXEt[uHR(f+Ka > TVc=d倲D9P)ץ~%ո +5EDatcŀ^rXg𚋼JX-Dx7)}%ΦN,qgѳ^M*cdd㮀"eЯG>'b,q/R%9nnY͖PuuU=`ECo@?fՔPL\T!!e؅AzM |+hy%7{ V1ޛfwlX\w(a,C!JraDAb +NyԄo38VMH \(\""2)`t{MAU,L\Ah㤅LL=&<& 7Q!(`t8hD9gO= +@2Jg_3lLB(d D9m CiT+R@jDD<)^ar^a)q4۬ '#Q" ~j,zҊִHϞ:>H߳W}ӯGϷLjjjg(dG뱿?e`g)" 7 e!#XҸk P4| .gi<5=LvyA! 1> )e(.jƍtE{iubImdK[5zlAj$g*2&J7W' -})r4-/?e@Tll{Jl,M}an0@Sy%y1pj+ s'T:F>[ѩWG89BjMRZ#Q ,ӄ~I/~k2ʡȁ +"miPR"l0L"iYW=S/K|SωVGnŇϻ.wFT$ݟv3л>?}8ؼz,^~5gլ/O?.a5lٯ~'d+_||ؽӼrR6 ؐMs4Kp <KWm)J"JSgv27ӆ8 }ESU=2zА &T5} Պ0o !3Ft&F3J 4uo{A;M (sQJVL[028H6l@rZE'!Hb2/g< 6 +Y_eD=Pƒ %eBCʑ1U4`A!>eL:P"(}5*SPuOxlٌ(ʓ眖^\cGiQTYVFr yX#-바VsX"9)R&Ep5 U"jr!B0wԪ'jN>c {e@[n@Hw_5P!TgXXȃd7 | ,;Ƀe{S>lR^Z+MCF ǭʤ^}F0bf2c'g(z u@W_Ot֓I O6 J"MvW3 b@>!gSO̤`7S׋r&Fr-&>zfqy.Ub*yF!qyFh͖Fՠa .m)ʹ#NhݡohSzCWTP{?7V2n{ CgX뒖,ꅵİ.FlsSjSQVd /-n +J(&F{'ʑ”4iR  qۀt j? ۩Ϸi膃o @Ww^yv,oՊqP-d=ivk_˯y0;tq!x9^C$n2H˓2.׌IEhfYsBѹxصӐཌH%JYB%v芻N^Mp<'V$ n3 j0fa'6T.﨏 AKO)HŨ`G??A3~C+j}tQ<[M '=l;H_#pB&JrAVqOkh'Y9q<$30M =yݡ +[K4ar8q5mDLm_hbEQ$]X1⨏tAL̴\cF)r*k ]u.R2̃D4֦#k!Q3ard 70q*j}(f:wL}gKa +4Y^S6b $ٻ3AEc,]">6s<]d.g{{X~ZpdE;ZX xaayJbխUG+W":tlǏf$H yS%\`q7ޔ7V[#Y.;y8>?<ۿ}X>|,. +Setk9=qd'I.VZҊq*# E<6)Q{؝F_?x4%_ڋ_6#~O˖/ \ +~=ͥ CB7.~Pf;޿ ><=(X%ȻO?V_OXī-!~]΁WPߘ#D= ~H+ՓtULz}ow +endstream +endobj +308 0 obj +<< +/Filter [/FlateDecode] +/Length 912 +>> +stream +x}U]o: }У(Y  ЭE>zHKJtZD< ]p-R1}}9%} -S8h#2Ȧe">#lY#Rv2.J&jٗ,++p$q-o0rLLnJX=ЍY JQ_*M'1: 1(*<]2 +.*Dx N8pozmfweo*Y΄D $[5k&2]ssHu^۾ !5 AHٯ>qpYjY;1=;qmyMD@c6bFh"ɯmޭ۱;qO(_s6F9baf9w+:>ntBi xWcҁDBJR^K`CJ<kpfE^\#3L&I)|1A +iݖ0PdO]jޯrߧ\׼9xUQIBOg?][4-Γ?DFiذ@]xt!]^P$mݶ߰O%k^.(MmT4Th0'%_eIsX`(M{OBzd㗛lM'N|8W6a635Yա]?PvȒ}j 4!ٿYƂڦ6`0 T0ٟŲd:x*)@[! HO-SLNJ +endstream +endobj +309 0 obj +<< +/Filter [/FlateDecode] +/Length 7118 +>> +stream +xڭ]],m}_яsT$TUAby3^^#Czfֻ#v")")VO/_?^vroݷO_Q}~`׏\[K}+xB-_A>u۟VSsaK9GtO},y7<7g %:%t}F:04^RDO +{rm\}ݧ_9׆ZgFLڝع$VeQu'|J~A;۶BYm!fRvarˆ&@ouNl+T(z +=Xivij;ً7lþk#,ǪY f.t  +$&''T;{!X*g9)8ym*{IEٓz}Rw:6NxH&>7.%u&c̖I첝TYm4 sIQK3?aޫevVBE^Rߴd?PMsسe[iKзB6MV1B6RˤR!mn;_jhx!<등.[g@JM/')$Qq3 ]Ȩ~iCE=gwѵ%.fBV>^fexZVW>#x Vb[נ.%ȧL)`-J `ȱᔒ3RKl3MH,t;b ǜj7RukoxƭpN_ ?N<-q*F$RQCiO<ޯDe$VY-JS8sq +Wf%F_[* gEV ACً +mǖNO2 E'_y_)= oSn~KU ʆúGfЕ竬~(4"@/ 0+;"SܳsU1#*qRF7v`+Ώ`P ]T]jR=J *U-A&P4/Bo {:[sM3dl%PeExu=YGNv$(^ +dH#8)9U'ܜ½˙xv`XIH(ʫz+l;YgRjf!#?쌊J|YU00 Pie>Ҽ2)oOUMqj;x􇹥`m\MڥM8"g_pšɓ8Z66A18߹QoeSY.gR9;L5Iy U(H?kdxaR,}OF2Kչ}wt;Jv&Bu袟}[o6;z%S9/X'G&,tz8dA)GxV>u)Gq9g,PeQNՍ\NYU|mF>i+Ϯǰy<_VUn"Zqn%'a堎ے3{Zzx)nQ䋐G_G;Z){wi4KBumP +o=8 x:{,0g +/s{ 0SoxܲxG7P/0J|M_8 ƘNգE81nxK֔mrWu8KM%y#Dz\](_Mn6 I:]] m+JPr{JثGP(5mjp8AlWG_P5|}E +=sGU|0"\~`_I*.<lKX.,^VԈ2I1@tnDYcȉXDYIJ>zοjŬ$"8{ Ȫ1nLً8u #+ ]wfTx@P} eSFxCh퀍Mo/1%eYy.*{ӭU:!gn/?ff +(F[5UtΛ +y0Y0+ϨINvFI ZVd0[tGaYu]c̫  bb ,LDB(soΗ&%jbECS[*s`No㙵q +N4 KaogT*/[hUerOy73 N5וm:P):Cuknw)[hLǏ(-Js:{(Pqvq .}QKP}T}J0|&JwBR"귅RpZ#o<2?:N2lOK󔙍a"/? 3*̂[6п`W}ڹa!ع-% =0=>"'3SXo=VQz %2R{cGMq~0pJo(6>˃>B1J;#VD?mb;:0o\kʂPpQ0[J>4i6۪?v 7%5%S 8'TpF+#|~O/to/ޛW/חIr/z?S:_o~sɟ_nO9k嗷m_~{K%śX$])2jDy^0@eO|d07׸FIEh7E)haOTRk7DᨙDwI&x.}b* +%̔ǽ%Q +"q0SӖ3fN6=ӽ ^!.5M x 8m5brp 5?8a +@3o[bQA,)خ;QH1y"0dPI,.&A6;W+F=Ѣ:yisvДParf2ulI + Ԥ@[##OesNZ^\okZ@$txR\TA0: fϧnB2Z.4`9qIaql5N:w ?`^QxL $ >L$N YNȕb2HJ^nU46 ]aB:q%ΘT|079H@DӢ0pND-]zp+2A$!@;x8&U> L~+%׊`qxm< TU&u#J~&f,AVB8(?PMǐJQEXL Nu%L6DZ_ WAxiJF0h c[V,#iP(Θ''_*om `}8%q 00 NOCZAY$@q ?!UHX8R7pV|\8<yB8i P1/d($^@?MǼ fFe4֞1^1KNcc}G~|_ ퟟGFԮ0c"[R"jh8h4巈4A4'6 gHheO_(KEuKׄ98%rfCNNf.Nw|2nyY* JǤJNbbN默J] -,[iV @%BPCH^j<1zEc̡J]!q%=xs#ćYL%y}"Rs h_k+qGq_F +wWyzgX}/D~? i/G!Uя0 $pL[1}_dLY=V_͊Ť`@xǫd W6jЦ~1^<aVcbTLkw w@i8Jci; eJm}RjHlWU.jcfkN"M]/FU\W}D˜ o~UMB`AVy:t* +8U^ +٥{pi9P鿧eOׯ}Z_lTrGίDgFC'V,v>tl7f+xsg/%I +endstream +endobj +310 0 obj +<< +/Filter [/FlateDecode] +/Length 1145 +>> +stream +xڥVQo6~ׯ#A I:d-0XC`#*b;eدwGI$xw~|~K**h>ru-)TU␸V;<&#-b0ڪ~O^*FbOVni +jۄ2Ѫ" vbf2ɷ/Umy8ES&w*xnz&?%;U\||N\ [^peH]OʹՂeP>Bf2`EYʖ${V":Mj6}5ϛ$SbMKbJlI,nsܼ3V&wɽrH3[ʱ9Y<f*9~ţ] +xWaaOoX7VxY۷GšlJ1Sl~M$*ʡ>Hˏvl`Q9)O}X bd \Yx+DLt8nR@nCR(&S0n70V; +Rz'JUXGMbZsjJ +EKAQuiRӟ ͬ.iC<zr5(hJ1!cIY-gCAnOECUc-9+NC )mևҾkH4km܏- w!( #'Sǥ+Kv"d*s^і{KSzpnPRҶBCepI!4d!mʚw׷d9ءgKOsWmm=Qb1ٺ+YN6>yl/mƦvr+xC-4*͙2M0 +UϚ ЗN+w2>t 7.j6}|eQLVЋc _6 HJ +endstream +endobj +311 0 obj +<< +/Filter [/FlateDecode] +/Length 4041 +>> +stream +xڭɎ\_Ǟ, b{0rPdIva+}j6f fuX,N'vO'zt藟~H!=vN84?mv-Fݷvbۣ^rڡp{ k80ZS&#wewܼ/{`< IQ=VWHΧ;FiIl{_^[4"4ŲPOs<ܑ =XuEPs +N4 敚 ʗP + rB +&N\TNvaDs<M9-BK*G^gwn8nGط=ܓQt7" )uv/bqDn%5(r΁VY* +I +Ζy$bM]/EU{Cnlxqk%PQL&٫jl! +m1hY9b0" +)UAr$-Ue t6j=chA6;ބ}~=sAO9hV fXw{έS3fAdG5!O)%v*+BO<1S91BC5X_ţ ),$wZBJ3~)KGw=jYFMAg48 e>ޣu2z8, +PӤE RG$FЯ+`$C܋AUkıYb 2xVJknǧ!(tB?!NX撷e-y}%pEYfҒrCVMQ0W{ /-Ÿ:iRqѺWS/Di&%,@X݁B$$ͧ +(bIii} +Z׍-g 0Kӌ^E=ǣ qRcoW='_Sկ:e~3*A1 ):ݳ=7=Ib'͜9NmLaL'@֨ĮU='M4{uӶϏOwZ)y?WOޞ-o͙ۛW?#qAT/њWyD̫fnF Aa߳ +TIF[MȂ(E$xd= inI5*} NnM tv.v6fU{Zoj)ބDYq\iRrE,Ynbz$E IIz9qW 6tšCJ&=ÌWqְ^S2 ~Dha +`w<&.82l2Wv?Xz}$ +;7mdGAH+GG&2й(;]-n-VfI2*!Y[2}#D̊!"~ڞË+!ZQ1(ON։nP {2HK?T;3$kymD0JaA j6 +hL\k&5'z@ۣŒȹ~>M;}[iuzgRSв宙/k(ηck :@*RM|4ͶP +.h@nլx",Ik nJڢ$ +miyխV2} 1]@|͌*յ!`5 EO+Z5}8hͧfr*E&S"!+&dֆ(*12WcW)@;j%s_C:S˅aaY릾8%^R&7*p Z6I'!-;7C4V46ch+Ȓ*\C:Р Y+D4<7U~C+A-fWm78QQqvѴth!?$wQE#X1lۺ yfH0 rvm8ZcP5Q(+;$"{'bA dsNx;ly=@eԲLv]&Uw[AҫbJzdID)PџL{:M7högvڟDItS0= +*,62+DEIʁ9w s 4,Hcx~HRn,gHgj)iJ K3w'$ZGd7 x)r oXߣfIiլi)Q=@"O֮/J,~)WB"EW 35f}W? +ANby͹?=D]$DOn_B+YX[C@,r鿫r8|Zvtgo +Qԏ=^on}!>||\XӶ}߫}Z[8szB|=]˿oF!]?|F7d[VvǗw륀*7Jy ޕmGI!=K_~Fwn_rw +endstream +endobj +312 0 obj +<< +/Filter [/FlateDecode] +/Length 885 +>> +stream +xڵU]o:}ϯ#dcvz{AHHVRCH͖l +_όcom=gΌ0KdUb/ g 9ؾ&HoO}6AKae%+#(K֑\v)I֑n)IHI@cQFw`k 9:/yR.-WNʰw/Wy?<#RV+nN:2m`yVCd"Ƞ2a7 lD2ߐ1 +԰][SB#8X@ڛwbsKkKmyp,?1Tc]+>L)RDB}/B YhU14.Z;B|/j>bj>uQrd@㇛:Vk֖ah[ s;)z 'B6 Xs}<_)4w +]Q2hi9GTĸ8B-DM2Jf)$H(&;dc0Ie?G^ED $,ua%.m*ASZO![qF Bmy9ށ䕊<Ń"|KӻOR*z;ɤR*Ф[IA) W&)B8$LV<ׁq02$@qi>ăw=^g7ûze.4#Ĺ^Y a1 ۚpn lc);Q,zʙW(jgksSYW|pFF;LmwܐݞΩ!U-Bcc ́wp\!"_Lqg-%$|x''D4Ƒ0ghAHR0t/7tnvBUqR q0?{<Ʀ<,sH"dS;&Ů~0Y aEOQň'T<8D}xSlfbl(UcT'3}3#Idlut .5D+T԰S1s76vȲr\4\AܙmI՞YZxHF#pqZ(a4v}E0L=aBA +8ft#$j%Rz_{/CxK~FҧT%NC6C_!6;U+IxClBl>v ɝD?/Yp6U2+xyI4SZA2g-='_Q$ +&HA*퍺怐SUݖ[bOgm `dpp~l5n.oDw_'b(?h&`t4>H$p"cE:~yn^ ~yrEO?߿9A{*\үY‡ߟ~GcR@w.O~_۳(|qw_3M sdoIO?*M$./oOv/n]u{QBgj~fl$U(mezOɎiB|u' 9F|qD:/[ %{u0Md JbikI:O"C=C&1HFl )eA5'5C=FFW MF0$ Ѣr1w׃RMK;8p+Шcc]&*NhבaߴR"(H;J#5M:j֊Q_Ye06t<Ɠ95#*&XFv2"?plo}Siaل "qWש:x*[]/_CB]kMoAy[JtT MIUf=g|((/k`ێc1ʡ'T4bpR,rikC?P*SZzRÂk xg-7!][cK܎] KZn u׫@ +9Z2>!(sc<)q,^6 9:c Q3D4+PbKb%k -]Y|J%0 hoBC0' !كTީ !Y P  {wQ1 Զw)qxddvH":w=*r 7BxPY$ԍ6j&VG x6R51aŭscZ)tR%ބ1@C',6 ,@UxWXD lI?2bS4? +P1C~l$f%j|ʆfXA/K nXN.Z2fK=NŬY~ 7lb٠^;jU$k( 5+fF)xiͭ'ÆMM;HM,vdjhΏLw3`+kN>Bs9՚ ?s> +stream +xڕUn8}W‚ Wu +FQ 0HNeewH27ep!"?_=WC\/0R,h޸-e$9XHq{iDNb_@bQt¤Xit+pB븗Ԙ` #&@%ҷ]Z +V msNFL)5w>6s`1D>LS7ܮHYaǩ 5hQFx$@prkkih?bt֋g'M p5îeOMa͸u0''2b21܄1DL@CQEQnXj'`M!Ƥ$wD#GT4\OK2ӏ s)o c o{^˃Q9Ϝ8(y&90Wл!YN"/[]ߣ΄T&lJ^dN,/i\]#*XnM/͢ⲭ+6=3Tm +uPm:ƹD1%I'?uJv}손"WlE2ASIy7e(#H&6ńMJq8e.Nsžy~Zڟ +endstream +endobj +315 0 obj +<< +/Filter [/FlateDecode] +/Length 11025 +>> +stream +xڭ}M$9n=EwCrF5V5]]!^Mh/ ="+K3c֕D }{ +ײ]ӿ[}nrMyTRuǧ5\:(nZ>~* ֋zm;{:~! eU:aS5ȿW%ѶRQm"$X cQ֮Q"-+D ڮMjDiʟ ]k~|u\zft,0$G/XuT,/[n:\5ɟa)vQ_:Ȉ85SC' 65Zcgopca"K*:%\u% +7]2/.}iG}t)0o,U+EyGX`gwp0`Ĥsepy?2H;t}t c. { ڄȚ@,#3sǢ$Ցw1>xf !*Xu͙{iD}oG] 9S7xH}Y93}M}q(>/۴cu3R^ {6a4u&*>W{@d%Z q "+\*cjBra@uYQu@-[Xu{/y7aU&cѽ>CiTpEjEk®Oe_uQb=@|`}~49'wYYao:)#T<ͅۃ?r2HnVц=X~I1?ʼa`,{Xb6H#q)YVINƒ[CB94wtl&P,Qk3'}efB:k z{uZ!־q[Je4]DH0-}_&Ʋm}Dc\VɼJ/Tc{CJCfl!SZD5,ŗV[p &UI~Bv|,ׯ"r. |AHUƍ0v˱~k"o5U_M|y%Py Oj/?A]:r=l!>]<}1oB(sQ,LS*KMg:ZEz4_%vNj2+ĩg4*v͛U +nBVEQ1qIWsȼl& y[PL^ӼK99j,ӫ=/\ qg F*}gmP~Wdp6}86.l8b{x *I](7^ +[{{w V=d""J? kV5 %^jtu}tї,# Rƌ;39)<^ɝ⪬5@r.FlA 0t,i/բwg&ä5ӟ4b'sI Z]K2YY yn@u7p*o^*w:o^7U©:͜?FVHgiLL ˣ&f.0Stp;3,/ nuңf^ͳ E3ǨSq7cӐ= kzOC_5Y#EX 8+?,,tUTyL8$Db qQcl"´^ȶ(@ QI%vwGu Lr*A?݆0EQǹCp#3MA+7LR;Owk7(tnrPPu#mRݔ[-aQä`buW`TZVi B5Nzs^\ UU5V=ݭǾ)Pt Z@szH8y[?&'N,oC]x|JTA/C1{Ly z*F{tDyQpnsj" By.?o#=_Zco@e8mk#71& ԩ o>e+7_Y HBU5ݖz9H8oR8qX3 '"ŀ꺆wV=ظKncD#4 j`xHtƛcq9`=Ց`[+ȹX?AnKGrkއ1vźCIs_':M$k]=.8VcOf-Fiq~//$8)NY_^z`xp,(Ů(6\hi!pB7k5vy}CS m8w}IWK|F^}%?|rK9_z>ws Rx50Vj +><}@ɱUl +&?8 cI"HnO<˹]Dgfkkjt@ +zjCEǤ S$̇}CGs\8gئі]#(+ ڈ)E;vJSZ`#>@YR@hd]6yKSk'Zp2dHyo=KZ,ZZ +AY(VJpzB<,7T zpmpwbxcQ3mfh8OW +_qjhjOGHd6[M xR}*tnP?A} nm[ %]67/6KTזG4DKl%gJ:>QyquQj`Nۙ-B{"OgbצBF)SIdcs nM/+/$6}_;dYCw̬Qx2l-ߊt鵡 TM/䁪w/k%k1~Pwt0R`+ )Q-crA"8#!q9ƅPWF&Oj|Rp"E֛<0s-\.EMs yh"31&$;h- Uorܘ\@_ε?zэ4qY=ðeŏ,&\7lV7~CxF 湅ZPl䰃Y:O'.12+X:́[:!o +DtcQFW䐘^)*@M [D5egDxujR>2֝4X;!tK6mò59ɀ v]VQc^>4[Mq:68߫PHxT:8y3!WbO,ͩMO9T׻YBq7 xz9>N[tvԱVզj/`jׄSad'j DyDXT֠bZ,Fr(FnBs +m<Y1]ޭAHz<zJ)/ܼ6 d26saG-ܘ!vt3ՓZAw7V.򀇙27<85ڕ 3ȩFƁCBaƠ 4Y^WK8V <9E!vH\&uтnd "ʓ Cc %|pO"s,#)sZUUAٲn ̶ DU.xFJM9 b83@6gx[5~{JX{(Lk# MCl1C9˞mql|t*;V= +GY;1IZߚ Rbȍ4G0g;fC%uxc@A!|DJ]s@!ʰ7;/29 ۦ獸w,Uu!atI  Nэ"i<#Y +wIyK'rl&G$̶aj5Q61{'pR-;ܴc$1 /ZS?E˻&Eŀv0j;J^+KhrXU;}'NEY+51)S6g +id ?CYԫ}7AI5[ذ7<2+%2mR'J @ Yy3{צj6\6|  5yA2hծPSbcj:^PLBTmTF2uFa40j-g`FiCpPtJ&oL3U~j-T-lȇ2&@ Y;>Ua2_Fptp<6nuSqM>'6kKa VP3ô2ǣ g^#&DڬtЦmsUKR63PƬE di(Il@>rZU9cNB>Z:$)*PQzz\uشxhMB1O{ѕ 5e4ͩ<kBjWSʑE[NZ?0(4v:aie倛eSak0c]= \n tEoVwfeۗ:GIc8QQ[Yuq vތ&L5lx϶1k8U:ǚ+L7a5ԷF>'F2֯GT!d4n@(q4'xK|Hgc@ $ &p@ܥr(@M r#MዴEFLJ:hq:6[s퀘gLJ@vKtGw[+J<0{;N8Ɨ"3{q+,ogԾ7 rV-{jI.0EA3Z կx1Ԩ2}@6Afʸu1n_$ĆF"vvs X:č 9 q q1W4uTf< '^n^;})a :9ae:0gzfk@݆}[bgNu;!2mqG&+ H0O@&b~fm0B=$ k0b6;tC^i8bBCä e4+O  l2b#atΠc#fžPaX ͑y00#&=<h4it~ vIb$n-쪙;ਖ਼n 5쐙&2:e;~vK90T Lt EGƉ8X'Gnl4u2Gy MoړYD, Lif<2?Sb +_MmGcE\\G[`Eab.PO Y> pq04,󴰆& J>yhLVF(TˇV/Ϝ {yW̪]fM ~n+H :4a#M1zCtՈL«霙{Q?Q )HhT>7%@ U`S#4Mӑ0m P΀nJj%j 4n[㘓L9g"61l=1 + ñ8O>O-vy-Hy4^gh|A;NߦhKhGS7-`-7S-ȫ8>|MÿL@dFgHQƽ*x:M#.릹vH "&dt.|2Өy:2 + TppO\WB*Lu.~69s>wA۱kF ;wo2ݜ3E)l L:5X +ӇG߼򜶑 ZKUdd[f ˻,!Eg?"دtEM.ӧ`#7R4= +Z-iK挨"xlɉiL"<]D, +|B*!(CdZbO/Q碄4VE~/ WH+ fvy2@e׏7T4Z7I,oC , _& }e RX+d hDHEd }Ô29xPPOM.27`ܮlruWSUiv*5oHd؁6Ό:řP⭤NnGJU46Fkk|ra d,m=XcIUt3i.&+j~HpVLiWsFUB^~&Kɍ>-%\V0S^EHbIzcŊLڛЈO4C w1&פ|uUdC_PH\LS:,MV6% +4JR;',N5۔s.#Ko`td`=0cYHl-nH3? g< NnO?Lr;mg<$ -7?EDEȌĭ-}rGL [Qz'TCang* +voE̋C M;e+*G7w œ ]7N)VԿՐ8uM<1e+cNt1:11T#uVy?GqL^ԷBx[yk yj6X (gKI3W ~բ 7@6w*l(4*MГ] #+>3I*Q$̎d +"9?e!m`ZCwkGᓻXv\4 e=̂>2" ,() (̰*Ca^FI4&m7SsxW3mW| KmCN2SVΏ|uܧٴ€Xf06X&vhE2GFXo,#\"lClwߪ޿&ɑ58򥛲M|z_/V~a j oEI]M;";1\4 w_-q}G=˷|z?|s^5{'#{U7ra{(|{WӇ㯗oA>eno?h7S:'GNíO?,>\~; #9ZCs-+vj_>$O/H`~3y:5|dLTQf`E2s;| ֖́@ ,#aѫ ö>D-k?lM9`{EMNQu;E|wV[Mam8b@+8Equr;Ho=\C}xEzM|vŇ>U?~՗O?\UL ^]VI> +Ge(y/.QUˋ$s!Esߕİp3?nlzb2t +endstream +endobj +316 0 obj +<< +/Type /Font +/Widths [600 0 0 0 0 0 0 0 0 0 0 600 0 0 0 0 +0 0 600 600 0 0 0 0 0 0 0 0 0 600 0 0 +0 600 600 600 600 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 600 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 600] +/Subtype /TrueType +/BaseFont /CourierNewPSMT +/Encoding /WinAnsiEncoding +/LastChar 120 +/FirstChar 32 +/FontDescriptor 419 0 R +>> +endobj +317 0 obj +<< +/Filter [/FlateDecode] +/Length 1063 +>> +stream +xڕV[o6~ׯ#A o;ea@n[vTXr*+H_sH]mg@@|#o 0mk")k"هiagI k$8&:Whm +gJ +zfP0ڣ˅WAW h+ +tr‰BjׇEޡOkr'!3SJXr$kt.vhhFkA0^ KQ4r^ص Y'[DAo969s/T@*a qؚ>;n5Wj!L2!a6xV& *Xo(97`^iLy?1\|ӳ JZ>`rȩ!)iΙBې$s(xݼ4lWQӞ=w}}btK1)7ՉKė'$ݥX Tc0F廱0Ca6ǒRFYkOPʜvCC. 4P!/@@ AE6!n7o>VugFuw +c^jk;Q?a\cP(fA +J%f ")>aӥT-*=WwGj#M.E2|L5)m*)+);Î~"7ݩa +2a~!_NGB+ M\4ۙS#h'd1=* wLN/a^gbFxƦM⇠z9"1RqM9mU +XB\!e!ٚ0o+้s5^ z[%-Q[b #t:0q}aq;fPQy#SǗT.BbU= %yG2+b +C2T6w/.9kpleQăX`B=Xl`EYv {"4iC3µ*Z|6|esE]uNj6':v:"$u.ƋOx#BoMW@½M+{iE~ @D"7P?XTA +endstream +endobj +318 0 obj +<< +/Filter [/FlateDecode] +/Length 2314 +>> +stream +xڭYYF~ׯL@JcB!Lv6_:[-a *ڟ;ǿ7G _^:Tƣ:/eço5 09:NqnDt;|}7}̹ц9y\Asud LcPӿ;n'XC4eR8V<&GÂHL16]xjVÜbCCvsL+CXZgpDγ 85W7_>uF8`g b@U>قo-wX!G8U|nNd!Xgf.m`ՙt +8##=֓!\-E7Ut[OxV;G[$ek_Z7յV|' 9qy.yNŢ53%9 +3@ԚB199 462 ("A'~ P(,F=)A6߁JXdX:jqSfo'&Cʶ̥ìd̯sބ*Gsv|OK,^')?K̾R@#OTwLm6Pdƀаq2gpv3l߀m'S߂ez*}@CGz_ak>"AR\G6ϱ b4s#RԶue!>Q2 EL+L*oyJD&o%ΡĄfH9RSL{BXk>^'%D (. F4ڭq@A7Rz{Sa]0GrjW yPoUCsõ7dƜu/ 8a7 Hx eBi!,A90rrdɘ)6+ZU虇ddRk):C++dg6 +s1a +~<< ;RzOX*HW{3fo&k ~-.>Z!<s~~;;0|Zaxǐ\P!@NToJS+H\E\9)$ȖZDj|$?FJlPlSqB`a\i'~DSbB{1,2UUF}b\N; {PM9Jต'wkNn2 X>@ єdm2lR> +stream +x}Uߏ6 ~_Gudzp[an1 8!M\ڹ:.n_?R0(#|Pﶧ +TKm匲1 +gr>&*o/;_g'Jk._p {2AHȡWQb]NX|49 +`+9b)owl+NgE h}TگЭFe_Ɠ`bInY02FsZJq_UVH[i _QD|} yzG܉)͸ͫ'qJѭ07Fq-(h^VQG;{}́wnL$NkC%J: y}qh ŠGfhhZeϤ֮z8^nMsOS^$rn oA~,|3SAW+)XX-jfh6T$6 ]8ûCjW 7̘2/icbSx:v]^9R)O<C-䃳z~LS)f&6Y^8(r,lL4&v}>V }ZRf銎[lrJau \|B37p̭qa~9Ow@xjޕY_;Cm<^ 58׫/3OUUDcp3,$Μ#-m5< 6a)jtA0Ğ2pf/Wy({0eKEt"ߩ{_U +o%!Kӛ//c +endstream +endobj +320 0 obj +<< +/Filter [/FlateDecode] +/Length 10940 +>> +stream +xڽ}[tQI&ϗ +/뾿K0<S_e/D@EUJ9i!:jDVkwydiJmTez4=PK RKYK^drZօ'~/})>D +Rsȁf$s:_fF(\ Rd|;{čoh,nLnL&(?ڔfa +!b`ikt.SбuS@[҄, 5ypt}#ςJ&7㭲)1ol47F x#"߅TVqUhZܱ+UcO3w_J#>tK7~2n\:0mj㥎rQZivIǀgϲ4׷U-1cWAָ7XT% +)X~5/~O՟ʥwW=3!{%8|@OwƋlZq噯uY{:d\r0u?c;&βqU܉gxtu={N3FTg3 )E\JŜr#O/Sp p4 v2ޮQQiJ<[rUCd$Wƒ8njPKҊ]Y +\}7GTfY9F׻HέIO1x7YuA'BrkŽS[u(;LUf_0@5&k+:y1uED-(bla=ד(659:[TI] +x눻x.풄 wddLm"qli$4GwELtGX%Sd.G.TQG㰈{3 ?|W3ɴ"KhB*( Ss?Y%uA %F\=0KWz$娨DEQXR uTe/Gwh<|G/e:`ls+/d2FN-jO;JU:&5=)5=\=%ǀJ=V 󋧄)RdIP)*\WEmB6}|(OE/>jtAHx2O+;˗]]YV{ t@92a.`FsXmcn |%F٪l;|ʮc'lIQ+yݣ&b^y(Ix{_p%VQ Ϲ9}h5&G;.&Dz'pnɁ7Һ5^w(/h,X&Ǥ 8S~`SUj٫4WKh4؋d/=g qө#~ȮXwDPJ+,tEX)qu!ZAߦ:Z/J+{qu4P *;Y?JRR'^#~ \_ycD(=p rօlSR jG^je1uQՌhLBeMLv:1.S +=Jbl^!1Ti?nZUUmʄQi8ɧYXy~X 7c*!> +kzɖq܂R`FBј:$Tt$7Q (,cM;rwp .-*+ؑ|C1vXԷh"~cl$XXo6Fo"(Gy58F|ҁpf Iqx 2g1@+Pʀ%,#%\ -qDtEtʌwTc>ɔg|{P\_8aD)7!q]=&bѵ*CWߨE16m$@9f\DJZiRX%e  6z} @ůf>luXlNoD'rX!v6"<39&2a[RF:0@sR/2lI 1Bx"2ˮcrvMEaq@J dcB'=͚j.Y3I#Zuڷ]`AN2=HF4wn+Pv7%2}{g] q()7!O};Q3h $Ĺ#@2I WEв۷tAQY1@##!KB ̹>Q^ieKX.D> gŮF $OKS|267\ fn"DD3AJ>&eU!V0-lMNUVej;;\gWOܘ%TZb/yZ|b- IV'Ñ*hB$O[ۂhU2I>+c5(묆N x'q?̢,AsVvPI F}*ќ$9r S+0]KM|0k47@R!`T=|m] KΈ<\HDmͩpll֖:hZ{5U$Ri%VC{BzQDŠU"m²I%&u2Z׶t PӢ,՚[r.&Ys&ckꀕ~mjN`ʨokkCYd1DAf}aw%%!~wG3YzP"%x#:m5nh.O"F|xz+M\GW@Z:ol2 #V7CSNpWia#lЃpHv&mlQYfdLө *ӑe*NpٚOULgdxU_OסrQ9r uqSky~"_Z&d`rhّ} ۋSK$>eG-ANMMlm-@?H}l @6]9J!'E?Ԗs]ȼ4'a1.HڻoʊOk@ykI]X >ȁzu{pj#6Z]!0|%44?D-.!PM)ω]gV}kAy1CuE׵q1| ys Q99iayߞm" o7C49ΟE#s=|m?D=<6ocD5/{h;p۔6sT=#҂-t]kSiCqua3tF`scp ;xއhn½hLJ v΃]oM[o-*?aIbw )OѰF|bTkv/&߇s7YNҫ{:S Aivx&6o͇G3[bpujYs5s޸:9ى6;of q -Z4v6T!NcJ*K'$ݹ:O"{G6¢upu24Ƶs!fdW A.8Nki34׌J G9V8)Q!BCZz0nAtj- o[W)m6B;mִ">9)yсKu9$;i'|Ȏ[qy9`?JY:P ~l%ur"Zige^BX˨-r&2-%㽄0{s!RhRLFlل +hO"HN 2Iy(' +O! @_I_1oAMʦ'//_+kC.=]]R>EilQWaw'&9~[6VAJPzm|2`ߌ]Rqʴ*p1mkc<䭛D&6x6L/r텂?n:M!$s,(:)߶)iF a#ROؓ!aVS"O\+MOX3$i&Clu٘HHO#PRGWWI#o%ſ ![\oAͶ?^┞Lu(zϨ\/iEM(yQc"ɼ&1E.6冋ݍAXܧ6x@XB]uK)g{f/r 8~Xڹ@{+?hk|96F$N<⥜' +'ޢ enQDoP,-mNDm%[u_׉ |96X~~/)/_D-Mq2{}㗿=O V:|O kHVWן~nI@ +XvlQoO\&%33B;\DP?;[n;u#BB#rƣ<5=@Uc+OIy M`G/Fve(ᒂz+Aʘ D% {ǀf#'i&wJ:O.b+SAc|N mǎQvTFY`XG6T43^dN\x1_ai/.[d9 n)>vTPp3G`V 9CĶ(s`Wç-v?A5)QpܻdG7@9y蛝ǃ_e7ou65Ng&Qzd!pͺkR˨n,2zG^6x#䲟*2qa ;]{pD!=sÀyA^R9A6g} "- M zc2N^^A]7^+ť3q~2sxUq^XVZBֺ z_K_x?}W/I4\5T[ s ?}VE/Uo_~8(|;w2_Xm6E75-_pƲ['޿z +7p|f'hiPR@:4XLv% ^}ЭrWirN\mc}a+^]=&ZD6Fp .K g4eLW$Lmł8(>0#bAiV/x"HIӓQFQn9G ׏H>bNO>bZ(e>" 1oP }ۜen7e(LƠ .<S# 48%ʙT;RȀ DI;y 0PأOm#`.Jޅw !s4n_XQbMA=g1R&'`!8P|tzL~o=Ʈ@cnWD!$NS8Iz:GA^'9I p 3^хR%(}D;%vmP# +: g *'t+-%Wӆ)dl0]$|i{4g\|bHv8A I?7!n3$ީMCs/g2YJ"={IRHl֞xh "W3V~W c?\.Ef+Nv^Nz<|Ma &w$ObD PP=jB)ңM3ʚ2|OmE/%N|L8;誋6klxbpDLqӵVy"诇zD _V͋yH[S.Gg'sNe#S@&3=Xf ] +`>uK[賓*>Jau6 0B99`sn22Z,K2r9٩bHQo +'S!|#Ixb +j,YjWNV͑\-.t n],ARo|+HAĺś^؍pm`U_Hb2zW5r8:iWnw T^75*CŜx ?yhutz [-Po'|SAb*(i ZP"a6A!qBQtލO$`iC m;(Tm0vX.uY rdlk*aɂz8ScQ&v,R05]4U4I'[}Y+#_Qڴ+F<s*E $ȉEJ)Cr+QeN)In J?:G %F_oz2w?;-B4`-? BBRQ8Y'fz)*}ZRIp_5ѴسꕐV f_P=I:p|Wձxzge\[=A; Ul|Oh9سހ$܏юu`YwFIJC ־uQ||wx6QH} x}SeG89XGW˃p {iXB Bt"K_56VF][hFKg,-ó U#PLЙs)A{zv쓃_VBH}Ir~$TՒZ鲄*bO pR R3SbVyz`qqj0> n.1X|^0ilNKEy8D&xŇ7 V>&_({n(w/p)f +Y Ytai=;ä̻DE1вjovbhFꭍR6InA?3^ O3:%>IX|p) htGa&⹴B>=U3[tpWBP͙t2"' - x@KJ o0_̊;~ . $?}0rI“ vkyX*ZLiMLʅ98!3u"/y (NZvMT%&,^>醨8^5[ .t[^ݰJ:,-}ܴ0lFDkzfw|}XW$ +~VC7$vі> G4ݼ\A3&ʓGLq?)?*МZ몘ly + `R{Vlɼy<o:ud-u*fc곔}X5APC(M?MINʏnk}tHKZƯl߄`,& ?TRj>\ea]?NvK/@*K&W>ao^sI)Wׯ~rV|>'2y5SlwC,-r^.STӛ@Zaal*(ӟP3MS&i8I9iu} +C%"|dB穾. :lW:՝>${ie%!x<9>Ty4gp"]8*-o'Tye3eHcU׾oHퟶ,t(2\MڝG1N:!RvWfȗ,tvvh3V|Au:'fb2|dbERf< :~2Ojt"x>GiuنufE LPEne JZc>">Uz2E(ֺ y:A-}(1sD 8u%X/L^@'SbԢ:_BEWZRv=;z + +YzuػToaռAR4ѢokYJU!ۃϗ_C}V +l?<Frm\6v}~gp0iWDN\nGΟJ{0M@%ȞNIR0Mg?&AJ=?Ѵ!(;2[yN!,e[?<)ى{EȚTSbc63VxHDGVm g}.Ŗ6_\Acc̞P4E9$%F/G]+%wVeV +ics6 +9H/"Rrx*3fV 'tuɘ +endstream +endobj +321 0 obj +<< +/Filter [/FlateDecode] +/Length 8531 +>> +stream +x]ے]q}83n$JJUrJ5:F!زUĠ{n` -N*`4}DžPǟUؗeU^?i +TR>?\eOZ/4}+>O}>h>h]Jq~s+3~è;hgbK:*1~yǸRPfҪ"1FԶ, qzzߨaZy]7dZK?0Qe 8.}JEXWXveUFA7&êR3*86Y9yiOn,*,J0~ |z-3/qQT,}\׿~R_yRWM*q5^:rD)wM æE)~z?XjMUses CH +^WZI^wT?hj#. }X *e1UHܐ*M.9C6ViZژ,/:lË&.,U j+ 6q/Z|A2[&1 EJ~CڕuօOKQoQ曫5>vX.BvPv?UO{:ZW;ŤHS]VyP&^? 0!wJGyfļ88gVv,$CC+bCõYAg"? %yu:DFF-LiɹTA``˪]{GUNo1oPZ(wk"\te'9Ulk/쇫hŸq<ˬVb2W9-UB紟/+m6$B\\lͥ9˹fE8Ga}x}Ah\}X ndA_Qjr_\9ÒvS7H]z!gX몫 u+&!:?Z*:7 }.u3V@41^Z-wIڮm'cO=4YvC٧њh)/6 +3@rE٦b@~:lyiҭO마zA*d:HbU c#yWʂ c0'F20;-TKP4bSR% 3ć LJd'AbZXe.9_ z>Ҁ4MaqHK)ʰF(D`#L[)"W@fZ6Ǻ2,3 CkR2%hyns;ϊA.K%ꝅ T(ȝlR+S4ݤɒ2,AHfXsFT2]™Ny )٣Ȁz_aIfͷ439@ܼ;MA8fni L;i@F'jad 4cIf Ctvn&bB>/Gb/61]I,&w5mBr6A߅\t S +:A_k%-IlZ$cn=7QwE]lL˻XW!4ֈo N=C2oy1;ܙ[zK$6`}1=?}o&& э)xN-! +N욕7q}D;o+Va`ngl3ƁL4ʀ^g$P@L=J=4!3÷rږα+U˲“>PfZD@t+u!X, U{ "Q^d B* BOvfOB|Bzfƍja 4䐃ÒԲ'{f:݃@ȱGK܊$sNnb[ y]X?g{N[iDѩi +Zn)-wa;RrA9&!NSuMMihmLMUP3d4PʪZR.ijД;YUdf%BR hdLzAd1J6۵ =&w敼 jE  u1eMDFS9u +'TO+i&m(w1w1V3 4ԝ!m_~:IQPdN+fB B) <'j%sXT{B`5+È! +gXTv32MdynDݜ?=xcIݳ% Xz[K! +x<`ZPZ-|W׎c)ouąQGa 4 +`=}&Td8 Hx0J&N*ZHeQBX-ӓE^O2CY}$Bh.Mkz-q_E[ed<.LzM!Z@IHw]5K}̴!fs!/uLv+mPmQ;hn{mAe11-N̂`)cL.ݞ(nhJ$Np2h +7Ț`Rn]Z0~+h@L O9pR;@ Kn.,+Ў PG %&4iTkxDM2Uy݊EuT:&dyx'kIz p~|{/_^Uݫ4wrGQ Ϯ>73 +zs7Uw]~|]O7U}\?ꇅՏ +ok?QX$]2ӹҷY*spcvA}z{at݇׏Oocx߽{Dؚ[Gzd&KSۍP~>nr~&yXyMOoRM^_&sYo%ǃ@~8<=ݽ{됓M +xwOw^}+#VI]4t_ݡ=ovoweet?ݾn_~ꮂU^?P>oj]?Tkz *@]1ѕAIqn L1$q;{]ǛT߿{z}W~8ؿՙ>}:::e{FA{y|.[O1L"W~ZGtu]&_?I>[!*ߣU $FӼ>F3'W[UIT׻*wP.h:4Ouu4X$ \y\:VϖȇL-ic&p\p0BWFݻ;|Ty|N,>O'ow*=wwEZ~SY(޸6C`eͯԈs{SD֎3Tzw\ #_ndO+ |_~SG뻩7Mg^{lk& }n-ϴZU.UzgTQ4ū%Mwoߥ׷T-y4fE}^2QGy Qu)*a5_ݑRuowxh/j9w6 ޢ8KwKVĊ ypy<\iӸ9Kh ]\rf} FA2m`B 2u?Q(#glQ$Q6>.l'K ɮ~~wSQ"iX + Oa 3؉Hɾ_.G FE1CXX OW !P\\YI'~S"s6_4C:1+YᎿSc}9FO]]Ȏ A-m-~Bfۑ +nø=ۛ R da3$)mm읅5=Z%nf?~+gKi`cֽζVJXAuC ޽BRfP3vHٍޏ@/w1:bYҎPAc6y]:/gckȾM*ө׺ #{X#V-J- +?hМ~9g AvlN5 +*ؓ+yڧ0?׷-+r/[2<4k2DӔ»-NHIz B[/iϴXS>,噧Sow1;㍎1 +c]T\)IQ4sơym,<癌3)cP;򰙙IMLzS6fikh* +6sRΗy1v!7E^_ {i]30;3 f! . N~~V4 ^7@/_}| N]3m +97/{kgW2$xh0`n,>hذJ C<5v1J,D&I +TC{W&,>l.tF1ڱd@(g3.nh_Fi,痩C#58㠇-/-\#0ƒub\(R;:\Ğ)$"{ҏmHn.uM0w:}6kC S@N|Ѷ⌒?("Bs-`NP}-P nHBܸY ڎ fw2T>^hǵCfΑH6ͳ6j$Pme BPH, ^,TMSns'xCa\C\Ǟuڱ;Ew?cFXdғBve7.LL}^2y0MR2`2zq oRq=Cu㙤ddȔt9#.&$;bZFr#ӹt$^O.Aqe_/> H'^"˰џ OyrUTE{wOo'}tVs2'1+tnv* 8d>-pP +Dkk6Eyst]T{IjgF[ZiȋCI.;m@TwǨp>y ([r/Jϴ[=a/i5_l<"53HR۶&G0M;᝜A{G@ɡovzTwv '>;hWI{VH[pP;tQȤL"*2y?_E52~|3IrLF9ٿ +Hhq {Sq=C8-f_Br⚔nod;߼ӞzWlRoZ;z3J>3 xm_721`>qblRh3,m[愖U1S Ʒ?ynCEp$@ 9(>O`#I1)\=:w_^s?ë<=\[ƹs{m~s0ib.:H:Ds]N{hӰHFOt rO Eļ`3u܃%Kh2:I jX) Fqdྔ^72l՟@ 8aw~B&FIi<1_; Ea?2F[fΛbwK^^[+bөC,(}_!&|oA~ vw#*cBۺAVܼ= &g3Ud=͚?e_\.šf!qU'=NyͷX )sk pA{q|Emٿc! 'j} +@s0Ͼ +endstream +endobj +322 0 obj +<< +/Filter [/FlateDecode] +/Length 12456 +>> +stream +x}[$7X5@FH +Eľy1> .dx<0z xOUv,tvi!w +7,&H1UX&/HEL\W +-,] +ަ?>Vk{oD{NRDnfPL0QdkL mB^LJSUP+0~O5 ׎v>ͅa7`BJ㧕l( +Zby4MBG I[Қҿ0`p߃AG;h$% –XR*݈ٲq (^GUƗD|FcZYV-&(eBQb\=Յj,=[ٟGVL7 +F3$`tU3fdW`z,ڦna}%J-y ÊW/"7}< +x@2 +;Y5!?!++|^G$Tc8~^:AW/@ \uhrYXTtY ;8#=v4tu6Mrkh҃b7:̬ >J(R']8H-q" ԆE vv8 5eQ{qR ROlyR )%\~ < 6â@h 2`Im0ُ,DݛY\ \Djuj;sY G5!3#vdk| A-hsNznMNy)'4бأmWs"sa۹}nLC;FeDqiVhŶF{P.KdzlLh=!r+< +͘:/HPGe/z1G>B}Y 5"|W*|-Dfjk1X.\7aBwqXfN;0GE[3:? bYY]/o. SPd,fO?:1r\SLѴ0v +-lW_|SVS`Zͱ!d0CB62jaiaJCX4VAm[9TlX@ P1HM#93|N0i|DTgwdT9,2Hdv"'y ] OaN' n[t~ͽamJd%aq,n%3&4RvmQ%&AjT{v+114b0~tjNlIET`Q vOquPg\9%3IvƉ nf4zo\963n<88r;oD>ndOz|qW-;W=u)p|$ޘz3zKy9Y$U : #$ؒ*l8Ϝ~$."RM ʠ{BS. e2Vy1S@S h*5L'wn]Giiܰ!L3&t qY:ԽwΦkg10; Cee<WAof&t8])9V X8Uotwɳ-w +6 /r@ +Y0-"u["NG`[NtmH&/K*9ʆgzPMuiTRk3Sf` +(j4;#wFqS&$<6&.,TC[Dc%t.lȸQ^aEPMgaD!)!֖~q`2X,@!gAvyH:#S]a^ (qI,r;hQQ`(HOnwX$$"IrzU_4H~OUsSf gD4^3 Շ&:ד!9xۄԂޓ $9SY:HZa +$ 0Lmt/HM֗W{<ʢPLC||M&d@H pK@axòʩ&t4M8U2dp\(磲CKc7Zכ}efF$1ںA@bCwk mc4KQc>QzDu oLeic;^0:{`E1s5d1USJcs,=|eaܥQWJ c;g9ӏwK|y~凿-n*Hnl%/n8P[ݾ5P*0 PTm)ԛtNS:۷GWj7)A#Tu+F%!cM 9愵~S??Қ"Cܛ1 9՘Qj \>8q_O=7]R%?v_Y` %irY)`J#1=X&/h@Vf(#;ٻnq6F"(8Nh)'%.n7"o"ߨMCaړi{b qց\4I$!o]x1$6I:@w] xPF,P`b3Њ"" &<}k$DSs;z c8_;!432|SF~t=t|M,P;l'|kb`z5m+aڀ:L6Z`A:1=6xu5,s,V3ߞ5k V2N}9UԢWo;Աsghԟ=qEO5zk=jQy0J×f!j7=`3 [a+x&}8{gaBI. `s8%̳gP,xI(Ɣ8GU;gv7;46<ΠP5X"ytMBYG ^Xw +9~UrY ( X8+`d@d#|7# {(NΣ @{z7Ş.0NO)V_TܸE#D ŕqJxTEF 栔$\B6jQQ>oCܺuq0 3p$णKaM,̻*'ݢu#%亊GVIS F rOst3,ETGEᰱp2THOoϠ3]D=sTB[aIGNoǁDp7/;f*ήͪx2Dؓ˃ѿj^tp!A*>kbMaP2 MӳQy/|@ h0=UͮU`.pH-x:lY'A֌jւcb[:xkJZ8} h{guș9E mkF0WNђeK$gG*lΣ`bT21NmU:5a+*&T& 1;~$Cf'1dh!a/K[ u@1(:Ԣ\ۿ5]^NnW2hu'#P>2)ӛQA.F\&3C`I 0|kv@6Uxq* +g?oh.=٦);V/xO˗C_T'y`_3[~7n M VOxĈibjOӆqԣrx]wӍ}fhLS_'I7>ZWU}mMhkC-ϖOkgd=G'.Ϛ4q  +a';{%?MP4$>bONCѰquq'92uD\I,L.ǜL_C9:N(!~$MydȽg\l= cWy&D)hVt:ݎp>DXr]e!tZAB !-(/7ORΏ"p@iuq˸᨟zl|WE7q,Jϒ{;:4xjz ` 06xs;Y@E 6Asz5 =@/"x0[OòhbK|;fǁ>9&{IrJ`j|9J>$ӹc0*mHZi$(YZftRU3q2Qvk[D&V렖\A)Jb7K.Zc#b:K +B;=B-y6`PTdl|TQ`5aD/PÓaTm<[aDS֚6A?i p`]+rr,3hvrޱ2&"=n"͌CKx$nZ (@^Y0<_4'CCeFeLZ)IIxLb=z#j@WSj{4 w2Ry,&)(n񈉨O"Fa2li䒁T 9Ib.cp%YiCۅU-=in<; cp3 ^@P +yDLϼrAva؅ +gh>Gv08^"*kԁ6Ff)$yVw"b) >Ǡo؂`|MAQø0<9pd˅r W M}1i07A{'%\ %Q^lMa$:M䮔Xtdn60Bi| ?n󞢇.=z\wg L*] Ƽ>01M-Q=-1#ICZДI RdA퀙Ѽ5S$԰KW gZ˭tt1LI~Uw!|bR*, +k=p$Q \+I /Њ@8|d 66X<3g5xٴ K>km&m 4>.C`kt iwS.Rj8IհԠڅa|= Rܳ1!?T8ø)o!\Z\H|.ls):IXq$uvmBۧVH6u=-}o-٘3%m4Յ6&\jJ؂0PǏ//  ':(j:)w%"eASw5&(tFHrĤf7R!P:ިi~ٿB5c!I9`A,UX*=˞[89!V}0gWyCx/~E.9)aqHJM7,f#ye f$QOf 5 Ec:VmTTWrEw2U#?MQ!1"Z nA|BS uƜdKJк=4-tH:cLK2^6MRaVJ={wRGQ\srg䱑%M8-?B*vc$IUt(v"Srx^=^9FɏPfw\7<FuT|lF(⡲ꨳG6Sh9Ned0en"ʆx=ǭNƁoy`X$]/8$ciRo{1,P;]0B v>| *4Ns0*^WН(^G<9^.s:e27hb c@<#ya*poYD0@>KU"7kXS찝FpK~{d䣼RCm[ѹA8/D]8(E[7W {DV]&aEd8 qY/bg7~+xw fx@e'}bh/;5vQF7e +G)dyECGBJG#[mH'c#?,xRF:Z˹+R,gE޵ +4zռ /iTh< ߞa(1H r_Fz5ѵ4baqiIz.m i(/G]+ķpԶDfSyyQeL9<5Z^Eq/ +_FÔ#ק|M9Z!Xt̃.quaя q F7$},jb{{c0qz~9@ȃ{%9D8Dǣz~?"R2E `cG]xP5.s٢>kE4HZG[ C:@,ӤcE<睊MrhxDޥ6*8ش03z$Ϥi.n7"GhLڐr1}_tݏ,ĕ%$+ 6џ^PH=-Uow%fy +~5u @+a=׬則ȩ7Ͳi2 <lf {J̶8s5Ϋij_#HZ<…м>8?,ZR=hS%,Z}x,%{ ;ȓ}3;'c0^T8oR͈ۆb/HB쨍vX0Jwi4ȉf#H_x/D^FSuϘ) ;wwS;@^ۋk.vd𮋼WƔId^&Mf#|CSշ lk؇־=T9+U> v'֥!m E.1Z9&^]WxuxVU^-:[R5N,iz!b<y58DŽU7be8b\/5"(3W1Wq]4Trheȍۇ0]>l5of~emKd|?/χ/8ti˿c}ӧ?})|_|i?u|w}?6FzD:o$#dLJû?~I>:1\~0ǎ0 n[||~@M`~yw]~/)wXǭ4#ٗ`I?}zaCIg$b/ƞ;O$oy:8'._[񔄇Ԧ:)ۑ +3DnZeqٙNWN\] qtN76\@ +\Uo?24/EQ&_.6)ً(zXJSk(R0E?58L f@ܔ +o#o_3tÌ+ÿLysɤ+>ţP3 2$o#Y8}4x\1|)kqx(z?\LyleIw_D[[<Ĕ|̻643f:rwSaZo2|uGٶu$u}T7ݦiæ /?}<6nM{|]>[?} +(q͗.˯>5)/}/>}ukڊ6LRϏ->rỏ۷_.M]1ݠpO=Iب:GṲ/ϟ^)S*ko}/o7M1O!:Wv-&:_.4gkcƗΗHzkRxsvƭhӜ2Fe f"AtY;_ɔo-RiGęeђA 2"VW/ NMO.hYiYKj Ut205e~} i,|8R~dv.tkkNLdcYYLÄ),&}JS&ٛiKvm0tT^QBjDJP/-z3/0Z `)b|ز 9AA+0rQл,5 טp9ʯu7g0YqInj)'l䘑Ȓ{ب.1Q: ,emBLbşY/ѪI[tW _0],ry ITf`s{ybud4^EVq"ˑmWU٥躡8UW5]11F#7(ݳkV՝r걱fP']V,2حhj'/_LyRTPB3gk@dzdݘ r?iӈ-j[S5ux[ 6z*-VY> +stream +xڭV[o6~ׯ#A4I:d +%FW ؃jӎN-PKP4l\9SL?}vbode;Es^hI ]fFy_sJ'dYT^T3/D8U 8{f-C g&Aԗih@+ cuҐ@ IN+UQWt7g`t'jY9Yo + Ib+}Z c & !HjBA-F%U\i̔G\i͔̕ d$~^f2r Yi||-,sF +o.[)56 ]E./ǃሻw _?8kDJё(+u e,{]~k;so+* B+;Fg|y1la;'O]O +vteyș+>dS*2LRQ}}sa7]F`ZNzBϑo\t.C΁ҍԀ@lMIwmGuWDc2_@)GUk +u 54>AWzoqHd|1X4$`o黼yǙKn+B߷i(B:}{l麵. +C(>68 3FQJUnSЩ, ii{ mlՆrw5nz׬#vIW&b=>/?]m 1Ѽ0B1Q|* /{F)fw6bviYhQ i>6TYkp< +Ϫiˤ%}_?<- +1gon)Ǜk#+OVo"::Jk!\!ٯYŇ :UfS׋o`8X4Q `%"16h1,?dQ0n +.Űm/|Doyu*efR^[fh~Y2/ +endstream +endobj +324 0 obj +<< +/Filter [/FlateDecode] +/Length 3381 +>> +stream +xڭZK cO5O`oM zFׇGJ۱z*$Cɝ7+?5{}?~|nkI\]Ck<_\OKYί>Npy깮.]XymiM#Zhu ++23I̵8&tr['qIC[kG.xaOR&naR_ b8}Ki!>0ڭ%ɳkONo~CLOx+aXH#~-4%)EޙwSBvəpÁҀpGEҖti +~|Zd='saFdO'ʰ: !2+6Y¦I lgH{A+Խг# <'qC_2tw^؍f'd_9Y$Y6Oȟ`vq[s5#<4:Zq&lޭ52'AL![eL&@&~;%wS,N ]ڼ}=ѩf~$ГW1_v^(lDaf/=Lxߑ8mv?ٗn>M? ]\G\` 96˅,t +̘*:: xvQُ I˞~~w(;slIOxyz}/?\mǯ7MNeV U+Px%N~!l}/_}BVbFб3Cx}zyaq/ +鲜J /~ӅR&h?>,Cъ0ժH^'3˻lQ#o\9Ȑ%]&Hup鲴?(H\d36ާg^,/ +!|We-*±L=mS8pKKꛭ!kgZ栈q/$ tVig٤t9@nܐ(QTxe.(r!":bYlin |^BgvqFs1EbWagoήx7J +!+3"WEjGr\ּ"_&xvQזojS(O +6}h;72U_,ae'9 z愽;ki tU 3vz004٥WG`L1;2[Gב޻Ev06p 3y<J݋m>rwSQ`H3#zЉ =Kw%M^Z$:Ե>K&tEϔNZ΋1@`x#A[&QY:kƆkmʬа}5J &Re&UWtЀWɌUڀ1r +7 9\VݫTj3RUii-\XeVM2TP9) 0=pz?`n؎ppdAv熷'C7Ewmm]Ec~m:}0u4Hݍ4G\)mv8vB t"}YG M;MQD =.X`cT\\1j33eTt8)ĭDvQTBn % ] Z8#zip MsP6t4+1èl6P`w}aRuu]k9^ٗa]N( OZuTwI74E!uT_OFv\zred ݎTOG 6]8zT] b +I9݄koPJZKf(QS5DzWU7f:f:>.ssBL=OF?,I!IfhC_yU*{ 44]L388LAƆtyXn0-q~՛9!SٝV*i%dL|imP'Ql{OfvJTH&q:x2P7{Ч* 1c x 2jSfd>sڡ뎎,dȚ b: +8]"]/NMrMN:Hw+'TWq37RDqK$/Ӝƚkvi:rŸWT= +敯Q.<8g > +stream +xVK6WHsl P$EE +; +V#+ݢ3Cʦl p{grR2 z-J̔T;6)&=))Sw)O  ?P#$ `~ ;o0內lάgq}dBB~eVU׬y| XFXe%BsWe*{_-\|ѷS+kn1sSy߱gP-]6G +P1FZBԳ/./Twy+>-0/[gpRx޲]+a-?߭qrc; dx8u~cv]˦ @G9Pe"%՛蟐 :fI~qjhԳYZ6 +< q!킀nZ`)Vc8 nRU,5{0_B]9Xis +I# l!7[,p9?5Q,a9hDϚrH[]WYVSUy5W+03i ƪ-ߦ?w.TBtq(&S49=ГgB}] ;NZ +7[< E<~u-BiUxњRLx~a[l̿B@ + +.U%2rcVĤP"cJGmAw~o +B;c> +stream +xڭ][%m~_яt*k؀n8ގꅻx}ڏۙ#vKU\*t۷|"tw藔n=oc?>_F#ٟ^]P1|ӆp myYy}^T|P[\Hrsʖ^S/Jjxӭ杳ȸH*m.,ƾZo{n] >eَk,.0՜K9yjͷUDμnZL\}/K*nKpM_~q!sג}qbS}A ~:[<.-_ap%Νz/-"j>Wk>6ײYLTuV(x`G4_N^j"U$Yc e5ŠR㦛tᬖU\MFXJ@µk3HؔW}@V 1lJ@HO#)۫n+vf];H8rZ NJ>%Kc6R- [HT;u\O,*Mwy:tN%YQW(MɌYi=]SveLKMm=zoضw׮\TJQ(>:WG&l6ݶIݮ)?btע*V«0kp邪tVদXc$ +o@]6Yz}dr6SsG_(cU[?J,4NzDK;`ct +-AW\)W>Vc#]k&_ze̒t/h_a{5@{qo}Gx(yȰ扨1sןvݞ ЩșBtoDy'(6Z&z90VTiNd yu .v(X{1˚ίC88Dk՞ӡ +M֑*rѤddHJphTK¦q -@G_$P M^I\^8z2]ΰ̥k Npr҉a4ZIhA5XÌw}]rHi h R۾tݓ8TnF8~!c9x(IGA)OVF,i$r#fhLM+|O[:;qrDe-@lAW9j1`ȁߔk&iT-eZ+x͖Eח3>:qҺ M}&|Ct 3 =!xMXNUk" zjE<\{wI?C߭ǃUmX*;I%3 Т7&]}㵨 t҃4U݇>,P7hVL +c#Zip-E-ZPEZlkhqXQ1磊b>גx<5% h 5iҎ K.,VaZ>eٖn}hYuB٢<('^CyiLP&TN7(_q{sPz/VkOjUV }\n7{ؙHrf $Uuv^e4F2)͚3T)M>!Y[Ҵ{/|J蟝h'1K^Ǎfb@CʎkjlaA6 NbӋ1LLesF琉Ssb ggK̟jN_3$2j{ow/(½k)!_C +rJ`N1} GrowUv.1oyX$f?[Ne,CSI1S)Ivnn{LC׉#EN s"p!hAXhMVgvr{0oIN-v!4e6:8mOGNJ_&Mob٦9.:U1H4My7Ld~~x+ɴ"tx;dl IFb?rC5aΉ'9l~$>I04o!GQgz't'9۔dS~;zMk*kgU[^lߊM՜+ѩ5'?Țw_ȴ;bW}nc7='!Ā9<7{鉾3t9$j _eBZ4Xk|ˡMBgs O=<>m-mG<9ER:j5֚btA7gպ.:M)azF EhKݱftn |<[:H +a E˩sU3<{Z.O00%,d#n{8f)w9UM"ie6V;V)8jUbGs38;0!NJөjKúN@!-^r]+?7*ߋ#ߋxw?"df3;O=."y{x5Gˌ bO8̬{x98,'l¨Qधgstg;9#&H +c8V(IdLȠ TE=jZx݉UEHQ +8'dsMFʦV/B\+:C(DOX/d<R5zg[NsA̺A t>u-}#DŽ?=(ٙO]DS}䟪J=ɪ9i;ߣ9PM=Ώh?Aʏ sHo +JДrw9| aS7 C.?-+ nm-}Om>]?*;}^Ke{YYɾ^\{LW ȑE}q2 +[{v/biP(EZtMY?Dp5~'走 "6bΆaQrO$Xk<ƎDڏ >L%be.Zf"M qijR!M%L0,5O&#,de~Ӄˮq,;rFm/ Ttm/'4Q!$| Y&RclE>MOT=q}i%XK?c''\:D_Al(k≬>rZ{{~.$g`S@ bG;=$c§A9@of\3e}S^FuH/m#]mB/Ja0M^%!hR1"!aMj2! rGbV6䎹Z}Cs8(֢ k@]gޠgǎH |%$%Z&/fDRT@@~AFڭ'o8Abw\ GaoVrI'.cQ}ieM7zu"tޟI@j  +8BXZ`POrC ~HF|_:% !m(;H9bQA0F2<b5*iS/C CfcZ2|⻟ѥo=>'Ka.ٱF5)YӛVcscFBhE> $ ]Vb^bÖsXrN.^5QvfЬׇVmfAeu'd_袬z$UNxY' J>d-]yPz]8"CٗGbޱA)8z”% vWW8uWkyoYüuk5kMfC6F'S+:eT=n@s;`w^ݵ" +R]Q t*WQ^v% ʤ˛T#)9d?xQXw,*h<r""awRY[ܙd }9* b2Ny1'MnQ.gk8/-{1r)+#LyhE@nsuIa3΢,M`hAs{0LsܛdXu%Y_xfmvc.NZ); 9i;i-$!z YK[F: 52k%@#݉ #`׌qۅx%܌65qas!YYCo "az6g͜&L' p8_@hT\og m}e: 1e\gHP-1DvK78ce^m`#9=J2> ^HhzDwD[{K4yĸA@еpx祢C!xMfmH D5m1pcqsD\u@t -º{{:ج,8+28M90z[f^AZ*@ (>kg#/`;Zgn&ǁ;Ŏ6E+go57ҐA 4%cd`ޘݺ"z;YK +ђ $nadǴsf]/CX`nzz5u/~__,룈;pVf*7N=hÁrAsʼn$۾P"YG )v{ֻP')2]>dVW70ף3*P?l+jB?ExN&{#?p?xbn#Ħ)0y@l .a h!H!NjG9$DYyMARj4o1@p]5H$)s5\ئVy ^^r~bèvM`)0R͈dIY,q,r<(lB;L%` "@F +|s`vgPJk̟2#3#b,J~%$8wX# xq,X A=2҄fcC +jȄċ'j /yBR>ajV(p[qצ(vD65DOCA jȕb@Q^:| Po0V `FxR$X3FME5/2@6Nې< 70?=PiF hNa'm\70VE.@^GwPX{Z({[62َ0-M4K$Qy&o3hvI7?L[ oTDe=L@VbkΟ@`\(:󯹑i&Ys;QHEAk(vM+Ar>FܦPD4Q@ADc9 nS}(s +,$[V]@S سGؓ7Hʞ!і]o`|(rz4G;2 < aX+]# +Z5 +l}Z.4=~#wh}G "ХQiʇWnQxr-brw\ɇٳ˰ ~KJW$a[OgW9jRbj^!kCo iz_s*v9˟UQ WAXGU$HkQ {T_5}TCƤAj7IvY+[׿w~3>%KwS)[r$ST Po3Bkɛx 40%~+7W9 +endstream +endobj +327 0 obj +<< +/Filter [/FlateDecode] +/Length 17950 +>> +stream +x}[-my'ZvkĀlo ?(ǒ,cFe'E~Y3v fbׅdX,Oy;ߟ_G5?T۽$tm۟ק[Jvm{g=%b\IITgȇ[VM/VDn; +|!^c??|-'d,qK[y<jrXZm>YeM?ޥ*>G`>ѻ6$Yt0IdKL6?:'iHיjyyҤ[N <ߚnB-{9.鞥[q&Ol^%=+>uRKm¯O>a7 1Lii+4qA2coS{ 'v?;%>CGqܕLt욶:8Z> "7ZZ7kLɀ5_=|s۹ g2co ;F v4KKҿD/Rua90וh~j/Az6 !T \9|[A ɚ۹dmcmv@鷲isrN-sZ&[v)=V9']Zuvʬ ">Gg?*ptP:sݤ +ؓs]]f*7ssVj@p7qAxSvEHR"w{ 0㲧9 C*ƒ0L0.ڄ 90аDz 1=VlӖdԼA=8]st6%Sy3y+y^4Sj1Z~MK#okeERe'AJמ:{ΕWӮb_QB(؁N3)k=ޙ[6M~T!bJ`>TLt9N1EE_1vӹύLajS0s&gsvgޜsc:*J[U.a$$NvҞ | li/UH+V_sL'I]'f?7KsklNݪRw;{b$kǰ5^[oT*  +8\1tt!.>B|iS_s^ q9}W@^&`aW.meW>4ubE[l"KX)t]V )1}'kGuLr< 7΀̽@z.c֒mx,a7OԚ/Rl.B񦎲x?5Zs1 jfyM2)lVXV2x'.""V\߻,M%rJ׫_j--eˎ‡ǁzD/|%)ElKc; <{|&WۏDymO?Tc`k?b^vYYelinzw@-upo/L-\'T9yȖ9ڷ"}ɋ\"N4^ fFcfWEGTx- g"08WK?XGg˪ zs\T[3=$Eئ|T|fUo.0l.*l"ѕzGN +h6NLow` 7‘FŎwMjM6ߜ7ߖ7ݐy 2hjo3zl^՝B9r@W:dj +b5r%^CBw 1Ŵ~!C"9~MY+k*PT6H`uU\2M/Rl&ilﺎMkwL!a,rmUE2TQ JWL yTRNg_Yݼ^ ϞvEPב']T)R('E&r +\0fz+fR!B!yӼpPɽ$T7Ё6nJ-"ˡۡug R`2[G/|c9m9Aͤs.W5CP6]P +(٢VyZ+q&MRy!2BPtUvv꜃_:l-泔,NdoyS#_UPuΚu7ɚicM{ytrYemwz_]nyR#OzsN1|Th\׵Ժl LIv~(x:b]Ȳ"@?yRCWVO!!|ReA`0yi*5 kr|Wi G'zfFN4*d]iCB'L`R+H!]kwUBH,-]0( yawv0VcJB#9(1-\5Pa$,5<Y‘wLLdI׺B-k*{2~,Ix4E2g=82ߓXXz3;kԣATcՔWgn8( 4M?2qO1ç״kK D2%L(8M@KAtSM5͓| +yO!s ^GH!𜀃U}ǖ]>?[7Qz2z)ڃ"w8HRpI,EB\kH; +{`hj tspE;H_!1p(t|!²vp:/XXV7:5𬦴-~X#/M|aAmm6Va`*p D^x̯/tnb_hyuiAOW5<]i 9*j+4R 9Ц~"Wv&I 59`܂Ыwt~$Ȕm~,(dX$_4+&RMjM{`Πi $\}W;sirvIT/z[zSl +;mi]l@ͱ7*|-7*,ywAxuw_ٷ؂HUoCCZuB ?Z݃KVrK^>4%E+ee9UWԠz EЩT Mq +9'r䡗 0SM*9C$a np5O<`h-ڝ=Z曹,9:7wMT!]w0TŮMP1,ʟRu9]N \-;U!M[۴8~g]w`]/SB[ +MnG%oSUi# m#}Y ^faS3kGWe4:\MKsr%TAhO(ZNkspw䯶&mf8tO z%f&5 +?Cۄ/B._oZe]+w6WHz+}3\):Uڐuwٯӣ!e(GVDt"yB2W#* +u!UB+[$:Gl?jbՉGPw-\'i~We&OQtOO,|<U<p|cIp>/V+#u@}i#ջɺh耠/lG>],Q(bxTJ9`H[wW 1zCzӐyW(3o&蹹ei5D.9mDN0D#{7u7 Gy9&|$|WCi0 +GǗo⭀RYm㱱{Jy,'4dKV1 u|$1rU;חr{|~^"#i*6d C?I^_u4+hse-MBO1m:u(z{~p÷Wh>wvޜ7;|a/<6 ?<8 IE|K BXKDlܷɃc-#%rHY/rzC_IzkO{NkSiQ'gW?TWtB:* scwsDz(8 s.G?R^X4Bċ.aP"<_B;xgJ~EXh2H!rcvZF )\o?8ܴ`nhF{`=,-=Q몗'K1/}bz}!hN!h9TP^(3TOQ&_}ۖA)n`g)_4bNҲа%&=-oYcwנ#d_*)&!saz*j"T8MYߕiPUoomr3Yu rRrjSΔ_0 BSVo5~N`>ZN+nj}4ɐ;BjD/kBqPx4yau )W:6t1%i?}tJhlp҆?F%N5}4 %v&n8%G+rzڄū:q~VϺ8a35kcXB,>/\'߅qKW} Ts4 .aqRx9hˆdXHVˤbS{r:,i:zEk*׃8j :UڠEa9?"N]K/Sps827}B,7Y+Mq9;{(6 +%uj1dEi]1/ oJFO~^0b{fs8n4e~ WEff*}=0 ,CDLr[yb^VW,dt +.;wd\-fs3;|se:餰MN1F<;DYg@$˜0I bQbq1f6Ok?3Mo1OwcXi3=O/ԕRW [}#yDkc; M7:O/Yiigt_kJ} h}lbM1IR^0H#-ɫRe!AM<|yVOQMSnohl)[ JSNh-t1'Ƣ6mn=rn0MEnV &/_,4;!D2$FjMJD}*=ji[^Q.Ai['[op :B[%.,-MrF"𵦋wrgGiРjJf1{) jVY3Xlb#~x}ꬋ>3`{5b]Lc^vQqjKqu&6fo / WDW}Csrl ?El6CJ1V +m&Zω>AAzCsQ!*7 +p 8R4$Ak񇟌# ⋑EXnJhZ ܰٚ>rSӈ̟N.ԂƎ[lN$E\ +ͅR,ǘ%Ys]t@Һ)V/QmtU tQ>QXdYg'|xUNCCk:vmCsVc[6.}b +Ԍ͘2QaFO3ީr/y5Gϲ;if 8%j Sel!ɷ)]Y\zx *]Ayxs> 7I&p1bl?;m]b}鞎ptMw;l D1ɼ}a^>n}~WWBJ +9a=n>!<_!XZ"J\ +ŒקXŒ'<fsXqNʹ6"#^H?+ecyO-i##^{0>#a:y>䭮5X,Nfe~+c}bbdH>%ݠ܋?Xa7>S9M U<v]"H#5 c\X36Gvy]qSAcK8@gۂo5yBP({Ũ/uJzcGw֎|@MLT>;d! VQy |0*fՏD~^xD #B؍CSPeP0zl=VFlDԀo~S!Cf]ӧH81_FhǗ10ю0>Bmp˳[pTK[[./0|zw!^[&70H2w^~k\?zkrz@zg\v2Wm,u,b"`mc$j8}W1owa=~,9-ؒm=$xNEma_DǍ›[[OxrÑCgWfl"' W Jۚj8&L&a{>t:,՚f' 8 2"r(/$پ/̓pڞ5⤗Sz4yߌrSm +}aԊUm 5nr vfXi ?$\ su|yX)ۚS}On9O?x>'8}?ӯ,үNHTM%}?i8L&/sjU9O<Ȯԙإg{'ޭ4f6:G͟)s4:f,뽫wƵt.åq}xGjI *3`8[WeCc&V,F-{ +rL%U_Tl{Ulw Jv4f獋}&I(3fPeIS|YLRR+ t$,K +%KM_%pK.5 (f-򖰾 .j|oW$BKRʪ]4ͰZЪ#:ݗ#%x' "HG:<7#FxLi&%Q{0`"T$!묇vAIאy*j"]yG= F,/g56G{EBgBFT7q8G74˸#DCSM3jҽYGCP '&]>ե}#1xOEXoNUgpw2`-1t>vG>,+NK1!No$$iyh]Co "!yk>$ͫ\FE!X`^bTgiA Ti--x5gzxWd~2~ر\/O[D̲?3s}15g&x\XLuZBn6cXYL*hȎiTAsH6[ز<ȝh 0=>sDp^ü*]x^!=߰Ww I5Uv/E0&a7سhL+c3D-3 9[6w|櫩M#QZo)2H0Y0`8UX_kb-^<{MSyURwlvq"8H re0e"0#H\ RTM&&}†04 kCǭϰϼfpt˴3A:88y! 6LXg^҈'7^4xFiPגUۉx(9'd7revCv'pqO-BCd=9 $COSfnoh?\HҲk˨O-sm f.9"$@.h"VWܛ (6eW'3a-D/3z}"L%M24$7w<3CYE.^^m>q/qQ&fy0D!gHb$lǛery>:>'OHciCj;1S?41bύnzO+Pe<.r0ژξ'C},odaQѷLҚg~!-ؔ"<\ԾZRޙsb9\zVM߳ilMTGNV5xL;(`2 :(+3MS=0W>*b=ju-zT齇*w-<(e%8 M\y8< b%:AK? R\^<.|LӢ;#=W&-.z&GNIxP`z3:kǐ,슲-|{Sg?BReVg +q2E;, =Lk-cX[‰iլ}5t?(-#bCOd!}2YĴ>UfrUg }^J k΢Hf[`:W;$Z;#D*FƇj_<*}ҽVu;nXެkGbiJ(xtjF',^$#r@I@d6_)Kp_94aW#+Sⵖe5GCDεP~TV;e XqDž+<؜+yibzS+9wvflWݗvzӘ55@ vT +.{73Dp"BDE~a-:x^RqM:{>Sd(8XaR@ˆ/lK +[͒$ȧe,w +ꝏ&0󱨂! :I5[%[ /ИJkli"e5t.x^h%Jf^hjPhf(uS  _hG[ . Vd\X-}8j gUv-qeU|qs/P*^8ƅ@P)TH?@U^Y-Q ȯ^W [%j$>C]%> Ep 7(j-7"E=:){BX,Ε;ӭ*҃tW/I|9NlʄQq Q(Z }kZc'k:ik!~`q +51"G[k"EXJT!AUCʱB%bS=V,0c #ACZk@IӑљPxFEY-QSơ쪲tWD/'hH4f%S5Y`,|T]ޣ-4dSaE0 + U8^A2)-?α$~L7$@)Dg~cBtlu2X'6V5U,; eQ"a*A]2.Gc;? n^H kڸe9{/j BrD*tGfr PMc<6}.|-hkwc>R nټ0xcY ԉ?ޣ@8 LPz|Y^hV#, yAWA^m<t#=8pbFUmi:0rܧn>pRNUmԮ<ܐuh+ELt}UMozGY>3AS>viKuAaxbQ6'A|bA^L{[F7q:dxb2}h|JK!''DVqi{I:T~j)[ hU0DRt +OE޲U +0^T7k1Gl2, D|ɰO'`aSe6L`mm #YoС@Ș!g >tzV'P1'@dq,I bXѤBIAQ=?5f7-x緱M w"0#t: @tQͤ*]q@bSD0TAtMqSԅ'52~hDF XYR#r()t,s= IP7H:Lҥo2bbt0j,!{)дriu/%0k[: Eܧg>Q?ɲ'Yw,{Ḭ'-H3%o#FlBIF{ pl!טK%ȡMtTjӨjd`3,x&a`wPpJF)k_U z%5n[*i=FhӁ 5N0>p| ě}%?:u&b@YDޟ8ɑ!5/c##';̥qpmW( Lef> ]7L ^PN)S +"iӂY.WM[,KPlw380 :WjIO2K~O̝7gxS[f>z(vnmjF{x{:2|wWH4> MS«D + DR5Y'yfZ6^ 3 yQQ%X*H9N#Ҏ]:HJŖW_K +rBYݵQ'͞sJ )Íok-Ɠ?Wu]zbUw|(MvSMbݸ!GPOnzxsAj";Lw:lO to\jު  +'!=o+Fz Tok[]7719)8pgNj[4{ "8Ew|d$W/Dp~h+{, gzZgh 5޾BsPkv3Ij;5yvv T㕄Rą!$V`0x_oIݠtYkYf(F`s[ݞ{"@D3X`'=݈"Y6 Y)vm /b7 <]dջa:p:#nL)1c=/­p]*8084 Nc0:"Rxt$Z4BFy:֮yD!ӊ95VӼJ {d_-0_p8TVT"t8""LK؅rZ V\8h9 P= Lk={&Ik7Z v?nBb l;v~#-rCͦutQd/{AӘUvp״M(i {>AA2 a|PT!IG +8]V3w4KFr%qᑁM+XNOA` pTd;ox{}u ~6"]krᥚ'PT>C† # ףmNA0u%l|w{sWsQ >pb@ )B2zkzܐGωir)7Ha:9 +8˥ry5Kn +P\!{*1Tq2cumյLEeаL GQ:$YC2N 64 }z֞`~.ޟ\aI6-jYcZ4uf(Nv P=̟AQre#U:?Eu06@p/X)7G_p<*w L5%(޽^g'UIZa:xFuro+tI!)$kNuƷO]BHwXk O"R[3t=xmhE1W3x,?y",VZTI:|6k1"DF w`Ē Ay :qB툄 [\ҹxIٯ9':]Q%Ǿ@ +ַuooes4= ҟS[4Kiz U}Yhў7 mk޾UXw h?V!bVXd-jctuBV[ݲi*pm^͊Edɿ8BTv]%橇<|'$ ɢ(#K ABvF!^e Zi ѷ2FU-s:vdQPaQTV=܅[u÷œՇA A2X1m;_{ƫubرSz o&p(*$wF7q&_G5!>X7 !R׫a3>|pf7\8܉co5FkTe:y*Qsn֡(74,Ռ(|B`$l;VsR93BL9bڰL:p)H>zZ 0c0:1>0 k!BVm=-)?6[Ŷ7Ƀ +L[im#K\e7%~ㅆm@1cBNKr|%A:g"qWW bG Z^!Ƽim79oXm'#ț + -Xg=]D>6Ί0 GW[2;(ًfBTyG(T@ہW"2@vwgy˄8v\\x3!mwrP2K^$GK<&ZUS晧 U@SQ&QZ p KSYm;/@UIu[e B ; +Y› I !_J!Doo֭Dpnn>AU˹i-L4 @< o֖.C ArqY+ mݸ׍k.# ]l\Vo^6_&ǡV*O&n#]Pd(X{Я1wllKwu)02E3$F%HG fH<g0ޡst9 Ҿa샅9ld[$qّZ]S@fR)5q`iIoƆW;ԆкޜKʬ҉ZxR%>庬*"kTu T٣N.kA=x +QA7qWXi1ىH@`9Lq(Ov.BY" Pj TV3 23` ӂ9]ԂƧr)ʥvd8,Tp; N80~Yag*#p6Jm̲Yx)0py:F~ֶ=Zl*+qXJ~q}#;B t +v8ku\v6jT)d0l(LׁތeoQ +oc;ѼcjZ,rCNYC sErG6om6֥:k|n} 9/rˆs!)eoZ^MI_3(J%yt|MV)% @d]oE"̬bp-H4bgbDYoM-Zoſ! wfpZ6DȋQ8hy4,)^hLJ HiXI|;5;鍸Ggi­O~ͯ$D z\.:\EOu܆x a^/Ҫ&R;U;js4+4VN Y!TqH:Y _֨];NrŚi4.L EyjQNS蔈a5 '-HbDX˃ELq6quguKrm]!@wV\NWONVМ@X+qG[7FbjU}QyvfJmv4ru"Z*1%nL̨ݪW,tZnцn +Ywp2Bf4"~U %B$YʮV>gjO17S]HI#Jt4VmqUCXRlq=3Aj\yʪ.֭#ԅ.GCeb } +ƶ+_OVϊ衍-4Ę h&e`]4vU6KCڱ^.&uh˼xe8h^CCDj͏doo2b4/H0]t3M zzBK@~NHB6t4{$29}ɇuObFt94·&>l|:-߽IBq1"{s8 $jg0mTK8'7$1EWe~ ,{aKk^qYȱc@VgR_^5lJo1aZ!@iiI>*XwzC#iq/ɸZ !ڜ O90| +F|KNg6#RY%uVXn͔/U3S@˂j[VlP> 0}TGbњx,&/&fZ}1jiæ7VS%CZˣ X +1oصUf.:[ɴ=(Ar' qx=3F,CUWͼ4Ijˠ@)%Z ICSкiHz +):Ʒ0:Ǻ<ؑPa{}?.guo}_?7: tSj?/՟ç_t+O<>[?3Uڧ8)ۧs*ks^f.gaj7rŦ𧔺Do,Hm \OLؐ~*ӯbq]j%&,)f #ʳ(Zny-ɝ빾B +endstream +endobj +328 0 obj +<< +/Filter [/FlateDecode] +/Length 15101 +>> +stream +xڵ}Y&9r@I.Л ÀqgB}#h$az'.]]5F~ n?ǝyZ_˓}?2|q]Pxڏ+]/ik>O/v>Otl/)y{9UXې]oWڽ_`qK>/ƒ?/dј]SyُP]/K.{zYK_RfB +_-˝%`&?j|cR^J,(wnϱlŏ;]rlZ_[^X[}:߿c,hyj}z 2e.@ +XqhL\oK/KKzI5^u˵vL9oLի-{kZ{wbA=信*`y؈z<]&G؈tNW8Z:+6u.t)N+Rs==[{}MAm x /4_2}\`UYڦ:!ܢ^tma{8$M1xd ur鞪$gV2o3ƿWLcː!JrPX8j|r_Q'Ja$-e-}<`cJD'pn[KЉܫ79L}_~7o تN`>Qew>`tS, ~Y[74jCt9y7\^O/V +KٲXy$kxoN$ Dр4\h8l= ؎ r. +NuWW錟Չ!@EGM_!UM lTV3s9O;IⅧ)ށ{*_1$Ҡ@lS1G w )J{@\Qa1/ro +eז{l儰xduԀ}."|xҁi6{n[~Ò-N]X57/6LfnJM_mj_()>ݲX[CGqԦ>u`yUգ9kZ]7vzEue9r8ˬM!ٿ/'xs`7yib-H~}׾G:T Պd_Tm\2"z ZemP@=;|5 3:>oi}e0,SKh[йի҇?O +>r>A>+ K˾i'~wA֏hXA\ˉջs~bX[T=~FT~F2m2n&[ߡsƮ[&;yr}S ѡ6۩ױIzN8l\KSkGp/?8DC|l:4{Əۗt`/rT={^"zZw'vX^/v6(b*{Du@k5[=<fBj'^M0 6)D iU@dΟڮQϦ.Aa\Mf5j_m&kt(ml +e5.ٯT=C3 m#`))GS5LO9/ BS3lF6q;iZێX ڐ웆S_B]F=W?B>UAG +J'1xiwo-S`J{%ᘛ>MP3)dWUIz'c|=rRxb %!q?-&f]3eڻ^α1㉫rh]Rƪh7'}-iyQqGst[D6bgo7cmJ1fܹޮ@n7hmC^krs6ksBO޿Bۥ5K_a ٶԩCTA54]vOKowHSfv\jKFu$Fm(nv6k&@w_Gź2hrd4ve~@/n +8'bZ\v0hn&^^*{hwo!kIgp +پ8˜em +C{7i-?lkٜTv\`χX[иEpܕmsS 9<ƪ>ﲶR q"`i(;MNDJ̘}.E@Z8 +٪+=V?ƺfg ܊ƚ>7ӬY2Mbgmm7^we uFY e(0+sDKXN3,0ɟtBT8=cѻ"Eq +3K8ֆܽp;bI +C}.pm"}sj w8va5 <:b2hsNu1FysQ8cZߗsŐPdbrh½;Ca?*eЧ{aԵ9RW^zphwύ__;SE2Mhu_wcUlvzO[w̫9Ca}%a#gւhR]W vo}?a'i|$YV|3y2Q^CW0EưLhBB|Z")l>nƣJ{㦃Izu ui<]"S{/5[z!tl +<ư3L'󽘳T1W"ΐ#> ʚW) "dtZG[T&&xrFla h `)0k{]&&wI͇* ud/TИ)4+L󥃔IlTrJ< \o!gt4osux( m!Zpt7tڰi\*"^k*|iӓt'A \4so${J8V+v#}mN'Qa0xS\/s&svQ0KuySm?7ABn4-7b#k5j(@(z4ޫ<ZSck\!sY‚k'G[-FNX'l6lƠ%t1lHϾs#ltA ݐRx#f'Wp⽊idޔˣmDPsmQxQ{7iۣ1R2ht > { + +]bmK`TP"9c a˰};Fh3H?8jf3EUvh(cc3xD.\)3m>К墍3MbsC6(Ц/)}?&ꊮ"+̆ ^ $! R)_^>5׸⌸!NpU#>H#UP>9 4DXJLbA:_*4_W4XyKb_= (</y51hfW#6ޮh}ݠP3BfDxf[`PS)Wilӑ"mSP&/ +0:!;7066ab>aze$-lKUKq0>f=1~)W}s.RB +2^<3R01 E" +-(^+ +@Tmx5fM/gJ/$,&x{/9GpJPE=ycl%+Eh}VHW冾0~%&ʼ169l.Eyp6ĊDtLW٬Vfۈ;g鮇fc{ؾ7 m~vu>vFZdE^m怎:ퟁcg?wwEV`U؃ +ouA}V ݰφXkn:L8|kn'b<;Â>[cVq'[zVzB0pXp#V˰.Òk2.b>LXY4-cVeXzq]w ێRU2.˰/q^%xk%KXË/ċċ/3\&p~Q1FF+uK ajIN= Zi]:¼|ʜ麟/ .eyXEy\%yXyX^VdsIA:Ա7LA砒Cvc*or3l p9@߀9l +<Y4^O!_M1A翊ΗI eGhE7qZ,4~k+$Qg7B%6QM̡EzM\a`HKI^P[Ri"*vzboUF7-q =Њ 8l<[lVLnqV\Jűd0_1=K<|Co_"g~$n־Ɲ#c}:1d|?mZsB]~g;x4 @fIJC}3O~kC \ c9?t<8wז(|6rJ~siƕgս$w=v l5]Yp@ G^AjJԻR?1#e.ymĦKc#f}Ȧ#ee{ aBǜ}'vgO mC>qtx9DA+b[_L潅r\i_nl\5(|~Rq/ndk͓7CqOze/`@;>5.Sa*meJFHRY'w=WzaqQcL$p‘EZT״få8jӮiV,^6]=$HVIcݢwC1 /f5|yQhԂhES "}0/Fڞ32}i.#LC{Dشvav )a #8(YNL55 vL%Ď5Mج-UӍ{ҶȦg:nx/qp~Pad^Lsu.-^3ltζ|˂2ྊǐ [Ά|KJrːOg<ƜCYfM~^,~gJUwvgptu#۱77nm g!4nZՈ a]\KюmZsl=ln6m +ujw{qK2loOgǥ + >3MUqc +<,oKc'>b-F;̀7:Rtp·;{صhvEъLw_ ToԇIx/)+ _&}LFvB$ϓ܅T<*w^ï͛"佸)[a7TK˺*|+sŗCOjaI&e,YnY,Oy)K^߿O\G<"Oy` 'dbY9W ,~ҶRa** +)zAo+lf3U6)"WES/]⃝dƀ-'|(I' dwŸ%+sK]Q[|y=b#7% +{ɷBU ;@K(П~#G_q?+oXH[6]ty[@NS~t~qB\c7$^NT qFȥ:/ofjw%:;99llWs +8˹6_uO?t=j>zg7ON?ݒݒO? N!.O]]zT^w9eh{KHwBRg Uz<̑\pi2{u_x{\ u*ٍU F WU$mom$ӠB3PTnw.2R~Α0 ]ܪ+J_f[DaWne3 4Ew-#i{2gܫ VM.a0G +'OnYy6&&g$m3 +A2ʼqiUAI&ƙDuK.$LK'`$XW2: _pB=ͧ vᑜ|4]wd^%aG <]6O|ԲMz6ĸ2EnQ~TON7*Hhzd8EnQp@X=sq%ޮn~lpN{*+~1q`^XՂ{Yx:b!} _88qM)pjA k%lV "bpgJR_,Be:+q#?|a3~AS,]xOJ +ZR]\$VC3?`iS> f$ j. + T|zy/8;v5/<gŠJ$!XȅAϋ(ZP(. +sGHWMZG4-yt*ƥ_ zűZ-%#;ynp-b(mh T,<욺=e.}uH7/tGn`\j A0e@ID5 trޱI<1{_Zںef<}GeDӽǽ*1ըc*.4~dvU ӫp=0';/̰QB8^y'Iؾ-=B9"#6۰k D)öKa 5c + "EHc 6YN]CNG2/E~x䙷.w6Zp|dEzT(:dbU0S#DH]JMʉ: Xg]$漸/*]TOQkiٔCb5WZ$NX  *gJ\׳b+oX)blS!r-Tl34c;/'Q\iD  ԃ&C=1 ζK„8;e3ϋi^1m9K\Gu^Im^H#d +GH`E( jղUb]B5 rH!*eXcdk/_0"* jX\r*%"z va8uc_t2l#ZyDx ZDokIOvѯCCDK#Wٟn*tDb BJxTJ 7I yJ.B'H!*v?C0O5Y2MǺ!A9V[TEnRXX~ g5 (X!czж 9p(CYt6Q<%!68qϑ(Α xZ( 8b3ƃc}c!UMǚ'Mg)..:eq3-O؁(&H薎ԾSfIL Rx 5j4'H8oCP!@d-\( +"’˼q +O?*sRY@WWCADJP<'Ⳟsϯ0Vd8ԇ^iOUA`}chc9a;|{|ջIcQ:[m8d^sgAʓ\AxAP< xgA( ,- ss@ +s:cO$?Ir GHS0W{1&N5rUX* sO|B{dK03;@Qb! %vJ!{aAʜ/S d\1mx5ò(M*;%@ +YcS*Sl ^MY:io^)3RpNF5jA*C)f  =.*B +vCFP/%BgٽV&YL>_6<,KC}5|4̩ո?ҖIW݂v qXgN_Mk[|ȳM;=v +ӲhO￉~ i80E/ɱ CAd"s 絡ୁzUJ(Bts#D'޽cgUv\c+-js {b`䔍)]B*>]l:V:Az +÷W$":#p /LJT5к @ku4[sۥ̨̲:%m|VD=s3ǻdBqi +L)2$-ẖU2i!v8TD@L{OyrV'^{O yڌfx(mHQ^o%ywp2|n[B^n,7 iۄJVy„}.SH-d-G!:#FN78[-_Xf8kh!s P\xn6Bi H!2Q'9A*|J{5#eOs8H#R3OԬB!1^+o3U!GL IQyjU骱#檕čK1DiTW)eU1!E.J +nHrC!rQ Nc&)t@GOc+ Kr;8v9Ybo>,x&92G5S%+vxz%IÀu;b:σ?av\liIަ`iih΅ R"A(?O٢9&-eNzHGL 70>t ~a^0hV|Ң3)$J&< f=!E]a;ef·u +Q Rބ +Ԃ[x{q2m) SVr -DysP% Vc* l2egU-f 5vAE/ӦTт~?LC| 6Kv $aut碰tC4T_*m@׉ h'-bq}P N%݌w-mq =eYP.&0b4-Fu|B(nQz^nHW;7a3C4/{=>!{&Zv +E㙖]Y}[X0QVTBe:EnLU}M& XgNwdLEԢ#%O'N2k%N2T'uv=ϸZfsWڧX.% M"XFxH(F!@U4yM'd8errsR'URǛT \zE:]q"NUGΡ]3"(M,dqƉqC0$D %jzUrrR3#K7Q ٓXThЬ :0S?3}],YÀ_XGbm9P p9ܟ3(Yd:) p&N8~bs^ :쥩꼳^qAYossf8Vq˱$:Ѯ:9g XO٬zJ8TԍhQG ĎmdcwvDV5 QNzUg&^L -Ӱ\DyBMmh$ \W+N-=fnVFr"~rHښfoCNu S[q|tp4)|RbU:M4nM !ժUlR Ӿ{C}eƳUH65rS|b%L-!+cVqZi *qM4r"+76b7 6Xm&%4TNMuq7@2nTrQ6YH$FM`{c:z' RPn}x#(5@qб9W㶻ݚ8nybrҀ;@X)dKq=qBjbOBAIӢ4u +fm"ڈ3MCiL;)m mZeЪ-q.i^)'\IpB,^-VnoYKw.KLZMΫ +KGƐ 7%E$?膓ݸee؜y13/Q:b^uR +⸱P#O%!2ϼnyao /Du,.J4*Ķ!iu2na!d'y)jLr)㡑vՙU5e::\ I ϳ^$k7}rahԱhw({K1\|$g @!y +M, 4 __#)TwfΊӄ/2@*UE"k5  tHrxkX)3ޮC}$N| C6٥Ze!C!c&'BNjm𨮌6vmCi$`umD6UnqHq->mT'ʫ 7z8!0v&Ԅqƹ9 c*d$&l=SZ29FZ%W6RꦼWi= +?Av ]Fָnӱ'@غGUi8" si)ʴw[) S1WIW  +^L˔ r\`4p/s9BvuC @a2PȤl:sG8=R8`q]edRPMGy8<?i3;Gl5B&`cP%$[L[y7 BL|3G>?x>2OyiKFm!R2*NB. d3]}h1 3@ m$X\ń8-YD. a&nG ^uV^Eff,$Y9Yg x:ܠU鸯jE< n( =.mO/sS`˂zeeK5$UU- Įm.|NΚD*"不gN!WV褌i/s&q$Fz~^~G̶u}߿+맟Ï]?쑩OO}Uj/_~ݒOl]T>-޵>kym]hiHYףmgkQ +m/:?lHwOy/e%e;Y߲{YΠrfe,hi{9GKS=zGLbaV?OwOO{I_?S]OAm^(tP eلOeI6[wRYA> +stream +x}ߏ$9n{X}@B?"t4 =蚱gvOUU LW)Q$E))!?r~Vp[RxI~þ=W.^*?=?Foۈ]P U%.Gȶr6Cg?\.%Yq}\ g||:K۰].[/ev Z*%~fb__.n6[0n]]LZu~d|9n)ڷ{`RZFGs-:eQNiGպRɕԈb*v^%ŮA3hѥp,,IpiK>ݤxާxD=%RH=;j +BCnaeI:2WLcԭAK:XeY`U1~Aw> GMaIG1tݡB|) +z(Ui-D`G!C,3h V<[;Pʊ,թ&:ӷ,aҟ v!CR A);>CHгjX?n0,I)wViSgjcXcXjdXɰa3 诖;qTEluι&j + Pa^n3.~URqW7sb͡MQY1 ЭYFFwk4Y`vAU@B.20:zP`L&]J }5Ɂr* {JkQ$`g_v`S3$ŧw!b?G\TI\qqFцix&\=,`8`{!C?/[[q#]=q Ŗpq肸Hx:~Gs?YG$ީu*pX[ܭ@h^@*bhRTY.uEFKfg714KG}.E|.XSl +v^Ywm6tF`CTk'!\U2:e%B:p8 A"A6(B0DlH:FHqC acRKZ`,(D0gYx.).isYKb8kL9)!ԥ}Q]0ܐA%Ƕe1`=xamlO3Y%\M_K/ / ~l' 4:8,:}c=Zq*ˆyuq+U'Y.t{2xOpbVKDCO7"JVi~u? ,(7?$.4hsYB%燶Hײ!تMM3U=^)/LdX;&ݑM>U}Ab 2Ս=tBYpt`T8e"<Qj,;5D_aE+ +Ͳ+7˦z=?K8d1vR&kv#x;ζkqӽ+bS!]I#ܙ.o֛)ɽ`5_b|j]p߯5E>dO//]bb仐:8cDT|7 |~J_f[1[Q='H^FMC_\p_$12ֳX_~G_~]KBa]>?cchFS\ 뷨#qW 4Jƈm`!?sS ? QD,gWC/-ރ +T5g:~;"54;oFf?S[ݏ8GȰ-p uc?ƀ6!4pg +kG]kp'7aV 5ӱ2ryFƒװ'M# +0] {2 +8=Þb|#Jva]sMfL!,.Rijn5ոx3Z[AРE@i!Pe@u C KH hRXeNi8`lx}Qn*[EEB'- ~Mt4ٴN;Yk6Vcx튔8LE[,mS fE[\`ptnpDob@4DNw$W>⍁"R +}*VN5H4h2ɹn0#woz }>CڌGGW5IAdqFSd:! +u[߲qvd`%͉ݕ V8\n;zha.gGcߧ zS:H_ ,حQ; BxxÅipEn2cVPc\vwJe upqV~$&٩P="k;qkk8ES(=SM4T{6pڨ2Uu9tRCu/M-@KPJTQ)Mhe% cb[w[#}JbzSs+`1&am8>z*Gi2^H r^’ӎ>]שf<#0!.a1`XyF^ȼ_ +ykA)6_馿i]EQˉqҞ6eоzݍ;pWtU +W}pppCʃ/+jqٷpbRIuK!5}@n=߇mi p+^a@{%6fP +K=K-<Pa0Z:|#+jAAJ?˕^^zMdYi_u~Ht։D>`"B5Ėp-Lp'Łp͝m{CE!פ7t(l;$>W^~7oG)o9}#Е֗T.޵힨{Y} +zl6._5[}9穝U#Wg@t>_7B~WL߆jxlSpt8ɂܟߨ&o}}Ɋ x~+<#Vkl~|X.k ?=ԿpPZbk =?P^O??Wpx_< +w*$=қXzy2cۂ}t"Me_$nQvf9ǍJc1T JwrTY{i M >C!e}zпK' @! ؇ݼZE}tV}ov~Z8&BH59iCHRb 2Pe*H=2_(^'XY@.䖒҂RX]+[hZ)cERnc(VcW`hiV ОVۨdƄ[L*7 Hx'ZYm̵u0%l⑬*FxxpIH_Fq9(!CQYo{TQ$}bͤ 34 !;^ӛ sJhK*i#y ʽkJe#s=q0* :1V}i{אu:kLYq|ʁgWDO~@ɒJvZGROh %7,ɄLԡyX%)beixӐ7ms3;vIV="ZgOCu?㇐|~->\l`Ly 尀C^p?DtL0lwI67'g3̋Ti^x1;\m$2(^@y僋b l ppqFG'Q +ҞY>)1K3y`%oDXk#0<<x ,[Hgl v6 XWq0B + HxP=' kt!m*_ m(HpRخc)yQ<%, 87O ó d{NC-w;Ԭ°4nzj߮OkZ띀 uLٰ6h~6;QdjH:' kSFNqQ 8$Xvgb! d52TF  zYѬt dSVW]Jl`Y"=O;_XJ9^Wj1bKEY0Kd^ b>tH브J.QIOdf!QtpmsWl{8dW2Ӂv .BQz[:ȽܐrkEj]D[) L MW𻎡`Y<<(w󄕓f`Q(rZԯ^gE^UJ `=hyiW%"DsR haȪ'RHDD%(Ws;OKo) &gKsʻR*P\VAbxkV%*\S&'lt푉M0? +펟&I挲\ Exy]*k Edd!?kaSN*w:zM2m]/voxoɁy=/OS*i/6r0ɱܫA@! rwU9h' ^Z%@pyR"csG>TKӁ Ȫ.9 9dPI)*&z)1$QEMZ3pX>ũG:=3pln ! Dn;RT%V>VĽ[ sH7ЎL],%ג)ձV]w3 d؝`@ v : +P64nܱ<ɪs#@/>ᮏלQAJ~ZkfYKWQVtR[:"A^q29a`3R6` +2}J#M0 K_U! Y)e;#A/=AWc (eC˓:7 /54HGzׄ@j0K3kNa\~п$b<iʓ_0 +6̍Lc/  J(ĕ~&I;Ze/}8[L=Nmw DΊvyV +2Ԛ)rU(.nYuW@JD=/`r<a ;v0#>L2d~t& Q?9 r7 n ~ [oU%|85TAA8 $8PႭݵ.q9hr(+<#>yn۰o Iqi-D:hZȗghݧ^?d6YdYlL6$Ɂz6ڛ>jxdqCIVsq#ܯquvO.wRtLf#cxukJBpFɱcͺ;\C޶Ly|+"VIossH&u^L*Dc+clN~e:R{u]j#e[𐫭pSJz +M(p2'P^EX>0t0(1uXJLDzQo9E:jVZUrZZ[)nLS/8WFDþmHB#gxw%c+exզ+0ĊWfYVz.t B`5vd9lZ)*E3>F`?f;V |VG.m̥qw=hJZÕ s^g^? +d+L:9e +je+o@GI7cQJtHm%3yhH=ړzdE@E>KRLj͢V=(1&w:8 HksypٴL2ؽ!}&YNoE~rVVyd=zBY)ՕNh0+[^ko\CM9J 28AyN5k499AHxx~!ȥoZbCg˚k@&aCPm8$v'HJH8CCĞG "(!Ǐb7'iR5; t']k99DylUoK\&BGܘO)WXe@~t2yR!iʎ9&y;?I2*N^:S OC-ڹR6iJ#9Ņ^_i"r -l y ,,j+%w$~c2$FàJjc&&T9ZYq]Hr^ΰ"TH)/*r?N?r}uM!eLs($Oy1XGE;?4H)qyy($M1cBއuʌyyeh``sb0K@VScnC| i$3aF,&8'PkDVd( <7푪Z[rcLa'nj=yK)+{>ʅ$L=_OJI6tD]D 3,!9fe(+PQN=溒bcFhLxWU, +Yr&arosHyH4$Ȭ\{T;4EyLd՗Y|Ɏ<Ф=HG2̂flP$;͢3ZRdɎKdL?=KȔ@Vֽ${ώNoJÎz-v~l]χPN>?fr1pm?O惏lr,yގLŽPW_ڻT?Oӏ?}Sȏ|XR$}G~h/OXl_US=~mzחiq1~^@vڃ:^B8+O!? $xro{/S%p{?ֿߌblݰϵT~^5?vkZz}y4{Q5qݵHIՌwEtX fEr SO-%Dkocs{^ brpT  +|% O-*x_Ҫ#ηډk>s,X(o'6q.x"ʪ etz\ ^^;(|)#Z6\ůh냥{J<^ vQ8SA#8agRБ? +P6s-sQ1Ou/peqg3r>q݆1chCn"J/ZƆ\Jm0i}ӾM::74?=~Χr*BQyן˅.Y-ēxCeqNIOQElhw<&brSoӏ.)jY.ہJy(ֳh|k9{tyʒ +hA@/!=Ym{ӌBtoZp`$SvA0e{r/D;A L{` G>t}'Oo#` +k5Z,7"`=03+MU3Eqtj&$F,^3˕^槲zF^!ouS_eP/u1a0}{:w^+|T8|J/^dUSCyit2k{}ƻz(Ϥ^.].~X/wb0&QmTvW*%BU/nFDP;Z"7\xWR~?O7U~ʙ?A~IԹRRymY}wqJ*oלw_w;j:Z[:*JM%չ|{AGU)Nڋ=,)k'7??\h +endstream +endobj +330 0 obj +<< +/Filter [/FlateDecode] +/Length 9550 +>> +stream +x]K-qϯ(@l],YeܑG,Ŀ>MUy挮 6ŪbS|߼^?<[9x +ϿxꭞS( +O׿xW3u?nwikWk~}xUqaӭV\#E_?@rP̘'NpDbJo{g[=n S{/7ȥJ +X+jyka~j..90%WHjXŽVS>o$2>}}" <ݚn;ؖPSѩ?W3`rIZ];2K(<O@5xc xeS搇,rgHG4TnצŐe+(%Du*JYМ`||6а y]HЪB|#bS>J +xq3ty~ +ٯI.mESQTo*cTc7UUNSʘL+](ΪS& /oY[m*k>z;, ˫]ڥje^B!^q`ijC\1-l26Z-ŦI}t k9x JDn8.d[7[Y +dnKmhƵ]!Wmոqs eXΉ2e $WYFmetOU͵$Qخ m9u-@F6,Yإ% g,_)u):V=A6QzDOB9wX,(T̉7Z*{gY׾cLnsXOϩȶ +֚-?`/g_->R8K2(J D$Ủts|ҵB*$%7!݂+Lg* +.c<m,iYw Y>ឰ&+9%֬;6b L46[e w+hSJ)%X;' l8{JPhztKG$,R:ds0|3dьɢqFcgv1rRC9icæ]G:KiT/)a_DPOgx(V-Ĝ͗:vV I}ɺ.Ilʁa}?| ߜ$tFO~.y7mkl{Q%#!{'{p NmCʽaeԂߙ)Ꝯf-FL&Ldl lk7|ێ1;1-1Fxib˨1 6vwz<-v -oD|2LcN,8tfUX>@%L  a m+Ve`3 q~RPvPRc'<;aɻI' "mFj$Q<8me$r +DqZek(l̞X*E p[#}QTIWA5(Lj#ÔZwXq5P418#))1;>]ѢGqM͍rdό-+6,yn ItϚc$ ӄ㦧 +N&DvIۉ#xQy9DHIbY~xb#n"'r (=D0}& |h[s̞n <)Uc[# P&'&X GnH ]oU"u7ݗ/EM³^oa-#alU2⭱`biXeZNo4{ 3ql T'DTzSCQւ%4u$cAhy'9s@8=,Z!!WXNG:c!?rOa@R Oi +k̰StQBȮuE ˖,j$^vQ%RToc?SM% ح~cvU?Lt:˜҃{}H{aG>;lu2l"sevj,V]rl5mvLR c9icUuќq3wc]F'$p.-uepʦyB_(6G%{(>˟1ۧ|F^{go7|Q!~ %߿,hs?D=%pmbΗ[e],S͕69҆}C^\Ј|Fq4"#l8J~&GX*wf؛yH:\1-6Q&ȝ 3Nc pqB9fE"7x]Jt*UضM^h 9*$W^D( b,eoIĪ1jy*vٔc"xQd +h<9bRGbCxV 2QU` 4CgtWקԤ=MzM#Jy"N r"|6l 41)Hf?dO3'䴔!ҧ~πÁF- ǶT-.FAO'\92 RBDaAֵ}x .!3KF"{Xo󐰴R61X@ +gWY X^b `o(-R\±3E[l3 +ᦤLO8+6 {J 0y]A$Z)SD`&-Rg`!N4:k^9Ks3z)Ble^!]V)%XFDj[`M$,!F:e:Q2& 'ic-S,d͸:9YVT>k<)bnS 7ɚb1=T@ + ֈ|fH3" lzCT7 2(wH+J4L P˦d]׈:xGkj%%][EVEGG(8uYwdca@cdb{st`Y9&XT$Em-xͰb)N PFɶ^. +nSPB0ZiV&sֵ2t5*"buE3!XGLW'/e)2U/}CY ̫t:D4s.؀{Fشg.! +jhIf/r2p3n9!vzD0>9lرEZ]-Xό42Fw=XZ5+הL-ʡ$%n":6&¼hqxvAbV=QCPM*~J\Y,w-(GSwl% +726@v;55LOw AUV奘n%PB)kN.2OuTRbM)b'c iS5=VzIBGMR&[*wSH-pKϡm`6Rh  + fr Nk3"L"bvnS + 7EDDhȈa|R~GN0'O@waW)P$HޞQLiH:cmN)dcLh(ޜ/!Ж +}lf:w3Jwc+えE:f*N$#+=!2VMy@@f[1Acǔӣ#SZ0(+- 2QNg<֢EH]/^SeSSI{7TzY 63Y_' Ei,G5Xνj*.uXd[ר/_J0E(J?z^|hvar8?0,k5wUoR1$keIl\໌jHcTFՔ~iߩ;E!0bja9@DPd% +$R&X#,!3eV:Bƚ#"iuncAԻ62MlQf5F0fP Dn{'+$+& osڧT-8OLip㩜(fx=FU R—FR<\#?_A*8뮗 +t% 'i|FXb7 +[2l7 )`yL@r,Axh#uwp8|c8XV{v"}^v4Efq +sM!{q*2y .MK'SH&?td I`;,(ч3 bDqqJ^Y5T:@Pi蓓KD9ZivmbF(@< D9Hi}$g-n%}gUU)Beba93|걉sn.oᘎuG + +W,9J*WwFST#a&UA+%Fy.=gca[n܏՗؝'1 hqEW<ܳɻ>lqeudL.)ɺܔ[wdt L4vOUQ*VTPtJIcW UQq%$@YͧJOX,#{lU[̑N`b1Z,1~8㦝?:_Ȗ</Xfm%LI]wu9X [?IN#Յ)<A/( gY <-RXVejiAX!dv(Q$gRC8JY Yԓi3O؊ݳS)`X_QIXa4h `"2̃;fEء+78m^Ĵ&ZEg K> 8:m^t8FjSguLEd Fo}pmtjRpz Ɂ9*rH$. |qu|=b4e7:dq*Q| X"R rTRF:qAFs| n' +ttNVxx J y.yuKs8≖$G:8RTJĂ NdKKS;ޘɉjIW?c_&Y`dD磺[ :)~H踭gOOԝ6ćZ,*4i1j~s<`t'ИT9C>x Y$|R2*9j+}|'.b,_{䀬vG4EH*" d杁1G(}-u +yjHJT6{lKtRPK1ҺQ%c bK8.3$o%cfTTmR&m\2^츳ɚF= *xˢWO8+VfAEM01hWNV-A?Ⱦ(}.-x +*Lw]{(i9&*CRR/CR^C싇/80W(#ob5`vAV#)~7I0Wf5?|#o"pG&cٿ/_O_/b{oc3ܱ?_]_lxlƗ?}xk/=<}\(=n0|knϯKYyd{omA<pmG轪{?>!i^5}*X5A ^۷k/w?}4 +#:&H7o18&rI<>;㑛x.xpc2LGl?)_= +endstream +endobj +331 0 obj +<< +/Filter [/FlateDecode] +/Length 16899 +>> +stream +xڽ}]%m{YAf-` ΍8c#vf O\jso3hK$EIEQ^ۙ^_׿}i^뾵{;׷˗==!u{mg#˿[i뒧O 懷[Jv{7Ϛ.שgձvxU-m"ϊ~\1kU7QNC}/B}cd[ֿ_!l-ߏ6nC*jM˶{}M%C)g};Nk^IDslK_%Q<HpCq ]yٝ1ݥ9IE4o +7)y"* + )-9F:u)? +T e7K`?bCgh²h ǐN{Вtb*:u [^VDm֩"hbS@(^G*:kͼyΑ}ͧPoi[{dXN]zۮt!oA2|b~lsZoHMgB9NL RҡT9zOJ9uҫr$F, +|*F5܈ +Lc6=1z;?|Nh/wS1nxtJMpv*:D¥ sbbŷ+t~Y)هLu#c*շ*rKtJE]2S8W2-1$HևtI_=cYP߷Jt#l]E|]HY:{C}Jk:ׁyXuݚ_UrG2eH=rs,zJv3@ǜ&ۦ\nw]k}9]8mp ֘b@omv_!Bom );\ s nQ,A9G5jp=57wV{K`L߽9sl* .{,7=5%'P:9c\M9 +שQ93 Z@_'1mՑұ;iw9{. yܻS o/\2I'<~ +.G[N i}?SA ʓ"ALRcA*MSsEijtn +GNeVFR)d2`ad!Q 6ZvD>#jܔm!Mv.-ijoˈE=l3F[BNșEX7n65&;=K~)]y>GA{tx.ILI렓Il:倈!"αԇ 暫BB̯ _(¤̗}[.#O$k-m +[Z1*}R6s=oHmvt5&ȹrVuoMh@"1]sQ](WԭwΑ)C9&('%U}I4(TDh:蹳9{ӿhdpNfYnX?ZӊuBv[u-d#ʳbܓ,Q82TgnY%GkUl`2xjaPDߐ:dX|~]cpWvg~oOl ӹʆgLR>} Q!,?n,1Fj-Hg|3 T`QӯK~ +z[RIµ8>si|~Ň;k[}oFw 0RzK2,IL_s&or6V(5ͪ~Ԧfof{GYQ.`|WgBZ[YO!f+SQa*-s>Ֆ8K֢euKيY+7taI Cڞ*gEQː=YKQ;jKW'_9mtb7x,^`p=86Ηa\b#¥Z)ifU-]7s5}Nlznejsߪ&u3DZkl59:lh^;@7-RZrТ4+K !``st6{"*<' Y겖N+8 8 +9J晖N Nl<6 L-[W1zwD:L:MK4zQjriDl II˓j8}CϾfw@࣭NXuQW8(A4 dO)-rLaqZ w,դS$ nScĵ3dLt|M-O󙳍^ 9AUXQP&]QhGZ&\Q +y + 3 {%/Yd|E:+Lj/88@˖(IubH_ +>@Mqj3}꒘ h]̿gZ<2En(zpUM{V3 5g[J=}9Gba c?0ҍU:&9`\璚T7oל+z/M)dQ%iJš9CwlQC LhZS*T_ jەUU5ypK\k<.VmZ=\ +ٚ[59e)\1LI5 Y +ޛc:ddű%@ءH!9/ZGb$. +8$ +w."Q#d|TQl3NYjؙjUw{}VNmή ]Hp30e_JԞ0U)P|AU)R*:FR VTSxl6$ D^-cAG{uMsPI>w]NJ#G (H;:,bV٤tpKW9f^ߔ/ȱ9 +?ir>5{eB.Pe\Ѓ_fuV9}h 'ι +NKf[{|chkO{: (H?w`%1^R[a_cP)ˑ Ng%[T@ξt|gmWY !ЏTՔ~K]"͍TT›Zo5v>پ1zw̿=1>U]9%:N5~CMpwvA7~)OξGQ4y +PV[UU;up)&M;5=szthS(M&3T}bצۅij\Np &v5$=ObTT&?gITc86vnbLy2:te*G{.܂V_ͅUBWU~cYmA 4o癳:ye污Vc`x9zu}}<ԕP-'&t|4:Th[9Qd UhF;WLɵZGV}UڿR(龜97qoiM X6T=s^J뤕 L-Dbz2y)'\(CbUVuj;bɅØ/X~xE!k,: '`i%kE-+>KH +v;x<.-7Ly\w;ŕOs>:?nKkyfB #OzIb=xJ $9t:p{l:)ܓ4&I缩A{M}[~UC9醎N+YW*]T4C9/dO{BWˎ=a~7~/odQh&酮0 jOρU7:-M#"?4EȆ7I0JXw.̯'FW.7=ao.vq›$[D}x{agY1wB( “\|ɜS"#$#ߏȊ=uD6o{9`_gfLٿJӲǓ^BU&D%c7f}$KEd= l7.oLi!<` \??B[_mO͟nyF}'}?mntˈ8k_Gd}:9EM]]PB'{{6kS% +8&9w=/5bkBᒬ%GD1m9a.[T~ϐS^񨵴nJ3 +D$<\ >_>*E_/21_ךkX"\ o*_v\p>.s_^}"\LV|ݷ^y _&R߼&9g7/ǿ[Ο[~߿?O>_w}~ '~*&S钾/sa6! o9mcw?ow쪭,5ߙ_ˢךM.1 <{޴]8:|pAy}GղV*:I҃Iix&q(T<XQa\DE`F̮61W +K-y< 90>ӒG1Hg"?+|t4O-;YIʃœh-VeJ0B/[HI)r_?1 \Ŕ!ѬH}nWep"$݃0M{1\*<!ڨ%1)!o%'=h. 1fIؖt9ctЕDi9m%UGt<@tN,'G&f0^ Ƒ0ՊXc΄CL8D5԰YDXk;TMc2+íع=X*aDz q3 +Ci0Ј Om?$s"39+ۙW u r>"=wdJ!y U&9W< Cȅ +1X>H5$mJLPWz&xxiD:PYmUOrX,mZ>oi4e~Vlκ8@i?pyR#F !|l>`Y1Fc|+eH݌ lF PtȮ+SM#a[kHf7L ,ӗt1ݳz>;᏿~MT*q֓0x$<:Zv|޳)KV6zJ&zQHUj?d0k!ɘ-( W><>M[j8SYߠ5Gq8۷xŵ{<Ǣ" dNv= {$g⇇$=s" 1YqݦD4Cy2#q[qJ>Wi5#/Yj2y{uӟ5$IDm,`'lSyo@آn2Mfo9[GPEUXp b%롸z&+_x8]HV4ظ5Ij8"!1q,@c+1BX)Ig[%Ϋ7j"84Vn\4k.if^qa:(Q@B +65JNՋNEa e|!VSONa:Ս˱@RȰa+$`@ w jSx1D+S/_ K \'G Rd:_ B`5̕3b1tjOJ~a'z,aSh:?y`4I: ޱMzQBT-| YT Gp}F3.%t_=;`R Y(U^FL$^Tr$(< N-&y蒚Ʉ}<@%DWB*GìЦ=u /$o7E XwJ('E>ڒF2=hŖىv ډ&[ @i*=aRTR@jvg 5 1UP˾N|Os ,O4w6oܜbшmSlag lxk+,\dm ?+==K$p?B@lkpF3Unc:vOhT:><&.hYw4 T ;bBW&-PD4)u܅( %a-qȦ_C1ء@2"Ž€y fMCҩ +#rB]6!$"MaMWzX4Cj=}䵈jĕ/'vَ<ʸ.Hm-;C:oqVG {'OzwL1PZß-om f^H4A}A%ۛw\;D]5sCExB؎PVxmeq y8!N].!7B)h4{|N-KxpIFa+XC4v!%'5 + Y!FBʹG9Tb=NC35GDE;z>/X ݼȞ.Q4Bbc9L;ջ@6{$0?7a2~ o̐YbW慂 #Uc Yr^?ajBB2B(Bp(BÂۮD-(mt\B ]phuv3;NYXo'zGI'z8͆F=AY iEYZ2"Lb|P<6c=3QzirYɜ",_VҦ'rTFW- M1f*`FL+J #@oXtdq= ;i6mI3-[ֻGlX$ g_@j-EHЩp Y +4-¶bҳ3H,;WVe7秵 +qڰ +=Q#uyYW$TFne  2fob/ +*F1ٞR1Ld+I.P|S02c.҆Tih:2 F%Ly5 !VS{$w؛*xbuoxf-""86ly7L LPkD9{R9*;,ɪSP EwjMRw ^5ׅwҚ`IkuqCN#q ʈE5V+eB9rO#҆W<5u\0BBV8cF}Q +@ehf}Q 3tC٠XAc A]\0!aw 58@>R0A=bKAVn#t.{.4hv>:`K%frUz@tjqe +Bh NIW >7I5HJ:'D XSºUoYyG[mPH:sl|yHNdIL?/gUTk7Ȑ4Ngo'e\͝ZnH6#H{ sPpD{(H3X}A+TUihC8/\ث?l'l\@"3n "Tץ$t}ڨ %$t7Y3 M NQl&$+e#ͫ6S '˾\PN,:Yv8,\rpriKͬOWlj>V DFZxEKgtGq>MPC]em6.\EQ vzŨA73F횠v\!'ɋ߭+߼\7_zSAdX)8YJiKmŏOQƃ qvP^I0iN {]B͡ qN;|pKv(d&U -%Pl IDŽtûCstx'*1UE@ 8-tWFa[CQFM+nq)ƚTq/@_6z^iM<:'eB$<떉Ί7C +V26rεlLήsb !1Yӷpg{ZdGf7M"B@PN_6,E,/sB\4$M|`fׁ"XTP +;Al.$JV)6 A6İc{pO7\6 dYuxkch9 s<5lI!+qQScz_x7 y뼠.؋kSi0y^[LdDuPԥcK'r\JQbmw>tmb$D:>pb Ewyy/`}p#K#DKJUQjdhaobx1ϡwn!a{)NO^3%M -JWn70O/^Y@ Vs6J@Rk\pi 98M^)@S=4.ћ6-KV2K 5pXLuBǜU:q G&ϧdz}37 IG4l3[ u•@*vbf]Y)"LxՄXDQo 1r7 !փe|4׀`V)$eJXg_ڮͪAr yk7)W99v,6z00R~G VH qn:} Guɣ.*F<P9q>v5罱Tj#4ȏ$yl,eX56UYNvH(B@KVv۵.3rڑ 8J7خ*qf'TCA7hܓ>#ra7 ݾRbjO68zYzsDgE=f!V!AϴD c:90 "m($)ġY?W jӊDV` +,CB,`ƊRSWcSE\o_hתObRQ0lXƹzlY eڕ˥AmB= +hŁȅ7&E#1(C *0" ̊m0 3ndd` cLC"ضH~:@~"c%3lJ 4bl" moޡ02~Fߣe'5dsHfhY+<Pj dMwȈ\ `h 5$r@iBkİc)'5;+g +1i1B,08E2! HL9 ?!P8L2!W t2bqU0HXOYLjw:QXfsu6[ f 6F2u-HpR"vZ0Y7GL@rdA %-8J'ju lPd. /eё6+C2\qq}V 6QG'zXZY+Y- NUJ^0>є W19iAZKxT/g ޮ=lP mae}"`ºí%ӷLvVE WԶKraqk Z'߮GlPo JWA-0̭Jtr1ҜE .a!0seh92(9X# BXd,ѣ\WIhCW"V/8.oضcDcOtGtGo }v hX0,;w4!E|n#d=/vM]{uX*hh\=[83#~=2}$ +[׎S5?Xe{Mf{50+XPBXB4'sr[Fo]Bw@g3[d +^ryIA$㉩yP9KaUusV! +W N2C#GgA9+ Njb^]kV2gq'_/δ#ùMRlR vx{S?W??0-bG?#[h+& %[t7m4&1c@-. u+,eIțy[e-_=X }e/T ąF J}EppgLީ^T/cSW`P.`uH|{ KXC?XdZ^ƹTa >|U5|(̡-s@Gc+zeN\2- D˶b?\vja@ygQoYkbo =Z(^F׊>FYۙ4AahT&ʁHzHK 꾱P娫`Rs@3l}&rΞ9\ׇr#߃+RXScD}$ɾ{Vi@_+ xYr /;'d&2%凮FtaJNs}狫2kP&!"2M5n }+Vf">:r.K^m.J(ZxkocXWm {kL!x][e/ٚQI Ob|Iu+`)XM5^5x!D<]k;)W}S]0|/#q9Ui>n]:2kҦFwCߚl|LWhws ;ޏݓSOBoO44y9Y٧;V>1+GoD=2mN{*e҂.Ղ[L Py1Kn.̮f!g0 +G@ 8;ݏ50oldCP76,%0jػ{}6Fv-$oRn +Jl#rCIysg %~/Zq+ݩiǍT פ{2.${+8 G$hƮ+!X}K?ɻT` +һߏi~˧Ϗ[=7FR&ƁB`^ɾ~dɣ՛L4ߔg*t$xL5Fi_ m"S1gpl3J:6|C$6oxV:3^L9Jv+/S~U5 ->iɜy򴳎,8mȶ3(Msږ[dGEvNP# +endstream +endobj +332 0 obj +<< +/Filter [/FlateDecode] +/Length 15053 +>> +stream +xڽ}ˮ$9~]f hw +TA hѪAF{4夝sȈY +7hN͌o{+_m7oXr;-YTmۙWz?km[[Y/W +mm?;¿s%x$le{D%&gjj?o%^\' ye]Z\ZI$f̽l1-(lI:%b\H9b*i#׌m-&{Ho}AM}M;L~_w#|6quW}?:n%|4YC>z*˼-e>04 k|[l~wtu7tz7{u6v#[V[}vgGqJnJ]Kωm>/Ų\}<.+s͢ IIi ܆c Zt3].֦[ӵi.l:26^KQcӺb=m\+eG[l\xAa ~6oY{ژ(g c4I^,$3(1C_y,.Iֱkh)mMKk[mùP3: yqw};䜟ZkAu)N ɼTis*Uku;Sy-~4o&v։.9t9v.8~{Td%_n;*L 5?~f^(N ˎ!ͯ1BLB`-\1[u)OT2}2׎* l1--P"ĭ?̳s6Ku=a=sTO'SZmO瑽 {P(u`0ǟQtnO&ey)Adt">C))QH.Nid@WȰ}D8M*r q})A.QA <>J˂KmW-׉=hkx.d0Yp)zcvl[4]5PW8o>$[ >T/mn=oH~#O8B6S_СGo&y᧾$Yۿ>~ ~ ǰy~yFWBI6ЭĖ" Z +=6{G,vhk5VHy%)gٰ pMHcܮX4v0kTRQnmgc 6(KMk^;< &کt;]6tKoЛrK^MmQ{nE+@Ťgse6>@t^hcҎJ^)[:Z3ل٘Yw@zݒ֟- X $"$وみ^UM8hhʺbMT:46ӏDU'LN,AUZ嫬9MՔ@1K6e+MD%L FØ)yvs9֥׺zTve45kIEEtqu/?޶ޖ*bO6ށ=4vf}[liZ +6Iޥ imMXROyWl='/Sum m6W #\Q`,GMK[«:hC]UƗL3K]Sp#$gM5ƑlVᎽd(Iۗa_'dA4kI~XEMK3h5ij̳qL:Tzҵ>mLv;ѼtI&iPB:<+&wQY{ͬX~4:ߵ@jMke_Mʯզٺ ۶UV7[Mn=@^![ k۩A - (1igF $ð*C)V~j=WH됞5<6[mlAAfj_Ye[Il*iQ1Nh l AiXҍJF {XN_/1pKo9'U +.Nmؑ/_cY6Da㵬&0ȲĎ-\wۦl:ՖtB({Vh_n锽kv?O:c4LWIf06NTKXr-a6,lľCXR2zBޖ*-E",ŭCK[pĖR\^:D0--⋁6KkvZbS;QB:eČ6mŜu[hmZXi,Wȫ)l5-X1fmӕԾЛ^})_}V(u,ϜsÊ6zlL341 &f̵lwpJzϦ\ykɺ[}zTڍ66c6|C7bSB: BYcn 7F ~jj{@gPUރ zΏ:n{V&B>6UsܨnI`慗.)߁6f>x,P }U(q\w;Q$N?¶•-cAp'u= tJ`ߎ?/{Db K<2P8c?ҍ!۱8K{?-SnRgźymzuQ@)6yH0=s;ُ=9F5jXr%`ɊWKCo&&}3$ma7Ҧ֛qs I.R6St7K6K3] m4Գǧ~io f0 +!Hk]:X#ܷw95k`n%}4*v`~W6l ϊʔըݜMO#K0E2NeqS8}0Wlp FPxH1/ >u04R TJqҨH%PJȣ``REJ((me2: DFbb@(HaiFa`v9/ux˿&h=TAo[E_%}X}Xχ|[Ч~E%}ԭWܺYF> /ӰO> k//ViXޫ*b+]wj}~+4.ӰO"?/SOB?J?R?ZOVg X,/> ij>{1d:OOZ'}_WO~k~+Fΰԏ+Џ2?"?O0~ayW}Xǥ}\c' 2$]6}pFyg'׿7g[}~]K_A>] typp˿]aqqXU~\5oAa;GH@= _0I n:oOqq>=b uI?p\p%p\}puƬ2Ő:Y@dPߒdWCƂck+ YLNNx&M2vKT?3pfj?D=`I, +"JѬ[jz-8UQlN]AO p1[ik7χp+L٬JF'xW{`C^̒hkA#I\ׇ v u!g],zݐyAv!硑}q y,WAuF ɥԺ҂NXr d+)%Z?j?2vCчt܈Vs5p]γwdIgvGh0ZM[ې+gd pE8ʇ H&qBt|pIxQ!!V!w9--`yR]iH-4Ř_r9q̀Ɯmh"Bλg:R-nuϼq :WܳPR16)vCVƚfDF6y=cptTͯ2eLPMWקUʉi93#E?X={Gf +2p+a҂~&s)tc83/~7Vv8XtFD㆕h>L`!+wE֊[rݞ+ @hvmg66E67P")e /}4|ϩO=i,EOs\ 7}`^v`⃞}~/2nYE +|qY;CЈ_GD0yCͭ 4 nnC/w*2->fJ:M)&hTM35ܲVKub{UR2@N[,mvuELRf0U_͈}E÷p;1Hr[ׅ]zZ\c͛Bp|g*,e??D-+IJ͆ ozu]<8uqCB\[NB۩77Wql%Y-VËZaհ8t)\i)i P@9o"ޠa;鐁1[fӲuX#l+11-E +0/`MҮ q^"LWW@ ۃ + +{ȫ‚8yZ֖ sgY:l,5Ef'I+–5WgWQg-q*Rt wSt&R_RML& ֻhmG oPek6b|̃ݰ6ɴzؾd;vUP6W\}wWc*CwU~|*ߧ);ci_>n.[iQG4ψhq.8]3Ћq\9ѥGv?nm_>Kz;\bc<9֛C^7U.p ,x?>ψ!vQ`9i޴F9޷V25& ž}3w!6F83Yh{d!֥ E@wMѿq1iϻgJ d}ޫ>:##n k Mu~/:P=v&w|Lr&y=h2~jy|ds)Ns>MR.KoA%R[: }'Jw5 cgxJ-W}޶YFo it}Q %C]/˽5i1 ߓ0HQ%:@_e-^/,6A12bя󕤗ה ~=kY늙®1:1ަۼ-?v.}k?nit|_?0-ۧ_~o/Ο~- R>wejŗ?՗?mSSIקjPy'}h}rkb;~!k٢󄚟 +eWq{|Cvss+;Di䑀AV ӸPn];y+Km Bf_pݑn9Вj#XGfZ5ii }kDlJAX֮f/ѠdcC6H@6Ac5Җ(UV\PY1}1cl-|apu1ˀR=~O)$aȏЋG.Έ409 ) H`sNpJ>':֖%v=?4@Add)Kϓ$kҴbH_)$*dmhw•6eHBw)XϽ Yw(F;P^zdB0je6 2[i]LktV+8`ĦP :bõ%RKT"5+bc=7`IUPtb1eDIП eXD/+j,INҬҰPKS!s B~SӬ'^"~4A}HDy*{O>m Li#ǡjI trT͠@FPF,,ئ,'ǖ2 +踿:n2٤c*'_)Bvu-H#av vsѕȖP߇qUL7yұ:2"+\"?$pZ,3Tm.Q) HSUz&3ɇ])6PR]2Y%Ť^Y3"MlBlZ 9J_yQ*ڰ@T&/4j4'jz(1eQ?Sf(:XJũ+H#@ Gh5 %ic6C('y)vlcQS9+Q癧IVMa(cX1Gte8 <U@92l1T^;!N:\Vd7sߚT8T8[@B٥%MorO N૨1·OcDҌ^mN2 k\H)i8F<)&9wKU,Ȟw[0YYF uBCc. {|@pq^y`exEXYEF9`#(MqQ6OM4^[GIFjqTSn3)H%B{PkcԨB2oMpLՀ|8I76&1(XuPo+9V(BC͂A.jOJ|]pZMrU<7:HZ"W*b *%K9_Bdё;\ZجL#!IٌLZZ۹XAC20)fH9X + +$-\&< YvH#kuM%%=!&v,n~  qX,xh*ѤڝuaP+q,Ǩ5Rs,X`?ww)p#=ѧ1ucT5I'^+ "iD{^˾JThtg ж߳@AF !uHk/>4yn'%\z& eg{7 xs@hA>\!Pe,:@ +8:;5& +~8&-j:pp9 oS67B2P.( 9p֡/xa/9/ zG$$O,q_C軐`, Yg}`҃ *>8Bpq혂t8TH9Ux U@TJ %'B -KjAH $SG's9ʉ +w@]JDh {-ǮEc@= +vщ[ JV"Gemh [ XJޠGl/IwWz=|m1M3y;Cd8/Ϯx[pn L1}\/ڏOH+]qfP[K2rvV"@.$hKL8;=J +ttz2:AF2,\:8T,@r d-ɑ+FUvsǾ ơId,V"B{WBd-IIdpPKYaU]Ͷ׎I`9Fnbfi|>+C +L%F ( 5p(ISFM[M[HD眢6q58$ E5.18ęoaY;1l`2>T4^$FK1bM޹c%$"!lCC>vt"p`=$X`u ZBPߙ+4bCLMaLħe|f0Hcjv58 +.Dq<ƗJ+6%ą#Xq@ ^6; >"PD %$"b YQD`B#PHrxlN E[GD_`'1]RC~OQ[bh)SH5e$/Ǧ0 "Ũbu-ѵg]o~~c5&mCT5&CM*pohh/k mW͈6YpxCgsozuL7'VBAܶg6L0&AI!*+b {Lf{leOJ+ͱ:Q[c_؜`$.MJ#}MI{DijE޶(#@dalTrbmL!O1JjdG 2ʺDRp \b1S[i~g~^SD#J[Y9v +Lktzs+٪TH;r@ +;|0 ۻWIhYiƼ%:9vLǃi__Kf|IkPzoFv G̟ㆤT %H!O}h>bI5NMB0{2kl1>jL, cIJ wl/{;q&1( s%X6K-\-f \jlgEe0e²/faS-W;8=,Ֆ K*7F ˵ǍCM$; lIʄiRU_nzHw6`MksĈQ~m_t5rDܟ!R0;DԻSbm̒HːtQBӋ,h۷(-x!|V)i0mC*!u뺏Cxa sqK]bH2G.Ao`ܑzg$js<:d1u3f.sS;2wzEbF u2rFj RX e gN3^e2 ҢhF,MN!|&D~0'ҔEҒ2+iJ;z $n 9cPAG\e;t [L Jx%8)E)g|ߩ옷0C?tGlhl0[4{7xT}L-׾HX9* Wshtn#&URTZNu +#ͥXUBLʢ)4 +TXRc'̜ZZ,p`2ZiuQf^óx 9uef-xm?%F#-;Yg8`*G2[㼛хD훨6ef>4i J(Yj",QaECNsJ="+ĈA렢oJ8vlRO)졭@f!2 L_Ll]T( SFح*%@ph%`Ve@|s\8S)>\#,e=5`ࠌˏ^ |8q4IE~2Bt#pF5٦lKؓ羬'%fȱc( +=[^"F=i,`zXUUfFaUe0aM)Ot%=VIm%_뤬Z,gs;B Uf֨:X4%X'TbJ@C)ւ$|on>X&夅CkflBjf?oIc$oQه\"A0er29h +)g=HUr:M`D{3iYuADb:5!}})uH(; &[*!$m~RHߡB2bHiT`I)d̙UR4=x2Ȑi%Hck[X`QRJNe(M"m(.uCCh q3!HmrBx zX5JK*q+Lk7@\OMV +}[s Y-0 MzuӴ> +stream +x}Ϗ$9n:V? rC?#|= ‡qgw{v$~IEfVuWa0])DEJχOϭwX/yA?V!]XrtR/(~iۧwpeae !\JbE˫bgFBHB)*ߨIb[ǒXw:T˸hr2p,IKZcl4M.K|r٪"9};qL?,IEXG[y̅߿kpȧE +k4%Li0 0R굾 K24k؏>V]Č>04e%TULq_ckڇ}, hD8n =O1 :ؠt:/JMA|P,R)gbJtK } +X.+z制O1,& MGkw>@ t + >(}O4ǠB|s}DG"4$RZ[#+;+5,DU`nԔM6R6OxLLuk5"˾6wKwc&`-c/DTGgKt2 80C|$;}ȡ[eˆa6zlNtYMфiA|yZHߦv +,o+RCLlsklje;z4lCd4VՓh^fF{EhF(4jH>m2@N{j%CX{]ؓxeEkk.ÃP/W}cԋ "4NiIB@-# S+ezqG TwYbƱZ2Zrj(\ދUL >rPۊg)Eyp`@y/EW%q\6\hƎ6a"@&fyٺD>N3 ˻v;n. +m Մ\Fu}igQXӌoc9!;}(WdنXE8-]N;w6'I݈ ͣL8L̅aO>-L0_Tpy)_^Zٌk~LmvdA{ [~r氐wH{P C]r%̢Zz"V# b/Eb+ip:4h1ߕλpBc?u;VmZذ,}ջűK a2fv424lkxUgg]5x5 օh\Z߈pMW}e=L_ފwD `abpoUƎ|,2 4:(U+\G S_%-$h!k]X%.\PmWmvFHs,-0sEd%b@H@vCMFVIτaODMɿWɥAm(Fz@7 9`$xA~oƳy!]%p$ :$DƮb[}=x +I=]Ta 9Y>bw;JxN- x%JVtm@D_7b<`˾s)q-Z|W79J܏^%.}+q7nw$#K")g7}w#k};0W+r_" d_ +f߆]!z;gWxB*3Ra\-N09~+[?Sx0-ªWW]XS{ë)*T[O\7Ɨ,U.p9Y'.@xkcdi;7Dv#Q(KMBh&:[ȼ\=X)ؘ0e)ܱ}M)x(gS H?+hHr~ŷtY璜vtƕz&*Drr8ro+H9^7yDt_K|m_vBGJ=׊IM^RD{f% +=|no.`7M%Vie_S7 rYkx?pPJC) M70~xC[[=zl_>OqTkhR?ǿKa,Na+燏uuJ-rRniZIhqr[&!cKǷTi؟x~˃W߀ē$xIkM޶i_(m4 =KAҚnv?/x#φ4у`J)LjP5SV9@J* (=Ir>,Ӳ#ԣt*(эs2 +JR}TLa^e% + h|K4>c_͸Gϱe˲!C.B(+W^6i\-#.MJfvuDHF%٭ 3Pn-, >)a,o|,q9 LCG[sK՚J6J8NJvƻ. v041^G& $&j$&k>'4FQBu#c,Cup1I2Jg.fzBr* j>nHuW↓u-?liri> ma|h^?<~9~no&=Rչves:g:m}v糳9^][۾:qU=utězLv8sƨ i-8 Ŏ2rqNJ0ՙf9fF_75nI9ɇ'\ 0)}{ROFA;VIʎցLYq|OkZQҶb8F_1 Yܝs{XY6@/Lֲ$#q*`k"b&ZYNF-e >48D",Ի GcZVJ}\@IIF lIt715^2i/ě**tM?< 8ZGmN4[=) {M oQ>voٶ04g0[lc?8Y-)M0RO_grBRs.  Lu gk>/x1 g~ 2"PmC(L\$\$=0lprU\ASsr jD_8;6XDT~d9q~Mj_A;/R@F/zوElPlX<,,RaTуAt.lRp/^%̸9>A'UӈR(I?܅>ъ Yquu"^0J %!8ωcU"P:kRi67 oс0;XR {q^p$9 uNbJ)C aaSiPdL  >< K&d,XkQ$kq2S1v+6(IE $OGXlx\*2b&,Ex?f +vͧ1wK{ӓا1re=5|"%"N(';m&VK?H$bNr£CQYy6xK}lNZ剚N >3~ƶB͸) ($dbH jM\Ʌuʪ + m.!Nxx!׹B>v+0V3 4đT=T.l)9 fĎܐ5g;ARtsҾj8y lrC'!q2k ⩊oXme\1lSkv~ṷ!=Id%6 I༘אvS;Vehh\LA,"Z9=;A`πa;DT˗ $kŃsN{QHƓ ;!Xd+(nۨ氕6^de7X`c36*j}^+#j6&lU,v¥PPz}?ce+=֓c=K:XaXkNb*䔥`kJ:הq(rҔ5d4"ZS!ڈPXZj%mmY9%95x<(xs9i$Sr+)qDK' AH#{"o% Ȼ0BrTBƝn‰ud5wm$ kd$('ZblK,d84m$jYo8K)@Yvo #Wst]5>CWv8GM,W+>:*}Der UT?'3""kB +(=V^L})IݥbB!X/6JDԣD2\^Dsc&&nATȻ}V>8!!̜2D|hZ'U+#S!ySwt@z8uʨx \w\U#%"6A0ǒ\/ck&%a9 ͌~6' {A e 4"1~u{rYkݠV ^+L,V rQcQ7+G + ;y磨ǼOxZkeEZˮUMXpw,Q﷑]BP#͌/`v@aű{f{I*(hc3Y.U:+%wO&#ELK圂&fRgZuΐD%wl1QVNDy@Ai&x\;pjQҎZX+C%3ZɱVpMsgT?/8ҵBHMbOM9(;wT >z$?塶qeat *|}ڌRqs +Ig 1Ig <_i4$b;hIr29`ez vNry;4=P 6NȜY +Q+E̼uĎC\a1s(ڊ<(besMV`(DӢ #(lNlf6{*dʎ5 ^#W\d^ȠS=Bh؊|+`aghyWrhC3G?P;'7wD>hbirjvΓVk/ZKvTaOKm󒪿3/VNS!"6S];.L{8 #͌vLExuy1q9v||QQGkeNGY'T=_Ϝ{Ʉt˴098ʘ"b;q,m=_HؕrS#  +~;f̍ANפ\@}AxںFAkiDN8H+vnA!&6Q9;P$1"V$9$v7irs0YV(DiabО3q0f#yE#"V\\$eDHe':ƁA8?y2̜y9ey -OŨ QQ1c4R'5A:3ɞ* 1%|E\r(NT(ukH8ric@!JY"bJ9c ^$oLN12>6QR>9Y%E HxigI G7y'&t,,@H9V"F먭:j+%!4պnu; bў3q7/˺VHs>ƀ%T,bbRIsY#U8f#AaCRӴ2} P;~6%u=t%Ճ)leR-(lSDmd:RFm^г s]0Ǩ\bJj*\4ƲkG_A +V/b/1N hu̷yye3ӼOTj_ץ4-fܛ'vu{ U6#.W/?Hӏ)>OB}x^˥yiƻ}Kڟ~Kܟ"/kwRyZQ^mR岎ォ g8c%{g婭/><~K+qe[(v]_> OR|/rLoF_ "Jؚ0cs+էߦ7].O` qtq1S:d5qd?P)7qt "ޜ wb| O}^+u՞D!~hˉ/2-E^jfbw'p vRn[\oobq ӞcT?q7N+J" ~ck#8"`jaf Բ{22^ntRaxm79XA^ SUq֘Cx9FO@Zqp<1(.bvOTKM5֦(aKYx8_8b{uvo67iomuMawGvy㰻KNZ,&E:B^='XG"•a,TNo0x>N(HaݬboѲ'ժ wi+\0*'à־n7 `?!yLFQsA6^6#!czrכ yQli)dEHGcYi@(j>]c36gyu74G$^VМ$=+hYzFkMHe粮tzլ߮uR:enieaNkg!i{*y[BٷxR14e.F_㽂y9LwOW ;hKTMf4[>%5E.=g;{3Yq1}Lǽ%Ԭ[C.E"J>Pin%[=tRTŊWU=M =#&ߍ9]ӎe|eUPŻ;PO[3z []Ru_UǗ}4r9N~m_ +endstream +endobj +334 0 obj +<< +/Filter [/FlateDecode] +/Length 1872 +>> +stream +xڥXێ6}WyJU>H6iib46}PZ[rem;3$%ζyH$ >wG!DIs[׬e^5;&Vyi!y3o*DL pKG1I(~), иѰƳ2S$+Ck1Z|B߰,r |B$YL 44yD~4` 6il +te1&/edڞ̹w{ß3 W< %0gNO sL I W\6^H8{ʵbeY窌j8SsVB] _kr^z%2z'm,b]+QǤ,ɶU+m%d|Kn1TŇ'xِf,o4?OI.$$+DR +p\ +Ur6U1P%osDC-]Wt&c5yOKQ;۶rQX-3h}:Z󒔚(/ZGr^+* +Zg£5; +iCS'JR(=BV꒬b ɟ,a30-5;Rڬkraޤtm'}#+z.%!pp  e7&\՚`BK3i\ +<0ܤAE>Xcբ ]2”XIu(5U`_ #сcoW / + CFb0s)%0kgbX6􇿱@zN_L25akY)򞇭vȮyxM˵ʵp-Y·>FN%j@Ef,.W#'2PAA$3gAMe4il6 )D'sN :T4jY.ޛY.uQȏGjw+莋繑2tqgC*3oStl( cJG„dKaTq(j<]BYTD᪣ÝoģcYn[L60_ ͷb\wXP'Pa퐠uU_o+nn}!RvVt +R=tϰ;Jf`xE%v4.]8C!]0);**KwjB΄:6{ KΔFx?*ϿdžLG> +stream +xڽݎ-;x"/1١P1wv h\ncgL""URH%Q$ERKzٯ?]e/_^{/]?Z~/ﯹΏ&V(˖sygjGտ^k~=@kNkБ_'_E1_lrhqǫ^ҫW]{c\Ým}$B~3/xm?[>_r>Jrg!w+Zz~IzhU(qdzm[.-?/W}Sf}SrcגG$kZ'Je61iʨ=sZNX07Y)9WIZLu>k^b.x_2iYO^l8d8_wE, u}mK7+X2J p:ij _WnkMׯ,o_k߾$#Bˏc6ue#i6[.Swp_ۤʵį},EklK Q^"d=g'P[ϟteW6G[w8UYï'r߱z0p]j_K +qRFdD=Hfإ2'ɦ2P +pUXAw,|X&(_w _}. ktD RlCP@CP@J PBTbU q*!c;vlbPҢ\5@ Rk~15GAp;+E0@kf&k(Q *UA8ee.8JM ePl[7vLYxUtOG9{MfӶquMfc0ͿI#vh92Gj;ۃS? y>m.%իGX.iWM`2J˴F'nˆ<tIc fWljD᱓G6?c$X敡 n* 8j(Î = FAR%2%5i67ʒxͦ.x?uB)Ū4$"p55vuŵҢ볙Ef̩fjV}:BrTVQ}TX[Ɩ;fX&2TcKʽVu + .XX1jzف^q^΅)pNU޹w6t6cFfPU 'Ȯe=sY7ꑜi"Y0CMNlF XPF4;fYx֗ƋM1HC)1e/:rH[1,F8qکCL^Tmfp)Q8.(L1){W.Põ20O(gXsᗱTLE\LrWv;F%e Q*jLb0ThLx^Pc,|-ӞVMGUNlEbYrde + HZHpJgUHj;8.ݔ(S5v\o8V^C01wH~o6x씜e#~s]j=W=^eLo䯢Cw/"MP> ލRL1_,0 t0#pK'Q4W5!}$IU!urZLU$TgtL[bOXIۼU*cO(-JN67=5 +pjbzuTL1QVyؿbg8)as'јz6ɎH(<1j̬.`N4|֟k m8n3M!!U;Ek7;t{* \eh݃޽VoDN̄M%R뉠S. ZM  bxC(dUT5&n\꺛wIx7nV݌;mB'.^ N}4M7H`@#_R/ #Z],PS}cp~a5[,Ia> +6n30Xe[e ,0m̆,{pӱ-2,{8 PnC;|s"d`Xy:mOէmdt)nO]۠s)Ԩ}ܗ$nTޕߏۦuק߶mOw~n6\LciHNPNkY;yֻZSIF wM XڎJH){w f\- tr.FIb-ظ}[ݍbE:%Z=!; .6<ԉ7x|mfV#WZpw2SɄ:TtբKl58j (> Mu CiKtw¸ =5#v ;KkdB"V$F`PA\XKh[{n2{~;ץ=[zmnI:+a_8C +}eY|kKMM^rmb(ry !7p<0X p?IV/: z:tmF0h皲:dtj'fn?խb<ҕ1JEY-NE׾ýёV^R JdW]9Q*pVu@C°*$Nc@\* 684%2 ;iE +uv۴vFAjm:58txMU +(5AG-fns$A?yY$Dn-^@@9IHG)1 :Fj/Fu?ODqJ +33@m'hY8Y_̢[1=, q(A4'2;sgWa[0ANz<"4=`&ɠ3EN+. iMVݏ4'4]~|'JSz(i Go'RtA SC`8▅1EokX7R9= 匾8,9/DSC9>߉ި.h4:uj;1jT( f1:@' +bx8BfftZԏ(Wz~޹B Ujb5eåC:`=ShK߶)@6vY~P=&X(a#[@dn>UN# +)z U@CxՁTcҷ/,b5rqmJ(tf$h: t>J 19 S;0}Ajr Г.z+a'T (625$TXW*IatB2v>JI]кjս7SWUrg\!(":%U!V);&IU膿%ͪ€ OC?Q^< + mp +PGn\ͬAm +YCtaNaaoVR苴,ƍC+,p/@ʘh,6j(LlRҘ]>P6;h>i慏ijȓD7'?fUXd(ocfjX]FK[WĠD^\U~yU \##,bD(-k@ 2BsQ\Sssw]] PѻmQW#[$fe4I&l=Ñ+MUW/n pfd5svsdsgͽA6w?6(l|U^=1>\]8p?1g!OV6mdcl?x=> 3c3'lWقL"[U28l[._dwD)Эb^#33 Nyǁ_#_/TɎlaf'uƙTnrv/*sN/B|Gz6/rS+j+\YONU +rᕝ7(遲k8vgzCxP3KS^Tʼ3/{ nd|{GmU%I d+3nKoM5dngL3c73 ծ8~]Tȸ-MŅA`g ɤY-L6ȯ.«ˮOh͔ 84bth-JG|)u .ِ9u>t>uOsr bR/WRlQ|:u>Q>iN5}wnۼWpS`j|;Y6/P~Cyuش oo0z,>pOs7yU,H?gxtLΫ_2: }ꕼ ~|Yv .%ydt}IΫKG2@D}|~c|苼z\ed_{[L\9O!=7^o^-< }9q1+הqeM&1s[wGzG}7_ϡ~́{0c!MA߾UA|NU\AoA]=:š78qp1m+oK0"ѷlrF_\$̤gF`rSJw9?t2zE`0}ڢ~", "k4Cۭv0E3YWQb6z-ji{ȩ/ZrԗO_.}}up.]:]&Ğ zl_c06D٦#g~7$b3 ̌і8KU}e^2 s>5s: ;blDI]+_*_s[ /?_q?+Hj'YfyasSF }~Yn}SJSSzw^zˋ}Q0? ?sxk#֨Mg>gF +Zps$i̟h}&3==RsUvah1J_CZte[Mѫ6(UigޖșƐjniu.")g=<ȫqwDpJ_nώY/`[ $l22Cs}*7<})>*ӄ.2QMKkr^Eon49>$n,ܓ4ݸg}(8|,8$c7*쌻3>7<#F',|rLv?u~2'"ڣhw|)9yk~[ jyyfy*|/4t/5kޛ,d@j[K=ֳ܂G~lp4e|ʃпxLA.O]xy_뀌.L9s5ݟz. uޅ=E`8xB{w&Wof虲O}mOLo1~;04"Jf)'_oɟYx{+Ȍμ>62 5vtζAwKN/G!,[R׎9Co92\S8ַ2S‹8b!&oE/vs욘=GkXD}E?UΟT~Y`M.CUOx7ؒy呑 C&,I%F*3i-/_iK^.vJ[iï$%욆J>eC +yDh\>a9 +ʮ(H(ao^86m$HܺMiAe{%TIڐTv?c!N-P)t%s{xYlf9EKPAO rUqdϕ!"xrx  +YJIG,#썬FӈLrڏZ0f$ 7u۰>)jۙIHu`N0@x' 9)s8JwkSisI,"2W$^9/r"ښX[})13k '-`N<>v,3wbϼn3ϡCJN"U'24DgʔX@eYFdr& Km>}73r]sL>dUqeл 8 zYF΍X1\H%9Aؙ@Um'/ 3brXdtD9pPId}/5$_) ȌYCbP_gYYL€ O""Ihx "*h`b8q=u2K0`bsFL;43 p|g5|s%[aMV19<O4ʛ{);A&g{4jAd3*ܞ~IkVV g+QqGN p&ד`ȌAȷZ&Lq]R$nCk} + kÍp\ *"+ iH¢ǂC8 dI);@J7ǤBCm@ 6i-Y*|.9 -Qp2 5b䱖C+fxƫɓ5}W6o֜C>>h)M$+nI34/Ⱥ +8 + 5R"lhcv\,_ +S"6(ۚ'z.΂Xn>1ng)h0ϡF?|`q>f=04hd靌d+5&i&M,* +Xو#Hנ%8*\pړR9q RQ#}dQ9ǐᅍ®sP'oj7"0%՟TDX%Ux0pMp#kj;;@N/ wEɲe&UzIw>!d{,6f P|zm]ƯكcdN{JhqA`GY[Q΅ujAΙ[T۲B: di},(3@*Diw~ˀ YJަh|@+$c۠3׼ pVFokǘ `U& +׺S/eWJRYϪHҬ񬟤bVOd\ʟ} &wQ̔.,sX=iUGZ\}W{yFт7WK q:M-|WZ|f;՚26Ñ]QgwtsNk= ͱIZsп uy`g[dQM*|% :_DHX-z :&$pԑPAC}@RXA܊2. +kJׂuE U Am^aq-|^kEnŞsXV\-{^uUN\MlKPDⱇr읗}[1 "^!xr务ECR6Vk0iQ"ȟGd{|$g9P0@g\q0r8לnO欣1;| G0xWOdguKT\.}Q֍1W#NhA3G,eN|bU:aXZs.mU`3IЀ [t_շE<M3[hwzqH@[RY la"ā5g-2aq{L SM>&j3"2t\`||Td)f݂dRCOF:ФRǻ9]mä́gXgK M-jȁwi: 0?0qԴ]̣[jg^N*%#zȟAȞsićy.oX#S=31XO\Ѳ4 RJXq²{}+5]\8phm^W1WD7(O@p:VmgR \'J`Pb'É(Rd*Y8 .8sKRCv# Mjx׌ďjΦ^l-ξQ.'}2~T&ӿCEpTmH9'6fiDaPV*&Qv:uX +w_H8T!)Ty0tuZ^9IgD +@ ߚw&-bC & a5hNm(FSŌͯ5tK8d8 IqXN:M)8WghԶ +`x+u,QǶuve7 k:m/G5SuI̲,4kGha. VG?I-Pry##w`sk w,?#-/J[ybNZCXcЀ ʒ X'`,࢏MXҡW1Q~lL1tzHo!яCGWXJƤ`i;2i}2o[=1 +``6쓁jK@ɐ#֘Bh;_Ae3T_P*Q(֜F!2HS#v- 0@{cE|r`ɱ&$ȣX3\p.-( ҍ.;KI +1S #޹$0h +OhTFiTn @ĬIh1l`m*ڱ7ћTM0vO]΍Od[2?!(jkO:yXt-fDY!fMzITHZO8d EqBbn" iAHtOG# ${!b71TWa0i#e&3cB"1Hp \e!L;70Bg]􁴖;x7:y\u`$\ hRU3AX@4zb-5<9QT<TB3Λ,GsRH;!٪&Bz]M/T1rB .teuHg,uyp\ ^5CVp?aw8r%mƞz;4Β#ak@ +O}d +LÍ# +P:ۥK6ѐ0}E;6}œpeQ>wN A305DYWdr Б=Q>M<> вOl9P]*&R,[Y|%E8Oq- rsR 5ΕVȝ@D!j𱏵M:%*P /R3 0XOѵVʹ4w=$yOлp>^zmUD{eOOI,p rA`Um?<4dʸVA,.B60Bq}&?q5eۛqkuXApu +a;tֺ#R:s&&uPCM+ ^Q(q"eITA8.l2#X@T +m@@- +\=BF?PֵbOu/n(TVԕkP~KYtإQu(ls.v̧I7DF¬2&:_uӖw3=;/JbYR ßy+ ^+Y+ ac엌 C:sX<^m9ZNN79ms]\YCqi7x]} ;Pc4Ƞ~okZ{9=@dWm'؈xy4C_.kkV.W߻LA/soխ@ܧDM-a2XL\1 L ?c,=y`ź_]c`Hvbו=dg*+wq o?8%yX.a0 7Q gJ09L.D3[RRBd>Z(t1wBZlaƙR-īL<,3g, 9CT>ceX}.5gSCۖh=[ cCW}UswxFz߾1 +~܄ʾ!Tfe뼬OVf=]jS!ce8rb0-,)SĕԤ#_K }S;avxi aˎwx8(k6E)|G2<ⓒT 3a_^az P]_} IXthGq;j]wWo!⠘$2nTx8ԩBUַ!;ɋd4e`cMV@؄^!ٍ5ɤcLWޞ.pr>qX[0Qfmf$ )4YM5bHv]?GOPr{U9Oغ,DɚfXZ@s61tꨍm|H3}W&fB$kd晒fꛦǂR3K3v%YQMg8_j"D6ZtĽ3̦o:u&Z#4bJp;`=+Cs]zΘv#G/04'I^]^)Eq$f$ =_n=iLs+q̖?-B1~]v Wky7Jg5bl88`([Y>{04*D,*4)sgzcc蟗G5RǾSKC''f$:u52j.ݍ#!~9w<VD _ x%|y:lvJ4sx\{AHBH5@:[0S3k -@0_~0k +ꝠV ؙVSn.~+\'c͎W4D,$B.U,Ҡ= 9 [`_,uy.X؇gf6fo& ( iw77&Vi7!@|F2ɇE.޼0܈=S;mQUE%S3詢1 MD)!LD }nMNX!J %|Oo>n-OYgfVi a򅧱DňN8L5MK{PX,= DR7gŒ*℩Ig?VCx:rJ.pr Y,s3f$AD~{ +@+>|t_y]`h3j'N&uƦeYwyf=={BdCLĥ2[BYG>m+HR]Q,cWpJz ̢gOצd:,Kog"ֵUŖ|1N9t#-?Lj&jb['N)EEEb;a֘qkWŸ_`1\k8T۲jš)~H"~NK/?pG1O>]اmtGr_v##2?D +z}^DA֐i $8>ĽݝvXGe"7xCZ^@t JSg+~:KK3N?RL~j+u}Օ&5px N+u_oT5$:[:6^^ЂcI ͥjVBbo+NT;ZGCP:JXE]SوjG֑4;6Yy"ϊbefs.rMT\Dx5 +h͘sDžx VG]U\Vuv+4_3ܐ0 *iؘ {@@G<$bce{i?B]rqAQPALؼ@ .EBoLsҾ4 ,\B+`lR -dz @80g23& 1UjЮL1^rZv!O3N@ƫ.u x)oDR?*ݙ>!]uюDvOsh;庖]#Ju=uP#TsW$Ktђ*K@H-JS%P%j^o8򍿲$JE²Ōqs:&y[48.yU{ +|?gQzN8}8j}AщMa^~+9]B>3ĩhć96C#17w"cG!/ a,VC_;uE'"祵&0\Y/۳-] Lɐ6ȼ Ƅ4k#ZnAN':(rز|׶4^d |Oć*i{.;$9 nyo<{$P6-кGfPnIZ>v<4&KV.d> +stream +xڵݎe;n&xOyߥu;w: `􅧺\F~Y";"3 qkI%Q$ER[z|;Z˿~{mv_e5K{:^Z^{9W_KV/)~{6^{=K=ngq/87guі>R:۷^{W$~iJ{h}vK_[>^Hjʯz0]>ᯇЯlv[׷o'_[Yy!=k95[])'.Z'zM g31KxZ_S[lvkIF^dAC@l\76׭f]|b[n)N.-e<۶.wV&feЄ: s +(θَśd}'"n oX+E*Z\DC&>JL䉎n6l'al '|7Mr*?Ƃ +Bo!JWa(aL[-G'= <\'$AIMhR&4Md&Xŧ4ɡ4im޶UrB@V4]8Jo7itΟ22 Ly:L}v'UhWiyVZE$R5FH;tf&d vm_w\bRx,? xnr`~ ޾Ulig` ʮLBzƵSΝx< l8( =ny`)'@ǹpXyVuo*8s\,FO*{SCg]- ]iq "o>Ig,N'*|)f 3ҽVdUpk8j8 +6@KCIƹ@sƣ\M)#)i_g#qz/CbR˒ +*Sq?Gt&;XwEVbCz4"_0=WMQG;N?=== 3F5*Sl[ӉE6j +H*ڡxʻ\ʣ=KSJe+-B ѺAڤU;yn.癊S*^ =Jcl[F.|"7Et@0i"EunT(4anV[;IY\Ȳe ~𦪁iPyX,{"T|aJj"[ЎO]@+Yf3z `vsA*Io8ZiA,;W NY3d{ECIZXjOu}AMG͙nr +PT[)8'q06.B:cm *Jg`훮u,@0@[>S} d@Y>@D9(D F]:XT*]E"ZQCIisXT36%Orsԝbj\H :V_WfڔPvJZMR Qr-5j{R":H*t-M@5e +Vd6)nG"M0ͤR&UwSdt#+2d3*dgv`!usTׄ +$&BLP"̣֬HM%%[d55Mj8*Γ/hժn$Yn)5Y¨\p&ьA!*UYネYQK8k4Ή 4s֮ 7)u[禙tzQ4^YqѼ199*o;W#.5Չ*}Yo QZ8 Ó1jBwEe KJ]7=H@ۓlOAd\eD)V1i8O%ZcPer62>K\HUk`*D̸6 Q7m*`'LJ#fX@/TD+#yQi<,PUnjԋBUV^Rk6^Tң\̝++?s](_Wd/} ^taUŤUJSETo3Ɠva10eW]4JVih<3gAZ dgnr\;^,wn U 1ϓ!肂l1Q\QCC{C|15CޑL@:?Pv3xTaCvhv>XmH6Z-Q.۾`^WzVLQ;Bânv),٦j؊)iC?"׃Q^bqpY,sUl1FoǪ:tƫt^\o5u&'HB,ꪘ?jѧ*t[/QԻ[&.L/ǣPn,>`$Ba*amkSFGV&4|ܨҤD#CE~|x N*v;(el`VREykCbu$ ָս!uPqz/$%ftAZ֪^}FoM1GS桚+>//kK4}hw,GXEfdRWɌ1z*]Us+TGyܶ4' `9-jR5,f8Usp .¥q-(#zL=q0j]zLF{Y\"Qtf~b H&b`n4 >a])?Pu4N8#ʦ}'T[0׉JIx* +IApϮyBx +QrXr ]x[QͭҥxUJVaaץʼ3x?F҄wعmcp \ _\jswEAtEdbd{i4gbwEOJǮOpx +:tw1=;H7hQ_s1] }w~F譧Qp9aGT) A-? KKR(>;|{Q3m4!u/A_D_WьɹȂ}5-{<,&=;T[GcC؊ ӸWj}_7we@ cP=B+hK?!ӆ`b8]9r&g u4qG5/M!NӢ4Ϊ"| MtqzqS+HͬhJ*s?Oz[X]$6Oc^×:AM#@}gMbDm;( f}E<uiM|vA‚Bև(=B[T5 X~LP=@=L?t~H`>әEwAާzc~A)6<c΁H^q=O"ҹ+N{#䍩\0nx8Ab'MGa dDe /,s"}5,#;#1&$dԐCn*4XV*֡9eB7-f\ [fBƘޒ[ r2ȀLbLԾ SAm(1b$>LG% x1ĒJ!nNy _f_j|%j%̃9FՐfK-o]:!2D˩@P{A`R,LŢzHÃAZv/xphl(7"af|`P- +ֳ!)p3l}ßĬlt<:%0(twN/otWXj7YD7YͽLnfrs?}+[Л7NN[&v\7n$*t 5Ae:q!@\BO 0̎DGy܎fx[?==n@1mVPnEfuwDD\3q(33 NyW_#[r'GJvdKyKTT:C߇T3T!TQpTaHyȕZqT[Mڝ?lNВ Psqb>_S "FyXԸ`>[l3/blJ)͔z'~miMdzz? ##dJSW7| +J,0n KU)\=tįqßK~AeCD9n:]mw +;B.ÝJ^y{Aj@|B{KfW57a3o]m=Jyhm +m) $@`**d$6 Rn8]Vqꗍg~)<]UAd梬$S%O($ !UdiSz³.:sbiS0}⦍M{È-"z{ rqm%ڐE=tuvSv 29eT]+[<@:, HQ8qd|I9Uқ +copql_ +8t;]E >fpiyZOW<^S$}{u_\|Nsu]\K`cue<ȽxP̧:aG=N]#!q>/CPB8O6xי~ޗ/cIxeϡʪNG*kp?꼺Q_s}'^WB/@WzO/C}يwz[ֱ=^VkEzqxM/C)Sˮvel--rGǍIi+Sxޔ8ۈ^OKCuCXi٠Qr}αZxu_!RDwªmשpr].% *$Z:x)k+1y`Ӛn^8\сŇ4)94Ǩef{*\0UW%G=DMXoM2~)<_rwbל+L?4x04q;~wo?XCT_bNOKA q5 }y5_BKsoJs_+񞫄[zKYBVyY"VwxS\}g:XJ\%䃟]DRNUc<9_9BbxȁN!7:dU.jopCɑ;2"ZV]N`ޛ>Y7"}j:ZպLu}d|b_hJ隀'ٍZ"/F{#B9~ʅN<{Lpe7xsI#6M ;| }6jZ~/dt6t[Y]1Uw@߽xolƇx y9/1#6.$3 +pTK3.0ps7G&D(:~EiP.bڑrM2qtc&_H/f19_.4{z4 fj&P^>Rk^)U; ,o~+T$3$9fԺ~t3}z~)ٵU7F3R@>"Pb e.>Ѓs]{.GxIi[4.Vd`u_ٶ/[ʹ-[a~HN+ -|`~N/C"j d WjvWY2f"S*׎׹yGd$k4+poP(6mI%NГ}QU4bGa7>griou1P:WaY$^4TR|ֶ ,I[{#{}Gi_V}Z03\n+;}7WFn5,[آuݡ zw<ڡFW/I#m˾ʻS|^DL*]@cd/4W0~D#K]IpmP{D?,(^vij*.?P6Av߭d0J[Y]{ d X?6dELsϲv'5K;f̝DW({+/a4?;Ú>/|$!^'2x~G̒\=b-}hD6~ +~֯Ljz+x_(=T?ү7uM/pI ĚpXGכwSߘiq;},+m_M^wc}a{7\.oGTf !PO׷ࣹ$'[$|pϛ +Sy  Z~,#$-CCIޘrZ__jk{D06 }O`ps7==jܐwCtwAD KmȾw_w*ɿ6{8Ypxu$ޢ^X'AC/Q_~;YoR_kM)؋Se7κau-+H _hI2 0 )~IR[ =0ٓ<^]ͽt)(7tWNOpҋ,װ7{E{ǨVD6aZA@A;ܟμ@"wU7y5GL<*?,$e"ZrCo]9GR[;/Q >&yqYϏ͌#?HT$ƯOk;Co]*Li M ~?vMӵMs_|0oĤ$LA]'c׫>zpm/Ae TבξWwNtZOL|yku/V˥G{Z<6iAEj/J9ޅudh{?5]W"}1, +"k8WHׂRU3Bg_4-+^eHWiܟx+"WMeûQ_t|iPB'KYBjzxy rR޴1{"EfӃV0a$h{9+)qRW➗u_9h5bG qLPW@5mG\j@!c|@[2ױ ;vS<Ѯ f,Ƨh&,F-ei4<4W[K,/1nh+G١܅K;>'2|bJA]XmKOxj4 +,FR@!H;!= vȘ ٫@P +̎TIّce7+ Ӂ@ʁ>07cB;Sَ̖gy㉗c!}ycImƀAr oL: z˄[@mտ2v@Ii/ ^Aw>Rg=eaąw4GzmurûKN X'}d#`'*STt/@Qcr14J01Ut cK莈?ask$N< b8ƵM ݅z`N2))oϤM4X։J/^fT~Gs%$)o"62aMdRbuBt$;,ә>BtZW?kjHo@+ ډO5d@6 sƠȢGVuKo舩sYfH86X: ^I]pI n O;,rzCgG;ҺXbD%{tKg{z!: H{6Ar>^]\CO~b_!ͲWF-E$;iH&$M +L](^nW[z#$N_T0 |a3vF"$p߫{|IgY+\P@Ns&j.$|1T_&;YVN9 2_E!(̄qnmvxtظzg:IGN?T]I}]DԔw +zIC]<#Et}G)V}LVF#ZR,[RS3|\$4#|~IKҁ䪉ʎP>gd_w׼o^`8 +} -oj +,wRwƇ +flx9) ?"$d#=";t ` Di>>ld}6dX^ Z%8GgYr(4 #5Deogw -7 gßalB!6$gO*'>7"R*^ Yp 2A ;~3ChJs]v -;ĉ(t@",ryy7DR}svWg*'v/F$-jps-Ɣs9>ECƆĉH7ې +6iܹ21;r_zq:ah {wͅa|$9 pǝlVupz--0a2 a\jǿa`Xebj3d26 ^ۖ/ fkjwXo8@ Fz74Vh*˔~0Dlp#|v3qF%ɂifb'jiG!5>rخ](]+$HD2l1;Y(ĭN@DѾŇR%5Gj6M‰#d\`1R7`؟@8>Pv%:wPB8tM*oQbeME9^鷗ǣNTIz9Ygg$fJ֣aVT/4qԿjaI} +|5gT-OiNZ9ٴ_H: m:"O&s+iHv`a;՚Dp$Eb]5ņ c"g例 CcS?)F/ʳsbO(\_ኢM;MDgb-AFh + UI4DrvnE]VY5k:" +29H]L~7?s"I/ϲfBٽ>Qf{\֡gVB $}H:"&<,/nMRoŀK{a> !xr务&yG)B s0}Uex`FB/YŴa6w_W5["usWD>Iha%!b77}*w?8:JSUU*Ϩg*#1Xސۗ/헧dJ$jQЈ:<-Z ǜs~i "H1gd2 {qşf~^YlUi3QJOVzU7$co jPEI'Ə+)vVUqܽa+9 ެ>8#5s9O]z?bn'ZSx,4LH9a;~.HΗ3 +^1AV@1+`. `X.ڝ~ /!C *KDR̲@-R%rM,le-B؏ ȄE_ DPj)ۧPq >X&ɴ(Z;qx먷 H;y] ?G3'@ԞXMx?W϶-9V{'c +DPn4@5$&`Od>R"Ų _ب٦ѥ_ @zQy^aS5 >/PDſ' j-8QzT 9ٯU' ARaE3kވ : f)j:l>~ 2H`e@0bpIlE5C XV8?޵_\[Y 771p%k8@P,n% (dC*@ 3 :r&=wฎe cj2fDy7qFO{!*!PV>eP}I 4ˇX!$]lZڳY:PƔ+}RZ / M9qcyh;f;\>SYЊV)T|BP);vCl*6xot8zXgɹHoټ&HtSt؅;oװYcQAXuet԰. 0x7׹nz!"ɱ`0("7k2#YS7K/ W^@07/e eD3 Z3̔BC+F˸ӚC() kbTҾʎV&&W2u$Մ\qMj@`y,tT=dHcek1koAG{LzjÌZ,c&PVj=: 2|k¸ng(t[/[5t@Q7 ۴Fj}۵_)"@nQ]5\}Fm,jH m ԠR= `XFA/1ƴa5,>:6X,cGo~)3&cchΰiZZ3+fz0>SY\Ise邌3Z`tqY׆{]IJ:MMF&|~y@'z*5D8xpZQL$ƝJh>$`_Zmmnq(@w85 q/n#jq|[l3_5Hҝt  M2fLͅ,b"ɰaGkAZE!9]pxc1 z%$-3k|sd©.i MLIh U3ȏ4I2 +ށH\!jJh7RV*VP̲L01‡;4uB{[2w+;cӾf-Kԥ~Zҡn +F}>aÄFdB8CE@fZq4} 8@6 +ǦvZkO;o 2{\@!?HBR(cy8FmdSe"Y6K} ĝ!RS m 6b!5\ c0RuWwW+o~VhqQcȻېtR%jLuPk6DaVꚍqDu zWE,t؆IX+mEuaMiCdoJi*a]8hƼ KPtysu[:mczqt]rq83gH: vڱ!^L~!a|oUDQ{䏏xoU)*(r;Xf-'ђ|̜:;8lt{_'.iij鞗tHW9tD9Jztұ:j0_&BI4vT4?j\&^ȉnLNY>Te֌($djYaA֯y22~,"t>uo굈/sn4ՃLLɡd#v5kC蕀~j9qBnx-T 椷ݻ -p,;a?uyd,8/+cm4(T@rО[a}4HF7t65% M=zhI3Q,Lnia +&LkR.EkwGqsa;kcncPRւ5Ktւe;zW7{ޙ4 X*ōeHrxG'@ĮV @SVH\PC'JHcx`uVOBxqMN'i!Dy,*:q $$␁F} 5&P;2XHSU3rMOГײwK@. bXoca[s{`dcBf?88?ﱬ lyo$plv=,0/sxWnx-~:Iq\H4$`7)؉d |4[, ;of; J./*bT"%&Ċ_afy 1ćACK\jv>WQͬǰ~hP>(wj | +GaY3 [9i q5sx\W+prD /:\/Ł/đGL@v[RAVW1ͳ Po6 rE| H/WCQYPDJȾ˔tORE˾{7J' l!55Сg\!7/ s2X|!At0gKҫ93.p +3F GMܐEe>ĔۊflFH%WM\Ĵ?"'D>C5$Ery!eZ,$ Y0X6ƫd"`B:q;1`n|v b=uhvm/p6#nȴkd];%UE ;2@xwܳ +@z7v QrmF,`!(*\^b-3HU ̄ZzڡOp #Skk+)Ad-mJ88+;+<$d 3'AX R҃U@!-Xݶz;\u-x{B"ix%S ݙM$opw8p8d5h.OƄ%Ns̰| aGd88A 6+ܝ*Gf;§&&,cE38'a$tTNWHB\5Ez%Y0,|.[IR"51T*r@a4ۜrS/N1}XNn:EK&W_`c~f9wکLuLg΃(4Ht`XfINM~*s%xgB 8B;*qN `ZvP 8 3**ө@[$ɾX&f*6$hxj6!X<D-ZB]_ +gb6@O]E? و2 FkhV0V #X\.xI> V|ly(Yfrճb;r$bn`cOc əcIYrlU؞hnmnx AيaMABC鷺#1aN֛4_KN08'܅7REHB<-Lm!lͮm n4ZԫsCj_4xor8SqH-x0͏Ũ5NٺTZix 4zwbo{Β^Td ً,9fDW6fa= unP֪]aҿ,6 7 V`97<>؀ApVUeЏ?5:Du^QVv[(AZz=;ƂDI C/0vkҨN J'fp4ҎxU iOo+--iAQn`1P\֯$AQ}yGg4^dr +AN߆l zDJ+T~^1j8*|!xR4|,]0+yp䔇'99X U}Hw80ކYefP_a)B4ư H!mz bi&uO4\^X+ā(g;ES8ro&HT?uY1"y)UYZh 7/އ:iuKʤ9﷈U1-rpwå%ã&][J?A˒)qxs11̶8&6']$_FOϊn N4Jy۰LA. MH 9tX{Txe펌+3Kgvb1֕ŃfЅ`.Vag2HoWf*3 : +FMaTRy2^8xV/LLb5M ȴdt Aj UwBv+UO4e ]y洉Q(묥0OS\/,t,rp GEHM F?'uSP>,FdDJ.U=TGOE<'; p϶ՄZqKV +MNX3|f-0D6@(Ʀr$>bb Ȼ?Sii# +Z? +@q+"C:$n)+hO=G5m:8 @إa0d%ٝ3pbl)ŭ1\"#^D>kNC hXN&IDh@iNͲ$b:,"FA`7C0(xC1;_zs.H| h\?$ AnA`Tٞ1Fb-AxCoL>zf-Xzv`τu9gAa[`}[i>nÏQ=كH5p4l^yC.0lfܛ +[vb@+l뾌$ f>8G}+}~Wa|n؆эqiW.#s[K/ 1LfulÖ=ںLPs6,G>N*Ha"!z~+_4l{?R8|\+l2H_Q0҅>3@FJ7⪉N{ѠH,eh+esMG-@* 5&}%Í_jCDB.N ;Z [2Cکք҄wB;x*M%]\_sFAsfW6lU.ո*VS2&S[aS>6P$(ةkKžuV}g$s@7XRv) ;Z [6 wrׅyT ֪Iֳz8_V^3&Wuip}NN?~OlԿ?ߞ]6;8;:ץvi￿o2-[ڿ?=K}_9Osk-ExÆsժ2Xfd܆q)dC7qEϜ +endstream +endobj +337 0 obj +<< +/Filter [/FlateDecode] +/Length 4295 +>> +stream +xڵZm_A}' +ph>~YI8.:\6.wgfyO Ͽ7[\>ͧiY$ǜ> .ś2(ޅz 7,g&Ͱ4vo ͝>;j櫪؏|GT늮O/k#s}J i؏6܏R194CFphіzu'iK5(dp- ~AR~6HZpP!fظ{gaG@=. ~`$ V1y{͹pR +9>Ɛ{ +S}gv^x oI界L6(YvηV("Ƒ<( &QhHvjOXRSsZ z28iqY6sC@а E퀞&;(]I aآ86#)}G砇3@F ԀZI܀8JDVRD'hh >tβ&qHˎ4x"(yxOe+:;"HտvN^[ .⛵wа skNj.,AKuE錸ǥ3M1" +BtJ5s)ѩ: S4f.VRl% $T3cg frPgr)hȹ(28|űZV jkMK-Eq ٱKK)Jh˫Ub ]ei#m-<*,K ptxK-pΉF@WAWOzbqɍVItp.b&Qv"ǦU6U :HsPL90u}%N]Ys|.҆(4X@8O.uK:-BѪ.{,,H~㾠͙sNC̊MeCG)箮nyم{ ;Ȫ3y.)'zl,;PI8JՒ,D1дq7A`N"['\LEԋ jS80sāVMD @ zc6Eq&o$@J/k ۂQiy"PNs [OLk`s  5y\&KaIxc2"UL(yd4M9Q'mRX}'גmBЭ^fœ@2cJ顏h/ḧ́xTOc%vuD]QvBedNrCPsr +8!8h,\?,C)(Iq/@NFq]EQ`j-ƂOٙcpT֊"SiP縐裣Mq) AgL3P@i:fN]csQY<Ǥ жzM<@HCpT)[ĩQⓅM5a!&,TTlJI2/}J "[?Ro tLL+)m¥B-_){{n!2Ga('aMoDjЕ|0d%YIJ% :}x7 #',QX(QDM *jh1׽VQ@WJ+rUO\iܞߛETL,b=ġRKyt~nTHD%6E|YdIe=FRYTJLbc>芧N8*qgsƝxe*3_Ⱥǚt95*ΝT'=`g;8ܡbܗ w/biFljoSN{!Pz_ȸ$Z?%obiFϰDg4M?$#b=؂_] CPNTu֜A~7[zZiz5>Nkp+4{ZuVzm֓/ <3MA0˫`nm`HGc1u7xE}$3u裆j웄׋776Fk9ׯW(ssa}_B jYj-\e.6ן?Pa`Z5YIqGsqY7mnnplV\7aCQmCKMWx]/m(nhwҙկjy:~02a#fw[F&氹?nes#)`Wy۝oWy.%n?a~X +-+s#WZC,ҢpeRosyqe'[ԑ)M.{\ +VA4UPrK24܉ f+^^P#:|A@' rU/!NRB䜂.xvJս`>zj-Mvuq Nֺ-R%\?ͦwi8m]Lcu:1CǶkrOcjyyJyؖR% cy}$v-׉ez,;B/~Zw iN$ $ vHq#Ts{|)D`B<__"eF<+%SU8,e=.XǨ5dВi˴Si?][m$Ьȁ^Q&^ aA__/F~3G@Cgu6?zPtqJ~fWI^W~Hr}A^onMLod#uY6Q-Y^$'|5_]ȩ'r\$+G